Fixed EOL, indent.
This commit is contained in:
@@ -117,10 +117,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
@@ -242,10 +242,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
@@ -327,8 +327,9 @@ static bool cov_send_request(
|
|||||||
value_list[1].next = NULL;
|
value_list[1].next = NULL;
|
||||||
switch (cov_subscription->monitoredObjectIdentifier.type) {
|
switch (cov_subscription->monitoredObjectIdentifier.type) {
|
||||||
case OBJECT_BINARY_INPUT:
|
case OBJECT_BINARY_INPUT:
|
||||||
Binary_Input_Encode_Value_List(cov_subscription->
|
Binary_Input_Encode_Value_List
|
||||||
monitoredObjectIdentifier.instance, &value_list[0]);
|
(cov_subscription->monitoredObjectIdentifier.instance,
|
||||||
|
&value_list[0]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto COV_FAILED;
|
goto COV_FAILED;
|
||||||
@@ -426,8 +427,8 @@ static bool cov_subscribe(
|
|||||||
|
|
||||||
switch (cov_data->monitoredObjectIdentifier.type) {
|
switch (cov_data->monitoredObjectIdentifier.type) {
|
||||||
case OBJECT_BINARY_INPUT:
|
case OBJECT_BINARY_INPUT:
|
||||||
if (Binary_Input_Valid_Instance(cov_data->
|
if (Binary_Input_Valid_Instance
|
||||||
monitoredObjectIdentifier.instance)) {
|
(cov_data->monitoredObjectIdentifier.instance)) {
|
||||||
status =
|
status =
|
||||||
cov_list_subscribe(src, cov_data, error_class, error_code);
|
cov_list_subscribe(src, cov_data, error_class, error_code);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -43,12 +43,12 @@ static char My_Password[32] = "filister";
|
|||||||
void handler_dcc_password_set(
|
void handler_dcc_password_set(
|
||||||
char *new_password)
|
char *new_password)
|
||||||
{
|
{
|
||||||
size_t i = 0; /* loop counter */
|
size_t i = 0; /* loop counter */
|
||||||
|
|
||||||
if (new_password) {
|
if (new_password) {
|
||||||
for (i = 0; i < (sizeof(My_Password)-1); i++) {
|
for (i = 0; i < (sizeof(My_Password) - 1); i++) {
|
||||||
My_Password[i] = new_password[i];
|
My_Password[i] = new_password[i];
|
||||||
My_Password[i+1] = 0;
|
My_Password[i + 1] = 0;
|
||||||
if (new_password[i] == 0) {
|
if (new_password[i] == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,7 @@
|
|||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "getevent.h"
|
#include "getevent.h"
|
||||||
|
|
||||||
static get_event_info_function
|
static get_event_info_function Get_Event_Info[MAX_BACNET_OBJECT_TYPE];
|
||||||
Get_Event_Info[MAX_BACNET_OBJECT_TYPE];
|
|
||||||
|
|
||||||
void handler_get_event_information_set(
|
void handler_get_event_information_set(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
@@ -48,7 +47,7 @@ void handler_get_event_information_set(
|
|||||||
if (object_type < MAX_BACNET_OBJECT_TYPE) {
|
if (object_type < MAX_BACNET_OBJECT_TYPE) {
|
||||||
Get_Event_Info[object_type] = pFunction;
|
Get_Event_Info[object_type] = pFunction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handler_get_event_information(
|
void handler_get_event_information(
|
||||||
uint8_t * service_request,
|
uint8_t * service_request,
|
||||||
@@ -65,7 +64,7 @@ void handler_get_event_information(
|
|||||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
BACNET_ADDRESS my_address;
|
BACNET_ADDRESS my_address;
|
||||||
BACNET_OBJECT_ID object_id;
|
BACNET_OBJECT_ID object_id;
|
||||||
unsigned i = 0, j = 0; /* counter */
|
unsigned i = 0, j = 0; /* counter */
|
||||||
BACNET_GET_EVENT_INFORMATION_DATA getevent_data;
|
BACNET_GET_EVENT_INFORMATION_DATA getevent_data;
|
||||||
int valid_event = 0;
|
int valid_event = 0;
|
||||||
|
|
||||||
@@ -82,15 +81,14 @@ void handler_get_event_information(
|
|||||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
true);
|
true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "GetEventInformation: "
|
fprintf(stderr,
|
||||||
"Segmented message. Sending Abort!\n");
|
"GetEventInformation: " "Segmented message. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
goto GET_EVENT_ABORT;
|
goto GET_EVENT_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = getevent_decode_service_request(
|
len =
|
||||||
service_request,
|
getevent_decode_service_request(service_request, service_len,
|
||||||
service_len,
|
|
||||||
&object_id);
|
&object_id);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
/* bad decoding - send an abort */
|
/* bad decoding - send an abort */
|
||||||
@@ -98,17 +96,17 @@ void handler_get_event_information(
|
|||||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "GetEventInformation: Bad Encoding. Sending Abort!\n");
|
fprintf(stderr,
|
||||||
|
"GetEventInformation: Bad Encoding. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
goto GET_EVENT_ABORT;
|
goto GET_EVENT_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assume that there is an error */
|
/* assume that there is an error */
|
||||||
error = true;
|
error = true;
|
||||||
len = getevent_ack_encode_apdu_init(
|
len =
|
||||||
&Handler_Transmit_Buffer[pdu_len],
|
getevent_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len],
|
||||||
sizeof(Handler_Transmit_Buffer) - pdu_len,
|
sizeof(Handler_Transmit_Buffer) - pdu_len, service_data->invoke_id);
|
||||||
service_data->invoke_id);
|
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
error = true;
|
error = true;
|
||||||
goto GET_EVENT_ERROR;
|
goto GET_EVENT_ERROR;
|
||||||
@@ -117,11 +115,11 @@ void handler_get_event_information(
|
|||||||
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
|
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
|
||||||
if (Get_Event_Info[i]) {
|
if (Get_Event_Info[i]) {
|
||||||
for (j = 0; j < 0xffff; j++) {
|
for (j = 0; j < 0xffff; j++) {
|
||||||
valid_event = Get_Event_Info[i](j, &getevent_data);
|
valid_event = Get_Event_Info[i] (j, &getevent_data);
|
||||||
if (valid_event > 0) {
|
if (valid_event > 0) {
|
||||||
len = getevent_ack_encode_apdu_data(
|
len =
|
||||||
&Handler_Transmit_Buffer[pdu_len],
|
getevent_ack_encode_apdu_data(&Handler_Transmit_Buffer
|
||||||
sizeof(Handler_Transmit_Buffer)-pdu_len,
|
[pdu_len], sizeof(Handler_Transmit_Buffer) - pdu_len,
|
||||||
&getevent_data);
|
&getevent_data);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
error = true;
|
error = true;
|
||||||
@@ -134,10 +132,9 @@ void handler_get_event_information(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
len = getevent_ack_encode_apdu_end(
|
len =
|
||||||
&Handler_Transmit_Buffer[pdu_len],
|
getevent_ack_encode_apdu_end(&Handler_Transmit_Buffer[pdu_len],
|
||||||
sizeof(Handler_Transmit_Buffer)-pdu_len,
|
sizeof(Handler_Transmit_Buffer) - pdu_len, false);
|
||||||
false);
|
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
error = true;
|
error = true;
|
||||||
goto GET_EVENT_ERROR;
|
goto GET_EVENT_ERROR;
|
||||||
@@ -146,7 +143,7 @@ void handler_get_event_information(
|
|||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "GetEventInformation: Sending Ack!\n");
|
fprintf(stderr, "GetEventInformation: Sending Ack!\n");
|
||||||
#endif
|
#endif
|
||||||
GET_EVENT_ERROR:
|
GET_EVENT_ERROR:
|
||||||
if (error) {
|
if (error) {
|
||||||
if (len == -2) {
|
if (len == -2) {
|
||||||
/* BACnet APDU too small to fit data, so proper response is Abort */
|
/* BACnet APDU too small to fit data, so proper response is Abort */
|
||||||
@@ -155,8 +152,8 @@ GET_EVENT_ERROR:
|
|||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "GetEventInformation: "
|
fprintf(stderr,
|
||||||
"Reply too big to fit into APDU!\n");
|
"GetEventInformation: " "Reply too big to fit into APDU!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
len =
|
len =
|
||||||
@@ -168,7 +165,7 @@ GET_EVENT_ERROR:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GET_EVENT_ABORT:
|
GET_EVENT_ABORT:
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
|
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
|
||||||
|
|||||||
+162
-131
@@ -50,99 +50,122 @@
|
|||||||
|
|
||||||
DATABLOCK MyData[MYMAXBLOCK];
|
DATABLOCK MyData[MYMAXBLOCK];
|
||||||
|
|
||||||
uint8_t IOBufferPT[MAX_APDU]; /* Buffer for building response in */
|
uint8_t IOBufferPT[MAX_APDU]; /* Buffer for building response in */
|
||||||
|
|
||||||
void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
|
||||||
|
|
||||||
|
void ProcessPT(
|
||||||
|
BACNET_PRIVATE_TRANSFER_DATA * data)
|
||||||
{
|
{
|
||||||
int iLen; /* Index to current location in data */
|
int iLen; /* Index to current location in data */
|
||||||
char cBlockNumber;
|
char cBlockNumber;
|
||||||
uint32_t ulTemp;
|
uint32_t ulTemp;
|
||||||
int tag_len;
|
int tag_len;
|
||||||
uint8_t tag_number;
|
uint8_t tag_number;
|
||||||
uint32_t len_value_type;
|
uint32_t len_value_type;
|
||||||
BACNET_CHARACTER_STRING bsTemp;
|
BACNET_CHARACTER_STRING bsTemp;
|
||||||
|
|
||||||
iLen = 0;
|
iLen = 0;
|
||||||
|
|
||||||
/* Decode the block number */
|
/* Decode the block number */
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&data->serviceParameters[iLen],
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { /* Bail out early if wrong type */
|
&tag_number, &len_value_type);
|
||||||
data->serviceParametersLen = 0; /* and signal unexpected error */
|
iLen += tag_len;
|
||||||
return;
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { /* Bail out early if wrong type */
|
||||||
}
|
data->serviceParametersLen = 0; /* and signal unexpected error */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, &ulTemp);
|
iLen +=
|
||||||
cBlockNumber = (char)ulTemp;
|
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
|
||||||
if(cBlockNumber < MY_MAX_BLOCK) {
|
&ulTemp);
|
||||||
if(data->serviceNumber == MY_SVC_READ) {
|
cBlockNumber = (char) ulTemp;
|
||||||
/* Read Response is an unsigned int with 0 for success or a non 0 error code */
|
if (cBlockNumber < MY_MAX_BLOCK) {
|
||||||
/* For a successful read the 0 success code is followed by the block number */
|
if (data->serviceNumber == MY_SVC_READ) {
|
||||||
/* and then the block contents which consist of 2 unsigned ints (in 0 to 255 */
|
/* Read Response is an unsigned int with 0 for success or a non 0 error code */
|
||||||
/* range as they are really chars) a single precision real and a string which */
|
/* For a successful read the 0 success code is followed by the block number */
|
||||||
/* will be up to 32 chars + a nul */
|
/* and then the block contents which consist of 2 unsigned ints (in 0 to 255 */
|
||||||
|
/* range as they are really chars) a single precision real and a string which */
|
||||||
|
/* will be up to 32 chars + a nul */
|
||||||
|
|
||||||
iLen = 0;
|
iLen = 0;
|
||||||
|
|
||||||
iLen += encode_application_unsigned(&IOBufferPT[iLen], MY_ERR_OK); /* Signal success */
|
iLen += encode_application_unsigned(&IOBufferPT[iLen], MY_ERR_OK); /* Signal success */
|
||||||
iLen += encode_application_unsigned(&IOBufferPT[iLen], cBlockNumber); /* Followed by the block number */
|
iLen += encode_application_unsigned(&IOBufferPT[iLen], cBlockNumber); /* Followed by the block number */
|
||||||
iLen += encode_application_unsigned(&IOBufferPT[iLen], MyData[cBlockNumber].cMyByte1); /* And Then the block contents */
|
iLen += encode_application_unsigned(&IOBufferPT[iLen], MyData[cBlockNumber].cMyByte1); /* And Then the block contents */
|
||||||
iLen += encode_application_unsigned(&IOBufferPT[iLen], MyData[cBlockNumber].cMyByte2);
|
iLen +=
|
||||||
iLen += encode_application_real(&IOBufferPT[iLen], MyData[cBlockNumber].fMyReal);
|
encode_application_unsigned(&IOBufferPT[iLen],
|
||||||
characterstring_init_ansi(&bsTemp, MyData[cBlockNumber].sMyString);
|
MyData[cBlockNumber].cMyByte2);
|
||||||
iLen += encode_application_character_string(&IOBufferPT[iLen], &bsTemp);
|
iLen +=
|
||||||
}
|
encode_application_real(&IOBufferPT[iLen],
|
||||||
else { /* Write operation */
|
MyData[cBlockNumber].fMyReal);
|
||||||
/* Write block consists of the block number followed by the block contents as */
|
characterstring_init_ansi(&bsTemp, MyData[cBlockNumber].sMyString);
|
||||||
/* described above for the read operation. The returned result is an unsigned */
|
iLen +=
|
||||||
/* response which is 0 for success and a non 0 error code otherwise. */
|
encode_application_character_string(&IOBufferPT[iLen],
|
||||||
|
&bsTemp);
|
||||||
|
} else { /* Write operation */
|
||||||
|
/* Write block consists of the block number followed by the block contents as */
|
||||||
|
/* described above for the read operation. The returned result is an unsigned */
|
||||||
|
/* response which is 0 for success and a non 0 error code otherwise. */
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&data->serviceParameters[iLen],
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
&tag_number, &len_value_type);
|
||||||
data->serviceParametersLen = 0;
|
iLen += tag_len;
|
||||||
return;
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
}
|
data->serviceParametersLen = 0;
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, &ulTemp);
|
return;
|
||||||
MyData[cBlockNumber].cMyByte1 = (char)ulTemp;
|
}
|
||||||
|
iLen +=
|
||||||
|
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
|
||||||
|
&ulTemp);
|
||||||
|
MyData[cBlockNumber].cMyByte1 = (char) ulTemp;
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&data->serviceParameters[iLen],
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
&tag_number, &len_value_type);
|
||||||
data->serviceParametersLen = 0;
|
iLen += tag_len;
|
||||||
return;
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
}
|
data->serviceParametersLen = 0;
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, &ulTemp);
|
return;
|
||||||
MyData[cBlockNumber].cMyByte2 = (char)ulTemp;
|
}
|
||||||
|
iLen +=
|
||||||
|
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
|
||||||
|
&ulTemp);
|
||||||
|
MyData[cBlockNumber].cMyByte2 = (char) ulTemp;
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&data->serviceParameters[iLen],
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_REAL) {
|
&tag_number, &len_value_type);
|
||||||
data->serviceParametersLen = 0;
|
iLen += tag_len;
|
||||||
return;
|
if (tag_number != BACNET_APPLICATION_TAG_REAL) {
|
||||||
}
|
data->serviceParametersLen = 0;
|
||||||
iLen += decode_real(&data->serviceParameters[iLen], &MyData[cBlockNumber].fMyReal);
|
return;
|
||||||
|
}
|
||||||
|
iLen +=
|
||||||
|
decode_real(&data->serviceParameters[iLen],
|
||||||
|
&MyData[cBlockNumber].fMyReal);
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&data->serviceParameters[iLen],
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
&tag_number, &len_value_type);
|
||||||
data->serviceParametersLen = 0;
|
iLen += tag_len;
|
||||||
return;
|
if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
||||||
}
|
data->serviceParametersLen = 0;
|
||||||
decode_character_string(&data->serviceParameters[iLen], len_value_type, &bsTemp);
|
return;
|
||||||
strncpy(MyData[cBlockNumber].sMyString, characterstring_value(&bsTemp), MY_MAX_STR); /* Only copy as much as we can accept */
|
}
|
||||||
MyData[cBlockNumber].sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */
|
decode_character_string(&data->serviceParameters[iLen],
|
||||||
|
len_value_type, &bsTemp);
|
||||||
iLen = encode_application_unsigned(&IOBufferPT[0], MY_ERR_OK); /* Signal success */
|
strncpy(MyData[cBlockNumber].sMyString, characterstring_value(&bsTemp), MY_MAX_STR); /* Only copy as much as we can accept */
|
||||||
}
|
MyData[cBlockNumber].sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */
|
||||||
}
|
|
||||||
else {
|
iLen = encode_application_unsigned(&IOBufferPT[0], MY_ERR_OK); /* Signal success */
|
||||||
iLen = encode_application_unsigned(&IOBufferPT[0], MY_ERR_BAD_INDEX); /* Signal bad index */
|
}
|
||||||
}
|
} else {
|
||||||
data->serviceParametersLen = iLen;
|
iLen = encode_application_unsigned(&IOBufferPT[0], MY_ERR_BAD_INDEX); /* Signal bad index */
|
||||||
data->serviceParameters = IOBufferPT;
|
}
|
||||||
|
data->serviceParametersLen = iLen;
|
||||||
|
data->serviceParameters = IOBufferPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -162,7 +185,7 @@ void handler_conf_private_trans(
|
|||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
||||||
{
|
{
|
||||||
BACNET_PRIVATE_TRANSFER_DATA data;
|
BACNET_PRIVATE_TRANSFER_DATA data;
|
||||||
int len;
|
int len;
|
||||||
int pdu_len;
|
int pdu_len;
|
||||||
bool error;
|
bool error;
|
||||||
@@ -180,76 +203,84 @@ void handler_conf_private_trans(
|
|||||||
error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,"Received Confirmed Private Transfer Request!\n");
|
fprintf(stderr, "Received Confirmed Private Transfer Request!\n");
|
||||||
#endif
|
#endif
|
||||||
/* encode the NPDU portion of the response packet as it will be needed */
|
/* encode the NPDU portion of the response packet as it will be needed */
|
||||||
/* no matter what the outcome. */
|
/* no matter what the outcome. */
|
||||||
|
|
||||||
datalink_get_my_address(&my_address);
|
datalink_get_my_address(&my_address);
|
||||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
|
pdu_len =
|
||||||
|
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
|
||||||
|
&npdu_data);
|
||||||
|
|
||||||
if (service_data->segmented_message)
|
if (service_data->segmented_message) {
|
||||||
{
|
len =
|
||||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
|
true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,"CPT: Segmented Message. Sending Abort!\n");
|
fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
goto CPT_ABORT;
|
goto CPT_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ptransfer_decode_service_request(service_request, service_len, &data);
|
len =
|
||||||
|
ptransfer_decode_service_request(service_request, service_len, &data);
|
||||||
/* bad decoding - send an abort */
|
/* bad decoding - send an abort */
|
||||||
if (len < 0)
|
if (len < 0) {
|
||||||
{
|
len =
|
||||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER, true);
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,"CPT: Bad Encoding. Sending Abort!\n");
|
fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
goto CPT_ABORT;
|
goto CPT_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simple example with service number of 0 for read block and 1 for write block */
|
/* Simple example with service number of 0 for read block and 1 for write block */
|
||||||
/* We also only support our own vendor ID. In theory we could support others */
|
/* We also only support our own vendor ID. In theory we could support others */
|
||||||
/* for compatability purposes but these interfaces are rarely documented... */
|
/* for compatability purposes but these interfaces are rarely documented... */
|
||||||
|
|
||||||
if((data.vendorID == BACNET_VENDOR_ID) && (data.serviceNumber <= MY_SVC_WRITE)){ /* We only try to understand our own IDs and service numbers */
|
if ((data.vendorID == BACNET_VENDOR_ID) && (data.serviceNumber <= MY_SVC_WRITE)) { /* We only try to understand our own IDs and service numbers */
|
||||||
ProcessPT(&data); /* Will either return a result block or an app level status block */
|
ProcessPT(&data); /* Will either return a result block or an app level status block */
|
||||||
if(data.serviceParametersLen == 0){ /* No respopnse means fatal error */
|
if (data.serviceParametersLen == 0) { /* No respopnse means fatal error */
|
||||||
error = true;
|
error = true;
|
||||||
error_class = ERROR_CLASS_SERVICES;
|
error_class = ERROR_CLASS_SERVICES;
|
||||||
error_code = ERROR_CODE_OTHER;
|
error_code = ERROR_CODE_OTHER;
|
||||||
#if PRINT_ENABLED
|
|
||||||
fprintf(stderr,"CPT: Error servicing request!\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
len = ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
|
|
||||||
}
|
|
||||||
else /* Not our vendor ID or bad service parameter */
|
|
||||||
{
|
|
||||||
error = true;
|
|
||||||
error_class = ERROR_CLASS_SERVICES;
|
|
||||||
error_code = ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED;
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,"CPT: Not our Vendor ID or invalid service code!\n");
|
fprintf(stderr, "CPT: Error servicing request!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
len =
|
||||||
|
ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, &data);
|
||||||
|
} else { /* Not our vendor ID or bad service parameter */
|
||||||
|
|
||||||
if (error){
|
error = true;
|
||||||
len = ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, error_class, error_code, &data);
|
error_class = ERROR_CLASS_SERVICES;
|
||||||
}
|
error_code = ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED;
|
||||||
CPT_ABORT:
|
#if PRINT_ENABLED
|
||||||
pdu_len += len;
|
fprintf(stderr, "CPT: Not our Vendor ID or invalid service code!\n");
|
||||||
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
len =
|
||||||
|
ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, error_class, error_code, &data);
|
||||||
|
}
|
||||||
|
CPT_ABORT:
|
||||||
|
pdu_len += len;
|
||||||
|
bytes_sent =
|
||||||
|
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
|
||||||
|
pdu_len);
|
||||||
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (bytes_sent <= 0)
|
if (bytes_sent <= 0) {
|
||||||
{
|
fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
|
||||||
fprintf(stderr,"Failed to send PDU (%s)!\n",
|
}
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,115 +48,132 @@
|
|||||||
extern uint8_t IOBufferPT[300]; /* Somewhere to build the encoded result block for Private Transfers */
|
extern uint8_t IOBufferPT[300]; /* Somewhere to build the encoded result block for Private Transfers */
|
||||||
|
|
||||||
|
|
||||||
void DecodeBlock(char cBlockNum, uint8_t *pData)
|
void DecodeBlock(
|
||||||
|
char cBlockNum,
|
||||||
|
uint8_t * pData)
|
||||||
{
|
{
|
||||||
int iLen;
|
int iLen;
|
||||||
uint32_t ulTemp;
|
uint32_t ulTemp;
|
||||||
int tag_len;
|
int tag_len;
|
||||||
uint8_t tag_number;
|
uint8_t tag_number;
|
||||||
uint32_t len_value_type;
|
uint32_t len_value_type;
|
||||||
BACNET_CHARACTER_STRING bsName;
|
BACNET_CHARACTER_STRING bsName;
|
||||||
DATABLOCK Response;
|
DATABLOCK Response;
|
||||||
|
|
||||||
iLen = 0;
|
iLen = 0;
|
||||||
|
|
||||||
if(cBlockNum >= MY_MAX_BLOCK)
|
if (cBlockNum >= MY_MAX_BLOCK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&pData[iLen], &tag_number,
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
|
&len_value_type);
|
||||||
return;
|
iLen += tag_len;
|
||||||
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
|
||||||
|
return;
|
||||||
|
|
||||||
iLen += decode_unsigned(&pData[iLen], len_value_type, &ulTemp);
|
iLen += decode_unsigned(&pData[iLen], len_value_type, &ulTemp);
|
||||||
Response.cMyByte1 = (char)ulTemp;
|
Response.cMyByte1 = (char) ulTemp;
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&pData[iLen], &tag_number,
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
|
&len_value_type);
|
||||||
return;
|
iLen += tag_len;
|
||||||
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
|
||||||
|
return;
|
||||||
|
|
||||||
iLen += decode_unsigned(&pData[iLen], len_value_type, &ulTemp);
|
iLen += decode_unsigned(&pData[iLen], len_value_type, &ulTemp);
|
||||||
Response.cMyByte2 = (char)ulTemp;
|
Response.cMyByte2 = (char) ulTemp;
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&pData[iLen], &tag_number,
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_REAL)
|
&len_value_type);
|
||||||
return;
|
iLen += tag_len;
|
||||||
|
if (tag_number != BACNET_APPLICATION_TAG_REAL)
|
||||||
|
return;
|
||||||
|
|
||||||
iLen += decode_real(&pData[iLen], &Response.fMyReal);
|
iLen += decode_real(&pData[iLen], &Response.fMyReal);
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&pData[iLen], &tag_number,
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING)
|
&len_value_type);
|
||||||
return;
|
iLen += tag_len;
|
||||||
|
if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING)
|
||||||
|
return;
|
||||||
|
|
||||||
iLen += decode_character_string(&pData[iLen], len_value_type, &bsName);
|
iLen += decode_character_string(&pData[iLen], len_value_type, &bsName);
|
||||||
strncpy(Response.sMyString, characterstring_value(&bsName), MY_MAX_STR);
|
strncpy(Response.sMyString, characterstring_value(&bsName), MY_MAX_STR);
|
||||||
Response.sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */
|
Response.sMyString[MY_MAX_STR] = '\0'; /* Make sure it is nul terminated */
|
||||||
|
|
||||||
printf("Private Transfer Read Block Response\n");
|
printf("Private Transfer Read Block Response\n");
|
||||||
printf("Data Block: %d\n", (int)cBlockNum);
|
printf("Data Block: %d\n", (int) cBlockNum);
|
||||||
printf(" First Byte : %d\n", (int)Response.cMyByte1);
|
printf(" First Byte : %d\n", (int) Response.cMyByte1);
|
||||||
printf(" Second Byte : %d\n", (int)Response.cMyByte2);
|
printf(" Second Byte : %d\n", (int) Response.cMyByte2);
|
||||||
printf(" Real : %f\n", Response.fMyReal);
|
printf(" Real : %f\n", Response.fMyReal);
|
||||||
printf(" String : %s\n\n", Response.sMyString);
|
printf(" String : %s\n\n", Response.sMyString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data)
|
void ProcessPTA(
|
||||||
|
BACNET_PRIVATE_TRANSFER_DATA * data)
|
||||||
{
|
{
|
||||||
int iLen; /* Index to current location in data */
|
int iLen; /* Index to current location in data */
|
||||||
uint32_t uiErrorCode;
|
uint32_t uiErrorCode;
|
||||||
char cBlockNumber;
|
char cBlockNumber;
|
||||||
uint32_t ulTemp;
|
uint32_t ulTemp;
|
||||||
int tag_len;
|
int tag_len;
|
||||||
uint8_t tag_number;
|
uint8_t tag_number;
|
||||||
uint32_t len_value_type;
|
uint32_t len_value_type;
|
||||||
|
|
||||||
iLen = 0;
|
iLen = 0;
|
||||||
|
|
||||||
/* Error code is returned for read and write operations */
|
/* Error code is returned for read and write operations */
|
||||||
|
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&data->serviceParameters[iLen],
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
&tag_number, &len_value_type);
|
||||||
|
iLen += tag_len;
|
||||||
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
printf("CPTA: Bad Encoding!\n");
|
printf("CPTA: Bad Encoding!\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, &uiErrorCode);
|
iLen +=
|
||||||
|
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
|
||||||
|
&uiErrorCode);
|
||||||
|
|
||||||
if(data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be full block of data or error */
|
if (data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be full block of data or error */
|
||||||
/* Decode the error type and if necessary block number and then fetch the info */
|
/* Decode the error type and if necessary block number and then fetch the info */
|
||||||
|
|
||||||
if(uiErrorCode == MY_ERR_OK) {
|
if (uiErrorCode == MY_ERR_OK) {
|
||||||
/* Block Number */
|
/* Block Number */
|
||||||
tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen], &tag_number, &len_value_type);
|
tag_len =
|
||||||
iLen += tag_len;
|
decode_tag_number_and_value(&data->serviceParameters[iLen],
|
||||||
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
&tag_number, &len_value_type);
|
||||||
|
iLen += tag_len;
|
||||||
|
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
printf("CPTA: Bad Encoding!\n");
|
printf("CPTA: Bad Encoding!\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type, &ulTemp);
|
iLen +=
|
||||||
cBlockNumber = (char)ulTemp;
|
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
|
||||||
DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]);
|
&ulTemp);
|
||||||
}
|
cBlockNumber = (char) ulTemp;
|
||||||
else { /* Read error */
|
DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]);
|
||||||
printf("Private Transfer read operation returned error code: %u\n", uiErrorCode);
|
} else { /* Read error */
|
||||||
return;
|
printf("Private Transfer read operation returned error code: %u\n",
|
||||||
}
|
uiErrorCode);
|
||||||
}
|
return;
|
||||||
else { /* Write I/O block - should just be an OK type message */
|
}
|
||||||
printf("Private Transfer write operation returned error code: %u\n", uiErrorCode);
|
} else { /* Write I/O block - should just be an OK type message */
|
||||||
}
|
printf("Private Transfer write operation returned error code: %u\n",
|
||||||
|
uiErrorCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -183,28 +200,27 @@ void handler_conf_private_trans_ack(
|
|||||||
* we were expecting. But this is just to silence some compiler
|
* we were expecting. But this is just to silence some compiler
|
||||||
* warnings from Borland.
|
* warnings from Borland.
|
||||||
*/
|
*/
|
||||||
src = src;
|
src = src;
|
||||||
service_data = service_data;
|
service_data = service_data;
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
|
||||||
len = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
printf("Received Confirmed Private Transfer Ack!\n");
|
printf("Received Confirmed Private Transfer Ack!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
len = ptransfer_decode_service_request(service_request, service_len, &data); /* Same decode for ack as for service request! */
|
len = ptransfer_decode_service_request(service_request, service_len, &data); /* Same decode for ack as for service request! */
|
||||||
if (len < 0)
|
if (len < 0) {
|
||||||
{
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
printf("cpta: Bad Encoding!\n");
|
printf("cpta: Bad Encoding!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessPTA(&data); /* See what to do with the response */
|
ProcessPTA(&data); /* See what to do with the response */
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -223,4 +239,3 @@ void PTErrorHandler(
|
|||||||
Error_Detected = true;
|
Error_Detected = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -39,11 +39,9 @@
|
|||||||
|
|
||||||
static uint8_t Temp_Buf[MAX_APDU] = { 0 };
|
static uint8_t Temp_Buf[MAX_APDU] = { 0 };
|
||||||
|
|
||||||
static read_property_function
|
static read_property_function Read_Property[MAX_BACNET_OBJECT_TYPE];
|
||||||
Read_Property[MAX_BACNET_OBJECT_TYPE];
|
|
||||||
|
|
||||||
static object_valid_instance_function
|
static object_valid_instance_function Valid_Instance[MAX_BACNET_OBJECT_TYPE];
|
||||||
Valid_Instance[MAX_BACNET_OBJECT_TYPE];
|
|
||||||
|
|
||||||
void handler_read_property_object_set(
|
void handler_read_property_object_set(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
@@ -54,7 +52,7 @@ void handler_read_property_object_set(
|
|||||||
Read_Property[object_type] = pFunction1;
|
Read_Property[object_type] = pFunction1;
|
||||||
Valid_Instance[object_type] = pFunction2;
|
Valid_Instance[object_type] = pFunction2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encodes the property APDU and returns the length,
|
/* Encodes the property APDU and returns the length,
|
||||||
or sets the error, and returns -1 */
|
or sets the error, and returns -1 */
|
||||||
@@ -79,11 +77,10 @@ int Encode_Property_APDU(
|
|||||||
object_rp = Read_Property[object_type];
|
object_rp = Read_Property[object_type];
|
||||||
object_valid = Valid_Instance[object_type];
|
object_valid = Valid_Instance[object_type];
|
||||||
}
|
}
|
||||||
if (object_rp && object_valid &&
|
if (object_rp && object_valid && object_valid(object_instance)) {
|
||||||
object_valid(object_instance)) {
|
apdu_len =
|
||||||
apdu_len = object_rp(
|
object_rp(&apdu[0], object_instance, property, array_index,
|
||||||
&apdu[0], object_instance, property,
|
error_class, error_code);
|
||||||
array_index, error_class, error_code);
|
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_OBJECT;
|
*error_class = ERROR_CLASS_OBJECT;
|
||||||
*error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
|
*error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
|
||||||
|
|||||||
@@ -41,9 +41,8 @@
|
|||||||
|
|
||||||
static uint8_t Temp_Buf[MAX_APDU] = { 0 };
|
static uint8_t Temp_Buf[MAX_APDU] = { 0 };
|
||||||
|
|
||||||
static rpm_property_lists_function
|
static rpm_property_lists_function RPM_Lists[MAX_BACNET_OBJECT_TYPE];
|
||||||
RPM_Lists[MAX_BACNET_OBJECT_TYPE];
|
|
||||||
|
|
||||||
struct property_list_t {
|
struct property_list_t {
|
||||||
const int *pList;
|
const int *pList;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
@@ -77,27 +76,25 @@ void handler_read_property_multiple_list_set(
|
|||||||
if (object_type < MAX_BACNET_OBJECT_TYPE) {
|
if (object_type < MAX_BACNET_OBJECT_TYPE) {
|
||||||
RPM_Lists[object_type] = pFunction;
|
RPM_Lists[object_type] = pFunction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for a given object type, returns the special property list */
|
/* for a given object type, returns the special property list */
|
||||||
static void RPM_Property_List(
|
static void RPM_Property_List(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
struct special_property_list_t *pPropertyList)
|
struct special_property_list_t *pPropertyList)
|
||||||
{
|
{
|
||||||
rpm_property_lists_function object_property_list = NULL;
|
rpm_property_lists_function object_property_list = NULL;
|
||||||
pPropertyList->Required.pList = NULL;
|
pPropertyList->Required.pList = NULL;
|
||||||
pPropertyList->Optional.pList = NULL;
|
pPropertyList->Optional.pList = NULL;
|
||||||
pPropertyList->Proprietary.pList = NULL;
|
pPropertyList->Proprietary.pList = NULL;
|
||||||
|
|
||||||
if (object_type < MAX_BACNET_OBJECT_TYPE) {
|
if (object_type < MAX_BACNET_OBJECT_TYPE) {
|
||||||
object_property_list = RPM_Lists[object_type];
|
object_property_list = RPM_Lists[object_type];
|
||||||
}
|
}
|
||||||
if (object_property_list) {
|
if (object_property_list) {
|
||||||
object_property_list(
|
object_property_list(&pPropertyList->Required.pList,
|
||||||
&pPropertyList->Required.pList,
|
&pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList);
|
||||||
&pPropertyList->Optional.pList,
|
}
|
||||||
&pPropertyList->Proprietary.pList);
|
|
||||||
}
|
|
||||||
/* fill the count */
|
/* fill the count */
|
||||||
if (pPropertyList->Required.pList) {
|
if (pPropertyList->Required.pList) {
|
||||||
pPropertyList->Required.count =
|
pPropertyList->Required.count =
|
||||||
|
|||||||
@@ -208,8 +208,8 @@ static void PrintReadPropertyMultipleData(
|
|||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (listOfProperties->propertyIdentifier < 512) {
|
if (listOfProperties->propertyIdentifier < 512) {
|
||||||
fprintf(stdout, " %s: ",
|
fprintf(stdout, " %s: ",
|
||||||
bactext_property_name(
|
bactext_property_name(listOfProperties->
|
||||||
listOfProperties->propertyIdentifier));
|
propertyIdentifier));
|
||||||
} else {
|
} else {
|
||||||
fprintf(stdout, " proprietary %u: ",
|
fprintf(stdout, " proprietary %u: ",
|
||||||
listOfProperties->propertyIdentifier);
|
listOfProperties->propertyIdentifier);
|
||||||
@@ -250,10 +250,10 @@ static void PrintReadPropertyMultipleData(
|
|||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
/* AccessError */
|
/* AccessError */
|
||||||
fprintf(stdout, "BACnet Error: %s: %s\r\n",
|
fprintf(stdout, "BACnet Error: %s: %s\r\n",
|
||||||
bactext_error_class_name((int) listOfProperties->error.
|
bactext_error_class_name((int) listOfProperties->
|
||||||
error_class),
|
error.error_class),
|
||||||
bactext_error_code_name((int) listOfProperties->error.
|
bactext_error_code_name((int) listOfProperties->
|
||||||
error_code));
|
error.error_code));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
listOfProperties = listOfProperties->next;
|
listOfProperties = listOfProperties->next;
|
||||||
|
|||||||
@@ -43,21 +43,21 @@ static uint8_t Temp_Buf[MAX_APDU] = { 0 };
|
|||||||
or sets the error, and returns -1 */
|
or sets the error, and returns -1 */
|
||||||
int Encode_RR_payload(
|
int Encode_RR_payload(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
BACNET_READ_RANGE_DATA *pRequest,
|
BACNET_READ_RANGE_DATA * pRequest,
|
||||||
BACNET_ERROR_CLASS * error_class,
|
BACNET_ERROR_CLASS * error_class,
|
||||||
BACNET_ERROR_CODE * error_code)
|
BACNET_ERROR_CODE * error_code)
|
||||||
{
|
{
|
||||||
int apdu_len = -1;
|
int apdu_len = -1;
|
||||||
|
|
||||||
/* FIXME: Stub function at the moment which just returns something
|
/* FIXME: Stub function at the moment which just returns something
|
||||||
* for the sake of testing things out. Need to look at existing objects
|
* for the sake of testing things out. Need to look at existing objects
|
||||||
* and see how we can do this for real.
|
* and see how we can do this for real.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pRequest->ItemCount = 6;
|
pRequest->ItemCount = 6;
|
||||||
bitstring_init(&pRequest->ResultFlags);
|
bitstring_init(&pRequest->ResultFlags);
|
||||||
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_FIRST_ITEM, true);
|
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_FIRST_ITEM, true);
|
||||||
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_LAST_ITEM, true);
|
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_LAST_ITEM, true);
|
||||||
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, false);
|
bitstring_set_bit(&pRequest->ResultFlags, RESULT_FLAG_MORE_ITEMS, false);
|
||||||
pRequest->FirstSequence = 0;
|
pRequest->FirstSequence = 0;
|
||||||
|
|
||||||
@@ -91,10 +91,15 @@ void handler_read_range(
|
|||||||
/* encode the NPDU portion of the packet */
|
/* encode the NPDU portion of the packet */
|
||||||
datalink_get_my_address(&my_address);
|
datalink_get_my_address(&my_address);
|
||||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
|
pdu_len =
|
||||||
|
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
|
||||||
|
&npdu_data);
|
||||||
if (service_data->segmented_message) {
|
if (service_data->segmented_message) {
|
||||||
/* we don't support segmentation - send an abort */
|
/* we don't support segmentation - send an abort */
|
||||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
len =
|
||||||
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
|
true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "RR: Segmented message. Sending Abort!\n");
|
fprintf(stderr, "RR: Segmented message. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -108,7 +113,9 @@ void handler_read_range(
|
|||||||
#endif
|
#endif
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
/* bad decoding - send an abort */
|
/* bad decoding - send an abort */
|
||||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER, true);
|
len =
|
||||||
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "RR: Bad Encoding. Sending Abort!\n");
|
fprintf(stderr, "RR: Bad Encoding. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -123,7 +130,9 @@ void handler_read_range(
|
|||||||
data.application_data = &Temp_Buf[0];
|
data.application_data = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
len = rr_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
|
len =
|
||||||
|
rr_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "RR: Sending Ack!\n");
|
fprintf(stderr, "RR: Sending Ack!\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -132,12 +141,18 @@ void handler_read_range(
|
|||||||
if (error) {
|
if (error) {
|
||||||
if (len == -2) {
|
if (len == -2) {
|
||||||
/* BACnet APDU too small to fit data, so proper response is Abort */
|
/* BACnet APDU too small to fit data, so proper response is Abort */
|
||||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
len =
|
||||||
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id,
|
||||||
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "RR: Reply too big to fit into APDU!\n");
|
fprintf(stderr, "RR: Reply too big to fit into APDU!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
|
len =
|
||||||
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
|
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
|
error_class, error_code);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "RR: Sending Error!\n");
|
fprintf(stderr, "RR: Sending Error!\n");
|
||||||
#endif
|
#endif
|
||||||
@@ -145,7 +160,9 @@ void handler_read_range(
|
|||||||
}
|
}
|
||||||
RR_ABORT:
|
RR_ABORT:
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
bytes_sent =
|
||||||
|
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
|
||||||
|
pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (bytes_sent <= 0)
|
if (bytes_sent <= 0)
|
||||||
fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
|
fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ static void PrintReadRangeData(
|
|||||||
/* FIXME: what if application_data_len is bigger than 255? */
|
/* FIXME: what if application_data_len is bigger than 255? */
|
||||||
/* value? need to loop until all of the len is gone... */
|
/* value? need to loop until all of the len is gone... */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
len = bacapp_decode_application_data(application_data, (uint8_t) application_data_len, &value);
|
len =
|
||||||
|
bacapp_decode_application_data(application_data,
|
||||||
|
(uint8_t) application_data_len, &value);
|
||||||
if (first_value && (len < application_data_len)) {
|
if (first_value && (len < application_data_len)) {
|
||||||
first_value = false;
|
first_value = false;
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -1,62 +1,61 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
* "Software"), to deal in the Software without restriction, including
|
* "Software"), to deal in the Software without restriction, including
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
* the following conditions:
|
* the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
* in all copies or substantial portions of the Software.
|
* in all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "txbuf.h"
|
#include "txbuf.h"
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
#include "abort.h"
|
#include "abort.h"
|
||||||
#include "ptransfer.h"
|
#include "ptransfer.h"
|
||||||
|
|
||||||
void handler_unconfirmed_private_transfer(
|
void handler_unconfirmed_private_transfer(
|
||||||
uint8_t * service_request,
|
uint8_t * service_request,
|
||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src)
|
BACNET_ADDRESS * src)
|
||||||
{
|
{
|
||||||
BACNET_PRIVATE_TRANSFER_DATA private_data;
|
BACNET_PRIVATE_TRANSFER_DATA private_data;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,"Received Unconfirmed Private Transfer Request!\n");
|
fprintf(stderr, "Received Unconfirmed Private Transfer Request!\n");
|
||||||
#endif
|
#endif
|
||||||
(void) src;
|
(void) src;
|
||||||
len = ptransfer_decode_service_request(
|
len =
|
||||||
service_request, service_len, &private_data);
|
ptransfer_decode_service_request(service_request, service_len,
|
||||||
if (len >= 0) {
|
&private_data);
|
||||||
#if PRINT_ENABLED
|
if (len >= 0) {
|
||||||
fprintf(stderr,
|
#if PRINT_ENABLED
|
||||||
"UnconfirmedPrivateTransfer: "
|
fprintf(stderr,
|
||||||
"vendorID=%u serviceNumber=%u\n",
|
"UnconfirmedPrivateTransfer: " "vendorID=%u serviceNumber=%u\n",
|
||||||
private_data.vendorID, private_data.serviceNumber);
|
private_data.vendorID, private_data.serviceNumber);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,8 @@
|
|||||||
#include "abort.h"
|
#include "abort.h"
|
||||||
#include "wp.h"
|
#include "wp.h"
|
||||||
|
|
||||||
static write_property_function
|
static write_property_function Write_Property[MAX_BACNET_OBJECT_TYPE];
|
||||||
Write_Property[MAX_BACNET_OBJECT_TYPE];
|
|
||||||
|
|
||||||
void handler_write_property_object_set(
|
void handler_write_property_object_set(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
write_property_function pFunction)
|
write_property_function pFunction)
|
||||||
@@ -47,7 +46,7 @@ void handler_write_property_object_set(
|
|||||||
if (object_type < MAX_BACNET_OBJECT_TYPE) {
|
if (object_type < MAX_BACNET_OBJECT_TYPE) {
|
||||||
Write_Property[object_type] = pFunction;
|
Write_Property[object_type] = pFunction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handler_write_property(
|
void handler_write_property(
|
||||||
uint8_t * service_request,
|
uint8_t * service_request,
|
||||||
@@ -87,7 +86,7 @@ void handler_write_property(
|
|||||||
len = wp_decode_service_request(service_request, service_len, &wp_data);
|
len = wp_decode_service_request(service_request, service_len, &wp_data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"WP: type=%u instance=%u property=%u priority=%u index=%d\n",
|
"WP: type=%u instance=%u property=%u priority=%u index=%d\n",
|
||||||
wp_data.object_type, wp_data.object_instance,
|
wp_data.object_type, wp_data.object_instance,
|
||||||
wp_data.object_property, wp_data.priority, wp_data.array_index);
|
wp_data.object_property, wp_data.priority, wp_data.array_index);
|
||||||
|
|||||||
@@ -1,104 +1,102 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
* "Software"), to deal in the Software without restriction, including
|
* "Software"), to deal in the Software without restriction, including
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
* the following conditions:
|
* the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
* in all copies or substantial portions of the Software.
|
* in all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "datalink.h"
|
#include "datalink.h"
|
||||||
#include "tsm.h"
|
#include "tsm.h"
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
#include "txbuf.h"
|
#include "txbuf.h"
|
||||||
|
|
||||||
/* returns the invoke id, 0=unsuccessful */
|
/* returns the invoke id, 0=unsuccessful */
|
||||||
uint8_t Send_CEvent_Notify(
|
uint8_t Send_CEvent_Notify(
|
||||||
uint32_t device_id,
|
uint32_t device_id,
|
||||||
BACNET_EVENT_NOTIFICATION_DATA * data)
|
BACNET_EVENT_NOTIFICATION_DATA * data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
BACNET_ADDRESS my_address;
|
BACNET_ADDRESS my_address;
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
|
|
||||||
if (!dcc_communication_enabled())
|
if (!dcc_communication_enabled())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* is the device bound? */
|
/* is the device bound? */
|
||||||
status = address_get_by_device(device_id, &max_apdu, &dest);
|
status = address_get_by_device(device_id, &max_apdu, &dest);
|
||||||
/* is there a tsm available? */
|
/* is there a tsm available? */
|
||||||
if (status)
|
if (status)
|
||||||
invoke_id = tsm_next_free_invokeID();
|
invoke_id = tsm_next_free_invokeID();
|
||||||
if (invoke_id) {
|
if (invoke_id) {
|
||||||
/* encode the NPDU portion of the packet */
|
/* encode the NPDU portion of the packet */
|
||||||
datalink_get_my_address(&my_address);
|
datalink_get_my_address(&my_address);
|
||||||
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
|
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len =
|
pdu_len =
|
||||||
npdu_encode_pdu(
|
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
|
||||||
&Handler_Transmit_Buffer[0],
|
&npdu_data);
|
||||||
&dest, &my_address,
|
/* encode the APDU portion of the packet */
|
||||||
&npdu_data);
|
len =
|
||||||
/* encode the APDU portion of the packet */
|
cevent_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
len = cevent_notify_encode_apdu(
|
invoke_id, data);
|
||||||
&Handler_Transmit_Buffer[pdu_len], invoke_id, data);
|
pdu_len += len;
|
||||||
pdu_len += len;
|
/* will it fit in the sender?
|
||||||
/* will it fit in the sender?
|
note: if there is a bottleneck router in between
|
||||||
note: if there is a bottleneck router in between
|
us and the destination, we won't know unless
|
||||||
us and the destination, we won't know unless
|
we have a way to check for that and update the
|
||||||
we have a way to check for that and update the
|
max_apdu in the address binding table. */
|
||||||
max_apdu in the address binding table. */
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0],
|
bytes_sent =
|
||||||
(uint16_t) pdu_len);
|
datalink_send_pdu(&dest, &npdu_data,
|
||||||
bytes_sent =
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
datalink_send_pdu(&dest, &npdu_data,
|
#if PRINT_ENABLED
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
if (bytes_sent <= 0) {
|
||||||
#if PRINT_ENABLED
|
fprintf(stderr,
|
||||||
if (bytes_sent <= 0) {
|
"Failed to Send ConfirmedEventNotification Request (%s)!\n",
|
||||||
fprintf(stderr,
|
strerror(errno));
|
||||||
"Failed to Send ConfirmedEventNotification Request (%s)!\n",
|
}
|
||||||
strerror(errno));
|
#endif
|
||||||
}
|
} else {
|
||||||
#endif
|
tsm_free_invoke_id(invoke_id);
|
||||||
} else {
|
invoke_id = 0;
|
||||||
tsm_free_invoke_id(invoke_id);
|
#if PRINT_ENABLED
|
||||||
invoke_id = 0;
|
fprintf(stderr,
|
||||||
#if PRINT_ENABLED
|
"Failed to Send ConfirmedEventNotification Request "
|
||||||
fprintf(stderr,
|
"(exceeds destination maximum APDU)!\n");
|
||||||
"Failed to Send ConfirmedEventNotification Request "
|
#endif
|
||||||
"(exceeds destination maximum APDU)!\n");
|
}
|
||||||
#endif
|
}
|
||||||
}
|
|
||||||
}
|
return invoke_id;
|
||||||
|
}
|
||||||
return invoke_id;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -50,10 +50,8 @@ uint8_t Send_Private_Transfer_Request(
|
|||||||
uint32_t device_id,
|
uint32_t device_id,
|
||||||
uint16_t vendor_id,
|
uint16_t vendor_id,
|
||||||
uint32_t service_number,
|
uint32_t service_number,
|
||||||
char block_number,
|
char block_number,
|
||||||
DATABLOCK *block
|
DATABLOCK * block)
|
||||||
)
|
|
||||||
|
|
||||||
{ /* NULL=optional */
|
{ /* NULL=optional */
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
BACNET_ADDRESS my_address;
|
BACNET_ADDRESS my_address;
|
||||||
@@ -64,9 +62,9 @@ uint8_t Send_Private_Transfer_Request(
|
|||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
static uint8_t pt_req_buffer[300]; /* Somewhere to build the request packet */
|
static uint8_t pt_req_buffer[300]; /* Somewhere to build the request packet */
|
||||||
BACNET_PRIVATE_TRANSFER_DATA pt_block;
|
BACNET_PRIVATE_TRANSFER_DATA pt_block;
|
||||||
BACNET_CHARACTER_STRING bsTemp;
|
BACNET_CHARACTER_STRING bsTemp;
|
||||||
|
|
||||||
/* if we are forbidden to send, don't send! */
|
/* if we are forbidden to send, don't send! */
|
||||||
if (!dcc_communication_enabled())
|
if (!dcc_communication_enabled())
|
||||||
@@ -86,28 +84,32 @@ uint8_t Send_Private_Transfer_Request(
|
|||||||
&npdu_data);
|
&npdu_data);
|
||||||
/* encode the APDU portion of the packet */
|
/* encode the APDU portion of the packet */
|
||||||
|
|
||||||
pt_block.vendorID = vendor_id;
|
pt_block.vendorID = vendor_id;
|
||||||
pt_block.serviceNumber = service_number;
|
pt_block.serviceNumber = service_number;
|
||||||
if(service_number == MY_SVC_READ)
|
if (service_number == MY_SVC_READ) {
|
||||||
{
|
len += encode_application_unsigned(&pt_req_buffer[len], block_number); /* The block number we want to retrieve */
|
||||||
len += encode_application_unsigned(&pt_req_buffer[len], block_number); /* The block number we want to retrieve */
|
} else {
|
||||||
}
|
len += encode_application_unsigned(&pt_req_buffer[len], block_number); /* The block number */
|
||||||
else
|
len += encode_application_unsigned(&pt_req_buffer[len], block->cMyByte1); /* And Then the block contents */
|
||||||
{
|
len +=
|
||||||
len += encode_application_unsigned(&pt_req_buffer[len], block_number); /* The block number */
|
encode_application_unsigned(&pt_req_buffer[len],
|
||||||
len += encode_application_unsigned(&pt_req_buffer[len], block->cMyByte1); /* And Then the block contents */
|
block->cMyByte2);
|
||||||
len += encode_application_unsigned(&pt_req_buffer[len], block->cMyByte2);
|
len +=
|
||||||
len += encode_application_real(&pt_req_buffer[len], block->fMyReal);
|
encode_application_real(&pt_req_buffer[len], block->fMyReal);
|
||||||
characterstring_init_ansi(&bsTemp, block->sMyString);
|
characterstring_init_ansi(&bsTemp, block->sMyString);
|
||||||
len += encode_application_character_string(&pt_req_buffer[len], &bsTemp);
|
len +=
|
||||||
}
|
encode_application_character_string(&pt_req_buffer[len],
|
||||||
|
&bsTemp);
|
||||||
|
}
|
||||||
|
|
||||||
pt_block.serviceParameters = &pt_req_buffer[0];
|
pt_block.serviceParameters = &pt_req_buffer[0];
|
||||||
pt_block.serviceParametersLen = len;
|
pt_block.serviceParametersLen = len;
|
||||||
len = ptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &pt_block);
|
len =
|
||||||
|
ptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
|
||||||
|
&pt_block);
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
|
|
||||||
/* will it fit in the sender?
|
/* will it fit in the sender?
|
||||||
note: if there is a bottleneck router in between
|
note: if there is a bottleneck router in between
|
||||||
us and the destination, we won't know unless
|
us and the destination, we won't know unless
|
||||||
we have a way to check for that and update the
|
we have a way to check for that and update the
|
||||||
|
|||||||
@@ -67,19 +67,23 @@ uint8_t Send_ReadRange_Request(
|
|||||||
/* is there a tsm available? */
|
/* is there a tsm available? */
|
||||||
if (status)
|
if (status)
|
||||||
invoke_id = tsm_next_free_invokeID();
|
invoke_id = tsm_next_free_invokeID();
|
||||||
|
|
||||||
if (invoke_id) {
|
if (invoke_id) {
|
||||||
/* encode the NPDU portion of the packet */
|
/* encode the NPDU portion of the packet */
|
||||||
datalink_get_my_address(&my_address);
|
datalink_get_my_address(&my_address);
|
||||||
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
|
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &npdu_data);
|
pdu_len =
|
||||||
|
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
|
||||||
|
&npdu_data);
|
||||||
|
|
||||||
/* encode the APDU portion of the packet */
|
/* encode the APDU portion of the packet */
|
||||||
len = rr_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, read_access_data);
|
len =
|
||||||
|
rr_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
|
||||||
|
read_access_data);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
/* is it small enough for the the destination to receive?
|
/* is it small enough for the the destination to receive?
|
||||||
note: if there is a bottleneck router in between
|
note: if there is a bottleneck router in between
|
||||||
@@ -87,18 +91,22 @@ uint8_t Send_ReadRange_Request(
|
|||||||
we have a way to check for that and update the
|
we have a way to check for that and update the
|
||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len);
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
bytes_sent = datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
|
||||||
|
bytes_sent =
|
||||||
|
datalink_send_pdu(&dest, &npdu_data,
|
||||||
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (bytes_sent <= 0)
|
if (bytes_sent <= 0)
|
||||||
fprintf(stderr,
|
fprintf(stderr, "Failed to Send ReadRange Request (%s)!\n",
|
||||||
"Failed to Send ReadRange Request (%s)!\n", strerror(errno));
|
strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
tsm_free_invoke_id(invoke_id);
|
tsm_free_invoke_id(invoke_id);
|
||||||
invoke_id = 0;
|
invoke_id = 0;
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Failed to Send ReadRange Request (exceeds destination maximum APDU)!\n");
|
fprintf(stderr,
|
||||||
|
"Failed to Send ReadRange Request (exceeds destination maximum APDU)!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,76 +1,76 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
* "Software"), to deal in the Software without restriction, including
|
* "Software"), to deal in the Software without restriction, including
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
* the following conditions:
|
* the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
* in all copies or substantial portions of the Software.
|
* in all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "txbuf.h"
|
#include "txbuf.h"
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
#include "tsm.h"
|
#include "tsm.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "datalink.h"
|
#include "datalink.h"
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "ptransfer.h"
|
#include "ptransfer.h"
|
||||||
/* some demo stuff needed */
|
/* some demo stuff needed */
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
#include "txbuf.h"
|
#include "txbuf.h"
|
||||||
|
|
||||||
void Send_UnconfirmedPrivateTransfer(
|
void Send_UnconfirmedPrivateTransfer(
|
||||||
BACNET_ADDRESS * dest,
|
BACNET_ADDRESS * dest,
|
||||||
BACNET_PRIVATE_TRANSFER_DATA *private_data)
|
BACNET_PRIVATE_TRANSFER_DATA * private_data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
|
|
||||||
if (!dcc_communication_enabled())
|
if (!dcc_communication_enabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* encode the NPDU portion of the packet */
|
/* encode the NPDU portion of the packet */
|
||||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len =
|
pdu_len =
|
||||||
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, NULL, &npdu_data);
|
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, NULL, &npdu_data);
|
||||||
/* encode the APDU portion of the packet */
|
/* encode the APDU portion of the packet */
|
||||||
len = uptransfer_encode_apdu(
|
len =
|
||||||
&Handler_Transmit_Buffer[pdu_len],
|
uptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
private_data);
|
private_data);
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
|
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
|
||||||
pdu_len);
|
pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (bytes_sent <= 0)
|
if (bytes_sent <= 0)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Failed to Send UnconfirmedPrivateTransfer Request (%s)!\n",
|
"Failed to Send UnconfirmedPrivateTransfer Request (%s)!\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,8 +139,9 @@ uint8_t Send_Write_Property_Request(
|
|||||||
#if PRINT_ENABLED_DEBUG
|
#if PRINT_ENABLED_DEBUG
|
||||||
fprintf(stderr, "WriteProperty service: " "%s tag=%d\n",
|
fprintf(stderr, "WriteProperty service: " "%s tag=%d\n",
|
||||||
(object_value->context_specific ? "context" : "application"),
|
(object_value->context_specific ? "context" : "application"),
|
||||||
(int) (object_value->context_specific ? object_value->
|
(int) (object_value->
|
||||||
context_tag : object_value->tag));
|
context_specific ? object_value->context_tag : object_value->
|
||||||
|
tag));
|
||||||
#endif
|
#endif
|
||||||
len = bacapp_encode_data(&application_data[apdu_len], object_value);
|
len = bacapp_encode_data(&application_data[apdu_len], object_value);
|
||||||
if ((len + apdu_len) < MAX_APDU) {
|
if ((len + apdu_len) < MAX_APDU) {
|
||||||
|
|||||||
@@ -85,10 +85,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
@@ -207,10 +207,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
@@ -286,18 +286,15 @@ uint16_t MSTP_Get_Reply(
|
|||||||
static char Capture_Filename[32] = "mstp_20090123091200.cap";
|
static char Capture_Filename[32] = "mstp_20090123091200.cap";
|
||||||
static FILE *pFile = NULL; /* stream pointer */
|
static FILE *pFile = NULL; /* stream pointer */
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
static HANDLE hPipe = NULL; /* pipe handle */
|
static HANDLE hPipe = NULL; /* pipe handle */
|
||||||
|
|
||||||
static void named_pipe_create(char *name)
|
static void named_pipe_create(
|
||||||
|
char *name)
|
||||||
{
|
{
|
||||||
fprintf(stdout, "mstpcap: Creating Named Pipe \"%s\"\n", name);
|
fprintf(stdout, "mstpcap: Creating Named Pipe \"%s\"\n", name);
|
||||||
hPipe = CreateNamedPipe(
|
hPipe =
|
||||||
name,
|
CreateNamedPipe(name, PIPE_ACCESS_OUTBOUND,
|
||||||
PIPE_ACCESS_OUTBOUND,
|
PIPE_TYPE_MESSAGE | PIPE_WAIT, 1, 65536, 65536, 300, NULL);
|
||||||
PIPE_TYPE_MESSAGE | PIPE_WAIT,
|
|
||||||
1, 65536, 65536,
|
|
||||||
300,
|
|
||||||
NULL);
|
|
||||||
if (hPipe == INVALID_HANDLE_VALUE) {
|
if (hPipe == INVALID_HANDLE_VALUE) {
|
||||||
RS485_Print_Error();
|
RS485_Print_Error();
|
||||||
return;
|
return;
|
||||||
@@ -305,43 +302,48 @@ static void named_pipe_create(char *name)
|
|||||||
ConnectNamedPipe(hPipe, NULL);
|
ConnectNamedPipe(hPipe, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t data_write(const void *ptr, size_t size, size_t nitems)
|
size_t data_write(
|
||||||
|
const void *ptr,
|
||||||
|
size_t size,
|
||||||
|
size_t nitems)
|
||||||
{
|
{
|
||||||
DWORD cbWritten = 0;
|
DWORD cbWritten = 0;
|
||||||
if (hPipe != INVALID_HANDLE_VALUE) {
|
if (hPipe != INVALID_HANDLE_VALUE) {
|
||||||
(void)WriteFile(
|
(void) WriteFile(hPipe, /* handle to pipe */
|
||||||
hPipe, /* handle to pipe */
|
ptr, /* buffer to write from */
|
||||||
ptr, /* buffer to write from */
|
size * nitems, /* number of bytes to write */
|
||||||
size*nitems, /* number of bytes to write */
|
&cbWritten, /* number of bytes written */
|
||||||
&cbWritten, /* number of bytes written */
|
NULL); /* not overlapped I/O */
|
||||||
NULL); /* not overlapped I/O */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fwrite(ptr, size, nitems, pFile);
|
return fwrite(ptr, size, nitems, pFile);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int FD_Pipe = -1;
|
static int FD_Pipe = -1;
|
||||||
static void named_pipe_create(char *name)
|
static void named_pipe_create(
|
||||||
|
char *name)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
rv = mkfifo(name, 0666);
|
rv = mkfifo(name, 0666);
|
||||||
if (( rv == -1) && (errno != EEXIST))
|
if ((rv == -1) && (errno != EEXIST)) {
|
||||||
{
|
perror("Error creating named pipe");
|
||||||
perror("Error creating named pipe");
|
exit(1);
|
||||||
exit(1);
|
}
|
||||||
}
|
FD_Pipe = open(name, O_WRONLY);
|
||||||
FD_Pipe = open(name, O_WRONLY);
|
|
||||||
if (FD_Pipe == -1) {
|
if (FD_Pipe == -1) {
|
||||||
perror("Error connecting to named pipe");
|
perror("Error connecting to named pipe");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t data_write(const void *ptr, size_t size, size_t nitems)
|
size_t data_write(
|
||||||
|
const void *ptr,
|
||||||
|
size_t size,
|
||||||
|
size_t nitems)
|
||||||
{
|
{
|
||||||
ssize_t bytes = 0;
|
ssize_t bytes = 0;
|
||||||
if (FD_Pipe != -1) {
|
if (FD_Pipe != -1) {
|
||||||
bytes = write(FD_Pipe, ptr, size*nitems);
|
bytes = write(FD_Pipe, ptr, size * nitems);
|
||||||
bytes = bytes;
|
bytes = bytes;
|
||||||
}
|
}
|
||||||
return fwrite(ptr, size, nitems, pFile);
|
return fwrite(ptr, size, nitems, pFile);
|
||||||
@@ -455,10 +457,10 @@ static BOOL WINAPI CtrlCHandler(
|
|||||||
DWORD dwCtrlType)
|
DWORD dwCtrlType)
|
||||||
{
|
{
|
||||||
dwCtrlType = dwCtrlType;
|
dwCtrlType = dwCtrlType;
|
||||||
|
|
||||||
if (hPipe) {
|
if (hPipe) {
|
||||||
FlushFileBuffers(hPipe);
|
FlushFileBuffers(hPipe);
|
||||||
DisconnectNamedPipe(hPipe);
|
DisconnectNamedPipe(hPipe);
|
||||||
CloseHandle(hPipe);
|
CloseHandle(hPipe);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|||||||
@@ -217,7 +217,8 @@ int Analog_Input_Encode_Property_APDU(
|
|||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analog_Input_Init(void)
|
void Analog_Input_Init(
|
||||||
|
void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -433,8 +433,8 @@ bool Analog_Output_Write_Property(
|
|||||||
object_index =
|
object_index =
|
||||||
Analog_Output_Instance_To_Index(wp_data->object_instance);
|
Analog_Output_Instance_To_Index(wp_data->object_instance);
|
||||||
status =
|
status =
|
||||||
Analog_Output_Present_Value_Relinquish(wp_data->
|
Analog_Output_Present_Value_Relinquish
|
||||||
object_instance, wp_data->priority);
|
(wp_data->object_instance, wp_data->priority);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
|
|||||||
@@ -463,6 +463,7 @@ bool bacfile_write_stream_data(
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bacfile_init(void)
|
void bacfile_init(
|
||||||
|
void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -364,8 +364,8 @@ bool Binary_Output_Write_Property(
|
|||||||
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
||||||
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
||||||
object_index =
|
object_index =
|
||||||
Binary_Output_Instance_To_Index(wp_data->
|
Binary_Output_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
priority--;
|
priority--;
|
||||||
Binary_Output_Level[object_index][priority] = level;
|
Binary_Output_Level[object_index][priority] = level;
|
||||||
/* Note: you could set the physical output here if we
|
/* Note: you could set the physical output here if we
|
||||||
|
|||||||
@@ -345,8 +345,8 @@ bool Binary_Value_Write_Property(
|
|||||||
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
||||||
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
||||||
object_index =
|
object_index =
|
||||||
Binary_Value_Instance_To_Index(wp_data->
|
Binary_Value_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
priority--;
|
priority--;
|
||||||
Binary_Value_Level[object_index][priority] = level;
|
Binary_Value_Level[object_index][priority] = level;
|
||||||
/* Note: you could set the physical output here if we
|
/* Note: you could set the physical output here if we
|
||||||
|
|||||||
@@ -42,12 +42,10 @@
|
|||||||
#include "bacfile.h" /* object list dependency */
|
#include "bacfile.h" /* object list dependency */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static object_count_function
|
static object_count_function Object_Count[MAX_BACNET_OBJECT_TYPE];
|
||||||
Object_Count[MAX_BACNET_OBJECT_TYPE];
|
static object_index_to_instance_function
|
||||||
static object_index_to_instance_function
|
|
||||||
Object_Index_To_Instance[MAX_BACNET_OBJECT_TYPE];
|
Object_Index_To_Instance[MAX_BACNET_OBJECT_TYPE];
|
||||||
static object_name_function
|
static object_name_function Object_Name[MAX_BACNET_OBJECT_TYPE];
|
||||||
Object_Name[MAX_BACNET_OBJECT_TYPE];
|
|
||||||
|
|
||||||
void Device_Object_Function_Set(
|
void Device_Object_Function_Set(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
@@ -60,7 +58,7 @@ void Device_Object_Function_Set(
|
|||||||
Object_Index_To_Instance[object_type] = index_function;
|
Object_Index_To_Instance[object_type] = index_function;
|
||||||
Object_Name[object_type] = name_function;
|
Object_Name[object_type] = name_function;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Device_Properties_Required[] = {
|
static const int Device_Properties_Required[] = {
|
||||||
@@ -377,11 +375,11 @@ unsigned Device_Object_List_Count(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
unsigned count = 1; /* 1 for the device object */
|
unsigned count = 1; /* 1 for the device object */
|
||||||
unsigned i = 0; /* loop counter */
|
unsigned i = 0; /* loop counter */
|
||||||
|
|
||||||
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
|
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
|
||||||
if (Object_Count[i]) {
|
if (Object_Count[i]) {
|
||||||
count += Object_Count[i]();
|
count += Object_Count[i] ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,18 +394,18 @@ bool Device_Object_List_Identifier(
|
|||||||
bool status = false;
|
bool status = false;
|
||||||
unsigned object_index = 0;
|
unsigned object_index = 0;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
unsigned i = 0; /* loop counter */
|
unsigned i = 0; /* loop counter */
|
||||||
|
|
||||||
if (array_index == 0) {
|
if (array_index == 0) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
/* device object */
|
/* device object */
|
||||||
if (array_index == 1) {
|
if (array_index == 1) {
|
||||||
*object_type = OBJECT_DEVICE;
|
*object_type = OBJECT_DEVICE;
|
||||||
*instance = Object_Instance_Number;
|
*instance = Object_Instance_Number;
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
/* array index starts at 1, and if we are this far,
|
/* array index starts at 1, and if we are this far,
|
||||||
we are not the device object, so array_index must
|
we are not the device object, so array_index must
|
||||||
@@ -417,10 +415,10 @@ bool Device_Object_List_Identifier(
|
|||||||
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
|
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
|
||||||
if (Object_Count[i] && Object_Index_To_Instance[i]) {
|
if (Object_Count[i] && Object_Index_To_Instance[i]) {
|
||||||
object_index -= count;
|
object_index -= count;
|
||||||
count = Object_Count[i]();
|
count = Object_Count[i] ();
|
||||||
if (object_index < count) {
|
if (object_index < count) {
|
||||||
*object_type = i;
|
*object_type = i;
|
||||||
*instance = Object_Index_To_Instance[i](object_index);
|
*instance = Object_Index_To_Instance[i] (object_index);
|
||||||
status = true;
|
status = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -505,7 +503,7 @@ int Device_Encode_Property_APDU(
|
|||||||
int object_type = 0;
|
int object_type = 0;
|
||||||
uint32_t instance = 0;
|
uint32_t instance = 0;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
|
|
||||||
object_instance = object_instance;
|
object_instance = object_instance;
|
||||||
switch (property) {
|
switch (property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
@@ -740,8 +738,8 @@ bool Device_Write_Property(
|
|||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||||
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
(Device_Set_Object_Instance_Number(value.type.
|
||||||
instance))) {
|
Object_Id.instance))) {
|
||||||
/* FIXME: we could send an I-Am broadcast to let the world know */
|
/* FIXME: we could send an I-Am broadcast to let the world know */
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -776,8 +774,8 @@ bool Device_Write_Property(
|
|||||||
case PROP_VENDOR_IDENTIFIER:
|
case PROP_VENDOR_IDENTIFIER:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
/* FIXME: bounds check? */
|
/* FIXME: bounds check? */
|
||||||
Device_Set_Vendor_Identifier((uint16_t) value.type.
|
Device_Set_Vendor_Identifier((uint16_t) value.
|
||||||
Unsigned_Int);
|
type.Unsigned_Int);
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -787,8 +785,8 @@ bool Device_Write_Property(
|
|||||||
case PROP_SYSTEM_STATUS:
|
case PROP_SYSTEM_STATUS:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
|
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
|
||||||
/* FIXME: bounds check? */
|
/* FIXME: bounds check? */
|
||||||
Device_Set_System_Status((BACNET_DEVICE_STATUS) value.type.
|
Device_Set_System_Status((BACNET_DEVICE_STATUS) value.
|
||||||
Enumerated);
|
type.Enumerated);
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -802,8 +800,8 @@ bool Device_Write_Property(
|
|||||||
characterstring_encoding(&value.type.Character_String);
|
characterstring_encoding(&value.type.Character_String);
|
||||||
if (encoding == CHARACTER_ANSI_X34) {
|
if (encoding == CHARACTER_ANSI_X34) {
|
||||||
status =
|
status =
|
||||||
Device_Set_Object_Name(characterstring_value(&value.
|
Device_Set_Object_Name(characterstring_value
|
||||||
type.Character_String),
|
(&value.type.Character_String),
|
||||||
characterstring_length(&value.type.Character_String));
|
characterstring_length(&value.type.Character_String));
|
||||||
if (!status) {
|
if (!status) {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -822,8 +820,8 @@ bool Device_Write_Property(
|
|||||||
case PROP_MAX_INFO_FRAMES:
|
case PROP_MAX_INFO_FRAMES:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
if (value.type.Unsigned_Int <= 255) {
|
if (value.type.Unsigned_Int <= 255) {
|
||||||
dlmstp_set_max_info_frames((uint8_t) value.type.
|
dlmstp_set_max_info_frames((uint8_t) value.
|
||||||
Unsigned_Int);
|
type.Unsigned_Int);
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -859,7 +857,8 @@ bool Device_Write_Property(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device_Init(void)
|
void Device_Init(
|
||||||
|
void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = {
|
|||||||
"dim lights 20%",
|
"dim lights 20%",
|
||||||
"dim lights 30%"
|
"dim lights 30%"
|
||||||
};
|
};
|
||||||
|
|
||||||
static float Shed_Level_Values[MAX_SHED_LEVELS] = {
|
static float Shed_Level_Values[MAX_SHED_LEVELS] = {
|
||||||
90.0,
|
90.0,
|
||||||
80.0,
|
80.0,
|
||||||
|
|||||||
@@ -551,11 +551,11 @@ bool Lighting_Output_Write_Property(
|
|||||||
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
|
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
|
||||||
level = LIGHTING_LEVEL_NULL;
|
level = LIGHTING_LEVEL_NULL;
|
||||||
object_index =
|
object_index =
|
||||||
Lighting_Output_Instance_To_Index(wp_data->
|
Lighting_Output_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
status =
|
status =
|
||||||
Lighting_Output_Present_Value_Relinquish(wp_data->
|
Lighting_Output_Present_Value_Relinquish
|
||||||
object_instance, wp_data->priority);
|
(wp_data->object_instance, wp_data->priority);
|
||||||
if (wp_data->priority == 6) {
|
if (wp_data->priority == 6) {
|
||||||
/* Command priority 6 is reserved for use by Minimum On/Off
|
/* Command priority 6 is reserved for use by Minimum On/Off
|
||||||
algorithm and may not be used for other purposes in any
|
algorithm and may not be used for other purposes in any
|
||||||
@@ -580,8 +580,8 @@ bool Lighting_Output_Write_Property(
|
|||||||
case PROP_OUT_OF_SERVICE:
|
case PROP_OUT_OF_SERVICE:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||||
object_index =
|
object_index =
|
||||||
Lighting_Output_Instance_To_Index(wp_data->
|
Lighting_Output_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
Lighting_Output_Out_Of_Service[object_index] =
|
Lighting_Output_Out_Of_Service[object_index] =
|
||||||
value.type.Boolean;
|
value.type.Boolean;
|
||||||
status = true;
|
status = true;
|
||||||
|
|||||||
@@ -317,8 +317,8 @@ bool Life_Safety_Point_Write_Property(
|
|||||||
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
|
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
|
||||||
if (value.type.Enumerated <= MAX_LIFE_SAFETY_MODE) {
|
if (value.type.Enumerated <= MAX_LIFE_SAFETY_MODE) {
|
||||||
object_index =
|
object_index =
|
||||||
Life_Safety_Point_Instance_To_Index(wp_data->
|
Life_Safety_Point_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
Life_Safety_Point_Mode[object_index] =
|
Life_Safety_Point_Mode[object_index] =
|
||||||
value.type.Enumerated;
|
value.type.Enumerated;
|
||||||
status = true;
|
status = true;
|
||||||
@@ -334,8 +334,8 @@ bool Life_Safety_Point_Write_Property(
|
|||||||
case PROP_OUT_OF_SERVICE:
|
case PROP_OUT_OF_SERVICE:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||||
object_index =
|
object_index =
|
||||||
Life_Safety_Point_Instance_To_Index(wp_data->
|
Life_Safety_Point_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
Life_Safety_Point_Out_Of_Service[object_index] =
|
Life_Safety_Point_Out_Of_Service[object_index] =
|
||||||
value.type.Boolean;
|
value.type.Boolean;
|
||||||
status = true;
|
status = true;
|
||||||
|
|||||||
@@ -44,8 +44,7 @@
|
|||||||
#define MULTISTATE_NUMBER_OF_STATES (254)
|
#define MULTISTATE_NUMBER_OF_STATES (254)
|
||||||
#endif
|
#endif
|
||||||
/* Here is our Present Value */
|
/* Here is our Present Value */
|
||||||
static uint8_t
|
static uint8_t Present_Value[MAX_MULTISTATE_INPUTS];
|
||||||
Present_Value[MAX_MULTISTATE_INPUTS];
|
|
||||||
/* Writable out-of-service allows others to manipulate our Present Value */
|
/* Writable out-of-service allows others to manipulate our Present Value */
|
||||||
static bool Out_Of_Service[MAX_MULTISTATE_INPUTS];
|
static bool Out_Of_Service[MAX_MULTISTATE_INPUTS];
|
||||||
static char Object_Name[MAX_MULTISTATE_INPUTS][64];
|
static char Object_Name[MAX_MULTISTATE_INPUTS][64];
|
||||||
@@ -138,7 +137,7 @@ bool Multistate_Input_Valid_Instance(
|
|||||||
uint32_t object_instance)
|
uint32_t object_instance)
|
||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
|
|
||||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
if (index < MAX_MULTISTATE_INPUTS) {
|
if (index < MAX_MULTISTATE_INPUTS) {
|
||||||
return true;
|
return true;
|
||||||
@@ -167,7 +166,7 @@ bool Multistate_Input_Present_Value_Set(
|
|||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
|
|
||||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
if (index < MAX_MULTISTATE_INPUTS) {
|
if (index < MAX_MULTISTATE_INPUTS) {
|
||||||
if (value < MULTISTATE_NUMBER_OF_STATES) {
|
if (value < MULTISTATE_NUMBER_OF_STATES) {
|
||||||
@@ -175,7 +174,7 @@ bool Multistate_Input_Present_Value_Set(
|
|||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +183,7 @@ char *Multistate_Input_Description(
|
|||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
char *pName = NULL; /* return value */
|
char *pName = NULL; /* return value */
|
||||||
|
|
||||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
if (index < MAX_MULTISTATE_INPUTS) {
|
if (index < MAX_MULTISTATE_INPUTS) {
|
||||||
pName = Object_Description[index];
|
pName = Object_Description[index];
|
||||||
@@ -198,8 +197,8 @@ bool Multistate_Input_Description_Set(
|
|||||||
char *new_name)
|
char *new_name)
|
||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
size_t i = 0; /* loop counter */
|
size_t i = 0; /* loop counter */
|
||||||
bool status = false; /* return value */
|
bool status = false; /* return value */
|
||||||
|
|
||||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
if (index < MAX_MULTISTATE_INPUTS) {
|
if (index < MAX_MULTISTATE_INPUTS) {
|
||||||
@@ -217,7 +216,7 @@ bool Multistate_Input_Description_Set(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +225,7 @@ char *Multistate_Input_Name(
|
|||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
char *pName = NULL; /* return value */
|
char *pName = NULL; /* return value */
|
||||||
|
|
||||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
if (index < MAX_MULTISTATE_INPUTS) {
|
if (index < MAX_MULTISTATE_INPUTS) {
|
||||||
pName = Object_Name[index];
|
pName = Object_Name[index];
|
||||||
@@ -241,9 +240,9 @@ bool Multistate_Input_Name_Set(
|
|||||||
char *new_name)
|
char *new_name)
|
||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
size_t i = 0; /* loop counter */
|
size_t i = 0; /* loop counter */
|
||||||
bool status = false; /* return value */
|
bool status = false; /* return value */
|
||||||
|
|
||||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
if (index < MAX_MULTISTATE_INPUTS) {
|
if (index < MAX_MULTISTATE_INPUTS) {
|
||||||
status = true;
|
status = true;
|
||||||
@@ -271,9 +270,9 @@ char *Multistate_Input_State_Text(
|
|||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
char *pName = NULL; /* return value */
|
char *pName = NULL; /* return value */
|
||||||
|
|
||||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
if ((index < MAX_MULTISTATE_INPUTS) &&
|
if ((index < MAX_MULTISTATE_INPUTS) &&
|
||||||
(state_index < MULTISTATE_NUMBER_OF_STATES)) {
|
(state_index < MULTISTATE_NUMBER_OF_STATES)) {
|
||||||
pName = State_Text[index][state_index];
|
pName = State_Text[index][state_index];
|
||||||
}
|
}
|
||||||
@@ -288,11 +287,11 @@ bool Multistate_Input_State_Text_Set(
|
|||||||
char *new_name)
|
char *new_name)
|
||||||
{
|
{
|
||||||
unsigned index = 0; /* offset from instance lookup */
|
unsigned index = 0; /* offset from instance lookup */
|
||||||
size_t i = 0; /* loop counter */
|
size_t i = 0; /* loop counter */
|
||||||
bool status = false; /* return value */
|
bool status = false; /* return value */
|
||||||
|
|
||||||
index = Multistate_Input_Instance_To_Index(object_instance);
|
index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
if ((index < MAX_MULTISTATE_INPUTS) &&
|
if ((index < MAX_MULTISTATE_INPUTS) &&
|
||||||
(state_index < MULTISTATE_NUMBER_OF_STATES)) {
|
(state_index < MULTISTATE_NUMBER_OF_STATES)) {
|
||||||
status = true;
|
status = true;
|
||||||
if (new_name) {
|
if (new_name) {
|
||||||
@@ -375,8 +374,7 @@ int Multistate_Input_Encode_Property_APDU(
|
|||||||
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
|
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
|
||||||
break;
|
break;
|
||||||
case PROP_OUT_OF_SERVICE:
|
case PROP_OUT_OF_SERVICE:
|
||||||
object_index =
|
object_index = Multistate_Input_Instance_To_Index(object_instance);
|
||||||
Multistate_Input_Instance_To_Index(object_instance);
|
|
||||||
state = Out_Of_Service[object_index];
|
state = Out_Of_Service[object_index];
|
||||||
apdu_len = encode_application_boolean(&apdu[0], state);
|
apdu_len = encode_application_boolean(&apdu[0], state);
|
||||||
break;
|
break;
|
||||||
@@ -388,10 +386,10 @@ int Multistate_Input_Encode_Property_APDU(
|
|||||||
case PROP_STATE_TEXT:
|
case PROP_STATE_TEXT:
|
||||||
if (array_index == 0) {
|
if (array_index == 0) {
|
||||||
/* Array element zero is the number of elements in the array */
|
/* Array element zero is the number of elements in the array */
|
||||||
apdu_len = encode_application_unsigned(&apdu[0],
|
apdu_len =
|
||||||
|
encode_application_unsigned(&apdu[0],
|
||||||
MULTISTATE_NUMBER_OF_STATES);
|
MULTISTATE_NUMBER_OF_STATES);
|
||||||
}
|
} else if (array_index == BACNET_ARRAY_ALL) {
|
||||||
else if (array_index == BACNET_ARRAY_ALL) {
|
|
||||||
/* if no index was specified, then try to encode the entire list */
|
/* if no index was specified, then try to encode the entire list */
|
||||||
/* into one packet. */
|
/* into one packet. */
|
||||||
object_index =
|
object_index =
|
||||||
@@ -400,8 +398,8 @@ int Multistate_Input_Encode_Property_APDU(
|
|||||||
characterstring_init_ansi(&char_string,
|
characterstring_init_ansi(&char_string,
|
||||||
Multistate_Input_State_Text(object_instance, i));
|
Multistate_Input_State_Text(object_instance, i));
|
||||||
/* FIXME: this might go beyond MAX_APDU length! */
|
/* FIXME: this might go beyond MAX_APDU length! */
|
||||||
len = encode_application_character_string(
|
len =
|
||||||
&apdu[apdu_len],
|
encode_application_character_string(&apdu[apdu_len],
|
||||||
&char_string);
|
&char_string);
|
||||||
/* add it if we have room */
|
/* add it if we have room */
|
||||||
if ((apdu_len + len) < MAX_APDU) {
|
if ((apdu_len + len) < MAX_APDU) {
|
||||||
@@ -419,11 +417,10 @@ int Multistate_Input_Encode_Property_APDU(
|
|||||||
if (array_index <= MULTISTATE_NUMBER_OF_STATES) {
|
if (array_index <= MULTISTATE_NUMBER_OF_STATES) {
|
||||||
array_index--;
|
array_index--;
|
||||||
characterstring_init_ansi(&char_string,
|
characterstring_init_ansi(&char_string,
|
||||||
Multistate_Input_State_Text(
|
Multistate_Input_State_Text(object_instance,
|
||||||
object_instance,
|
|
||||||
array_index));
|
array_index));
|
||||||
apdu_len = encode_application_character_string(
|
apdu_len =
|
||||||
&apdu[0],
|
encode_application_character_string(&apdu[0],
|
||||||
&char_string);
|
&char_string);
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -469,9 +466,8 @@ bool Multistate_Input_Write_Property(
|
|||||||
case PROP_PRESENT_VALUE:
|
case PROP_PRESENT_VALUE:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
if (Out_Of_Service[object_index]) {
|
if (Out_Of_Service[object_index]) {
|
||||||
if (Multistate_Input_Present_Value_Set(
|
if (Multistate_Input_Present_Value_Set(wp_data->
|
||||||
wp_data->object_instance,
|
object_instance, value.type.Unsigned_Int)) {
|
||||||
value.type.Unsigned_Int)) {
|
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -489,10 +485,9 @@ bool Multistate_Input_Write_Property(
|
|||||||
case PROP_OUT_OF_SERVICE:
|
case PROP_OUT_OF_SERVICE:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||||
object_index =
|
object_index =
|
||||||
Multistate_Input_Instance_To_Index(wp_data->
|
Multistate_Input_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
Out_Of_Service[object_index] =
|
Out_Of_Service[object_index] = value.type.Boolean;
|
||||||
value.type.Boolean;
|
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -560,5 +555,5 @@ int main(
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* TEST */
|
#endif /* TEST */
|
||||||
|
|||||||
@@ -364,8 +364,8 @@ bool Multistate_Output_Write_Property(
|
|||||||
(value.type.Unsigned_Int <= MULTISTATE_NUMBER_OF_STATES)) {
|
(value.type.Unsigned_Int <= MULTISTATE_NUMBER_OF_STATES)) {
|
||||||
level = value.type.Unsigned_Int;
|
level = value.type.Unsigned_Int;
|
||||||
object_index =
|
object_index =
|
||||||
Multistate_Output_Instance_To_Index(wp_data->
|
Multistate_Output_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
priority--;
|
priority--;
|
||||||
Multistate_Output_Level[object_index][priority] =
|
Multistate_Output_Level[object_index][priority] =
|
||||||
(uint8_t) level;
|
(uint8_t) level;
|
||||||
@@ -388,8 +388,8 @@ bool Multistate_Output_Write_Property(
|
|||||||
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
|
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
|
||||||
level = MULTISTATE_NULL;
|
level = MULTISTATE_NULL;
|
||||||
object_index =
|
object_index =
|
||||||
Multistate_Output_Instance_To_Index(wp_data->
|
Multistate_Output_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
priority = wp_data->priority;
|
priority = wp_data->priority;
|
||||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||||
priority--;
|
priority--;
|
||||||
@@ -414,8 +414,8 @@ bool Multistate_Output_Write_Property(
|
|||||||
case PROP_OUT_OF_SERVICE:
|
case PROP_OUT_OF_SERVICE:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||||
object_index =
|
object_index =
|
||||||
Multistate_Output_Instance_To_Index(wp_data->
|
Multistate_Output_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
Multistate_Output_Out_Of_Service[object_index] =
|
Multistate_Output_Out_Of_Service[object_index] =
|
||||||
value.type.Boolean;
|
value.type.Boolean;
|
||||||
status = true;
|
status = true;
|
||||||
|
|||||||
+176
-162
@@ -63,8 +63,8 @@ uint8_t Send_Private_Transfer_Request(
|
|||||||
uint32_t device_id,
|
uint32_t device_id,
|
||||||
uint16_t vendor_id,
|
uint16_t vendor_id,
|
||||||
uint32_t service_number,
|
uint32_t service_number,
|
||||||
char block_number,
|
char block_number,
|
||||||
DATABLOCK *block);
|
DATABLOCK * block);
|
||||||
|
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* buffer used for receive */
|
||||||
@@ -73,7 +73,7 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
|||||||
/* global variables used in this file */
|
/* global variables used in this file */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
||||||
|
|
||||||
static int Target_Mode = 0;
|
static int Target_Mode = 0;
|
||||||
|
|
||||||
static BACNET_ADDRESS Target_Address;
|
static BACNET_ADDRESS Target_Address;
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
@@ -137,7 +137,7 @@ static void Init_Service_Handlers(
|
|||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
handler_read_property);
|
handler_read_property);
|
||||||
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER,
|
||||||
handler_conf_private_trans);
|
handler_conf_private_trans);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
@@ -146,7 +146,7 @@ static void Init_Service_Handlers(
|
|||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER,
|
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER,
|
||||||
handler_conf_private_trans_ack);
|
handler_conf_private_trans_ack);
|
||||||
|
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
@@ -169,53 +169,54 @@ int main(
|
|||||||
time_t timeout_seconds = 0;
|
time_t timeout_seconds = 0;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
DATABLOCK NewData;
|
DATABLOCK NewData;
|
||||||
int iCount = 0;
|
int iCount = 0;
|
||||||
int iType = 0;
|
int iType = 0;
|
||||||
int iKey;
|
int iKey;
|
||||||
static int iLimit[3] = {7, 11, 7};
|
static int iLimit[3] = { 7, 11, 7 };
|
||||||
|
|
||||||
if (((argc != 2) && (argc != 3)) || ((argc >= 2) && (strcmp(argv[1], "--help") == 0))) {
|
if (((argc != 2) && (argc != 3)) || ((argc >= 2) &&
|
||||||
printf("%s\n",argv[0]);
|
(strcmp(argv[1], "--help") == 0))) {
|
||||||
|
printf("%s\n", argv[0]);
|
||||||
printf("Usage: %s server local-device-instance\r\n or\r\n"
|
printf("Usage: %s server local-device-instance\r\n or\r\n"
|
||||||
" %s remote-device-instance\r\n"
|
" %s remote-device-instance\r\n",
|
||||||
, filename_remove_path(argv[0]), filename_remove_path(argv[0]));
|
filename_remove_path(argv[0]), filename_remove_path(argv[0]));
|
||||||
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
||||||
printf("\r\nServer mode:\r\n\r\n"
|
printf("\r\nServer mode:\r\n\r\n"
|
||||||
"local-device-instance determins the device id of the application\r\n"
|
"local-device-instance determins the device id of the application\r\n"
|
||||||
"when running as the server end of a test set up.\r\n\r\n"
|
"when running as the server end of a test set up.\r\n\r\n"
|
||||||
"Non server:\r\n\r\n"
|
"Non server:\r\n\r\n"
|
||||||
"remote-device-instance indicates the device id of the server\r\n"
|
"remote-device-instance indicates the device id of the server\r\n"
|
||||||
"instance of the application.\r\n"
|
"instance of the application.\r\n"
|
||||||
"The non server application will write a series of blocks to the\r\n"
|
"The non server application will write a series of blocks to the\r\n"
|
||||||
"server and then retrieve them for display locally\r\n"
|
"server and then retrieve them for display locally\r\n"
|
||||||
"First it writes all 8 blocks plus a 9th which should trigger\r\n"
|
"First it writes all 8 blocks plus a 9th which should trigger\r\n"
|
||||||
"an out of range error response. Then it reads all the blocks\r\n"
|
"an out of range error response. Then it reads all the blocks\r\n"
|
||||||
"including the ninth and finally it repeats the read operation\r\n"
|
"including the ninth and finally it repeats the read operation\r\n"
|
||||||
"with some deliberate errors to trigger a nack response\r\n");
|
"with some deliberate errors to trigger a nack response\r\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* decode the command line parameters */
|
/* decode the command line parameters */
|
||||||
if(_stricmp(argv[1], "server") == 0)
|
if (_stricmp(argv[1], "server") == 0)
|
||||||
Target_Mode = 1;
|
Target_Mode = 1;
|
||||||
else
|
else
|
||||||
Target_Mode = 0;
|
Target_Mode = 0;
|
||||||
|
|
||||||
Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);
|
Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);
|
||||||
|
|
||||||
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
||||||
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup my info */
|
/* setup my info */
|
||||||
if(Target_Mode)
|
if (Target_Mode)
|
||||||
Device_Set_Object_Instance_Number(Target_Device_Object_Instance);
|
Device_Set_Object_Instance_Number(Target_Device_Object_Instance);
|
||||||
else
|
else
|
||||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||||
|
|
||||||
address_init();
|
address_init();
|
||||||
Init_Service_Handlers();
|
Init_Service_Handlers();
|
||||||
dlenv_init();
|
dlenv_init();
|
||||||
@@ -223,147 +224,160 @@ int main(
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
|
|
||||||
if(Target_Mode) {
|
if (Target_Mode) {
|
||||||
printf("Entering server mode. press q to quit program\r\n\r\n");
|
printf("Entering server mode. press q to quit program\r\n\r\n");
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
/* increment timer - exit if timed out */
|
|
||||||
current_seconds = time(NULL);
|
|
||||||
if(current_seconds != last_seconds) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns 0 bytes on timeout */
|
for (;;) {
|
||||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
/* increment timer - exit if timed out */
|
||||||
|
current_seconds = time(NULL);
|
||||||
|
if (current_seconds != last_seconds) {
|
||||||
|
}
|
||||||
|
|
||||||
/* process */
|
/* returns 0 bytes on timeout */
|
||||||
if (pdu_len) {
|
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
|
||||||
}
|
|
||||||
/* at least one second has passed */
|
|
||||||
if (current_seconds != last_seconds) {
|
|
||||||
putchar('.'); /* Just to show that time is passing... */
|
|
||||||
last_seconds = current_seconds;
|
|
||||||
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_kbhit()) {
|
|
||||||
iKey = toupper(_getch());
|
|
||||||
if(iKey == 'Q') {
|
|
||||||
printf("\r\nExiting program now\r\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* returns 0 bytes on timeout */
|
/* process */
|
||||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
if (pdu_len) {
|
||||||
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
|
}
|
||||||
|
/* at least one second has passed */
|
||||||
|
if (current_seconds != last_seconds) {
|
||||||
|
putchar('.'); /* Just to show that time is passing... */
|
||||||
|
last_seconds = current_seconds;
|
||||||
|
tsm_timer_milliseconds(((current_seconds -
|
||||||
|
last_seconds) * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
/* process */
|
if (_kbhit()) {
|
||||||
if (pdu_len) {
|
iKey = toupper(_getch());
|
||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
if (iKey == 'Q') {
|
||||||
}
|
printf("\r\nExiting program now\r\n");
|
||||||
/* at least one second has passed */
|
exit(0);
|
||||||
if (current_seconds != last_seconds)
|
}
|
||||||
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
|
}
|
||||||
if (Error_Detected)
|
}
|
||||||
break;
|
} else {
|
||||||
/* 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 (invoke_id == 0) { /* Safe to send a new request */
|
|
||||||
switch(iType) {
|
|
||||||
case 0: /* Write blocks to server */
|
|
||||||
NewData.cMyByte1 = iCount;
|
|
||||||
NewData.cMyByte2 = 255 - iCount;
|
|
||||||
NewData.fMyReal = (float)iCount;
|
|
||||||
strcpy(NewData.sMyString, "Test Data - [x]");
|
|
||||||
NewData.sMyString[13] = 'a' + iCount;
|
|
||||||
printf("Sending block %d\n", iCount);
|
|
||||||
invoke_id = Send_Private_Transfer_Request(Target_Device_Object_Instance, BACNET_VENDOR_ID, 1, iCount, &NewData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: /* Read blocks from server */
|
/* try to bind with the device */
|
||||||
printf("Requesting block %d\n", iCount);
|
found =
|
||||||
invoke_id = Send_Private_Transfer_Request(Target_Device_Object_Instance, BACNET_VENDOR_ID, 0, iCount, &NewData);
|
address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
||||||
break;
|
&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);
|
||||||
|
|
||||||
case 2: /* Generate some error responses */
|
/* returns 0 bytes on timeout */
|
||||||
switch(iCount) {
|
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||||
case 0: /* Bad service number i.e. 2 */
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
case 6:
|
|
||||||
case 8:
|
|
||||||
printf("Requesting block %d with bad service number\n", iCount);
|
|
||||||
invoke_id = Send_Private_Transfer_Request(Target_Device_Object_Instance, BACNET_VENDOR_ID, 2, iCount, &NewData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: /* Bad vendor ID number */
|
/* process */
|
||||||
case 3:
|
if (pdu_len) {
|
||||||
case 5:
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
case 7:
|
}
|
||||||
printf("Requesting block %d with invalid Vendor ID\n", iCount);
|
/* at least one second has passed */
|
||||||
invoke_id = Send_Private_Transfer_Request(Target_Device_Object_Instance, BACNET_VENDOR_ID + 1, 0, iCount, &NewData);
|
if (current_seconds != last_seconds)
|
||||||
break;
|
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 (found) {
|
||||||
|
if (invoke_id == 0) { /* Safe to send a new request */
|
||||||
|
switch (iType) {
|
||||||
|
case 0: /* Write blocks to server */
|
||||||
|
NewData.cMyByte1 = iCount;
|
||||||
|
NewData.cMyByte2 = 255 - iCount;
|
||||||
|
NewData.fMyReal = (float) iCount;
|
||||||
|
strcpy(NewData.sMyString, "Test Data - [x]");
|
||||||
|
NewData.sMyString[13] = 'a' + iCount;
|
||||||
|
printf("Sending block %d\n", iCount);
|
||||||
|
invoke_id =
|
||||||
|
Send_Private_Transfer_Request
|
||||||
|
(Target_Device_Object_Instance,
|
||||||
|
BACNET_VENDOR_ID, 1, iCount, &NewData);
|
||||||
|
break;
|
||||||
|
|
||||||
break;
|
case 1: /* Read blocks from server */
|
||||||
}
|
printf("Requesting block %d\n", iCount);
|
||||||
}
|
invoke_id =
|
||||||
else if (tsm_invoke_id_free(invoke_id)) {
|
Send_Private_Transfer_Request
|
||||||
if(iCount != MY_MAX_BLOCK) {
|
(Target_Device_Object_Instance,
|
||||||
iCount++;
|
BACNET_VENDOR_ID, 0, iCount, &NewData);
|
||||||
invoke_id = 0;
|
break;
|
||||||
}
|
|
||||||
else {
|
|
||||||
iType++;
|
|
||||||
iCount = 0;
|
|
||||||
invoke_id = 0;
|
|
||||||
|
|
||||||
if(iType > 2)
|
case 2: /* Generate some error responses */
|
||||||
break;
|
switch (iCount) {
|
||||||
}
|
case 0: /* Bad service number i.e. 2 */
|
||||||
}
|
case 2:
|
||||||
else if (tsm_invoke_id_failed(invoke_id))
|
case 4:
|
||||||
{
|
case 6:
|
||||||
fprintf(stderr, "\rError: TSM Timeout!\r\n");
|
case 8:
|
||||||
tsm_free_invoke_id(invoke_id);
|
printf
|
||||||
Error_Detected = true;
|
("Requesting block %d with bad service number\n",
|
||||||
/* try again or abort? */
|
iCount);
|
||||||
break;
|
invoke_id =
|
||||||
}
|
Send_Private_Transfer_Request
|
||||||
}
|
(Target_Device_Object_Instance,
|
||||||
else
|
BACNET_VENDOR_ID, 2, iCount, &NewData);
|
||||||
{
|
break;
|
||||||
/* increment timer - exit if timed out */
|
|
||||||
elapsed_seconds += (current_seconds - last_seconds);
|
case 1: /* Bad vendor ID number */
|
||||||
if (elapsed_seconds > timeout_seconds) {
|
case 3:
|
||||||
printf("\rError: APDU Timeout!\r\n");
|
case 5:
|
||||||
Error_Detected = true;
|
case 7:
|
||||||
break;
|
printf
|
||||||
}
|
("Requesting block %d with invalid Vendor ID\n",
|
||||||
}
|
iCount);
|
||||||
/* keep track of time for next check */
|
invoke_id =
|
||||||
last_seconds = current_seconds;
|
Send_Private_Transfer_Request
|
||||||
}
|
(Target_Device_Object_Instance,
|
||||||
}
|
BACNET_VENDOR_ID + 1, 0, iCount,
|
||||||
|
&NewData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (tsm_invoke_id_free(invoke_id)) {
|
||||||
|
if (iCount != MY_MAX_BLOCK) {
|
||||||
|
iCount++;
|
||||||
|
invoke_id = 0;
|
||||||
|
} else {
|
||||||
|
iType++;
|
||||||
|
iCount = 0;
|
||||||
|
invoke_id = 0;
|
||||||
|
|
||||||
|
if (iType > 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (tsm_invoke_id_failed(invoke_id)) {
|
||||||
|
fprintf(stderr, "\rError: TSM Timeout!\r\n");
|
||||||
|
tsm_free_invoke_id(invoke_id);
|
||||||
|
Error_Detected = true;
|
||||||
|
/* try again or abort? */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* increment timer - exit if timed out */
|
||||||
|
elapsed_seconds += (current_seconds - last_seconds);
|
||||||
|
if (elapsed_seconds > timeout_seconds) {
|
||||||
|
printf("\rError: APDU Timeout!\r\n");
|
||||||
|
Error_Detected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* keep track of time for next check */
|
||||||
|
last_seconds = current_seconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Error_Detected)
|
if (Error_Detected)
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -176,10 +176,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
@@ -113,10 +113,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
@@ -111,10 +111,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
+290
-344
@@ -77,8 +77,8 @@ uint8_t Send_Private_Transfer_Request(
|
|||||||
uint32_t device_id,
|
uint32_t device_id,
|
||||||
uint16_t vendor_id,
|
uint16_t vendor_id,
|
||||||
uint32_t service_number,
|
uint32_t service_number,
|
||||||
char block_number,
|
char block_number,
|
||||||
DATABLOCK *block);
|
DATABLOCK * block);
|
||||||
|
|
||||||
|
|
||||||
/* buffer used for receive */
|
/* buffer used for receive */
|
||||||
@@ -87,7 +87,7 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
|||||||
/* global variables used in this file */
|
/* global variables used in this file */
|
||||||
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
|
||||||
|
|
||||||
static int Target_Mode = 0;
|
static int Target_Mode = 0;
|
||||||
|
|
||||||
static BACNET_ADDRESS Target_Address;
|
static BACNET_ADDRESS Target_Address;
|
||||||
static bool Error_Detected = false;
|
static bool Error_Detected = false;
|
||||||
@@ -145,145 +145,81 @@ static void Init_Object(
|
|||||||
object_index_to_instance_function index_function,
|
object_index_to_instance_function index_function,
|
||||||
object_name_function name_function)
|
object_name_function name_function)
|
||||||
{
|
{
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(object_type, rp_function,
|
||||||
object_type,
|
|
||||||
rp_function,
|
|
||||||
object_valid_function);
|
object_valid_function);
|
||||||
handler_write_property_object_set(
|
handler_write_property_object_set(object_type, wp_function);
|
||||||
object_type,
|
handler_read_property_multiple_list_set(object_type, rpm_list_function);
|
||||||
wp_function);
|
Device_Object_Function_Set(object_type, count_function, index_function,
|
||||||
handler_read_property_multiple_list_set(
|
|
||||||
object_type,
|
|
||||||
rpm_list_function);
|
|
||||||
Device_Object_Function_Set(
|
|
||||||
object_type,
|
|
||||||
count_function,
|
|
||||||
index_function,
|
|
||||||
name_function);
|
name_function);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Init_Objects(void)
|
static void Init_Objects(
|
||||||
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_DEVICE, Device_Property_Lists,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number,
|
||||||
Device_Property_Lists,
|
Device_Write_Property, NULL, NULL, NULL);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number,
|
|
||||||
Device_Write_Property,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Analog_Input_Init();
|
Analog_Input_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_INPUT, Analog_Input_Property_Lists,
|
||||||
OBJECT_ANALOG_INPUT,
|
Analog_Input_Encode_Property_APDU, Analog_Input_Valid_Instance, NULL,
|
||||||
Analog_Input_Property_Lists,
|
Analog_Input_Count, Analog_Input_Index_To_Instance, Analog_Input_Name);
|
||||||
Analog_Input_Encode_Property_APDU,
|
|
||||||
Analog_Input_Valid_Instance,
|
|
||||||
NULL,
|
|
||||||
Analog_Input_Count,
|
|
||||||
Analog_Input_Index_To_Instance,
|
|
||||||
Analog_Input_Name);
|
|
||||||
|
|
||||||
Analog_Output_Init();
|
Analog_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_OUTPUT, Analog_Output_Property_Lists,
|
||||||
OBJECT_ANALOG_OUTPUT,
|
Analog_Output_Encode_Property_APDU, Analog_Output_Valid_Instance,
|
||||||
Analog_Output_Property_Lists,
|
Analog_Output_Write_Property, Analog_Output_Count,
|
||||||
Analog_Output_Encode_Property_APDU,
|
Analog_Output_Index_To_Instance, Analog_Output_Name);
|
||||||
Analog_Output_Valid_Instance,
|
|
||||||
Analog_Output_Write_Property,
|
|
||||||
Analog_Output_Count,
|
|
||||||
Analog_Output_Index_To_Instance,
|
|
||||||
Analog_Output_Name);
|
|
||||||
|
|
||||||
Analog_Value_Init();
|
Analog_Value_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_VALUE, Analog_Value_Property_Lists,
|
||||||
OBJECT_ANALOG_VALUE,
|
Analog_Value_Encode_Property_APDU, Analog_Value_Valid_Instance,
|
||||||
Analog_Value_Property_Lists,
|
Analog_Value_Write_Property, Analog_Value_Count,
|
||||||
Analog_Value_Encode_Property_APDU,
|
Analog_Value_Index_To_Instance, Analog_Value_Name);
|
||||||
Analog_Value_Valid_Instance,
|
|
||||||
Analog_Value_Write_Property,
|
|
||||||
Analog_Value_Count,
|
|
||||||
Analog_Value_Index_To_Instance,
|
|
||||||
Analog_Value_Name);
|
|
||||||
|
|
||||||
Binary_Input_Init();
|
Binary_Input_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_INPUT, Binary_Input_Property_Lists,
|
||||||
OBJECT_BINARY_INPUT,
|
Binary_Input_Encode_Property_APDU, Binary_Input_Valid_Instance, NULL,
|
||||||
Binary_Input_Property_Lists,
|
Binary_Input_Count, Binary_Input_Index_To_Instance, Binary_Input_Name);
|
||||||
Binary_Input_Encode_Property_APDU,
|
|
||||||
Binary_Input_Valid_Instance,
|
|
||||||
NULL,
|
|
||||||
Binary_Input_Count,
|
|
||||||
Binary_Input_Index_To_Instance,
|
|
||||||
Binary_Input_Name);
|
|
||||||
|
|
||||||
Binary_Output_Init();
|
Binary_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_OUTPUT, Binary_Output_Property_Lists,
|
||||||
OBJECT_BINARY_OUTPUT,
|
Binary_Output_Encode_Property_APDU, Binary_Output_Valid_Instance,
|
||||||
Binary_Output_Property_Lists,
|
Binary_Output_Write_Property, Binary_Output_Count,
|
||||||
Binary_Output_Encode_Property_APDU,
|
Binary_Output_Index_To_Instance, Binary_Output_Name);
|
||||||
Binary_Output_Valid_Instance,
|
|
||||||
Binary_Output_Write_Property,
|
|
||||||
Binary_Output_Count,
|
|
||||||
Binary_Output_Index_To_Instance,
|
|
||||||
Binary_Output_Name);
|
|
||||||
|
|
||||||
Binary_Value_Init();
|
Binary_Value_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_VALUE, Binary_Value_Property_Lists,
|
||||||
OBJECT_BINARY_VALUE,
|
Binary_Value_Encode_Property_APDU, Binary_Value_Valid_Instance,
|
||||||
Binary_Value_Property_Lists,
|
Binary_Value_Write_Property, Binary_Value_Count,
|
||||||
Binary_Value_Encode_Property_APDU,
|
Binary_Value_Index_To_Instance, Binary_Value_Name);
|
||||||
Binary_Value_Valid_Instance,
|
|
||||||
Binary_Value_Write_Property,
|
|
||||||
Binary_Value_Count,
|
|
||||||
Binary_Value_Index_To_Instance,
|
|
||||||
Binary_Value_Name);
|
|
||||||
|
|
||||||
Life_Safety_Point_Init();
|
Life_Safety_Point_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Property_Lists,
|
||||||
OBJECT_LIFE_SAFETY_POINT,
|
|
||||||
Life_Safety_Point_Property_Lists,
|
|
||||||
Life_Safety_Point_Encode_Property_APDU,
|
Life_Safety_Point_Encode_Property_APDU,
|
||||||
Life_Safety_Point_Valid_Instance,
|
Life_Safety_Point_Valid_Instance, Life_Safety_Point_Write_Property,
|
||||||
Life_Safety_Point_Write_Property,
|
Life_Safety_Point_Count, Life_Safety_Point_Index_To_Instance,
|
||||||
Life_Safety_Point_Count,
|
|
||||||
Life_Safety_Point_Index_To_Instance,
|
|
||||||
Life_Safety_Point_Name);
|
Life_Safety_Point_Name);
|
||||||
|
|
||||||
Load_Control_Init();
|
Load_Control_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_LOAD_CONTROL, Load_Control_Property_Lists,
|
||||||
OBJECT_LOAD_CONTROL,
|
Load_Control_Encode_Property_APDU, Load_Control_Valid_Instance,
|
||||||
Load_Control_Property_Lists,
|
Load_Control_Write_Property, Load_Control_Count,
|
||||||
Load_Control_Encode_Property_APDU,
|
Load_Control_Index_To_Instance, Load_Control_Name);
|
||||||
Load_Control_Valid_Instance,
|
|
||||||
Load_Control_Write_Property,
|
|
||||||
Load_Control_Count,
|
|
||||||
Load_Control_Index_To_Instance,
|
|
||||||
Load_Control_Name);
|
|
||||||
|
|
||||||
Multistate_Output_Init();
|
Multistate_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Property_Lists,
|
||||||
OBJECT_MULTI_STATE_OUTPUT,
|
|
||||||
Multistate_Output_Property_Lists,
|
|
||||||
Multistate_Output_Encode_Property_APDU,
|
Multistate_Output_Encode_Property_APDU,
|
||||||
Multistate_Output_Valid_Instance,
|
Multistate_Output_Valid_Instance, Multistate_Output_Write_Property,
|
||||||
Multistate_Output_Write_Property,
|
Multistate_Output_Count, Multistate_Output_Index_To_Instance,
|
||||||
Multistate_Output_Count,
|
|
||||||
Multistate_Output_Index_To_Instance,
|
|
||||||
Multistate_Output_Name);
|
Multistate_Output_Name);
|
||||||
|
|
||||||
#if defined(BACFILE)
|
#if defined(BACFILE)
|
||||||
bacfile_init();
|
bacfile_init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_FILE, BACfile_Property_Lists,
|
||||||
OBJECT_FILE,
|
bacfile_encode_property_apdu, bacfile_valid_instance,
|
||||||
BACfile_Property_Lists,
|
bacfile_write_property, bacfile_count, bacfile_index_to_instance,
|
||||||
bacfile_encode_property_apdu,
|
|
||||||
bacfile_valid_instance,
|
|
||||||
bacfile_write_property,
|
|
||||||
bacfile_count,
|
|
||||||
bacfile_index_to_instance,
|
|
||||||
bacfile_name);
|
bacfile_name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -305,16 +241,23 @@ static void Init_Service_Handlers(
|
|||||||
apdu_set_unrecognized_service_handler_handler
|
apdu_set_unrecognized_service_handler_handler
|
||||||
(handler_unrecognized_service);
|
(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
handler_read_property);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER, handler_conf_private_trans);
|
handler_read_property_multiple);
|
||||||
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE,
|
||||||
|
handler_read_range);
|
||||||
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER,
|
||||||
|
handler_conf_private_trans);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property_ack);
|
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_RANGE, handler_read_range_ack);
|
handler_read_property_ack);
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER, handler_conf_private_trans_ack);
|
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_RANGE,
|
||||||
|
handler_read_range_ack);
|
||||||
|
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER,
|
||||||
|
handler_conf_private_trans_ack);
|
||||||
|
|
||||||
/* handle any errors coming back */
|
/* handle any errors coming back */
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
|
||||||
apdu_set_error_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER, MyErrorHandler);
|
apdu_set_error_handler(SERVICE_CONFIRMED_PRIVATE_TRANSFER, MyErrorHandler);
|
||||||
apdu_set_abort_handler(MyAbortHandler);
|
apdu_set_abort_handler(MyAbortHandler);
|
||||||
@@ -337,51 +280,52 @@ int main(
|
|||||||
time_t timeout_seconds = 0;
|
time_t timeout_seconds = 0;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
BACNET_READ_RANGE_DATA Request;
|
BACNET_READ_RANGE_DATA Request;
|
||||||
int iCount = 0;
|
int iCount = 0;
|
||||||
int iType = 0;
|
int iType = 0;
|
||||||
int iKey;
|
int iKey;
|
||||||
static int iLimit[3] = {7, 11, 7};
|
static int iLimit[3] = { 7, 11, 7 };
|
||||||
|
|
||||||
if (((argc != 2) && (argc != 3)) || ((argc >= 2) && (strcmp(argv[1], "--help") == 0))) {
|
if (((argc != 2) && (argc != 3)) || ((argc >= 2) &&
|
||||||
printf("%s\n",argv[0]);
|
(strcmp(argv[1], "--help") == 0))) {
|
||||||
|
printf("%s\n", argv[0]);
|
||||||
printf("Usage: %s server local-device-instance\r\n or\r\n"
|
printf("Usage: %s server local-device-instance\r\n or\r\n"
|
||||||
" %s remote-device-instance\r\n"
|
" %s remote-device-instance\r\n"
|
||||||
"--help gives further information\r\n"
|
"--help gives further information\r\n",
|
||||||
, filename_remove_path(argv[0]), filename_remove_path(argv[0]));
|
filename_remove_path(argv[0]), filename_remove_path(argv[0]));
|
||||||
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
||||||
printf("\r\nServer mode:\r\n\r\n"
|
printf("\r\nServer mode:\r\n\r\n"
|
||||||
"<local-device-instance> determins the device id of the application\r\n"
|
"<local-device-instance> determins the device id of the application\r\n"
|
||||||
"when running as the server end of a test set up. The Server simply\r\n"
|
"when running as the server end of a test set up. The Server simply\r\n"
|
||||||
"returns dummy data for each ReadRange request\r\n\r\n"
|
"returns dummy data for each ReadRange request\r\n\r\n"
|
||||||
"Non server:\r\n\r\n"
|
"Non server:\r\n\r\n"
|
||||||
"<remote-device-instance> indicates the device id of the server\r\n"
|
"<remote-device-instance> indicates the device id of the server\r\n"
|
||||||
"instance of the application.\r\n"
|
"instance of the application.\r\n"
|
||||||
"The non server application will send a series of ReadRange requests to the\r\n"
|
"The non server application will send a series of ReadRange requests to the\r\n"
|
||||||
"server with examples of different range types.\r\n");
|
"server with examples of different range types.\r\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* decode the command line parameters */
|
/* decode the command line parameters */
|
||||||
if(_stricmp(argv[1], "server") == 0)
|
if (_stricmp(argv[1], "server") == 0)
|
||||||
Target_Mode = 1;
|
Target_Mode = 1;
|
||||||
else
|
else
|
||||||
Target_Mode = 0;
|
Target_Mode = 0;
|
||||||
|
|
||||||
Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);
|
Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);
|
||||||
|
|
||||||
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
||||||
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
|
||||||
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup my info */
|
/* setup my info */
|
||||||
if(Target_Mode)
|
if (Target_Mode)
|
||||||
Device_Set_Object_Instance_Number(Target_Device_Object_Instance);
|
Device_Set_Object_Instance_Number(Target_Device_Object_Instance);
|
||||||
else
|
else
|
||||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||||
|
|
||||||
Init_Objects();
|
Init_Objects();
|
||||||
address_init();
|
address_init();
|
||||||
Init_Service_Handlers();
|
Init_Service_Handlers();
|
||||||
@@ -390,219 +334,221 @@ int main(
|
|||||||
last_seconds = time(NULL);
|
last_seconds = time(NULL);
|
||||||
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
|
||||||
|
|
||||||
if(Target_Mode) {
|
if (Target_Mode) {
|
||||||
printf("Entering server mode. press q to quit program\r\n\r\n");
|
printf("Entering server mode. press q to quit program\r\n\r\n");
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
/* increment timer - exit if timed out */
|
|
||||||
current_seconds = time(NULL);
|
|
||||||
if(current_seconds != last_seconds) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns 0 bytes on timeout */
|
for (;;) {
|
||||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
/* increment timer - exit if timed out */
|
||||||
|
current_seconds = time(NULL);
|
||||||
|
if (current_seconds != last_seconds) {
|
||||||
|
}
|
||||||
|
|
||||||
/* process */
|
/* returns 0 bytes on timeout */
|
||||||
if (pdu_len) {
|
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
|
||||||
}
|
|
||||||
/* at least one second has passed */
|
|
||||||
if (current_seconds != last_seconds) {
|
|
||||||
putchar('.'); /* Just to show that time is passing... */
|
|
||||||
last_seconds = current_seconds;
|
|
||||||
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
|
|
||||||
address_cache_timer(current_seconds - last_seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_kbhit()) {
|
|
||||||
iKey = toupper(_getch());
|
|
||||||
if(iKey == 'Q') {
|
|
||||||
printf("\r\nExiting program now\r\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* returns 0 bytes on timeout */
|
/* process */
|
||||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
if (pdu_len) {
|
||||||
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
|
}
|
||||||
|
/* at least one second has passed */
|
||||||
|
if (current_seconds != last_seconds) {
|
||||||
|
putchar('.'); /* Just to show that time is passing... */
|
||||||
|
last_seconds = current_seconds;
|
||||||
|
tsm_timer_milliseconds(((current_seconds -
|
||||||
|
last_seconds) * 1000));
|
||||||
|
address_cache_timer(current_seconds - last_seconds);
|
||||||
|
}
|
||||||
|
|
||||||
/* process */
|
if (_kbhit()) {
|
||||||
if (pdu_len) {
|
iKey = toupper(_getch());
|
||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
if (iKey == 'Q') {
|
||||||
}
|
printf("\r\nExiting program now\r\n");
|
||||||
/* at least one second has passed */
|
exit(0);
|
||||||
if (current_seconds != last_seconds) {
|
}
|
||||||
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
|
}
|
||||||
address_cache_timer(current_seconds - last_seconds);
|
}
|
||||||
}
|
} else {
|
||||||
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 (invoke_id == 0) { /* Safe to send a new request */
|
|
||||||
switch(iCount) {
|
|
||||||
case 0:
|
|
||||||
Request.RequestType = RR_BY_POSITION;
|
|
||||||
Request.Range.RefIndex = 20;
|
|
||||||
Request.Count = 30;
|
|
||||||
Request.object_type = OBJECT_ANALOG_INPUT;
|
|
||||||
Request.object_instance = 0;
|
|
||||||
Request.object_property = PROP_PRESENT_VALUE;
|
|
||||||
Request.array_index = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
/* try to bind with the device */
|
||||||
Request.RequestType = RR_BY_SEQUENCE;
|
found =
|
||||||
Request.Range.RefSeqNum = 20;
|
address_bind_request(Target_Device_Object_Instance, &max_apdu,
|
||||||
Request.Count = 30;
|
&Target_Address);
|
||||||
Request.object_type = OBJECT_ANALOG_INPUT;
|
if (!found) {
|
||||||
Request.object_instance = 0;
|
Send_WhoIs(Target_Device_Object_Instance,
|
||||||
Request.object_property = PROP_PRESENT_VALUE;
|
Target_Device_Object_Instance);
|
||||||
Request.array_index = 2;
|
}
|
||||||
break;
|
/* loop forever */
|
||||||
|
for (;;) {
|
||||||
|
/* increment timer - exit if timed out */
|
||||||
|
current_seconds = time(NULL);
|
||||||
|
|
||||||
case 2:
|
/* returns 0 bytes on timeout */
|
||||||
Request.RequestType = RR_BY_TIME;
|
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||||
Request.Range.RefTime.date.year = 2009;
|
|
||||||
Request.Range.RefTime.date.month = 9;
|
|
||||||
Request.Range.RefTime.date.day = 23;
|
|
||||||
Request.Range.RefTime.date.wday = 0xFF; /* Day of week unspecified */
|
|
||||||
Request.Range.RefTime.time.hour = 22;
|
|
||||||
Request.Range.RefTime.time.min = 23;
|
|
||||||
Request.Range.RefTime.time.sec = 24;
|
|
||||||
Request.Range.RefTime.time.hundredths = 0;
|
|
||||||
|
|
||||||
Request.Count = 30;
|
|
||||||
Request.object_type = OBJECT_ANALOG_INPUT;
|
|
||||||
Request.object_instance = 0;
|
|
||||||
Request.object_property = PROP_PRESENT_VALUE;
|
|
||||||
Request.array_index = 3;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
Request.RequestType = RR_BY_POSITION;
|
|
||||||
Request.Range.RefIndex = 20;
|
|
||||||
Request.Count = 30;
|
|
||||||
Request.object_type = OBJECT_ANALOG_INPUT;
|
|
||||||
Request.object_instance = 0;
|
|
||||||
Request.object_property = PROP_PRESENT_VALUE;
|
|
||||||
Request.array_index = BACNET_ARRAY_ALL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
/* process */
|
||||||
Request.RequestType = RR_BY_SEQUENCE;
|
if (pdu_len) {
|
||||||
Request.Range.RefSeqNum = 20;
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
Request.Count = 30;
|
}
|
||||||
Request.object_type = OBJECT_ANALOG_INPUT;
|
/* at least one second has passed */
|
||||||
Request.object_instance = 0;
|
if (current_seconds != last_seconds) {
|
||||||
Request.object_property = PROP_PRESENT_VALUE;
|
tsm_timer_milliseconds(((current_seconds -
|
||||||
Request.array_index = BACNET_ARRAY_ALL;
|
last_seconds) * 1000));
|
||||||
break;
|
address_cache_timer(current_seconds - last_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 (invoke_id == 0) { /* Safe to send a new request */
|
||||||
|
switch (iCount) {
|
||||||
|
case 0:
|
||||||
|
Request.RequestType = RR_BY_POSITION;
|
||||||
|
Request.Range.RefIndex = 20;
|
||||||
|
Request.Count = 30;
|
||||||
|
Request.object_type = OBJECT_ANALOG_INPUT;
|
||||||
|
Request.object_instance = 0;
|
||||||
|
Request.object_property = PROP_PRESENT_VALUE;
|
||||||
|
Request.array_index = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 5:
|
case 1:
|
||||||
Request.RequestType = RR_BY_TIME;
|
Request.RequestType = RR_BY_SEQUENCE;
|
||||||
Request.Range.RefTime.date.year = 2009;
|
Request.Range.RefSeqNum = 20;
|
||||||
Request.Range.RefTime.date.month = 9;
|
Request.Count = 30;
|
||||||
Request.Range.RefTime.date.day = 23;
|
Request.object_type = OBJECT_ANALOG_INPUT;
|
||||||
Request.Range.RefTime.date.wday = 0xFF; /* Day of week unspecified */
|
Request.object_instance = 0;
|
||||||
Request.Range.RefTime.time.hour = 22;
|
Request.object_property = PROP_PRESENT_VALUE;
|
||||||
Request.Range.RefTime.time.min = 23;
|
Request.array_index = 2;
|
||||||
Request.Range.RefTime.time.sec = 24;
|
break;
|
||||||
Request.Range.RefTime.time.hundredths = 0;
|
|
||||||
|
|
||||||
Request.Count = 30;
|
|
||||||
Request.object_type = OBJECT_ANALOG_INPUT;
|
|
||||||
Request.object_instance = 0;
|
|
||||||
Request.object_property = PROP_PRESENT_VALUE;
|
|
||||||
Request.array_index = BACNET_ARRAY_ALL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
case 2:
|
||||||
Request.RequestType = RR_READ_ALL;
|
Request.RequestType = RR_BY_TIME;
|
||||||
Request.Range.RefTime.date.year = 2009;
|
Request.Range.RefTime.date.year = 2009;
|
||||||
Request.Range.RefTime.date.month = 9;
|
Request.Range.RefTime.date.month = 9;
|
||||||
Request.Range.RefTime.date.day = 23;
|
Request.Range.RefTime.date.day = 23;
|
||||||
Request.Range.RefTime.date.wday = 0xFF; /* Day of week unspecified */
|
Request.Range.RefTime.date.wday = 0xFF; /* Day of week unspecified */
|
||||||
Request.Range.RefTime.time.hour = 22;
|
Request.Range.RefTime.time.hour = 22;
|
||||||
Request.Range.RefTime.time.min = 23;
|
Request.Range.RefTime.time.min = 23;
|
||||||
Request.Range.RefTime.time.sec = 24;
|
Request.Range.RefTime.time.sec = 24;
|
||||||
Request.Range.RefTime.time.hundredths = 0;
|
Request.Range.RefTime.time.hundredths = 0;
|
||||||
|
|
||||||
Request.Count = 30;
|
|
||||||
Request.object_type = OBJECT_ANALOG_INPUT;
|
|
||||||
Request.object_instance = 0;
|
|
||||||
Request.object_property = PROP_PRESENT_VALUE;
|
|
||||||
Request.array_index = BACNET_ARRAY_ALL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
Request.Count = 30;
|
||||||
Request.RequestType = RR_READ_ALL;
|
Request.object_type = OBJECT_ANALOG_INPUT;
|
||||||
Request.Range.RefTime.date.year = 2009;
|
Request.object_instance = 0;
|
||||||
Request.Range.RefTime.date.month = 9;
|
Request.object_property = PROP_PRESENT_VALUE;
|
||||||
Request.Range.RefTime.date.day = 23;
|
Request.array_index = 3;
|
||||||
Request.Range.RefTime.date.wday = 0xFF; /* Day of week unspecified */
|
break;
|
||||||
Request.Range.RefTime.time.hour = 22;
|
case 3:
|
||||||
Request.Range.RefTime.time.min = 23;
|
Request.RequestType = RR_BY_POSITION;
|
||||||
Request.Range.RefTime.time.sec = 24;
|
Request.Range.RefIndex = 20;
|
||||||
Request.Range.RefTime.time.hundredths = 0;
|
Request.Count = 30;
|
||||||
|
Request.object_type = OBJECT_ANALOG_INPUT;
|
||||||
Request.Count = 30;
|
Request.object_instance = 0;
|
||||||
Request.object_type = OBJECT_ANALOG_INPUT;
|
Request.object_property = PROP_PRESENT_VALUE;
|
||||||
Request.object_instance = 0;
|
Request.array_index = BACNET_ARRAY_ALL;
|
||||||
Request.object_property = PROP_PRESENT_VALUE;
|
break;
|
||||||
Request.array_index = 7;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
invoke_id = Send_ReadRange_Request( Target_Device_Object_Instance, &Request);
|
case 4:
|
||||||
}
|
Request.RequestType = RR_BY_SEQUENCE;
|
||||||
else if (tsm_invoke_id_free(invoke_id)) {
|
Request.Range.RefSeqNum = 20;
|
||||||
if(iCount != MY_MAX_BLOCK) {
|
Request.Count = 30;
|
||||||
iCount++;
|
Request.object_type = OBJECT_ANALOG_INPUT;
|
||||||
invoke_id = 0;
|
Request.object_instance = 0;
|
||||||
}
|
Request.object_property = PROP_PRESENT_VALUE;
|
||||||
else {
|
Request.array_index = BACNET_ARRAY_ALL;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
case 5:
|
||||||
else if (tsm_invoke_id_failed(invoke_id))
|
Request.RequestType = RR_BY_TIME;
|
||||||
{
|
Request.Range.RefTime.date.year = 2009;
|
||||||
fprintf(stderr, "\rError: TSM Timeout!\r\n");
|
Request.Range.RefTime.date.month = 9;
|
||||||
tsm_free_invoke_id(invoke_id);
|
Request.Range.RefTime.date.day = 23;
|
||||||
/* Error_Detected = true; */
|
Request.Range.RefTime.date.wday = 0xFF; /* Day of week unspecified */
|
||||||
/* try again or abort? */
|
Request.Range.RefTime.time.hour = 22;
|
||||||
invoke_id = 0; /* Try next operation */
|
Request.Range.RefTime.time.min = 23;
|
||||||
|
Request.Range.RefTime.time.sec = 24;
|
||||||
|
Request.Range.RefTime.time.hundredths = 0;
|
||||||
|
|
||||||
|
Request.Count = 30;
|
||||||
|
Request.object_type = OBJECT_ANALOG_INPUT;
|
||||||
|
Request.object_instance = 0;
|
||||||
|
Request.object_property = PROP_PRESENT_VALUE;
|
||||||
|
Request.array_index = BACNET_ARRAY_ALL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
Request.RequestType = RR_READ_ALL;
|
||||||
|
Request.Range.RefTime.date.year = 2009;
|
||||||
|
Request.Range.RefTime.date.month = 9;
|
||||||
|
Request.Range.RefTime.date.day = 23;
|
||||||
|
Request.Range.RefTime.date.wday = 0xFF; /* Day of week unspecified */
|
||||||
|
Request.Range.RefTime.time.hour = 22;
|
||||||
|
Request.Range.RefTime.time.min = 23;
|
||||||
|
Request.Range.RefTime.time.sec = 24;
|
||||||
|
Request.Range.RefTime.time.hundredths = 0;
|
||||||
|
|
||||||
|
Request.Count = 30;
|
||||||
|
Request.object_type = OBJECT_ANALOG_INPUT;
|
||||||
|
Request.object_instance = 0;
|
||||||
|
Request.object_property = PROP_PRESENT_VALUE;
|
||||||
|
Request.array_index = BACNET_ARRAY_ALL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
Request.RequestType = RR_READ_ALL;
|
||||||
|
Request.Range.RefTime.date.year = 2009;
|
||||||
|
Request.Range.RefTime.date.month = 9;
|
||||||
|
Request.Range.RefTime.date.day = 23;
|
||||||
|
Request.Range.RefTime.date.wday = 0xFF; /* Day of week unspecified */
|
||||||
|
Request.Range.RefTime.time.hour = 22;
|
||||||
|
Request.Range.RefTime.time.min = 23;
|
||||||
|
Request.Range.RefTime.time.sec = 24;
|
||||||
|
Request.Range.RefTime.time.hundredths = 0;
|
||||||
|
|
||||||
|
Request.Count = 30;
|
||||||
|
Request.object_type = OBJECT_ANALOG_INPUT;
|
||||||
|
Request.object_instance = 0;
|
||||||
|
Request.object_property = PROP_PRESENT_VALUE;
|
||||||
|
Request.array_index = 7;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
invoke_id =
|
||||||
|
Send_ReadRange_Request(Target_Device_Object_Instance,
|
||||||
|
&Request);
|
||||||
|
} else if (tsm_invoke_id_free(invoke_id)) {
|
||||||
|
if (iCount != MY_MAX_BLOCK) {
|
||||||
|
iCount++;
|
||||||
|
invoke_id = 0;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (tsm_invoke_id_failed(invoke_id)) {
|
||||||
|
fprintf(stderr, "\rError: TSM Timeout!\r\n");
|
||||||
|
tsm_free_invoke_id(invoke_id);
|
||||||
|
/* Error_Detected = true; */
|
||||||
|
/* try again or abort? */
|
||||||
|
invoke_id = 0; /* Try next operation */
|
||||||
/* break; */
|
/* break; */
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
/* increment timer - exit if timed out */
|
||||||
{
|
elapsed_seconds += (current_seconds - last_seconds);
|
||||||
/* increment timer - exit if timed out */
|
if (elapsed_seconds > timeout_seconds) {
|
||||||
elapsed_seconds += (current_seconds - last_seconds);
|
printf("\rError: APDU Timeout!\r\n");
|
||||||
if (elapsed_seconds > timeout_seconds) {
|
/* Error_Detected = true;
|
||||||
printf("\rError: APDU Timeout!\r\n");
|
break; */
|
||||||
/* Error_Detected = true;
|
invoke_id = 0;
|
||||||
break; */
|
}
|
||||||
invoke_id = 0;
|
}
|
||||||
}
|
/* keep track of time for next check */
|
||||||
}
|
last_seconds = current_seconds;
|
||||||
/* keep track of time for next check */
|
}
|
||||||
last_seconds = current_seconds;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Error_Detected)
|
if (Error_Detected)
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -115,10 +115,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
+46
-110
@@ -75,145 +75,81 @@ static void Init_Object(
|
|||||||
object_index_to_instance_function index_function,
|
object_index_to_instance_function index_function,
|
||||||
object_name_function name_function)
|
object_name_function name_function)
|
||||||
{
|
{
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(object_type, rp_function,
|
||||||
object_type,
|
|
||||||
rp_function,
|
|
||||||
object_valid_function);
|
object_valid_function);
|
||||||
handler_write_property_object_set(
|
handler_write_property_object_set(object_type, wp_function);
|
||||||
object_type,
|
handler_read_property_multiple_list_set(object_type, rpm_list_function);
|
||||||
wp_function);
|
Device_Object_Function_Set(object_type, count_function, index_function,
|
||||||
handler_read_property_multiple_list_set(
|
|
||||||
object_type,
|
|
||||||
rpm_list_function);
|
|
||||||
Device_Object_Function_Set(
|
|
||||||
object_type,
|
|
||||||
count_function,
|
|
||||||
index_function,
|
|
||||||
name_function);
|
name_function);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Init_Objects(void)
|
static void Init_Objects(
|
||||||
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_DEVICE, Device_Property_Lists,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number,
|
||||||
Device_Property_Lists,
|
Device_Write_Property, NULL, NULL, NULL);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number,
|
|
||||||
Device_Write_Property,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Analog_Input_Init();
|
Analog_Input_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_INPUT, Analog_Input_Property_Lists,
|
||||||
OBJECT_ANALOG_INPUT,
|
Analog_Input_Encode_Property_APDU, Analog_Input_Valid_Instance, NULL,
|
||||||
Analog_Input_Property_Lists,
|
Analog_Input_Count, Analog_Input_Index_To_Instance, Analog_Input_Name);
|
||||||
Analog_Input_Encode_Property_APDU,
|
|
||||||
Analog_Input_Valid_Instance,
|
|
||||||
NULL,
|
|
||||||
Analog_Input_Count,
|
|
||||||
Analog_Input_Index_To_Instance,
|
|
||||||
Analog_Input_Name);
|
|
||||||
|
|
||||||
Analog_Output_Init();
|
Analog_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_OUTPUT, Analog_Output_Property_Lists,
|
||||||
OBJECT_ANALOG_OUTPUT,
|
Analog_Output_Encode_Property_APDU, Analog_Output_Valid_Instance,
|
||||||
Analog_Output_Property_Lists,
|
Analog_Output_Write_Property, Analog_Output_Count,
|
||||||
Analog_Output_Encode_Property_APDU,
|
Analog_Output_Index_To_Instance, Analog_Output_Name);
|
||||||
Analog_Output_Valid_Instance,
|
|
||||||
Analog_Output_Write_Property,
|
|
||||||
Analog_Output_Count,
|
|
||||||
Analog_Output_Index_To_Instance,
|
|
||||||
Analog_Output_Name);
|
|
||||||
|
|
||||||
Analog_Value_Init();
|
Analog_Value_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_VALUE, Analog_Value_Property_Lists,
|
||||||
OBJECT_ANALOG_VALUE,
|
Analog_Value_Encode_Property_APDU, Analog_Value_Valid_Instance,
|
||||||
Analog_Value_Property_Lists,
|
Analog_Value_Write_Property, Analog_Value_Count,
|
||||||
Analog_Value_Encode_Property_APDU,
|
Analog_Value_Index_To_Instance, Analog_Value_Name);
|
||||||
Analog_Value_Valid_Instance,
|
|
||||||
Analog_Value_Write_Property,
|
|
||||||
Analog_Value_Count,
|
|
||||||
Analog_Value_Index_To_Instance,
|
|
||||||
Analog_Value_Name);
|
|
||||||
|
|
||||||
Binary_Input_Init();
|
Binary_Input_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_INPUT, Binary_Input_Property_Lists,
|
||||||
OBJECT_BINARY_INPUT,
|
Binary_Input_Encode_Property_APDU, Binary_Input_Valid_Instance, NULL,
|
||||||
Binary_Input_Property_Lists,
|
Binary_Input_Count, Binary_Input_Index_To_Instance, Binary_Input_Name);
|
||||||
Binary_Input_Encode_Property_APDU,
|
|
||||||
Binary_Input_Valid_Instance,
|
|
||||||
NULL,
|
|
||||||
Binary_Input_Count,
|
|
||||||
Binary_Input_Index_To_Instance,
|
|
||||||
Binary_Input_Name);
|
|
||||||
|
|
||||||
Binary_Output_Init();
|
Binary_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_OUTPUT, Binary_Output_Property_Lists,
|
||||||
OBJECT_BINARY_OUTPUT,
|
Binary_Output_Encode_Property_APDU, Binary_Output_Valid_Instance,
|
||||||
Binary_Output_Property_Lists,
|
Binary_Output_Write_Property, Binary_Output_Count,
|
||||||
Binary_Output_Encode_Property_APDU,
|
Binary_Output_Index_To_Instance, Binary_Output_Name);
|
||||||
Binary_Output_Valid_Instance,
|
|
||||||
Binary_Output_Write_Property,
|
|
||||||
Binary_Output_Count,
|
|
||||||
Binary_Output_Index_To_Instance,
|
|
||||||
Binary_Output_Name);
|
|
||||||
|
|
||||||
Binary_Value_Init();
|
Binary_Value_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_VALUE, Binary_Value_Property_Lists,
|
||||||
OBJECT_BINARY_VALUE,
|
Binary_Value_Encode_Property_APDU, Binary_Value_Valid_Instance,
|
||||||
Binary_Value_Property_Lists,
|
Binary_Value_Write_Property, Binary_Value_Count,
|
||||||
Binary_Value_Encode_Property_APDU,
|
Binary_Value_Index_To_Instance, Binary_Value_Name);
|
||||||
Binary_Value_Valid_Instance,
|
|
||||||
Binary_Value_Write_Property,
|
|
||||||
Binary_Value_Count,
|
|
||||||
Binary_Value_Index_To_Instance,
|
|
||||||
Binary_Value_Name);
|
|
||||||
|
|
||||||
Life_Safety_Point_Init();
|
Life_Safety_Point_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Property_Lists,
|
||||||
OBJECT_LIFE_SAFETY_POINT,
|
|
||||||
Life_Safety_Point_Property_Lists,
|
|
||||||
Life_Safety_Point_Encode_Property_APDU,
|
Life_Safety_Point_Encode_Property_APDU,
|
||||||
Life_Safety_Point_Valid_Instance,
|
Life_Safety_Point_Valid_Instance, Life_Safety_Point_Write_Property,
|
||||||
Life_Safety_Point_Write_Property,
|
Life_Safety_Point_Count, Life_Safety_Point_Index_To_Instance,
|
||||||
Life_Safety_Point_Count,
|
|
||||||
Life_Safety_Point_Index_To_Instance,
|
|
||||||
Life_Safety_Point_Name);
|
Life_Safety_Point_Name);
|
||||||
|
|
||||||
Load_Control_Init();
|
Load_Control_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_LOAD_CONTROL, Load_Control_Property_Lists,
|
||||||
OBJECT_LOAD_CONTROL,
|
Load_Control_Encode_Property_APDU, Load_Control_Valid_Instance,
|
||||||
Load_Control_Property_Lists,
|
Load_Control_Write_Property, Load_Control_Count,
|
||||||
Load_Control_Encode_Property_APDU,
|
Load_Control_Index_To_Instance, Load_Control_Name);
|
||||||
Load_Control_Valid_Instance,
|
|
||||||
Load_Control_Write_Property,
|
|
||||||
Load_Control_Count,
|
|
||||||
Load_Control_Index_To_Instance,
|
|
||||||
Load_Control_Name);
|
|
||||||
|
|
||||||
Multistate_Output_Init();
|
Multistate_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Property_Lists,
|
||||||
OBJECT_MULTI_STATE_OUTPUT,
|
|
||||||
Multistate_Output_Property_Lists,
|
|
||||||
Multistate_Output_Encode_Property_APDU,
|
Multistate_Output_Encode_Property_APDU,
|
||||||
Multistate_Output_Valid_Instance,
|
Multistate_Output_Valid_Instance, Multistate_Output_Write_Property,
|
||||||
Multistate_Output_Write_Property,
|
Multistate_Output_Count, Multistate_Output_Index_To_Instance,
|
||||||
Multistate_Output_Count,
|
|
||||||
Multistate_Output_Index_To_Instance,
|
|
||||||
Multistate_Output_Name);
|
Multistate_Output_Name);
|
||||||
|
|
||||||
#if defined(BACFILE)
|
#if defined(BACFILE)
|
||||||
bacfile_init();
|
bacfile_init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_FILE, BACfile_Property_Lists,
|
||||||
OBJECT_FILE,
|
bacfile_encode_property_apdu, bacfile_valid_instance,
|
||||||
BACfile_Property_Lists,
|
bacfile_write_property, bacfile_count, bacfile_index_to_instance,
|
||||||
bacfile_encode_property_apdu,
|
|
||||||
bacfile_valid_instance,
|
|
||||||
bacfile_write_property,
|
|
||||||
bacfile_count,
|
|
||||||
bacfile_index_to_instance,
|
|
||||||
bacfile_name);
|
bacfile_name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,10 +87,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
@@ -54,10 +54,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|||||||
@@ -90,10 +90,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
@@ -111,9 +109,13 @@ static void Init_Service_Handlers(
|
|||||||
apdu_set_reject_handler(MyRejectHandler);
|
apdu_set_reject_handler(MyRejectHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(
|
||||||
|
int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
BACNET_ADDRESS src = {
|
BACNET_ADDRESS src = {
|
||||||
0}; /* address where message came from */
|
0
|
||||||
|
}; /* address where message came from */
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
time_t elapsed_seconds = 0;
|
time_t elapsed_seconds = 0;
|
||||||
|
|||||||
@@ -90,10 +90,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* Note: this applications doesn't need to handle who-is
|
/* Note: this applications doesn't need to handle who-is
|
||||||
it is confusing for the user! */
|
it is confusing for the user! */
|
||||||
/* set the handler for all the services we don't implement
|
/* set the handler for all the services we don't implement
|
||||||
@@ -159,9 +157,13 @@ static void print_address_cache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(
|
||||||
|
int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
BACNET_ADDRESS src = {
|
BACNET_ADDRESS src = {
|
||||||
0}; /* address where message came from */
|
0
|
||||||
|
}; /* address where message came from */
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
time_t total_seconds = 0;
|
time_t total_seconds = 0;
|
||||||
|
|||||||
@@ -170,10 +170,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
@@ -192,14 +190,17 @@ static void Init_Service_Handlers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void address_parse(BACNET_ADDRESS * dst,
|
static void address_parse(
|
||||||
int argc, char *argv[]) {
|
BACNET_ADDRESS * dst,
|
||||||
|
int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
int dnet = 0;
|
int dnet = 0;
|
||||||
unsigned mac[6];
|
unsigned mac[6];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
count =
|
count =
|
||||||
sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
||||||
&mac[3], &mac[4], &mac[5]);
|
&mac[3], &mac[4], &mac[5]);
|
||||||
@@ -240,9 +241,13 @@ static void address_parse(BACNET_ADDRESS * dst,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(
|
||||||
|
int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
BACNET_ADDRESS src = {
|
BACNET_ADDRESS src = {
|
||||||
0}; /* address where message came from */
|
0
|
||||||
|
}; /* address where message came from */
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
time_t total_seconds = 0;
|
time_t total_seconds = 0;
|
||||||
|
|||||||
@@ -133,10 +133,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
@@ -156,9 +154,13 @@ static void Init_Service_Handlers(
|
|||||||
apdu_set_reject_handler(MyRejectHandler);
|
apdu_set_reject_handler(MyRejectHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(
|
||||||
|
int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
BACNET_ADDRESS src = {
|
BACNET_ADDRESS src = {
|
||||||
0}; /* address where message came from */
|
0
|
||||||
|
}; /* address where message came from */
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
|
|||||||
@@ -131,10 +131,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is
|
/* we need to handle who-is
|
||||||
to support dynamic device binding to us */
|
to support dynamic device binding to us */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
@@ -156,9 +154,13 @@ static void Init_Service_Handlers(
|
|||||||
apdu_set_reject_handler(MyRejectHandler);
|
apdu_set_reject_handler(MyRejectHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(
|
||||||
|
int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
BACNET_ADDRESS src = {
|
BACNET_ADDRESS src = {
|
||||||
0}; /* address where message came from */
|
0
|
||||||
|
}; /* address where message came from */
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ extern "C" {
|
|||||||
|
|
||||||
void address_init_partial(
|
void address_init_partial(
|
||||||
void);
|
void);
|
||||||
|
|
||||||
void address_add(
|
void address_add(
|
||||||
uint32_t device_id,
|
uint32_t device_id,
|
||||||
unsigned max_apdu,
|
unsigned max_apdu,
|
||||||
@@ -92,12 +92,12 @@ extern "C" {
|
|||||||
int address_list_encode(
|
int address_list_encode(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
unsigned apdu_len);
|
unsigned apdu_len);
|
||||||
|
|
||||||
void address_set_device_TTL(
|
void address_set_device_TTL(
|
||||||
uint32_t device_id,
|
uint32_t device_id,
|
||||||
uint32_t TimeOut,
|
uint32_t TimeOut,
|
||||||
bool StaticFlag);
|
bool StaticFlag);
|
||||||
|
|
||||||
void address_cache_timer(
|
void address_cache_timer(
|
||||||
uint16_t uSeconds);
|
uint16_t uSeconds);
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,11 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
void Analog_Input_Property_Lists(
|
void Analog_Input_Property_Lists(
|
||||||
const int **pRequired,
|
const int **pRequired,
|
||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary);
|
const int **pProprietary);
|
||||||
|
|
||||||
bool Analog_Input_Valid_Instance(
|
bool Analog_Input_Valid_Instance(
|
||||||
uint32_t object_instance);
|
uint32_t object_instance);
|
||||||
unsigned Analog_Input_Count(
|
unsigned Analog_Input_Count(
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ extern "C" {
|
|||||||
uint32_t instance);
|
uint32_t instance);
|
||||||
|
|
||||||
|
|
||||||
void Analog_Output_Init(void);
|
void Analog_Output_Init(
|
||||||
|
void);
|
||||||
|
|
||||||
int Analog_Output_Encode_Property_APDU(
|
int Analog_Output_Encode_Property_APDU(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
@@ -129,10 +129,10 @@ extern "C" {
|
|||||||
unsigned max_apdu_len,
|
unsigned max_apdu_len,
|
||||||
BACNET_APPLICATION_DATA_VALUE * value);
|
BACNET_APPLICATION_DATA_VALUE * value);
|
||||||
|
|
||||||
bool bacapp_decode_application_data_safe(
|
bool bacapp_decode_application_data_safe(
|
||||||
uint8_t * new_apdu,
|
uint8_t * new_apdu,
|
||||||
uint32_t new_apdu_len,
|
uint32_t new_apdu_len,
|
||||||
BACNET_APPLICATION_DATA_VALUE * value);
|
BACNET_APPLICATION_DATA_VALUE * value);
|
||||||
|
|
||||||
int bacapp_encode_application_data(
|
int bacapp_encode_application_data(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
@@ -71,11 +71,11 @@ extern "C" {
|
|||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint8_t * tag_number,
|
uint8_t * tag_number,
|
||||||
uint32_t * value);
|
uint32_t * value);
|
||||||
int decode_tag_number_and_value_safe(
|
int decode_tag_number_and_value_safe(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t apdu_len_remaining,
|
uint32_t apdu_len_remaining,
|
||||||
uint8_t * tag_number,
|
uint8_t * tag_number,
|
||||||
uint32_t * value);
|
uint32_t * value);
|
||||||
/* returns true if the tag is an opening tag and matches */
|
/* returns true if the tag is an opening tag and matches */
|
||||||
bool decode_is_opening_tag_number(
|
bool decode_is_opening_tag_number(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
@@ -174,11 +174,11 @@ extern "C" {
|
|||||||
uint16_t * object_type,
|
uint16_t * object_type,
|
||||||
uint32_t * instance);
|
uint32_t * instance);
|
||||||
|
|
||||||
int decode_object_id_safe(
|
int decode_object_id_safe(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t len_value,
|
uint32_t len_value,
|
||||||
uint16_t * object_type,
|
uint16_t * object_type,
|
||||||
uint32_t * instance);
|
uint32_t * instance);
|
||||||
|
|
||||||
int decode_context_object_id(
|
int decode_context_object_id(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
@@ -325,11 +325,11 @@ extern "C" {
|
|||||||
int decode_bacnet_time(
|
int decode_bacnet_time(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
BACNET_TIME * btime);
|
BACNET_TIME * btime);
|
||||||
int decode_bacnet_time_safe(
|
int decode_bacnet_time_safe(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t len_value,
|
uint32_t len_value,
|
||||||
BACNET_TIME * btime);
|
BACNET_TIME * btime);
|
||||||
int encode_context_time(
|
int encode_context_time(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint8_t tag_number,
|
uint8_t tag_number,
|
||||||
BACNET_TIME * btime);
|
BACNET_TIME * btime);
|
||||||
@@ -364,11 +364,11 @@ extern "C" {
|
|||||||
int decode_date(
|
int decode_date(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
BACNET_DATE * bdate);
|
BACNET_DATE * bdate);
|
||||||
int decode_date_safe(
|
int decode_date_safe(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t len_value,
|
uint32_t len_value,
|
||||||
BACNET_DATE * bdate);
|
BACNET_DATE * bdate);
|
||||||
int decode_application_date(
|
int decode_application_date(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
BACNET_DATE * bdate);
|
BACNET_DATE * bdate);
|
||||||
int decode_context_date(
|
int decode_context_date(
|
||||||
|
|||||||
@@ -1428,7 +1428,7 @@ typedef enum BACnetDaysOfWeek {
|
|||||||
BACNET_DAYS_OF_WEEK_FRIDAY = 4,
|
BACNET_DAYS_OF_WEEK_FRIDAY = 4,
|
||||||
BACNET_DAYS_OF_WEEK_SATURDAY = 5,
|
BACNET_DAYS_OF_WEEK_SATURDAY = 5,
|
||||||
BACNET_DAYS_OF_WEEK_SUNDAY = 6,
|
BACNET_DAYS_OF_WEEK_SUNDAY = 6,
|
||||||
MAX_BACNET_DAYS_OF_WEEK = 7
|
MAX_BACNET_DAYS_OF_WEEK = 7
|
||||||
} BACNET_DAYS_OF_WEEK;
|
} BACNET_DAYS_OF_WEEK;
|
||||||
|
|
||||||
typedef enum BACnetEventTransitionBits {
|
typedef enum BACnetEventTransitionBits {
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ extern "C" {
|
|||||||
bool bacfile_write_stream_data(
|
bool bacfile_write_stream_data(
|
||||||
BACNET_ATOMIC_WRITE_FILE_DATA * data);
|
BACNET_ATOMIC_WRITE_FILE_DATA * data);
|
||||||
|
|
||||||
void bacfile_init(void);
|
void bacfile_init(
|
||||||
|
void);
|
||||||
|
|
||||||
/* handling for read property service */
|
/* handling for read property service */
|
||||||
int bacfile_encode_property_apdu(
|
int bacfile_encode_property_apdu(
|
||||||
|
|||||||
@@ -42,10 +42,10 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
int decode_real_safe(
|
int decode_real_safe(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t len_value,
|
uint32_t len_value,
|
||||||
float *real_value);
|
float *real_value);
|
||||||
|
|
||||||
int decode_real(
|
int decode_real(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
@@ -65,12 +65,12 @@ extern "C" {
|
|||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint8_t tag_number,
|
uint8_t tag_number,
|
||||||
double *double_value);
|
double *double_value);
|
||||||
int decode_double_safe(
|
int decode_double_safe(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t len_value,
|
uint32_t len_value,
|
||||||
double *double_value);
|
double *double_value);
|
||||||
|
|
||||||
int encode_bacnet_double(
|
int encode_bacnet_double(
|
||||||
double value,
|
double value,
|
||||||
uint8_t * apdu);
|
uint8_t * apdu);
|
||||||
|
|
||||||
|
|||||||
@@ -98,9 +98,9 @@ extern "C" {
|
|||||||
BACNET_BIT_STRING * dest,
|
BACNET_BIT_STRING * dest,
|
||||||
BACNET_BIT_STRING * src);
|
BACNET_BIT_STRING * src);
|
||||||
|
|
||||||
bool bitstring_same(
|
bool bitstring_same(
|
||||||
BACNET_BIT_STRING * bitstring1,
|
BACNET_BIT_STRING * bitstring1,
|
||||||
BACNET_BIT_STRING * bitstring2);
|
BACNET_BIT_STRING * bitstring2);
|
||||||
|
|
||||||
/* returns false if the string exceeds capacity
|
/* returns false if the string exceeds capacity
|
||||||
initialize by using length=0 */
|
initialize by using length=0 */
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ extern "C" {
|
|||||||
const char *bactext_object_type_name(
|
const char *bactext_object_type_name(
|
||||||
unsigned index);
|
unsigned index);
|
||||||
bool bactext_object_type_index(
|
bool bactext_object_type_index(
|
||||||
const char *search_name,
|
const char *search_name,
|
||||||
unsigned *found_index);
|
unsigned *found_index);
|
||||||
const char *bactext_property_name(
|
const char *bactext_property_name(
|
||||||
unsigned index);
|
unsigned index);
|
||||||
bool bactext_property_index(
|
bool bactext_property_index(
|
||||||
@@ -103,7 +103,7 @@ extern "C" {
|
|||||||
unsigned index);
|
unsigned index);
|
||||||
const char *bactext_segmentation_name(
|
const char *bactext_segmentation_name(
|
||||||
unsigned index);
|
unsigned index);
|
||||||
|
|
||||||
const char *bactext_event_transition_name(
|
const char *bactext_event_transition_name(
|
||||||
unsigned index);
|
unsigned index);
|
||||||
bool bactext_event_transition_index(
|
bool bactext_event_transition_index(
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ extern "C" {
|
|||||||
|
|
||||||
void Binary_Value_Init(
|
void Binary_Value_Init(
|
||||||
void);
|
void);
|
||||||
|
|
||||||
int Binary_Value_Encode_Property_APDU(
|
int Binary_Value_Encode_Property_APDU(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ extern "C" {
|
|||||||
|
|
||||||
void Send_UnconfirmedPrivateTransfer(
|
void Send_UnconfirmedPrivateTransfer(
|
||||||
BACNET_ADDRESS * dest,
|
BACNET_ADDRESS * dest,
|
||||||
BACNET_PRIVATE_TRANSFER_DATA *private_data);
|
BACNET_PRIVATE_TRANSFER_DATA * private_data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,11 +40,17 @@
|
|||||||
#include "bacenum.h"
|
#include "bacenum.h"
|
||||||
#include "wp.h"
|
#include "wp.h"
|
||||||
|
|
||||||
typedef unsigned (*object_count_function) (void);
|
typedef unsigned (
|
||||||
typedef uint32_t (*object_index_to_instance_function)
|
*object_count_function) (
|
||||||
(unsigned index);
|
void);
|
||||||
typedef char * (*object_name_function)
|
typedef uint32_t(
|
||||||
(uint32_t object_instance);
|
*object_index_to_instance_function)
|
||||||
|
(
|
||||||
|
unsigned index);
|
||||||
|
typedef char *(
|
||||||
|
*object_name_function)
|
||||||
|
(
|
||||||
|
uint32_t object_instance);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -56,65 +56,66 @@ typedef struct BACnet_Get_Event_Information_Data {
|
|||||||
/* return 0 if no active event at this index
|
/* return 0 if no active event at this index
|
||||||
return -1 if end of list
|
return -1 if end of list
|
||||||
return +1 if active event */
|
return +1 if active event */
|
||||||
typedef int (*get_event_info_function) (
|
typedef int (
|
||||||
|
*get_event_info_function) (
|
||||||
unsigned index,
|
unsigned index,
|
||||||
BACNET_GET_EVENT_INFORMATION_DATA *getevent_data);
|
BACNET_GET_EVENT_INFORMATION_DATA * getevent_data);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
int getevent_encode_apdu(
|
int getevent_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint8_t invoke_id,
|
uint8_t invoke_id,
|
||||||
BACNET_OBJECT_ID * lastReceivedObjectIdentifier);
|
BACNET_OBJECT_ID * lastReceivedObjectIdentifier);
|
||||||
|
|
||||||
int getevent_decode_service_request(
|
int getevent_decode_service_request(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
unsigned apdu_len,
|
unsigned apdu_len,
|
||||||
BACNET_OBJECT_ID * object_id);
|
BACNET_OBJECT_ID * object_id);
|
||||||
|
|
||||||
int getevent_ack_encode_apdu_init(
|
int getevent_ack_encode_apdu_init(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
size_t max_apdu,
|
size_t max_apdu,
|
||||||
uint8_t invoke_id);
|
uint8_t invoke_id);
|
||||||
|
|
||||||
int getevent_ack_encode_apdu_data(
|
int getevent_ack_encode_apdu_data(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
size_t max_apdu,
|
size_t max_apdu,
|
||||||
BACNET_GET_EVENT_INFORMATION_DATA * get_event_data);
|
BACNET_GET_EVENT_INFORMATION_DATA * get_event_data);
|
||||||
|
|
||||||
int getevent_ack_encode_apdu_end(
|
int getevent_ack_encode_apdu_end(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
size_t max_apdu,
|
size_t max_apdu,
|
||||||
bool moreEvents);
|
bool moreEvents);
|
||||||
|
|
||||||
int getevent_ack_decode_service_request(
|
int getevent_ack_decode_service_request(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
int apdu_len, /* total length of the apdu */
|
int apdu_len, /* total length of the apdu */
|
||||||
BACNET_GET_EVENT_INFORMATION_DATA * get_event_data,
|
BACNET_GET_EVENT_INFORMATION_DATA * get_event_data,
|
||||||
bool *moreEvents);
|
bool * moreEvents);
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
#include "ctest.h"
|
#include "ctest.h"
|
||||||
int getevent_decode_apdu(
|
int getevent_decode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
unsigned apdu_len,
|
unsigned apdu_len,
|
||||||
uint8_t * invoke_id,
|
uint8_t * invoke_id,
|
||||||
BACNET_OBJECT_ID * lastReceivedObjectIdentifier);
|
BACNET_OBJECT_ID * lastReceivedObjectIdentifier);
|
||||||
|
|
||||||
int getevent_ack_decode_apdu(
|
int getevent_ack_decode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
int apdu_len, /* total length of the apdu */
|
int apdu_len, /* total length of the apdu */
|
||||||
uint8_t * invoke_id,
|
uint8_t * invoke_id,
|
||||||
BACNET_GET_EVENT_INFORMATION_DATA * get_event_data,
|
BACNET_GET_EVENT_INFORMATION_DATA * get_event_data,
|
||||||
bool *moreEvents);
|
bool * moreEvents);
|
||||||
|
|
||||||
void testGetEventInformationAck(
|
void testGetEventInformationAck(
|
||||||
Test * pTest);
|
Test * pTest);
|
||||||
|
|
||||||
void testGetEventInformation(
|
void testGetEventInformation(
|
||||||
Test * pTest);
|
Test * pTest);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ extern "C" {
|
|||||||
void handler_read_property_object_set(
|
void handler_read_property_object_set(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
read_property_function pFunction1,
|
read_property_function pFunction1,
|
||||||
object_valid_instance_function pFunction2);
|
object_valid_instance_function pFunction2);
|
||||||
|
|
||||||
void handler_read_property_ack(
|
void handler_read_property_ack(
|
||||||
uint8_t * service_request,
|
uint8_t * service_request,
|
||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
@@ -94,7 +94,7 @@ extern "C" {
|
|||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
||||||
|
|
||||||
void handler_write_property_object_set(
|
void handler_write_property_object_set(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
write_property_function pFunction);
|
write_property_function pFunction);
|
||||||
@@ -152,9 +152,9 @@ extern "C" {
|
|||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
||||||
|
|
||||||
void handler_read_property_multiple_list_set(
|
void handler_read_property_multiple_list_set(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
rpm_property_lists_function pFunction);
|
rpm_property_lists_function pFunction);
|
||||||
|
|
||||||
void handler_read_property_multiple_ack(
|
void handler_read_property_multiple_ack(
|
||||||
uint8_t * service_request,
|
uint8_t * service_request,
|
||||||
@@ -207,7 +207,7 @@ extern "C" {
|
|||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
||||||
|
|
||||||
void handler_conf_private_trans_ack(
|
void handler_conf_private_trans_ack(
|
||||||
uint8_t * service_request,
|
uint8_t * service_request,
|
||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
@@ -230,7 +230,7 @@ extern "C" {
|
|||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data);
|
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data);
|
||||||
|
|
||||||
void handler_get_event_information_set(
|
void handler_get_event_information_set(
|
||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
get_event_info_function pFunction);
|
get_event_info_function pFunction);
|
||||||
@@ -240,7 +240,7 @@ extern "C" {
|
|||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,9 +101,9 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
#if !defined(__BORLANDC__) && !defined(_MSC_VER)
|
#if !defined(__BORLANDC__) && !defined(_MSC_VER)
|
||||||
int stricmp(
|
int stricmp(
|
||||||
const char *s1,
|
const char *s1,
|
||||||
const char *s2);
|
const char *s2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ extern "C" {
|
|||||||
const int **pRequired,
|
const int **pRequired,
|
||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary);
|
const int **pProprietary);
|
||||||
|
|
||||||
bool Multistate_Input_Valid_Instance(
|
bool Multistate_Input_Valid_Instance(
|
||||||
uint32_t object_instance);
|
uint32_t object_instance);
|
||||||
unsigned Multistate_Input_Count(
|
unsigned Multistate_Input_Count(
|
||||||
@@ -47,7 +47,7 @@ extern "C" {
|
|||||||
uint32_t Multistate_Input_Index_To_Instance(
|
uint32_t Multistate_Input_Index_To_Instance(
|
||||||
unsigned index);
|
unsigned index);
|
||||||
unsigned Multistate_Input_Instance_To_Index(
|
unsigned Multistate_Input_Instance_To_Index(
|
||||||
uint32_t instance);
|
uint32_t instance);
|
||||||
|
|
||||||
int Multistate_Input_Encode_Property_APDU(
|
int Multistate_Input_Encode_Property_APDU(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
@@ -14,11 +14,8 @@
|
|||||||
#define MY_ERR_BAD_INDEX 1
|
#define MY_ERR_BAD_INDEX 1
|
||||||
|
|
||||||
typedef struct MyData {
|
typedef struct MyData {
|
||||||
uint8_t cMyByte1;
|
uint8_t cMyByte1;
|
||||||
uint8_t cMyByte2;
|
uint8_t cMyByte2;
|
||||||
float fMyReal;
|
float fMyReal;
|
||||||
int8_t sMyString[MY_MAX_STR+1]; /* A little extra for the nul */
|
int8_t sMyString[MY_MAX_STR + 1]; /* A little extra for the nul */
|
||||||
} DATABLOCK;
|
} DATABLOCK;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,21 +35,21 @@
|
|||||||
struct BACnet_Read_Range_Data;
|
struct BACnet_Read_Range_Data;
|
||||||
typedef struct BACnet_Read_Range_Data {
|
typedef struct BACnet_Read_Range_Data {
|
||||||
BACNET_OBJECT_TYPE object_type;
|
BACNET_OBJECT_TYPE object_type;
|
||||||
uint32_t object_instance;
|
uint32_t object_instance;
|
||||||
BACNET_PROPERTY_ID object_property;
|
BACNET_PROPERTY_ID object_property;
|
||||||
uint32_t array_index;
|
uint32_t array_index;
|
||||||
uint8_t *application_data;
|
uint8_t *application_data;
|
||||||
int application_data_len;
|
int application_data_len;
|
||||||
BACNET_BIT_STRING ResultFlags; /* FIRST_ITEM, LAST_ITEM, MORE_ITEMS */
|
BACNET_BIT_STRING ResultFlags; /* FIRST_ITEM, LAST_ITEM, MORE_ITEMS */
|
||||||
int RequestType; /* Index, sequence or time based request */
|
int RequestType; /* Index, sequence or time based request */
|
||||||
uint32_t ItemCount;
|
uint32_t ItemCount;
|
||||||
uint32_t FirstSequence;
|
uint32_t FirstSequence;
|
||||||
union { /* Pick the appropriate data type */
|
union { /* Pick the appropriate data type */
|
||||||
uint32_t RefIndex;
|
uint32_t RefIndex;
|
||||||
uint32_t RefSeqNum;
|
uint32_t RefSeqNum;
|
||||||
BACNET_DATE_TIME RefTime;
|
BACNET_DATE_TIME RefTime;
|
||||||
} Range;
|
} Range;
|
||||||
int32_t Count; /* SIGNED value as +ve vs -ve is important */
|
int32_t Count; /* SIGNED value as +ve vs -ve is important */
|
||||||
} BACNET_READ_RANGE_DATA;
|
} BACNET_READ_RANGE_DATA;
|
||||||
|
|
||||||
/* Defines to indicate which type of read range request it is */
|
/* Defines to indicate which type of read range request it is */
|
||||||
@@ -57,12 +57,12 @@ typedef struct BACnet_Read_Range_Data {
|
|||||||
#define RR_BY_POSITION 0
|
#define RR_BY_POSITION 0
|
||||||
#define RR_BY_SEQUENCE 1
|
#define RR_BY_SEQUENCE 1
|
||||||
#define RR_BY_TIME 2
|
#define RR_BY_TIME 2
|
||||||
#define RR_READ_ALL 4 /* Read all of array - so don't send any range in the request */
|
#define RR_READ_ALL 4 /* Read all of array - so don't send any range in the request */
|
||||||
|
|
||||||
/* Bit String Enumerations */
|
/* Bit String Enumerations */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RESULT_FLAG_FIRST_ITEM = 0,
|
RESULT_FLAG_FIRST_ITEM = 0,
|
||||||
RESULT_FLAG_LAST_ITEM = 1,
|
RESULT_FLAG_LAST_ITEM = 1,
|
||||||
RESULT_FLAG_MORE_ITEMS = 2
|
RESULT_FLAG_MORE_ITEMS = 2
|
||||||
} BACNET_RESULT_FLAGS;
|
} BACNET_RESULT_FLAGS;
|
||||||
|
|
||||||
@@ -88,4 +88,4 @@ int rr_ack_decode_service_request(
|
|||||||
|
|
||||||
uint8_t Send_ReadRange_Request(
|
uint8_t Send_ReadRange_Request(
|
||||||
uint32_t device_id, /* destination device */
|
uint32_t device_id, /* destination device */
|
||||||
BACNET_READ_RANGE_DATA * read_access_data);
|
BACNET_READ_RANGE_DATA * read_access_data);
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ typedef struct BACnet_Read_Property_Data {
|
|||||||
int application_data_len;
|
int application_data_len;
|
||||||
} BACNET_READ_PROPERTY_DATA;
|
} BACNET_READ_PROPERTY_DATA;
|
||||||
|
|
||||||
typedef int (*read_property_function) (
|
typedef int (
|
||||||
|
*read_property_function) (
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
BACNET_PROPERTY_ID property,
|
BACNET_PROPERTY_ID property,
|
||||||
@@ -56,8 +57,9 @@ typedef int (*read_property_function) (
|
|||||||
BACNET_ERROR_CLASS * error_class,
|
BACNET_ERROR_CLASS * error_class,
|
||||||
BACNET_ERROR_CODE * error_code);
|
BACNET_ERROR_CODE * error_code);
|
||||||
|
|
||||||
typedef bool (*object_valid_instance_function) (
|
typedef bool(
|
||||||
uint32_t object_instance);
|
*object_valid_instance_function) (
|
||||||
|
uint32_t object_instance);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ typedef struct BACnet_Read_Access_Data {
|
|||||||
struct BACnet_Read_Access_Data *next;
|
struct BACnet_Read_Access_Data *next;
|
||||||
} BACNET_READ_ACCESS_DATA;
|
} BACNET_READ_ACCESS_DATA;
|
||||||
|
|
||||||
typedef void (*rpm_property_lists_function) (
|
typedef void (
|
||||||
|
*rpm_property_lists_function) (
|
||||||
const int **pRequired,
|
const int **pRequired,
|
||||||
const int **pOptional,
|
const int **pOptional,
|
||||||
const int **pProprietary);
|
const int **pProprietary);
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ extern "C" {
|
|||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
BACNET_TIMESTAMP * value);
|
BACNET_TIMESTAMP * value);
|
||||||
int bacapp_decode_timestamp(
|
int bacapp_decode_timestamp(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
BACNET_TIMESTAMP * value);
|
BACNET_TIMESTAMP * value);
|
||||||
|
|
||||||
|
|
||||||
int bacapp_encode_context_timestamp(
|
int bacapp_encode_context_timestamp(
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ typedef struct BACnet_Write_Property_Data {
|
|||||||
uint8_t priority; /* use BACNET_NO_PRIORITY if no priority */
|
uint8_t priority; /* use BACNET_NO_PRIORITY if no priority */
|
||||||
} BACNET_WRITE_PROPERTY_DATA;
|
} BACNET_WRITE_PROPERTY_DATA;
|
||||||
|
|
||||||
typedef bool (*write_property_function) (
|
typedef bool(
|
||||||
|
*write_property_function) (
|
||||||
BACNET_WRITE_PROPERTY_DATA * wp_data,
|
BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||||
BACNET_ERROR_CLASS * error_class,
|
BACNET_ERROR_CLASS * error_class,
|
||||||
BACNET_ERROR_CODE * error_code);
|
BACNET_ERROR_CODE * error_code);
|
||||||
@@ -61,7 +62,7 @@ typedef bool (*write_property_function) (
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/* encode service */
|
/* encode service */
|
||||||
int wp_encode_apdu(
|
int wp_encode_apdu(
|
||||||
uint8_t * apdu,
|
uint8_t * apdu,
|
||||||
|
|||||||
@@ -313,8 +313,8 @@ bool Analog_Value_Write_Property(
|
|||||||
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
|
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
|
||||||
level = (uint8_t) value.type.Real;
|
level = (uint8_t) value.type.Real;
|
||||||
object_index =
|
object_index =
|
||||||
Analog_Value_Instance_To_Index(wp_data->
|
Analog_Value_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
priority--;
|
priority--;
|
||||||
Present_Value[object_index] = level;
|
Present_Value[object_index] = level;
|
||||||
/* Note: you could set the physical output here if we
|
/* Note: you could set the physical output here if we
|
||||||
|
|||||||
@@ -225,8 +225,8 @@ bool Binary_Value_Write_Property(
|
|||||||
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
||||||
level = value.type.Enumerated;
|
level = value.type.Enumerated;
|
||||||
object_index =
|
object_index =
|
||||||
Binary_Value_Instance_To_Index(wp_data->
|
Binary_Value_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
priority--;
|
priority--;
|
||||||
/* NOTE: this Binary value has no priority array */
|
/* NOTE: this Binary value has no priority array */
|
||||||
Present_Value[object_index] = level;
|
Present_Value[object_index] = level;
|
||||||
|
|||||||
@@ -492,8 +492,8 @@ bool Device_Write_Property(
|
|||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||||
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
(Device_Set_Object_Instance_Number(value.type.
|
||||||
instance))) {
|
Object_Id.instance))) {
|
||||||
/* we could send an I-Am broadcast to let the world know */
|
/* we could send an I-Am broadcast to let the world know */
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -66,9 +66,8 @@ int Encode_Property_APDU(
|
|||||||
case OBJECT_DEVICE:
|
case OBJECT_DEVICE:
|
||||||
if (Device_Valid_Object_Instance_Number(object_instance)) {
|
if (Device_Valid_Object_Instance_Number(object_instance)) {
|
||||||
apdu_len =
|
apdu_len =
|
||||||
Device_Encode_Property_APDU(&apdu[0],
|
Device_Encode_Property_APDU(&apdu[0], object_instance,
|
||||||
object_instance, property,
|
property, array_index, error_class, error_code);
|
||||||
array_index, error_class, error_code);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_ANALOG_INPUT:
|
case OBJECT_ANALOG_INPUT:
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ static inline void bacnet_init(
|
|||||||
#endif
|
#endif
|
||||||
Device_Set_Object_Instance_Number(22222);
|
Device_Set_Object_Instance_Number(22222);
|
||||||
/* set up our confirmed service unrecognized service handler - required! */
|
/* set up our confirmed service unrecognized service handler - required! */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler
|
||||||
|
(handler_unrecognized_service);
|
||||||
/* we need to handle who-is to support dynamic device binding */
|
/* we need to handle who-is to support dynamic device binding */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
/* Set the handlers for any confirmed services that we support. */
|
/* Set the handlers for any confirmed services that we support. */
|
||||||
|
|||||||
@@ -200,8 +200,8 @@ bool Binary_Value_Write_Property(
|
|||||||
if ((value.type.Enumerated == BINARY_ACTIVE) ||
|
if ((value.type.Enumerated == BINARY_ACTIVE) ||
|
||||||
(value.type.Enumerated == BINARY_INACTIVE)) {
|
(value.type.Enumerated == BINARY_INACTIVE)) {
|
||||||
object_index =
|
object_index =
|
||||||
Binary_Value_Instance_To_Index(wp_data->
|
Binary_Value_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
/* NOTE: this Binary value has no priority array */
|
/* NOTE: this Binary value has no priority array */
|
||||||
Present_Value[object_index] =
|
Present_Value[object_index] =
|
||||||
(BACNET_BINARY_PV) value.type.Enumerated;
|
(BACNET_BINARY_PV) value.type.Enumerated;
|
||||||
|
|||||||
@@ -364,8 +364,8 @@ bool Device_Write_Property(
|
|||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||||
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
(Device_Set_Object_Instance_Number(value.type.
|
||||||
instance))) {
|
Object_Id.instance))) {
|
||||||
/* we could send an I-Am broadcast to let the world know */
|
/* we could send an I-Am broadcast to let the world know */
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -57,10 +57,8 @@ int Encode_Property_APDU(
|
|||||||
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
||||||
apdu_len =
|
apdu_len =
|
||||||
Device_Encode_Property_APDU(&apdu[0],
|
Device_Encode_Property_APDU(&apdu[0],
|
||||||
rp_data->object_instance,
|
rp_data->object_instance, rp_data->object_property,
|
||||||
rp_data->object_property,
|
rp_data->array_index, error_class, error_code);
|
||||||
rp_data->array_index,
|
|
||||||
error_class, error_code);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_ANALOG_VALUE:
|
case OBJECT_ANALOG_VALUE:
|
||||||
|
|||||||
@@ -200,8 +200,8 @@ bool Binary_Value_Write_Property(
|
|||||||
if ((value.type.Enumerated == BINARY_ACTIVE) ||
|
if ((value.type.Enumerated == BINARY_ACTIVE) ||
|
||||||
(value.type.Enumerated == BINARY_INACTIVE)) {
|
(value.type.Enumerated == BINARY_INACTIVE)) {
|
||||||
object_index =
|
object_index =
|
||||||
Binary_Value_Instance_To_Index(wp_data->
|
Binary_Value_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
/* NOTE: this Binary value has no priority array */
|
/* NOTE: this Binary value has no priority array */
|
||||||
Present_Value[object_index] =
|
Present_Value[object_index] =
|
||||||
(BACNET_BINARY_PV) value.type.Enumerated;
|
(BACNET_BINARY_PV) value.type.Enumerated;
|
||||||
|
|||||||
@@ -61,10 +61,8 @@ int Encode_Property_APDU(
|
|||||||
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
||||||
apdu_len =
|
apdu_len =
|
||||||
Device_Encode_Property_APDU(&apdu[0],
|
Device_Encode_Property_APDU(&apdu[0],
|
||||||
rp_data->object_instance,
|
rp_data->object_instance, rp_data->object_property,
|
||||||
rp_data->object_property,
|
rp_data->array_index, error_class, error_code);
|
||||||
rp_data->array_index,
|
|
||||||
error_class, error_code);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if MAX_ANALOG_VALUES
|
#if MAX_ANALOG_VALUES
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ uint32_t Analog_Input_Index_To_Instance(
|
|||||||
char *Analog_Input_Name(
|
char *Analog_Input_Name(
|
||||||
uint32_t object_instance)
|
uint32_t object_instance)
|
||||||
{
|
{
|
||||||
static char text_string[32]; /* okay for single thread */
|
static char text_string[32]; /* okay for single thread */
|
||||||
|
|
||||||
if (object_instance < MAX_ANALOG_INPUTS) {
|
if (object_instance < MAX_ANALOG_INPUTS) {
|
||||||
sprintf(text_string, "AI-%lu", object_instance);
|
sprintf(text_string, "AI-%lu", object_instance);
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ bool Binary_Input_Present_Value_Set(
|
|||||||
char *Binary_Input_Name(
|
char *Binary_Input_Name(
|
||||||
uint32_t object_instance)
|
uint32_t object_instance)
|
||||||
{
|
{
|
||||||
static char text_string[32]; /* okay for single thread */
|
static char text_string[32]; /* okay for single thread */
|
||||||
|
|
||||||
if (object_instance < MAX_BINARY_INPUTS) {
|
if (object_instance < MAX_BINARY_INPUTS) {
|
||||||
sprintf(text_string, "BI-%lu", object_instance);
|
sprintf(text_string, "BI-%lu", object_instance);
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ void Binary_Output_Level_Sync(
|
|||||||
char *Binary_Output_Name(
|
char *Binary_Output_Name(
|
||||||
uint32_t object_instance)
|
uint32_t object_instance)
|
||||||
{
|
{
|
||||||
static char text_string[32]; /* okay for single thread */
|
static char text_string[32]; /* okay for single thread */
|
||||||
|
|
||||||
if (object_instance < MAX_BINARY_OUTPUTS) {
|
if (object_instance < MAX_BINARY_OUTPUTS) {
|
||||||
sprintf(text_string, "BO-%lu", object_instance);
|
sprintf(text_string, "BO-%lu", object_instance);
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ void Device_Init(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Reinitialize_State = REINITIALIZED_STATE_IDLE;
|
Reinitialize_State = REINITIALIZED_STATE_IDLE;
|
||||||
|
|
||||||
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
|
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
|
||||||
/* Get the data from the eeprom */
|
/* Get the data from the eeprom */
|
||||||
eeprom_bytes_read(NV_EEPROM_DEVICE_0, (uint8_t *) & Object_Instance_Number,
|
eeprom_bytes_read(NV_EEPROM_DEVICE_0, (uint8_t *) & Object_Instance_Number,
|
||||||
@@ -143,8 +143,8 @@ void Device_Init(
|
|||||||
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_ENCODING,
|
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_ENCODING,
|
||||||
&Object_Name_Encoding, 1);
|
&Object_Name_Encoding, 1);
|
||||||
sprintf(Object_Name, "DEVICE-%lu", Object_Instance_Number);
|
sprintf(Object_Name, "DEVICE-%lu", Object_Instance_Number);
|
||||||
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_0, (uint8_t *) & Object_Name[0],
|
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_0,
|
||||||
NV_EEPROM_DEVICE_NAME_SIZE);
|
(uint8_t *) & Object_Name[0], NV_EEPROM_DEVICE_NAME_SIZE);
|
||||||
Object_Name_Length = strlen(Object_Name);
|
Object_Name_Length = strlen(Object_Name);
|
||||||
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_LENGTH, &Object_Name_Length,
|
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_LENGTH, &Object_Name_Length,
|
||||||
1);
|
1);
|
||||||
@@ -506,8 +506,8 @@ int Device_Encode_Property_APDU(
|
|||||||
apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
|
apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
|
||||||
break;
|
break;
|
||||||
case 9600:
|
case 9600:
|
||||||
apdu_len = encode_application_unsigned(&apdu[0],
|
apdu_len =
|
||||||
rs485_baud_rate());
|
encode_application_unsigned(&apdu[0], rs485_baud_rate());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -543,8 +543,8 @@ bool Device_Write_Property(
|
|||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||||
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
(Device_Set_Object_Instance_Number(value.type.
|
||||||
instance))) {
|
Object_Id.instance))) {
|
||||||
/* we could send an I-Am broadcast to let the world know */
|
/* we could send an I-Am broadcast to let the world know */
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -591,7 +591,7 @@ bool Device_Write_Property(
|
|||||||
characterstring_length(&value.type.Character_String);
|
characterstring_length(&value.type.Character_String);
|
||||||
if (length < 1) {
|
if (length < 1) {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
} else if (length < NV_EEPROM_DEVICE_NAME_SIZE) {
|
} else if (length < NV_EEPROM_DEVICE_NAME_SIZE) {
|
||||||
uint8_t encoding =
|
uint8_t encoding =
|
||||||
characterstring_encoding(&value.type.Character_String);
|
characterstring_encoding(&value.type.Character_String);
|
||||||
@@ -605,8 +605,8 @@ bool Device_Write_Property(
|
|||||||
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_LENGTH,
|
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_LENGTH,
|
||||||
&Object_Name_Length, 1);
|
&Object_Name_Length, 1);
|
||||||
pCharString =
|
pCharString =
|
||||||
characterstring_value(&value.type.
|
characterstring_value(&value.
|
||||||
Character_String);
|
type.Character_String);
|
||||||
for (i = 0; i < Object_Name_Length; i++) {
|
for (i = 0; i < Object_Name_Length; i++) {
|
||||||
Object_Name[i] = pCharString[i];
|
Object_Name[i] = pCharString[i];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -670,7 +670,8 @@ static void MSTP_Receive_Frame_FSM(
|
|||||||
#ifdef MSTP_DEBUG_STATES
|
#ifdef MSTP_DEBUG_STATES
|
||||||
static MSTP_MASTER_STATE Master_State_Log[128];
|
static MSTP_MASTER_STATE Master_State_Log[128];
|
||||||
static unsigned master_state_log_index = 0;
|
static unsigned master_state_log_index = 0;
|
||||||
void log_master_state(MSTP_MASTER_STATE state)
|
void log_master_state(
|
||||||
|
MSTP_MASTER_STATE state)
|
||||||
{
|
{
|
||||||
Master_State_Log[master_state_log_index] = state;
|
Master_State_Log[master_state_log_index] = state;
|
||||||
master_state_log_index++;
|
master_state_log_index++;
|
||||||
@@ -679,7 +680,7 @@ void log_master_state(MSTP_MASTER_STATE state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define log_master_state(n) (void)n;
|
#define log_master_state(n) (void)n;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* returns true if we need to transition immediately */
|
/* returns true if we need to transition immediately */
|
||||||
@@ -1362,7 +1363,8 @@ void dlmstp_get_broadcast_address(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *dlmstp_receive_state_text(void)
|
char *dlmstp_receive_state_text(
|
||||||
|
void)
|
||||||
{
|
{
|
||||||
switch (Receive_State) {
|
switch (Receive_State) {
|
||||||
case MSTP_RECEIVE_STATE_IDLE:
|
case MSTP_RECEIVE_STATE_IDLE:
|
||||||
@@ -1376,11 +1378,12 @@ char *dlmstp_receive_state_text(void)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
char *dlmstp_master_state_text(void)
|
char *dlmstp_master_state_text(
|
||||||
|
void)
|
||||||
{
|
{
|
||||||
switch (Master_State) {
|
switch (Master_State) {
|
||||||
case MSTP_MASTER_STATE_INITIALIZE:
|
case MSTP_MASTER_STATE_INITIALIZE:
|
||||||
@@ -1404,6 +1407,6 @@ char *dlmstp_master_state_text(void)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,19 +29,19 @@
|
|||||||
FUSES = {
|
FUSES = {
|
||||||
/* == LOW FUSE or LFUSE settings == */
|
/* == LOW FUSE or LFUSE settings == */
|
||||||
/* CKSEL3..0- Clock Select Configuration
|
/* CKSEL3..0- Clock Select Configuration
|
||||||
CKSEL3 CKSEL2 CKSEL1 CKSEL0 Description
|
CKSEL3 CKSEL2 CKSEL1 CKSEL0 Description
|
||||||
1 1 1 x 1111-1000=Low Power Crystal Oscillator
|
1 1 1 x 1111-1000=Low Power Crystal Oscillator
|
||||||
0 1 1 x 0111-0110=Full Swing Crystal Oscillator
|
0 1 1 x 0111-0110=Full Swing Crystal Oscillator
|
||||||
0 1 0 x 0101-0100=Low Frequency Crystal Oscillator
|
0 1 0 x 0101-0100=Low Frequency Crystal Oscillator
|
||||||
0 0 1 1 Internal 128kHz RC Oscillator
|
0 0 1 1 Internal 128kHz RC Oscillator
|
||||||
0 0 1 0 Calibrated Internal RC Oscillator
|
0 0 1 0 Calibrated Internal RC Oscillator
|
||||||
0 0 0 0 External Clock]
|
0 0 0 0 External Clock]
|
||||||
|
|
||||||
SUT1..0 - Clock Start Up Time selection
|
SUT1..0 - Clock Start Up Time selection
|
||||||
If CKSEL0=0, then SUT1..0 is 14CK+: 00=4.1ms,01=65ms,10=BOD,11=4.1ms
|
If CKSEL0=0, then SUT1..0 is 14CK+: 00=4.1ms,01=65ms,10=BOD,11=4.1ms
|
||||||
If CKSEL0=1, then SUT1..0 is 14CK+: 00=65ms,01=BOD,10=4.1ms,11=65ms
|
If CKSEL0=1, then SUT1..0 is 14CK+: 00=65ms,01=BOD,10=4.1ms,11=65ms
|
||||||
BOD means wait until internal Brown Out Detect Voltage is sufficient.
|
BOD means wait until internal Brown Out Detect Voltage is sufficient.
|
||||||
*/
|
*/
|
||||||
/* CKOUT: clock output on CKOUT pin */
|
/* CKOUT: clock output on CKOUT pin */
|
||||||
/* CKDIV8: divide clock by 8 */
|
/* CKDIV8: divide clock by 8 */
|
||||||
/* External Ceramic Resonator - configuration */
|
/* External Ceramic Resonator - configuration */
|
||||||
@@ -53,42 +53,39 @@ FUSES = {
|
|||||||
any fuses listed below are cleared fuses,
|
any fuses listed below are cleared fuses,
|
||||||
or are CKSEL or SUT bits that are zero. */
|
or are CKSEL or SUT bits that are zero. */
|
||||||
.low = (FUSE_CKSEL3 & FUSE_SUT1),
|
.low = (FUSE_CKSEL3 & FUSE_SUT1),
|
||||||
|
/* == HIGH FUSE or HFUSE settings == */
|
||||||
/* == HIGH FUSE or HFUSE settings == */
|
/* BOOTRST: Enable Bootloader Reset Vector */
|
||||||
/* BOOTRST: Enable Bootloader Reset Vector */
|
/* EESAVE: Enable preserve EEPROM on Chip Erase */
|
||||||
/* EESAVE: Enable preserve EEPROM on Chip Erase */
|
/* WDTON: Enable watchdog timer always on */
|
||||||
/* WDTON: Enable watchdog timer always on */
|
/* SPIEN: Enable Serial Program and Data Downloading */
|
||||||
/* SPIEN: Enable Serial Program and Data Downloading */
|
/* JTAGEN: Enable JTAG */
|
||||||
/* JTAGEN: Enable JTAG */
|
/* OCDEN: Enable OCD */
|
||||||
/* OCDEN: Enable OCD */
|
/* BOOTSZ configuration:
|
||||||
/* BOOTSZ configuration:
|
BOOTSZ1 BOOTSZ0 Boot Size
|
||||||
BOOTSZ1 BOOTSZ0 Boot Size
|
------- ------- ---------
|
||||||
------- ------- ---------
|
1 1 512
|
||||||
1 1 512
|
1 0 1024
|
||||||
1 0 1024
|
0 1 2048
|
||||||
0 1 2048
|
0 0 4096
|
||||||
0 0 4096
|
*/
|
||||||
*/
|
/* note: fuses are enabled by clearing the bit, so
|
||||||
/* note: fuses are enabled by clearing the bit, so
|
any fuses listed below are cleared fuses,
|
||||||
any fuses listed below are cleared fuses,
|
or are BOOTSZ bits that are zero. */
|
||||||
or are BOOTSZ bits that are zero. */
|
.high = (FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
|
||||||
.high =
|
/* == EXTENDED FUSE or EFUSE settings == */
|
||||||
(FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
|
/* BODLEVEL configuration
|
||||||
|
BODLEVEL2 BODLEVEL1 BODLEVEL0 Voltage
|
||||||
/* == EXTENDED FUSE or EFUSE settings == */
|
--------- --------- --------- --------
|
||||||
/* BODLEVEL configuration
|
1 1 1 disabled
|
||||||
BODLEVEL2 BODLEVEL1 BODLEVEL0 Voltage
|
1 1 0 1.8V
|
||||||
--------- --------- --------- --------
|
1 0 1 2.7V
|
||||||
1 1 1 disabled
|
1 0 0 4.3V
|
||||||
1 1 0 1.8V
|
*/
|
||||||
1 0 1 2.7V
|
/* note: fuses are enabled by clearing the bit, so
|
||||||
1 0 0 4.3V
|
any fuses listed below are cleared fuses,
|
||||||
*/
|
or are BODLEVEL bits that are zero. */
|
||||||
/* note: fuses are enabled by clearing the bit, so
|
/* Brown-out detection VCC=4.3V */
|
||||||
any fuses listed below are cleared fuses,
|
.extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0)
|
||||||
or are BODLEVEL bits that are zero. */
|
|
||||||
/* Brown-out detection VCC=4.3V */
|
|
||||||
.extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* AVR lock bits - unlocked */
|
/* AVR lock bits - unlocked */
|
||||||
|
|||||||
@@ -66,9 +66,8 @@ int Encode_Property_APDU(
|
|||||||
case OBJECT_DEVICE:
|
case OBJECT_DEVICE:
|
||||||
if (Device_Valid_Object_Instance_Number(object_instance)) {
|
if (Device_Valid_Object_Instance_Number(object_instance)) {
|
||||||
apdu_len =
|
apdu_len =
|
||||||
Device_Encode_Property_APDU(&apdu[0],
|
Device_Encode_Property_APDU(&apdu[0], object_instance,
|
||||||
object_instance, property,
|
property, array_index, error_class, error_code);
|
||||||
array_index, error_class, error_code);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_ANALOG_INPUT:
|
case OBJECT_ANALOG_INPUT:
|
||||||
|
|||||||
@@ -59,5 +59,5 @@ void init(
|
|||||||
PORTD = 0;
|
PORTD = 0;
|
||||||
/* Configure the watchdog timer - Disabled for testing */
|
/* Configure the watchdog timer - Disabled for testing */
|
||||||
/* wdt_enable(WDTO_2S); */
|
/* wdt_enable(WDTO_2S); */
|
||||||
wdt_disable();
|
wdt_disable();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ static void bacnet_init(
|
|||||||
Analog_Value_Init();
|
Analog_Value_Init();
|
||||||
|
|
||||||
/* set up our confirmed service unrecognized service handler - required! */
|
/* set up our confirmed service unrecognized service handler - required! */
|
||||||
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
|
apdu_set_unrecognized_service_handler_handler
|
||||||
|
(handler_unrecognized_service);
|
||||||
/* we need to handle who-is to support dynamic device binding */
|
/* we need to handle who-is to support dynamic device binding */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
/* Set the handlers for any confirmed services that we support. */
|
/* Set the handlers for any confirmed services that we support. */
|
||||||
@@ -190,7 +191,7 @@ void test_task(
|
|||||||
buffer[12] = (MSTP_MAC_Address & BIT4) ? '1' : '0';
|
buffer[12] = (MSTP_MAC_Address & BIT4) ? '1' : '0';
|
||||||
buffer[13] = (MSTP_MAC_Address & BIT5) ? '1' : '0';
|
buffer[13] = (MSTP_MAC_Address & BIT5) ? '1' : '0';
|
||||||
buffer[14] = (MSTP_MAC_Address & BIT6) ? '1' : '0';
|
buffer[14] = (MSTP_MAC_Address & BIT6) ? '1' : '0';
|
||||||
serial_bytes_send((uint8_t *)buffer, nbytes);
|
serial_bytes_send((uint8_t *) buffer, nbytes);
|
||||||
}
|
}
|
||||||
if (serial_byte_get(&data_register)) {
|
if (serial_byte_get(&data_register)) {
|
||||||
/* echo the character */
|
/* echo the character */
|
||||||
@@ -215,21 +216,23 @@ void test_task(
|
|||||||
}
|
}
|
||||||
if (data_register == 'm') {
|
if (data_register == 'm') {
|
||||||
sprintf(buffer, "->Master State: ");
|
sprintf(buffer, "->Master State: ");
|
||||||
nbytes = (uint8_t)strlen(buffer);
|
nbytes = (uint8_t) strlen(buffer);
|
||||||
serial_bytes_send((uint8_t *)buffer, nbytes);
|
serial_bytes_send((uint8_t *) buffer, nbytes);
|
||||||
extern char *dlmstp_master_state_text(void);
|
extern char *dlmstp_master_state_text(
|
||||||
|
void);
|
||||||
pBuffer = dlmstp_master_state_text();
|
pBuffer = dlmstp_master_state_text();
|
||||||
nbytes = (uint8_t)strlen(pBuffer);
|
nbytes = (uint8_t) strlen(pBuffer);
|
||||||
serial_bytes_send((uint8_t *)pBuffer, nbytes);
|
serial_bytes_send((uint8_t *) pBuffer, nbytes);
|
||||||
}
|
}
|
||||||
if (data_register == 'r') {
|
if (data_register == 'r') {
|
||||||
sprintf(buffer, "->Receive State: ");
|
sprintf(buffer, "->Receive State: ");
|
||||||
nbytes = (uint8_t)strlen(buffer);
|
nbytes = (uint8_t) strlen(buffer);
|
||||||
serial_bytes_send((uint8_t *)buffer, nbytes);
|
serial_bytes_send((uint8_t *) buffer, nbytes);
|
||||||
extern char *dlmstp_receive_state_text(void);
|
extern char *dlmstp_receive_state_text(
|
||||||
|
void);
|
||||||
pBuffer = dlmstp_receive_state_text();
|
pBuffer = dlmstp_receive_state_text();
|
||||||
nbytes = (uint8_t)strlen(pBuffer);
|
nbytes = (uint8_t) strlen(pBuffer);
|
||||||
serial_bytes_send((uint8_t *)pBuffer, nbytes);
|
serial_bytes_send((uint8_t *) pBuffer, nbytes);
|
||||||
}
|
}
|
||||||
serial_byte_send('\r');
|
serial_byte_send('\r');
|
||||||
serial_byte_send('\n');
|
serial_byte_send('\n');
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ static uint16_t Timer_Silence(
|
|||||||
{
|
{
|
||||||
return SilenceTime;
|
return SilenceTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Timer_Silence_Reset(
|
static void Timer_Silence_Reset(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -163,10 +163,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is to support dynamic device binding */
|
/* we need to handle who-is to support dynamic device binding */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, LocalIAmHandler);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, LocalIAmHandler);
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ static uint16_t Timer_Silence(
|
|||||||
{
|
{
|
||||||
return SilenceTime;
|
return SilenceTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Timer_Silence_Reset(
|
static void Timer_Silence_Reset(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ static uint16_t Timer_Silence(
|
|||||||
{
|
{
|
||||||
return SilenceTime;
|
return SilenceTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Timer_Silence_Reset(
|
static void Timer_Silence_Reset(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -310,8 +310,8 @@ bool Analog_Value_Write_Property(
|
|||||||
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
|
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
|
||||||
level = (uint8_t) value.type.Real;
|
level = (uint8_t) value.type.Real;
|
||||||
object_index =
|
object_index =
|
||||||
Analog_Value_Instance_To_Index(wp_data->
|
Analog_Value_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
priority--;
|
priority--;
|
||||||
Present_Value[object_index] = level;
|
Present_Value[object_index] = level;
|
||||||
/* Note: you could set the physical output here if we
|
/* Note: you could set the physical output here if we
|
||||||
|
|||||||
@@ -226,8 +226,8 @@ bool Binary_Value_Write_Property(
|
|||||||
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
||||||
level = value.type.Enumerated;
|
level = value.type.Enumerated;
|
||||||
object_index =
|
object_index =
|
||||||
Binary_Value_Instance_To_Index(wp_data->
|
Binary_Value_Instance_To_Index
|
||||||
object_instance);
|
(wp_data->object_instance);
|
||||||
priority--;
|
priority--;
|
||||||
/* NOTE: this Binary value has no priority array */
|
/* NOTE: this Binary value has no priority array */
|
||||||
Present_Value[object_index] = level;
|
Present_Value[object_index] = level;
|
||||||
|
|||||||
@@ -504,8 +504,8 @@ bool Device_Write_Property(
|
|||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||||
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
(Device_Set_Object_Instance_Number(value.type.
|
||||||
instance))) {
|
Object_Id.instance))) {
|
||||||
/* we could send an I-Am broadcast to let the world know */
|
/* we could send an I-Am broadcast to let the world know */
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -93,9 +93,8 @@ void handler_read_property(
|
|||||||
if (Device_Valid_Object_Instance_Number(data.object_instance)) {
|
if (Device_Valid_Object_Instance_Number(data.object_instance)) {
|
||||||
len =
|
len =
|
||||||
Device_Encode_Property_APDU(&Temp_Buf[0],
|
Device_Encode_Property_APDU(&Temp_Buf[0],
|
||||||
data.object_instance,
|
data.object_instance, data.object_property,
|
||||||
data.object_property, data.array_index, &error_class,
|
data.array_index, &error_class, &error_code);
|
||||||
&error_code);
|
|
||||||
if (len >= 0) {
|
if (len >= 0) {
|
||||||
/* encode the APDU portion of the packet */
|
/* encode the APDU portion of the packet */
|
||||||
data.application_data = &Temp_Buf[0];
|
data.application_data = &Temp_Buf[0];
|
||||||
|
|||||||
@@ -68,12 +68,15 @@ RTFDevice RTFDeviceList[] = {
|
|||||||
#define MAXTYPES 32
|
#define MAXTYPES 32
|
||||||
|
|
||||||
RTW32Handle RTHandleTable[MAXHANDLES] = { {0} };
|
RTW32Handle RTHandleTable[MAXHANDLES] = { {0} };
|
||||||
|
|
||||||
int RTHandleCount = MAXHANDLES;
|
int RTHandleCount = MAXHANDLES;
|
||||||
|
|
||||||
RTW32Object RTObjectTable[MAXOBJECTS] = { {0} };
|
RTW32Object RTObjectTable[MAXOBJECTS] = { {0} };
|
||||||
|
|
||||||
int RTObjectCount = MAXOBJECTS;
|
int RTObjectCount = MAXOBJECTS;
|
||||||
|
|
||||||
RTW32Types RTTypeTable[MAXTYPES] = { {0} };
|
RTW32Types RTTypeTable[MAXTYPES] = { {0} };
|
||||||
|
|
||||||
int RTTypeCount = MAXTYPES;
|
int RTTypeCount = MAXTYPES;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ static uint16_t Timer_Silence(
|
|||||||
{
|
{
|
||||||
return SilenceTime;
|
return SilenceTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Timer_Silence_Reset(
|
static void Timer_Silence_Reset(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
|
|||||||
+59
-120
@@ -68,145 +68,81 @@ static void Init_Object(
|
|||||||
object_index_to_instance_function index_function,
|
object_index_to_instance_function index_function,
|
||||||
object_name_function name_function)
|
object_name_function name_function)
|
||||||
{
|
{
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(object_type, rp_function,
|
||||||
object_type,
|
|
||||||
rp_function,
|
|
||||||
object_valid_function);
|
object_valid_function);
|
||||||
handler_write_property_object_set(
|
handler_write_property_object_set(object_type, wp_function);
|
||||||
object_type,
|
handler_read_property_multiple_list_set(object_type, rpm_list_function);
|
||||||
wp_function);
|
Device_Object_Function_Set(object_type, count_function, index_function,
|
||||||
handler_read_property_multiple_list_set(
|
|
||||||
object_type,
|
|
||||||
rpm_list_function);
|
|
||||||
Device_Object_Function_Set(
|
|
||||||
object_type,
|
|
||||||
count_function,
|
|
||||||
index_function,
|
|
||||||
name_function);
|
name_function);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Init_Objects(void)
|
static void Init_Objects(
|
||||||
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_DEVICE, Device_Property_Lists,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number,
|
||||||
Device_Property_Lists,
|
Device_Write_Property, NULL, NULL, NULL);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number,
|
|
||||||
Device_Write_Property,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Analog_Input_Init();
|
Analog_Input_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_INPUT, Analog_Input_Property_Lists,
|
||||||
OBJECT_ANALOG_INPUT,
|
Analog_Input_Encode_Property_APDU, Analog_Input_Valid_Instance, NULL,
|
||||||
Analog_Input_Property_Lists,
|
Analog_Input_Count, Analog_Input_Index_To_Instance, Analog_Input_Name);
|
||||||
Analog_Input_Encode_Property_APDU,
|
|
||||||
Analog_Input_Valid_Instance,
|
|
||||||
NULL,
|
|
||||||
Analog_Input_Count,
|
|
||||||
Analog_Input_Index_To_Instance,
|
|
||||||
Analog_Input_Name);
|
|
||||||
|
|
||||||
Analog_Output_Init();
|
Analog_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_OUTPUT, Analog_Output_Property_Lists,
|
||||||
OBJECT_ANALOG_OUTPUT,
|
Analog_Output_Encode_Property_APDU, Analog_Output_Valid_Instance,
|
||||||
Analog_Output_Property_Lists,
|
Analog_Output_Write_Property, Analog_Output_Count,
|
||||||
Analog_Output_Encode_Property_APDU,
|
Analog_Output_Index_To_Instance, Analog_Output_Name);
|
||||||
Analog_Output_Valid_Instance,
|
|
||||||
Analog_Output_Write_Property,
|
|
||||||
Analog_Output_Count,
|
|
||||||
Analog_Output_Index_To_Instance,
|
|
||||||
Analog_Output_Name);
|
|
||||||
|
|
||||||
Analog_Value_Init();
|
Analog_Value_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_ANALOG_VALUE, Analog_Value_Property_Lists,
|
||||||
OBJECT_ANALOG_VALUE,
|
Analog_Value_Encode_Property_APDU, Analog_Value_Valid_Instance,
|
||||||
Analog_Value_Property_Lists,
|
Analog_Value_Write_Property, Analog_Value_Count,
|
||||||
Analog_Value_Encode_Property_APDU,
|
Analog_Value_Index_To_Instance, Analog_Value_Name);
|
||||||
Analog_Value_Valid_Instance,
|
|
||||||
Analog_Value_Write_Property,
|
|
||||||
Analog_Value_Count,
|
|
||||||
Analog_Value_Index_To_Instance,
|
|
||||||
Analog_Value_Name);
|
|
||||||
|
|
||||||
Binary_Input_Init();
|
Binary_Input_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_INPUT, Binary_Input_Property_Lists,
|
||||||
OBJECT_BINARY_INPUT,
|
Binary_Input_Encode_Property_APDU, Binary_Input_Valid_Instance, NULL,
|
||||||
Binary_Input_Property_Lists,
|
Binary_Input_Count, Binary_Input_Index_To_Instance, Binary_Input_Name);
|
||||||
Binary_Input_Encode_Property_APDU,
|
|
||||||
Binary_Input_Valid_Instance,
|
|
||||||
NULL,
|
|
||||||
Binary_Input_Count,
|
|
||||||
Binary_Input_Index_To_Instance,
|
|
||||||
Binary_Input_Name);
|
|
||||||
|
|
||||||
Binary_Output_Init();
|
Binary_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_OUTPUT, Binary_Output_Property_Lists,
|
||||||
OBJECT_BINARY_OUTPUT,
|
Binary_Output_Encode_Property_APDU, Binary_Output_Valid_Instance,
|
||||||
Binary_Output_Property_Lists,
|
Binary_Output_Write_Property, Binary_Output_Count,
|
||||||
Binary_Output_Encode_Property_APDU,
|
Binary_Output_Index_To_Instance, Binary_Output_Name);
|
||||||
Binary_Output_Valid_Instance,
|
|
||||||
Binary_Output_Write_Property,
|
|
||||||
Binary_Output_Count,
|
|
||||||
Binary_Output_Index_To_Instance,
|
|
||||||
Binary_Output_Name);
|
|
||||||
|
|
||||||
Binary_Value_Init();
|
Binary_Value_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_BINARY_VALUE, Binary_Value_Property_Lists,
|
||||||
OBJECT_BINARY_VALUE,
|
Binary_Value_Encode_Property_APDU, Binary_Value_Valid_Instance,
|
||||||
Binary_Value_Property_Lists,
|
Binary_Value_Write_Property, Binary_Value_Count,
|
||||||
Binary_Value_Encode_Property_APDU,
|
Binary_Value_Index_To_Instance, Binary_Value_Name);
|
||||||
Binary_Value_Valid_Instance,
|
|
||||||
Binary_Value_Write_Property,
|
|
||||||
Binary_Value_Count,
|
|
||||||
Binary_Value_Index_To_Instance,
|
|
||||||
Binary_Value_Name);
|
|
||||||
|
|
||||||
Life_Safety_Point_Init();
|
Life_Safety_Point_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Property_Lists,
|
||||||
OBJECT_LIFE_SAFETY_POINT,
|
|
||||||
Life_Safety_Point_Property_Lists,
|
|
||||||
Life_Safety_Point_Encode_Property_APDU,
|
Life_Safety_Point_Encode_Property_APDU,
|
||||||
Life_Safety_Point_Valid_Instance,
|
Life_Safety_Point_Valid_Instance, Life_Safety_Point_Write_Property,
|
||||||
Life_Safety_Point_Write_Property,
|
Life_Safety_Point_Count, Life_Safety_Point_Index_To_Instance,
|
||||||
Life_Safety_Point_Count,
|
|
||||||
Life_Safety_Point_Index_To_Instance,
|
|
||||||
Life_Safety_Point_Name);
|
Life_Safety_Point_Name);
|
||||||
|
|
||||||
Load_Control_Init();
|
Load_Control_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_LOAD_CONTROL, Load_Control_Property_Lists,
|
||||||
OBJECT_LOAD_CONTROL,
|
Load_Control_Encode_Property_APDU, Load_Control_Valid_Instance,
|
||||||
Load_Control_Property_Lists,
|
Load_Control_Write_Property, Load_Control_Count,
|
||||||
Load_Control_Encode_Property_APDU,
|
Load_Control_Index_To_Instance, Load_Control_Name);
|
||||||
Load_Control_Valid_Instance,
|
|
||||||
Load_Control_Write_Property,
|
|
||||||
Load_Control_Count,
|
|
||||||
Load_Control_Index_To_Instance,
|
|
||||||
Load_Control_Name);
|
|
||||||
|
|
||||||
Multistate_Output_Init();
|
Multistate_Output_Init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Property_Lists,
|
||||||
OBJECT_MULTI_STATE_OUTPUT,
|
|
||||||
Multistate_Output_Property_Lists,
|
|
||||||
Multistate_Output_Encode_Property_APDU,
|
Multistate_Output_Encode_Property_APDU,
|
||||||
Multistate_Output_Valid_Instance,
|
Multistate_Output_Valid_Instance, Multistate_Output_Write_Property,
|
||||||
Multistate_Output_Write_Property,
|
Multistate_Output_Count, Multistate_Output_Index_To_Instance,
|
||||||
Multistate_Output_Count,
|
|
||||||
Multistate_Output_Index_To_Instance,
|
|
||||||
Multistate_Output_Name);
|
Multistate_Output_Name);
|
||||||
|
|
||||||
#if defined(BACFILE)
|
#if defined(BACFILE)
|
||||||
bacfile_init();
|
bacfile_init();
|
||||||
Init_Object(
|
Init_Object(OBJECT_FILE, BACfile_Property_Lists,
|
||||||
OBJECT_FILE,
|
bacfile_encode_property_apdu, bacfile_valid_instance,
|
||||||
BACfile_Property_Lists,
|
bacfile_write_property, bacfile_count, bacfile_index_to_instance,
|
||||||
bacfile_encode_property_apdu,
|
|
||||||
bacfile_valid_instance,
|
|
||||||
bacfile_write_property,
|
|
||||||
bacfile_count,
|
|
||||||
bacfile_index_to_instance,
|
|
||||||
bacfile_name);
|
bacfile_name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -320,10 +256,8 @@ static void Init_Service_Handlers(
|
|||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Device_Init();
|
Device_Init();
|
||||||
handler_read_property_object_set(
|
handler_read_property_object_set(OBJECT_DEVICE,
|
||||||
OBJECT_DEVICE,
|
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number);
|
||||||
Device_Encode_Property_APDU,
|
|
||||||
Device_Valid_Object_Instance_Number);
|
|
||||||
/* we need to handle who-is to support dynamic device binding */
|
/* we need to handle who-is to support dynamic device binding */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, LocalIAmHandler);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, LocalIAmHandler);
|
||||||
@@ -333,8 +267,10 @@ static void Init_Service_Handlers(
|
|||||||
apdu_set_unrecognized_service_handler_handler
|
apdu_set_unrecognized_service_handler_handler
|
||||||
(handler_unrecognized_service);
|
(handler_unrecognized_service);
|
||||||
/* we must implement read property - it's required! */
|
/* we must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
handler_read_property);
|
||||||
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
||||||
|
handler_read_property_multiple);
|
||||||
/* handle the data coming back from confirmed requests */
|
/* handle the data coming back from confirmed requests */
|
||||||
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
handler_read_property_ack);
|
handler_read_property_ack);
|
||||||
@@ -377,13 +313,16 @@ static void print_address_cache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(
|
||||||
|
int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
BACNET_ADDRESS src = {
|
BACNET_ADDRESS src = {
|
||||||
0}; /* address where message came from */
|
0
|
||||||
|
}; /* address where message came from */
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; /* milliseconds */
|
unsigned timeout = 100; /* milliseconds */
|
||||||
BACNET_ADDRESS my_address,
|
BACNET_ADDRESS my_address, broadcast_address;
|
||||||
broadcast_address;
|
|
||||||
|
|
||||||
(void) argc;
|
(void) argc;
|
||||||
(void) argv;
|
(void) argv;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user