indented using indent.sh script to get uniform looking code for release
This commit is contained in:
@@ -211,7 +211,8 @@ int main(
|
||||
}
|
||||
/* at least one second has passed */
|
||||
if (current_seconds != last_seconds)
|
||||
tsm_timer_milliseconds((uint16_t)((current_seconds - last_seconds) * 1000));
|
||||
tsm_timer_milliseconds((uint16_t) ((current_seconds -
|
||||
last_seconds) * 1000));
|
||||
if (Error_Detected)
|
||||
break;
|
||||
/* wait until the device is bound, or timeout and quit */
|
||||
|
||||
@@ -141,7 +141,8 @@ static struct property_value_list_t Property_Value_List[] = {
|
||||
{-1, NULL}
|
||||
};
|
||||
|
||||
static BACNET_APPLICATION_DATA_VALUE *object_property_value(int32_t property_id)
|
||||
static BACNET_APPLICATION_DATA_VALUE *object_property_value(
|
||||
int32_t property_id)
|
||||
{
|
||||
BACNET_APPLICATION_DATA_VALUE *value = NULL;
|
||||
int32_t index = 0;
|
||||
@@ -414,8 +415,10 @@ void CheckIsWritableProperty(
|
||||
bIsWritable = true;
|
||||
}
|
||||
} else if (object_type == OBJECT_NETWORK_SECURITY) {
|
||||
if ((rpm_property->propertyIdentifier == PROP_BASE_DEVICE_SECURITY_POLICY) ||
|
||||
(rpm_property->propertyIdentifier == PROP_NETWORK_ACCESS_SECURITY_POLICIES) ||
|
||||
if ((rpm_property->propertyIdentifier ==
|
||||
PROP_BASE_DEVICE_SECURITY_POLICY) ||
|
||||
(rpm_property->propertyIdentifier ==
|
||||
PROP_NETWORK_ACCESS_SECURITY_POLICIES) ||
|
||||
(rpm_property->propertyIdentifier == PROP_SECURITY_TIME_WINDOW) ||
|
||||
(rpm_property->propertyIdentifier == PROP_PACKET_REORDER_TIME) ||
|
||||
(rpm_property->propertyIdentifier == PROP_LAST_KEY_SERVER) ||
|
||||
@@ -434,7 +437,8 @@ void CheckIsWritableProperty(
|
||||
}
|
||||
|
||||
|
||||
static const char *protocol_services_supported_text(size_t bit_index)
|
||||
static const char *protocol_services_supported_text(
|
||||
size_t bit_index)
|
||||
{
|
||||
bool is_confirmed = false;
|
||||
size_t text_index = 0;
|
||||
@@ -1154,9 +1158,8 @@ void PrintHeading(
|
||||
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
||||
printf("Product Description: \"%s\"\r\n\r\n",
|
||||
characterstring_value(&value->type.Character_String));
|
||||
}else {
|
||||
printf(
|
||||
"Product Description: "
|
||||
} else {
|
||||
printf("Product Description: "
|
||||
"\"your product description here\"\r\n\r\n");
|
||||
}
|
||||
printf("BIBBs Supported:\r\n");
|
||||
@@ -1220,7 +1223,8 @@ void PrintHeading(
|
||||
printf("-- SubscribeCOVProperty Initiate Execute\r\n");
|
||||
#ifdef BAC_ROUTING
|
||||
if (Target_Address.net == 0) {
|
||||
printf("-- Note: The following Routing Services are Supported:\r\n");
|
||||
printf
|
||||
("-- Note: The following Routing Services are Supported:\r\n");
|
||||
printf("-- Who-Is-Router-To-Network Initiate Execute\r\n");
|
||||
printf("-- I-Am-Router-To-Network Initiate Execute\r\n");
|
||||
printf("-- Initialize-Routing-Table Execute\r\n");
|
||||
@@ -1441,7 +1445,8 @@ int main(
|
||||
current_seconds = time(NULL);
|
||||
/* Has at least one second passed ? */
|
||||
if (current_seconds != last_seconds) {
|
||||
tsm_timer_milliseconds((uint16_t)((current_seconds - last_seconds) * 1000));
|
||||
tsm_timer_milliseconds((uint16_t) ((current_seconds -
|
||||
last_seconds) * 1000));
|
||||
}
|
||||
|
||||
/* OK to proceed; see what we are up to now */
|
||||
@@ -1629,11 +1634,11 @@ int main(
|
||||
(Request_Invoke_ID ==
|
||||
Read_Property_Multiple_Data.service_data.invoke_id)) {
|
||||
Read_Property_Multiple_Data.new_data = false;
|
||||
PrintReadPropertyData
|
||||
(Read_Property_Multiple_Data.rpm_data->object_type,
|
||||
PrintReadPropertyData(Read_Property_Multiple_Data.
|
||||
rpm_data->object_type,
|
||||
Read_Property_Multiple_Data.rpm_data->object_instance,
|
||||
Read_Property_Multiple_Data.
|
||||
rpm_data->listOfProperties);
|
||||
Read_Property_Multiple_Data.rpm_data->
|
||||
listOfProperties);
|
||||
if (tsm_invoke_id_free(Request_Invoke_ID)) {
|
||||
Request_Invoke_ID = 0;
|
||||
} else {
|
||||
|
||||
@@ -150,7 +150,7 @@ int dlenv_register_as_foreign_device(
|
||||
if (retval < 0)
|
||||
fprintf(stderr, "FAILED to Register with BBMD at %s \n",
|
||||
inet_ntoa(addr));
|
||||
BBMD_Timer_Seconds = (uint16_t)bbmd_timetolive_seconds;
|
||||
BBMD_Timer_Seconds = (uint16_t) bbmd_timetolive_seconds;
|
||||
}
|
||||
|
||||
bbmd_result = retval;
|
||||
@@ -176,7 +176,7 @@ void dlenv_maintenance_timer(
|
||||
BBMD_Timer_Seconds -= elapsed_seconds;
|
||||
}
|
||||
if (BBMD_Timer_Seconds == 0) {
|
||||
(void)dlenv_register_as_foreign_device();
|
||||
(void) dlenv_register_as_foreign_device();
|
||||
/* If that failed (negative), maybe just a network issue.
|
||||
* If nothing happened (0), may be un/misconfigured.
|
||||
* Set up to try again later in all cases. */
|
||||
|
||||
@@ -125,8 +125,8 @@ void handler_ccov_notification(
|
||||
fprintf(stderr, "CCOV: ");
|
||||
if (pProperty_value->propertyIdentifier < 512) {
|
||||
fprintf(stderr, "%s ",
|
||||
bactext_property_name(pProperty_value->
|
||||
propertyIdentifier));
|
||||
bactext_property_name
|
||||
(pProperty_value->propertyIdentifier));
|
||||
} else {
|
||||
fprintf(stderr, "proprietary %u ",
|
||||
pProperty_value->propertyIdentifier);
|
||||
|
||||
@@ -311,7 +311,7 @@ static bool cov_list_subscribe(
|
||||
/* From BACnet Standard 135-2010-13.14.2
|
||||
...Cancellations that are issued for which no matching COV
|
||||
context can be found shall succeed as if a context had
|
||||
existed, returning 'Result(+)'.*/
|
||||
existed, returning 'Result(+)'. */
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -406,10 +406,10 @@ static void cov_lifetime_expiration_handler(
|
||||
/* expire the subscription */
|
||||
#if PRINT_ENABLED
|
||||
fprintf(stderr, "COVtimer: PID=%u ",
|
||||
COV_Subscriptions[index].subscriberProcessIdentifier);
|
||||
COV_Subscriptions[index].subscriberProcessIdentifier);
|
||||
fprintf(stderr, "%s %u ",
|
||||
bactext_object_type_name(
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.type),
|
||||
bactext_object_type_name(COV_Subscriptions[index].
|
||||
monitoredObjectIdentifier.type),
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.instance);
|
||||
fprintf(stderr, "time remaining=%u seconds ",
|
||||
COV_Subscriptions[index].lifetime);
|
||||
@@ -497,13 +497,13 @@ void handler_cov_task(
|
||||
object_type = (BACNET_OBJECT_TYPE)
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.type;
|
||||
object_instance =
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.
|
||||
instance;
|
||||
COV_Subscriptions[index].
|
||||
monitoredObjectIdentifier.instance;
|
||||
status = Device_COV(object_type, object_instance);
|
||||
if (status) {
|
||||
COV_Subscriptions[index].flag.send_requested = true;
|
||||
#if PRINT_ENABLED
|
||||
fprintf(stderr,"COVtask: Marking...\n");
|
||||
fprintf(stderr, "COVtask: Marking...\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -520,8 +520,8 @@ void handler_cov_task(
|
||||
object_type = (BACNET_OBJECT_TYPE)
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.type;
|
||||
object_instance =
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.
|
||||
instance;
|
||||
COV_Subscriptions[index].
|
||||
monitoredObjectIdentifier.instance;
|
||||
Device_COV_Clear(object_type, object_instance);
|
||||
}
|
||||
index++;
|
||||
@@ -537,8 +537,9 @@ void handler_cov_task(
|
||||
(COV_Subscriptions[index].invokeID)) {
|
||||
if (tsm_invoke_id_free(COV_Subscriptions[index].invokeID)) {
|
||||
COV_Subscriptions[index].invokeID = 0;
|
||||
} else if (tsm_invoke_id_failed(COV_Subscriptions[index].
|
||||
invokeID)) {
|
||||
} else
|
||||
if (tsm_invoke_id_failed(COV_Subscriptions
|
||||
[index].invokeID)) {
|
||||
tsm_free_invoke_id(COV_Subscriptions[index].invokeID);
|
||||
COV_Subscriptions[index].invokeID = 0;
|
||||
}
|
||||
@@ -566,13 +567,13 @@ void handler_cov_task(
|
||||
}
|
||||
if (send) {
|
||||
object_type = (BACNET_OBJECT_TYPE)
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.
|
||||
type;
|
||||
COV_Subscriptions[index].
|
||||
monitoredObjectIdentifier.type;
|
||||
object_instance =
|
||||
COV_Subscriptions[index].monitoredObjectIdentifier.
|
||||
instance;
|
||||
COV_Subscriptions[index].
|
||||
monitoredObjectIdentifier.instance;
|
||||
#if PRINT_ENABLED
|
||||
fprintf(stderr,"COVtask: Sending...\n");
|
||||
fprintf(stderr, "COVtask: Sending...\n");
|
||||
#endif
|
||||
/* configure the linked list for the two properties */
|
||||
value_list[0].next = &value_list[1];
|
||||
|
||||
@@ -56,24 +56,23 @@
|
||||
* decoded from the APDU header of this message.
|
||||
*/
|
||||
void get_alarm_summary_ack_handler(
|
||||
uint8_t *service_request,
|
||||
uint8_t * service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
BACNET_ADDRESS * src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
|
||||
{
|
||||
uint16_t apdu_len = 0;
|
||||
uint16_t len = 0;
|
||||
BACNET_GET_ALARM_SUMMARY_DATA data;
|
||||
|
||||
while(service_len - len){
|
||||
apdu_len = get_alarm_summary_ack_decode_apdu_data(
|
||||
&service_request[len],
|
||||
service_len - len,
|
||||
&data);
|
||||
while (service_len - len) {
|
||||
apdu_len =
|
||||
get_alarm_summary_ack_decode_apdu_data(&service_request[len],
|
||||
service_len - len, &data);
|
||||
|
||||
len += apdu_len;
|
||||
|
||||
if(apdu_len > 0){
|
||||
if (apdu_len > 0) {
|
||||
/* FIXME: Add code to process data */
|
||||
} else {
|
||||
break;
|
||||
|
||||
@@ -221,8 +221,8 @@ void rpm_ack_print_data(
|
||||
#if PRINT_ENABLED
|
||||
if (listOfProperties->propertyIdentifier < 512) {
|
||||
fprintf(stdout, " %s: ",
|
||||
bactext_property_name
|
||||
(listOfProperties->propertyIdentifier));
|
||||
bactext_property_name(listOfProperties->
|
||||
propertyIdentifier));
|
||||
} else {
|
||||
fprintf(stdout, " proprietary %u: ",
|
||||
(unsigned) listOfProperties->propertyIdentifier);
|
||||
@@ -269,10 +269,10 @@ void rpm_ack_print_data(
|
||||
#if PRINT_ENABLED
|
||||
/* AccessError */
|
||||
fprintf(stdout, "BACnet Error: %s: %s\r\n",
|
||||
bactext_error_class_name((int) listOfProperties->error.
|
||||
error_class),
|
||||
bactext_error_code_name((int) listOfProperties->error.
|
||||
error_code));
|
||||
bactext_error_class_name((int) listOfProperties->
|
||||
error.error_class),
|
||||
bactext_error_code_name((int) listOfProperties->
|
||||
error.error_code));
|
||||
#endif
|
||||
}
|
||||
listOfProperties = listOfProperties->next;
|
||||
|
||||
@@ -104,8 +104,8 @@ void handler_ucov_notification(
|
||||
fprintf(stderr, "UCOV: ");
|
||||
if (pProperty_value->propertyIdentifier < 512) {
|
||||
fprintf(stderr, "%s ",
|
||||
bactext_property_name(pProperty_value->
|
||||
propertyIdentifier));
|
||||
bactext_property_name
|
||||
(pProperty_value->propertyIdentifier));
|
||||
} else {
|
||||
fprintf(stderr, "proprietary %u ",
|
||||
pProperty_value->propertyIdentifier);
|
||||
|
||||
@@ -65,8 +65,9 @@ static void match_name_or_object(
|
||||
} else {
|
||||
/* valid object_name copy in my device? */
|
||||
found =
|
||||
Device_Object_Name_Copy((BACNET_OBJECT_TYPE) data->object.
|
||||
identifier.type, data->object.identifier.instance, &object_name);
|
||||
Device_Object_Name_Copy((BACNET_OBJECT_TYPE) data->
|
||||
object.identifier.type, data->object.identifier.instance,
|
||||
&object_name);
|
||||
if (found) {
|
||||
Send_I_Have(Device_Object_Instance_Number(),
|
||||
(BACNET_OBJECT_TYPE) data->object.identifier.type,
|
||||
|
||||
@@ -175,10 +175,9 @@ void handler_write_property_multiple(
|
||||
fprintf(stderr, "WPM: Sending Abort!\n");
|
||||
#endif
|
||||
} else if (len == BACNET_STATUS_ERROR) {
|
||||
apdu_len = wpm_error_ack_encode_apdu(
|
||||
&Handler_Transmit_Buffer[npdu_len],
|
||||
service_data->invoke_id,
|
||||
&wp_data);
|
||||
apdu_len =
|
||||
wpm_error_ack_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
|
||||
service_data->invoke_id, &wp_data);
|
||||
#if PRINT_ENABLED
|
||||
fprintf(stderr, "WPM: Sending Error!\n");
|
||||
#endif
|
||||
|
||||
@@ -97,7 +97,7 @@ uint8_t Send_Private_Transfer_Request(
|
||||
block->cMyByte2);
|
||||
len +=
|
||||
encode_application_real(&pt_req_buffer[len], block->fMyReal);
|
||||
characterstring_init_ansi(&bsTemp, (char *)block->sMyString);
|
||||
characterstring_init_ansi(&bsTemp, (char *) block->sMyString);
|
||||
len +=
|
||||
encode_application_character_string(&pt_req_buffer[len],
|
||||
&bsTemp);
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
* @return invoke id of outgoing message, or 0 if device is not bound or no tsm available
|
||||
*/
|
||||
uint8_t Send_Read_Property_Request_Address(
|
||||
BACNET_ADDRESS *dest,
|
||||
BACNET_ADDRESS * dest,
|
||||
uint16_t max_apdu,
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
@@ -149,7 +149,7 @@ uint8_t Send_Read_Property_Request(
|
||||
BACNET_PROPERTY_ID object_property,
|
||||
uint32_t array_index)
|
||||
{
|
||||
BACNET_ADDRESS dest = {0};
|
||||
BACNET_ADDRESS dest = { 0 };
|
||||
unsigned max_apdu = 0;
|
||||
uint8_t invoke_id = 0;
|
||||
bool status = false;
|
||||
@@ -157,10 +157,9 @@ uint8_t Send_Read_Property_Request(
|
||||
/* is the device bound? */
|
||||
status = address_get_by_device(device_id, &max_apdu, &dest);
|
||||
if (status) {
|
||||
invoke_id = Send_Read_Property_Request_Address(
|
||||
&dest, max_apdu, object_type,
|
||||
object_instance, object_property,
|
||||
array_index);
|
||||
invoke_id =
|
||||
Send_Read_Property_Request_Address(&dest, max_apdu, object_type,
|
||||
object_instance, object_property, array_index);
|
||||
}
|
||||
|
||||
return invoke_id;
|
||||
|
||||
@@ -157,8 +157,9 @@ uint8_t Send_Write_Property_Request(
|
||||
#if PRINT_ENABLED_DEBUG
|
||||
fprintf(stderr, "WriteProperty service: " "%s tag=%d\n",
|
||||
(object_value->context_specific ? "context" : "application"),
|
||||
(int) (object_value->context_specific ? object_value->
|
||||
context_tag : object_value->tag));
|
||||
(int) (object_value->
|
||||
context_specific ? object_value->context_tag : object_value->
|
||||
tag));
|
||||
#endif
|
||||
len = bacapp_encode_data(&application_data[apdu_len], object_value);
|
||||
if ((len + apdu_len) < MAX_APDU) {
|
||||
|
||||
@@ -316,13 +316,13 @@ static void packet_statistics_clear(
|
||||
}
|
||||
|
||||
static uint32_t Timer_Silence(
|
||||
void * pArg)
|
||||
void *pArg)
|
||||
{
|
||||
return timer_milliseconds(TIMER_SILENCE);
|
||||
}
|
||||
|
||||
static void Timer_Silence_Reset(
|
||||
void * pArg)
|
||||
void *pArg)
|
||||
{
|
||||
timer_reset(TIMER_SILENCE);
|
||||
}
|
||||
@@ -823,7 +823,7 @@ int main(
|
||||
if (test_global_header(argv[2])) {
|
||||
while (read_received_packet(mstp_port)) {
|
||||
packet_count++;
|
||||
fprintf(stderr, "\r%u packets", (unsigned)packet_count);
|
||||
fprintf(stderr, "\r%u packets", (unsigned) packet_count);
|
||||
}
|
||||
if (packet_count) {
|
||||
packet_statistics_print();
|
||||
|
||||
@@ -352,11 +352,11 @@ int Analog_Input_Read_Property(
|
||||
case PROP_LIMIT_ENABLE:
|
||||
bitstring_init(&bit_string);
|
||||
bitstring_set_bit(&bit_string, 0,
|
||||
(CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true :
|
||||
false);
|
||||
(CurrentAI->
|
||||
Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true : false);
|
||||
bitstring_set_bit(&bit_string, 1,
|
||||
(CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true :
|
||||
false);
|
||||
(CurrentAI->
|
||||
Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true : false);
|
||||
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
@@ -364,14 +364,14 @@ int Analog_Input_Read_Property(
|
||||
case PROP_EVENT_ENABLE:
|
||||
bitstring_init(&bit_string);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL,
|
||||
(CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true :
|
||||
false);
|
||||
(CurrentAI->
|
||||
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
|
||||
(CurrentAI->Event_Enable & EVENT_ENABLE_TO_FAULT) ? true :
|
||||
false);
|
||||
(CurrentAI->
|
||||
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
|
||||
(CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true :
|
||||
false);
|
||||
(CurrentAI->
|
||||
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false);
|
||||
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
@@ -379,8 +379,8 @@ int Analog_Input_Read_Property(
|
||||
case PROP_ACKED_TRANSITIONS:
|
||||
bitstring_init(&bit_string);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL,
|
||||
CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
|
||||
@@ -637,7 +637,7 @@ bool Analog_Input_Write_Property(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
|
||||
if (status) {
|
||||
switch ((BACNET_NOTIFY_TYPE)value.type.Enumerated) {
|
||||
switch ((BACNET_NOTIFY_TYPE) value.type.Enumerated) {
|
||||
case NOTIFY_EVENT:
|
||||
CurrentAI->Notify_Type = 1;
|
||||
break;
|
||||
@@ -922,17 +922,17 @@ void Analog_Input_Intrinsic_Reporting(
|
||||
event_data.notificationParams.outOfRange.exceedingValue =
|
||||
PresentVal;
|
||||
/* Status_Flags of the referenced object. */
|
||||
bitstring_init(&event_data.notificationParams.
|
||||
outOfRange.statusFlags);
|
||||
bitstring_set_bit(&event_data.notificationParams.
|
||||
outOfRange.statusFlags, STATUS_FLAG_IN_ALARM,
|
||||
bitstring_init(&event_data.notificationParams.outOfRange.
|
||||
statusFlags);
|
||||
bitstring_set_bit(&event_data.notificationParams.outOfRange.
|
||||
statusFlags, STATUS_FLAG_IN_ALARM,
|
||||
CurrentAI->Event_State ? true : false);
|
||||
bitstring_set_bit(&event_data.notificationParams.
|
||||
outOfRange.statusFlags, STATUS_FLAG_FAULT, false);
|
||||
bitstring_set_bit(&event_data.notificationParams.
|
||||
outOfRange.statusFlags, STATUS_FLAG_OVERRIDDEN, false);
|
||||
bitstring_set_bit(&event_data.notificationParams.
|
||||
outOfRange.statusFlags, STATUS_FLAG_OUT_OF_SERVICE,
|
||||
bitstring_set_bit(&event_data.notificationParams.outOfRange.
|
||||
statusFlags, STATUS_FLAG_FAULT, false);
|
||||
bitstring_set_bit(&event_data.notificationParams.outOfRange.
|
||||
statusFlags, STATUS_FLAG_OVERRIDDEN, false);
|
||||
bitstring_set_bit(&event_data.notificationParams.outOfRange.
|
||||
statusFlags, STATUS_FLAG_OUT_OF_SERVICE,
|
||||
CurrentAI->Out_Of_Service);
|
||||
/* Deadband used for limit checking. */
|
||||
event_data.notificationParams.outOfRange.deadband =
|
||||
@@ -952,30 +952,24 @@ void Analog_Input_Intrinsic_Reporting(
|
||||
case EVENT_STATE_OFFNORMAL:
|
||||
case EVENT_STATE_HIGH_LIMIT:
|
||||
case EVENT_STATE_LOW_LIMIT:
|
||||
CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked =
|
||||
false;
|
||||
CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].Time_Stamp =
|
||||
event_data.timeStamp.value.dateTime;
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked = false;
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
Time_Stamp = event_data.timeStamp.value.dateTime;
|
||||
break;
|
||||
|
||||
case EVENT_STATE_FAULT:
|
||||
CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked =
|
||||
false;
|
||||
CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].Time_Stamp =
|
||||
event_data.timeStamp.value.dateTime;
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].
|
||||
bIsAcked = false;
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].
|
||||
Time_Stamp = event_data.timeStamp.value.dateTime;
|
||||
break;
|
||||
|
||||
case EVENT_STATE_NORMAL:
|
||||
CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked =
|
||||
false;
|
||||
CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].Time_Stamp =
|
||||
event_data.timeStamp.value.dateTime;
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL].
|
||||
bIsAcked = false;
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL].
|
||||
Time_Stamp = event_data.timeStamp.value.dateTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1002,12 +996,12 @@ int Analog_Input_Event_Information(
|
||||
/* Acked_Transitions property, which has at least one of the bits
|
||||
(TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */
|
||||
IsNotAckedTransitions =
|
||||
(AI_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked ==
|
||||
false) | (AI_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked ==
|
||||
false) | (AI_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked == false);
|
||||
(AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked ==
|
||||
false) | (AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].
|
||||
bIsAcked ==
|
||||
false) | (AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].
|
||||
bIsAcked == false);
|
||||
} else
|
||||
return -1; /* end of list */
|
||||
|
||||
@@ -1022,8 +1016,8 @@ int Analog_Input_Event_Information(
|
||||
bitstring_init(&getevent_data->acknowledgedTransitions);
|
||||
bitstring_set_bit(&getevent_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_OFFNORMAL,
|
||||
AI_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
|
||||
AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked);
|
||||
bitstring_set_bit(&getevent_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_FAULT,
|
||||
AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
|
||||
@@ -1041,14 +1035,14 @@ int Analog_Input_Event_Information(
|
||||
/* Event Enable */
|
||||
bitstring_init(&getevent_data->eventEnable);
|
||||
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL,
|
||||
(AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true :
|
||||
false);
|
||||
(AI_Descr[index].
|
||||
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false);
|
||||
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT,
|
||||
(AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT) ? true :
|
||||
false);
|
||||
(AI_Descr[index].
|
||||
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false);
|
||||
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL,
|
||||
(AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true :
|
||||
false);
|
||||
(AI_Descr[index].
|
||||
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false);
|
||||
/* Event Priorities */
|
||||
Notification_Class_Get_Priorities(AI_Descr[index].Notification_Class,
|
||||
getevent_data->eventPriorities);
|
||||
@@ -1068,8 +1062,8 @@ int Analog_Input_Alarm_Ack(
|
||||
|
||||
|
||||
object_index =
|
||||
Analog_Input_Instance_To_Index(alarmack_data->
|
||||
eventObjectIdentifier.instance);
|
||||
Analog_Input_Instance_To_Index(alarmack_data->eventObjectIdentifier.
|
||||
instance);
|
||||
|
||||
if (object_index < MAX_ANALOG_INPUTS)
|
||||
CurrentAI = &AI_Descr[object_index];
|
||||
@@ -1082,22 +1076,22 @@ int Analog_Input_Alarm_Ack(
|
||||
case EVENT_STATE_OFFNORMAL:
|
||||
case EVENT_STATE_HIGH_LIMIT:
|
||||
case EVENT_STATE_LOW_LIMIT:
|
||||
if (CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked == false) {
|
||||
if (CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked == false) {
|
||||
if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) {
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
if (datetime_compare(&CurrentAI->Acked_Transitions
|
||||
[TRANSITION_TO_OFFNORMAL].Time_Stamp,
|
||||
if (datetime_compare(&CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].Time_Stamp,
|
||||
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* FIXME: Send ack notification */
|
||||
CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked = true;
|
||||
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked = true;
|
||||
} else {
|
||||
*error_code = ERROR_CODE_INVALID_EVENT_STATE;
|
||||
return -1;
|
||||
@@ -1111,8 +1105,8 @@ int Analog_Input_Alarm_Ack(
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
if (datetime_compare(&CurrentAI->Acked_Transitions
|
||||
[TRANSITION_TO_FAULT].Time_Stamp,
|
||||
if (datetime_compare(&CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].Time_Stamp,
|
||||
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
@@ -1134,8 +1128,8 @@ int Analog_Input_Alarm_Ack(
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
if (datetime_compare(&CurrentAI->Acked_Transitions
|
||||
[TRANSITION_TO_NORMAL].Time_Stamp,
|
||||
if (datetime_compare(&CurrentAI->
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].Time_Stamp,
|
||||
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
@@ -1180,16 +1174,16 @@ int Analog_Input_Alarm_Summary(
|
||||
bitstring_init(&getalarm_data->acknowledgedTransitions);
|
||||
bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_OFFNORMAL,
|
||||
AI_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
|
||||
AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked);
|
||||
bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_FAULT,
|
||||
AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].
|
||||
bIsAcked);
|
||||
AI_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
|
||||
bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_NORMAL,
|
||||
AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].
|
||||
bIsAcked);
|
||||
AI_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked);
|
||||
|
||||
return 1; /* active alarm */
|
||||
} else
|
||||
|
||||
@@ -451,11 +451,11 @@ bool Analog_Output_Write_Property(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
object_index =
|
||||
Analog_Output_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Analog_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
status =
|
||||
Analog_Output_Present_Value_Relinquish(wp_data->
|
||||
object_instance, wp_data->priority);
|
||||
Analog_Output_Present_Value_Relinquish
|
||||
(wp_data->object_instance, wp_data->priority);
|
||||
if (!status) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
|
||||
@@ -424,11 +424,11 @@ int Analog_Value_Read_Property(
|
||||
case PROP_LIMIT_ENABLE:
|
||||
bitstring_init(&bit_string);
|
||||
bitstring_set_bit(&bit_string, 0,
|
||||
(CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true :
|
||||
false);
|
||||
(CurrentAV->
|
||||
Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true : false);
|
||||
bitstring_set_bit(&bit_string, 1,
|
||||
(CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true :
|
||||
false);
|
||||
(CurrentAV->
|
||||
Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true : false);
|
||||
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
@@ -436,14 +436,14 @@ int Analog_Value_Read_Property(
|
||||
case PROP_EVENT_ENABLE:
|
||||
bitstring_init(&bit_string);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL,
|
||||
(CurrentAV->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true :
|
||||
false);
|
||||
(CurrentAV->
|
||||
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
|
||||
(CurrentAV->Event_Enable & EVENT_ENABLE_TO_FAULT) ? true :
|
||||
false);
|
||||
(CurrentAV->
|
||||
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
|
||||
(CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true :
|
||||
false);
|
||||
(CurrentAV->
|
||||
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false);
|
||||
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
@@ -451,8 +451,8 @@ int Analog_Value_Read_Property(
|
||||
case PROP_ACKED_TRANSITIONS:
|
||||
bitstring_init(&bit_string);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL,
|
||||
CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
|
||||
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
|
||||
@@ -735,7 +735,7 @@ bool Analog_Value_Write_Property(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
|
||||
if (status) {
|
||||
switch ((BACNET_NOTIFY_TYPE)value.type.Enumerated) {
|
||||
switch ((BACNET_NOTIFY_TYPE) value.type.Enumerated) {
|
||||
case NOTIFY_EVENT:
|
||||
CurrentAV->Notify_Type = 1;
|
||||
break;
|
||||
@@ -1017,17 +1017,17 @@ void Analog_Value_Intrinsic_Reporting(
|
||||
event_data.notificationParams.outOfRange.exceedingValue =
|
||||
PresentVal;
|
||||
/* Status_Flags of the referenced object. */
|
||||
bitstring_init(&event_data.notificationParams.
|
||||
outOfRange.statusFlags);
|
||||
bitstring_set_bit(&event_data.notificationParams.
|
||||
outOfRange.statusFlags, STATUS_FLAG_IN_ALARM,
|
||||
bitstring_init(&event_data.notificationParams.outOfRange.
|
||||
statusFlags);
|
||||
bitstring_set_bit(&event_data.notificationParams.outOfRange.
|
||||
statusFlags, STATUS_FLAG_IN_ALARM,
|
||||
CurrentAV->Event_State ? true : false);
|
||||
bitstring_set_bit(&event_data.notificationParams.
|
||||
outOfRange.statusFlags, STATUS_FLAG_FAULT, false);
|
||||
bitstring_set_bit(&event_data.notificationParams.
|
||||
outOfRange.statusFlags, STATUS_FLAG_OVERRIDDEN, false);
|
||||
bitstring_set_bit(&event_data.notificationParams.
|
||||
outOfRange.statusFlags, STATUS_FLAG_OUT_OF_SERVICE,
|
||||
bitstring_set_bit(&event_data.notificationParams.outOfRange.
|
||||
statusFlags, STATUS_FLAG_FAULT, false);
|
||||
bitstring_set_bit(&event_data.notificationParams.outOfRange.
|
||||
statusFlags, STATUS_FLAG_OVERRIDDEN, false);
|
||||
bitstring_set_bit(&event_data.notificationParams.outOfRange.
|
||||
statusFlags, STATUS_FLAG_OUT_OF_SERVICE,
|
||||
CurrentAV->Out_Of_Service);
|
||||
/* Deadband used for limit checking. */
|
||||
event_data.notificationParams.outOfRange.deadband =
|
||||
@@ -1047,30 +1047,24 @@ void Analog_Value_Intrinsic_Reporting(
|
||||
case EVENT_STATE_OFFNORMAL:
|
||||
case EVENT_STATE_HIGH_LIMIT:
|
||||
case EVENT_STATE_LOW_LIMIT:
|
||||
CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked =
|
||||
false;
|
||||
CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].Time_Stamp =
|
||||
event_data.timeStamp.value.dateTime;
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked = false;
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
Time_Stamp = event_data.timeStamp.value.dateTime;
|
||||
break;
|
||||
|
||||
case EVENT_STATE_FAULT:
|
||||
CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked =
|
||||
false;
|
||||
CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].Time_Stamp =
|
||||
event_data.timeStamp.value.dateTime;
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].
|
||||
bIsAcked = false;
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].
|
||||
Time_Stamp = event_data.timeStamp.value.dateTime;
|
||||
break;
|
||||
|
||||
case EVENT_STATE_NORMAL:
|
||||
CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked =
|
||||
false;
|
||||
CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].Time_Stamp =
|
||||
event_data.timeStamp.value.dateTime;
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL].
|
||||
bIsAcked = false;
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL].
|
||||
Time_Stamp = event_data.timeStamp.value.dateTime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1097,12 +1091,12 @@ int Analog_Value_Event_Information(
|
||||
/* Acked_Transitions property, which has at least one of the bits
|
||||
(TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */
|
||||
IsNotAckedTransitions =
|
||||
(AV_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked ==
|
||||
false) | (AV_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked ==
|
||||
false) | (AV_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked == false);
|
||||
(AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked ==
|
||||
false) | (AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].
|
||||
bIsAcked ==
|
||||
false) | (AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].
|
||||
bIsAcked == false);
|
||||
} else
|
||||
return -1; /* end of list */
|
||||
|
||||
@@ -1117,8 +1111,8 @@ int Analog_Value_Event_Information(
|
||||
bitstring_init(&getevent_data->acknowledgedTransitions);
|
||||
bitstring_set_bit(&getevent_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_OFFNORMAL,
|
||||
AV_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
|
||||
AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked);
|
||||
bitstring_set_bit(&getevent_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_FAULT,
|
||||
AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
|
||||
@@ -1136,14 +1130,14 @@ int Analog_Value_Event_Information(
|
||||
/* Event Enable */
|
||||
bitstring_init(&getevent_data->eventEnable);
|
||||
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL,
|
||||
(AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true :
|
||||
false);
|
||||
(AV_Descr[index].
|
||||
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false);
|
||||
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT,
|
||||
(AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT) ? true :
|
||||
false);
|
||||
(AV_Descr[index].
|
||||
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false);
|
||||
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL,
|
||||
(AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true :
|
||||
false);
|
||||
(AV_Descr[index].
|
||||
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false);
|
||||
/* Event Priorities */
|
||||
Notification_Class_Get_Priorities(AV_Descr[index].Notification_Class,
|
||||
getevent_data->eventPriorities);
|
||||
@@ -1162,8 +1156,8 @@ int Analog_Value_Alarm_Ack(
|
||||
|
||||
|
||||
object_index =
|
||||
Analog_Value_Instance_To_Index(alarmack_data->
|
||||
eventObjectIdentifier.instance);
|
||||
Analog_Value_Instance_To_Index(alarmack_data->eventObjectIdentifier.
|
||||
instance);
|
||||
|
||||
if (object_index < MAX_ANALOG_VALUES)
|
||||
CurrentAV = &AV_Descr[object_index];
|
||||
@@ -1176,22 +1170,22 @@ int Analog_Value_Alarm_Ack(
|
||||
case EVENT_STATE_OFFNORMAL:
|
||||
case EVENT_STATE_HIGH_LIMIT:
|
||||
case EVENT_STATE_LOW_LIMIT:
|
||||
if (CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked == false) {
|
||||
if (CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked == false) {
|
||||
if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) {
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
if (datetime_compare(&CurrentAV->Acked_Transitions
|
||||
[TRANSITION_TO_OFFNORMAL].Time_Stamp,
|
||||
if (datetime_compare(&CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].Time_Stamp,
|
||||
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clean transitions flag. */
|
||||
CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked = true;
|
||||
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked = true;
|
||||
} else {
|
||||
*error_code = ERROR_CODE_INVALID_EVENT_STATE;
|
||||
return -1;
|
||||
@@ -1205,8 +1199,8 @@ int Analog_Value_Alarm_Ack(
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
if (datetime_compare(&CurrentAV->Acked_Transitions
|
||||
[TRANSITION_TO_NORMAL].Time_Stamp,
|
||||
if (datetime_compare(&CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].Time_Stamp,
|
||||
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
@@ -1228,8 +1222,8 @@ int Analog_Value_Alarm_Ack(
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
if (datetime_compare(&CurrentAV->Acked_Transitions
|
||||
[TRANSITION_TO_FAULT].Time_Stamp,
|
||||
if (datetime_compare(&CurrentAV->
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].Time_Stamp,
|
||||
&alarmack_data->eventTimeStamp.value.dateTime) > 0) {
|
||||
*error_code = ERROR_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
@@ -1277,16 +1271,16 @@ int Analog_Value_Alarm_Summary(
|
||||
bitstring_init(&getalarm_data->acknowledgedTransitions);
|
||||
bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_OFFNORMAL,
|
||||
AV_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
|
||||
AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL].
|
||||
bIsAcked);
|
||||
bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_FAULT,
|
||||
AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].
|
||||
bIsAcked);
|
||||
AV_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
|
||||
bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
|
||||
TRANSITION_TO_NORMAL,
|
||||
AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].
|
||||
bIsAcked);
|
||||
AV_Descr[index].
|
||||
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked);
|
||||
|
||||
return 1; /* active alarm */
|
||||
} else
|
||||
|
||||
@@ -383,8 +383,8 @@ bool Binary_Output_Write_Property(
|
||||
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
||||
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
||||
object_index =
|
||||
Binary_Output_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Binary_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
priority--;
|
||||
Binary_Output_Level[object_index][priority] = level;
|
||||
/* Note: you could set the physical output here if we
|
||||
@@ -410,8 +410,8 @@ bool Binary_Output_Write_Property(
|
||||
if (status) {
|
||||
level = BINARY_NULL;
|
||||
object_index =
|
||||
Binary_Output_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Binary_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
priority = wp_data->priority;
|
||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||
priority--;
|
||||
|
||||
@@ -366,8 +366,8 @@ bool Binary_Value_Write_Property(
|
||||
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
||||
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
||||
object_index =
|
||||
Binary_Value_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Binary_Value_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
priority--;
|
||||
Binary_Value_Level[object_index][priority] = level;
|
||||
/* Note: you could set the physical output here if we
|
||||
@@ -393,8 +393,8 @@ bool Binary_Value_Write_Property(
|
||||
if (status) {
|
||||
level = BINARY_NULL;
|
||||
object_index =
|
||||
Binary_Value_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Binary_Value_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
priority = wp_data->priority;
|
||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||
priority--;
|
||||
|
||||
@@ -357,8 +357,8 @@ int CharacterString_Value_Read_Property(
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
object_index =
|
||||
CharacterString_Value_Instance_To_Index(rpdata->
|
||||
object_instance);
|
||||
CharacterString_Value_Instance_To_Index
|
||||
(rpdata->object_instance);
|
||||
state = Out_Of_Service[object_index];
|
||||
apdu_len = encode_application_boolean(&apdu[0], state);
|
||||
break;
|
||||
@@ -406,8 +406,8 @@ bool CharacterString_Value_Write_Property(
|
||||
&wp_data->error_code);
|
||||
if (status) {
|
||||
status =
|
||||
CharacterString_Value_Present_Value_Set(wp_data->
|
||||
object_instance, &value.type.Character_String);
|
||||
CharacterString_Value_Present_Value_Set
|
||||
(wp_data->object_instance, &value.type.Character_String);
|
||||
if (!status) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
@@ -419,8 +419,8 @@ bool CharacterString_Value_Write_Property(
|
||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
CharacterString_Value_Out_Of_Service_Set(wp_data->
|
||||
object_instance, value.type.Boolean);
|
||||
CharacterString_Value_Out_Of_Service_Set
|
||||
(wp_data->object_instance, value.type.Boolean);
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
|
||||
@@ -1161,8 +1161,8 @@ int Device_Read_Property_Local(
|
||||
{
|
||||
int apdu_len = 0; /* return value */
|
||||
int len = 0; /* apdu len intermediate value */
|
||||
BACNET_BIT_STRING bit_string = {0};
|
||||
BACNET_CHARACTER_STRING char_string = {0};
|
||||
BACNET_BIT_STRING bit_string = { 0 };
|
||||
BACNET_CHARACTER_STRING char_string = { 0 };
|
||||
unsigned i = 0;
|
||||
int object_type = 0;
|
||||
uint32_t instance = 0;
|
||||
@@ -1454,8 +1454,8 @@ bool Device_Write_Property_Local(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
||||
instance))) {
|
||||
(Device_Set_Object_Instance_Number(value.type.
|
||||
Object_Id.instance))) {
|
||||
/* FIXME: we could send an I-Am broadcast to let the world know */
|
||||
} else {
|
||||
status = false;
|
||||
@@ -1488,8 +1488,8 @@ bool Device_Write_Property_Local(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
/* FIXME: bounds check? */
|
||||
Device_Set_Vendor_Identifier((uint16_t) value.type.
|
||||
Unsigned_Int);
|
||||
Device_Set_Vendor_Identifier((uint16_t) value.
|
||||
type.Unsigned_Int);
|
||||
}
|
||||
break;
|
||||
case PROP_SYSTEM_STATUS:
|
||||
@@ -1519,7 +1519,7 @@ bool Device_Write_Property_Local(
|
||||
if (status) {
|
||||
/* All the object names in a device must be unique */
|
||||
if (Device_Valid_Object_Name(&value.type.Character_String,
|
||||
&object_type, &object_instance)) {
|
||||
&object_type, &object_instance)) {
|
||||
if ((object_type == wp_data->object_type) &&
|
||||
(object_instance == wp_data->object_instance)) {
|
||||
/* writing same name to same object */
|
||||
@@ -1539,8 +1539,8 @@ bool Device_Write_Property_Local(
|
||||
WPValidateString(&value, MAX_DEV_LOC_LEN, true,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
Device_Set_Location(characterstring_value(&value.type.
|
||||
Character_String),
|
||||
Device_Set_Location(characterstring_value(&value.
|
||||
type.Character_String),
|
||||
characterstring_length(&value.type.Character_String));
|
||||
}
|
||||
break;
|
||||
@@ -1550,8 +1550,8 @@ bool Device_Write_Property_Local(
|
||||
WPValidateString(&value, MAX_DEV_DESC_LEN, true,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
Device_Set_Description(characterstring_value(&value.type.
|
||||
Character_String),
|
||||
Device_Set_Description(characterstring_value(&value.
|
||||
type.Character_String),
|
||||
characterstring_length(&value.type.Character_String));
|
||||
}
|
||||
break;
|
||||
@@ -1560,8 +1560,8 @@ bool Device_Write_Property_Local(
|
||||
WPValidateString(&value, MAX_DEV_MOD_LEN, true,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
Device_Set_Model_Name(characterstring_value(&value.type.
|
||||
Character_String),
|
||||
Device_Set_Model_Name(characterstring_value(&value.
|
||||
type.Character_String),
|
||||
characterstring_length(&value.type.Character_String));
|
||||
}
|
||||
break;
|
||||
@@ -1573,8 +1573,8 @@ bool Device_Write_Property_Local(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
if (value.type.Unsigned_Int <= 255) {
|
||||
dlmstp_set_max_info_frames((uint8_t) value.type.
|
||||
Unsigned_Int);
|
||||
dlmstp_set_max_info_frames((uint8_t) value.
|
||||
type.Unsigned_Int);
|
||||
} else {
|
||||
status = false;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
|
||||
@@ -440,15 +440,11 @@ extern "C" {
|
||||
* - The interface between the implemented Objects and the BAC-stack services,
|
||||
* specifically the handlers, which are mediated through function calls to
|
||||
* the Device object.
|
||||
*/
|
||||
|
||||
/** @defgroup ObjHelpers Object Helper Functions
|
||||
*//** @defgroup ObjHelpers Object Helper Functions
|
||||
* @ingroup ObjFrmwk
|
||||
* This section describes the function templates for the helper functions that
|
||||
* provide common object support.
|
||||
*/
|
||||
|
||||
/** @defgroup ObjIntf Handler-to-Object Interface Functions
|
||||
*//** @defgroup ObjIntf Handler-to-Object Interface Functions
|
||||
* @ingroup ObjFrmwk
|
||||
* This section describes the fairly limited set of functions that link the
|
||||
* BAC-stack handlers to the BACnet Object instances. All of these calls are
|
||||
|
||||
@@ -492,8 +492,8 @@ bool Routed_Device_Write_Property_Local(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||
(Routed_Device_Set_Object_Instance_Number(value.
|
||||
type.Object_Id.instance))) {
|
||||
(Routed_Device_Set_Object_Instance_Number(value.type.
|
||||
Object_Id.instance))) {
|
||||
/* FIXME: we could send an I-Am broadcast to let the world know */
|
||||
} else {
|
||||
status = false;
|
||||
@@ -507,8 +507,8 @@ bool Routed_Device_Write_Property_Local(
|
||||
WPValidateString(&value, MAX_DEV_NAME_LEN, false,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
Routed_Device_Set_Object_Name(characterstring_encoding
|
||||
(&value.type.Character_String),
|
||||
Routed_Device_Set_Object_Name(characterstring_encoding(&value.
|
||||
type.Character_String),
|
||||
characterstring_value(&value.type.Character_String),
|
||||
characterstring_length(&value.type.Character_String));
|
||||
}
|
||||
|
||||
@@ -466,8 +466,8 @@ int Lighting_Output_Read_Property(
|
||||
object_index =
|
||||
Lighting_Output_Instance_To_Index(rpdata->object_instance);
|
||||
if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
|
||||
if (Lighting_Output_Level[object_index][rpdata->
|
||||
array_index - 1] == LIGHTING_LEVEL_NULL)
|
||||
if (Lighting_Output_Level[object_index][rpdata->array_index
|
||||
- 1] == LIGHTING_LEVEL_NULL)
|
||||
apdu_len = encode_application_null(&apdu[0]);
|
||||
else {
|
||||
real_value = Lighting_Output_Level[object_index]
|
||||
@@ -551,11 +551,11 @@ bool Lighting_Output_Write_Property(
|
||||
if (status) {
|
||||
level = LIGHTING_LEVEL_NULL;
|
||||
object_index =
|
||||
Lighting_Output_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Lighting_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
status =
|
||||
Lighting_Output_Present_Value_Relinquish(wp_data->
|
||||
object_instance, wp_data->priority);
|
||||
Lighting_Output_Present_Value_Relinquish
|
||||
(wp_data->object_instance, wp_data->priority);
|
||||
if (wp_data->priority == 6) {
|
||||
/* Command priority 6 is reserved for use by Minimum On/Off
|
||||
algorithm and may not be used for other purposes in any
|
||||
@@ -582,8 +582,8 @@ bool Lighting_Output_Write_Property(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
object_index =
|
||||
Lighting_Output_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Lighting_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
Lighting_Output_Out_Of_Service[object_index] =
|
||||
value.type.Boolean;
|
||||
}
|
||||
|
||||
@@ -338,8 +338,8 @@ bool Life_Safety_Point_Write_Property(
|
||||
if (status) {
|
||||
if (value.type.Enumerated <= MAX_LIFE_SAFETY_MODE) {
|
||||
object_index =
|
||||
Life_Safety_Point_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Life_Safety_Point_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
Life_Safety_Point_Mode[object_index] =
|
||||
value.type.Enumerated;
|
||||
} else {
|
||||
@@ -355,8 +355,8 @@ bool Life_Safety_Point_Write_Property(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
object_index =
|
||||
Life_Safety_Point_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Life_Safety_Point_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
Life_Safety_Point_Out_Of_Service[object_index] =
|
||||
value.type.Boolean;
|
||||
}
|
||||
|
||||
@@ -262,9 +262,9 @@ bool Multistate_Input_Description_Set(
|
||||
|
||||
static bool Multistate_Input_Description_Write(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *char_string,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
BACNET_CHARACTER_STRING * char_string,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code)
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
size_t length = 0;
|
||||
@@ -277,10 +277,9 @@ static bool Multistate_Input_Description_Write(
|
||||
if (length <= sizeof(Object_Description[index])) {
|
||||
encoding = characterstring_encoding(char_string);
|
||||
if (encoding == CHARACTER_UTF8) {
|
||||
status = characterstring_ansi_copy(
|
||||
Object_Description[index],
|
||||
sizeof(Object_Description[index]),
|
||||
char_string);
|
||||
status =
|
||||
characterstring_ansi_copy(Object_Description[index],
|
||||
sizeof(Object_Description[index]), char_string);
|
||||
if (!status) {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
@@ -346,9 +345,9 @@ bool Multistate_Input_Name_Set(
|
||||
|
||||
static bool Multistate_Input_Object_Name_Write(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING *char_string,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
BACNET_CHARACTER_STRING * char_string,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code)
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
size_t length = 0;
|
||||
@@ -361,10 +360,9 @@ static bool Multistate_Input_Object_Name_Write(
|
||||
if (length <= sizeof(Object_Name[index])) {
|
||||
encoding = characterstring_encoding(char_string);
|
||||
if (encoding == CHARACTER_UTF8) {
|
||||
status = characterstring_ansi_copy(
|
||||
Object_Name[index],
|
||||
sizeof(Object_Name[index]),
|
||||
char_string);
|
||||
status =
|
||||
characterstring_ansi_copy(Object_Name[index],
|
||||
sizeof(Object_Name[index]), char_string);
|
||||
if (!status) {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
@@ -434,9 +432,9 @@ bool Multistate_Input_State_Text_Set(
|
||||
static bool Multistate_Input_State_Text_Write(
|
||||
uint32_t object_instance,
|
||||
uint32_t state_index,
|
||||
BACNET_CHARACTER_STRING *char_string,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
BACNET_CHARACTER_STRING * char_string,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code)
|
||||
{
|
||||
unsigned index = 0; /* offset from instance lookup */
|
||||
size_t length = 0;
|
||||
@@ -451,10 +449,9 @@ static bool Multistate_Input_State_Text_Write(
|
||||
if (length <= sizeof(State_Text[index][state_index])) {
|
||||
encoding = characterstring_encoding(char_string);
|
||||
if (encoding == CHARACTER_UTF8) {
|
||||
status = characterstring_ansi_copy(
|
||||
State_Text[index][state_index],
|
||||
sizeof(State_Text[index][state_index]),
|
||||
char_string);
|
||||
status =
|
||||
characterstring_ansi_copy(State_Text[index][state_index],
|
||||
sizeof(State_Text[index][state_index]), char_string);
|
||||
if (!status) {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
@@ -562,7 +559,8 @@ int Multistate_Input_Read_Property(
|
||||
} else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. */
|
||||
max_states = Multistate_Input_Max_States(rpdata->object_instance);
|
||||
max_states =
|
||||
Multistate_Input_Max_States(rpdata->object_instance);
|
||||
for (i = 1; i <= max_states; i++) {
|
||||
characterstring_init_ansi(&char_string,
|
||||
Multistate_Input_State_Text(rpdata->object_instance,
|
||||
@@ -582,7 +580,8 @@ int Multistate_Input_Read_Property(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
max_states = Multistate_Input_Max_States(rpdata->object_instance);
|
||||
max_states =
|
||||
Multistate_Input_Max_States(rpdata->object_instance);
|
||||
if (rpdata->array_index <= max_states) {
|
||||
characterstring_init_ansi(&char_string,
|
||||
Multistate_Input_State_Text(rpdata->object_instance,
|
||||
@@ -650,7 +649,7 @@ bool Multistate_Input_Write_Property(
|
||||
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
||||
/* All the object names in a device must be unique */
|
||||
if (Device_Valid_Object_Name(&value.type.Character_String,
|
||||
&object_type, &object_instance)) {
|
||||
&object_type, &object_instance)) {
|
||||
if ((object_type == wp_data->object_type) &&
|
||||
(object_instance == wp_data->object_instance)) {
|
||||
/* writing same name to same object */
|
||||
@@ -661,11 +660,10 @@ bool Multistate_Input_Write_Property(
|
||||
wp_data->error_code = ERROR_CODE_DUPLICATE_NAME;
|
||||
}
|
||||
} else {
|
||||
status = Multistate_Input_Object_Name_Write(
|
||||
wp_data->object_instance,
|
||||
&value.type.Character_String,
|
||||
&wp_data->error_class,
|
||||
&wp_data->error_code);
|
||||
status =
|
||||
Multistate_Input_Object_Name_Write(wp_data->
|
||||
object_instance, &value.type.Character_String,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
}
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
@@ -674,11 +672,10 @@ bool Multistate_Input_Write_Property(
|
||||
break;
|
||||
case PROP_DESCRIPTION:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
||||
status = Multistate_Input_Description_Write(
|
||||
wp_data->object_instance,
|
||||
&value.type.Character_String,
|
||||
&wp_data->error_class,
|
||||
&wp_data->error_code);
|
||||
status =
|
||||
Multistate_Input_Description_Write(wp_data->
|
||||
object_instance, &value.type.Character_String,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
@@ -690,8 +687,8 @@ bool Multistate_Input_Write_Property(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
status =
|
||||
Multistate_Input_Present_Value_Set(wp_data->
|
||||
object_instance, value.type.Unsigned_Int);
|
||||
Multistate_Input_Present_Value_Set
|
||||
(wp_data->object_instance, value.type.Unsigned_Int);
|
||||
if (!status) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
@@ -716,44 +713,43 @@ bool Multistate_Input_Write_Property(
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
} else if (wp_data->array_index == BACNET_ARRAY_ALL) {
|
||||
max_states = Multistate_Input_Max_States(
|
||||
wp_data->object_instance);
|
||||
max_states =
|
||||
Multistate_Input_Max_States(wp_data->object_instance);
|
||||
array_index = 1;
|
||||
element_len = len;
|
||||
do {
|
||||
if (element_len) {
|
||||
status = Multistate_Input_State_Text_Write(
|
||||
wp_data->object_instance,
|
||||
array_index,
|
||||
status =
|
||||
Multistate_Input_State_Text_Write(wp_data->
|
||||
object_instance, array_index,
|
||||
&value.type.Character_String,
|
||||
&wp_data->error_class,
|
||||
&wp_data->error_code);
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
}
|
||||
max_states--;
|
||||
array_index++;
|
||||
if (max_states) {
|
||||
element_len = bacapp_decode_application_data(
|
||||
&wp_data->application_data[len],
|
||||
wp_data->application_data_len-len,
|
||||
&value);
|
||||
element_len =
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[len],
|
||||
wp_data->application_data_len - len, &value);
|
||||
if (element_len < 0) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_code =
|
||||
ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
break;
|
||||
}
|
||||
len += element_len;
|
||||
}
|
||||
} while (max_states);
|
||||
} else {
|
||||
max_states = Multistate_Input_Max_States(
|
||||
wp_data->object_instance);
|
||||
max_states =
|
||||
Multistate_Input_Max_States(wp_data->object_instance);
|
||||
if (wp_data->array_index <= max_states) {
|
||||
status = Multistate_Input_State_Text_Write(
|
||||
wp_data->object_instance,
|
||||
wp_data->array_index,
|
||||
status =
|
||||
Multistate_Input_State_Text_Write(wp_data->
|
||||
object_instance, wp_data->array_index,
|
||||
&value.type.Character_String,
|
||||
&wp_data->error_class,
|
||||
&wp_data->error_code);
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
|
||||
@@ -268,8 +268,8 @@ int Multistate_Output_Read_Property(
|
||||
/* into one packet. */
|
||||
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
object_index =
|
||||
Multistate_Output_Instance_To_Index(rpdata->
|
||||
object_instance);
|
||||
Multistate_Output_Instance_To_Index
|
||||
(rpdata->object_instance);
|
||||
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
|
||||
/* FIXME: check if we have room before adding it to APDU */
|
||||
if (Multistate_Output_Level[object_index][i] ==
|
||||
@@ -294,8 +294,8 @@ int Multistate_Output_Read_Property(
|
||||
}
|
||||
} else {
|
||||
object_index =
|
||||
Multistate_Output_Instance_To_Index(rpdata->
|
||||
object_instance);
|
||||
Multistate_Output_Instance_To_Index
|
||||
(rpdata->object_instance);
|
||||
if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
|
||||
if (Multistate_Output_Level[object_index]
|
||||
[rpdata->array_index - 1] == MULTISTATE_NULL)
|
||||
@@ -386,8 +386,8 @@ bool Multistate_Output_Write_Property(
|
||||
(value.type.Unsigned_Int <= MULTISTATE_NUMBER_OF_STATES)) {
|
||||
level = value.type.Unsigned_Int;
|
||||
object_index =
|
||||
Multistate_Output_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Multistate_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
priority--;
|
||||
Multistate_Output_Level[object_index][priority] =
|
||||
(uint8_t) level;
|
||||
@@ -414,8 +414,8 @@ bool Multistate_Output_Write_Property(
|
||||
if (status) {
|
||||
level = MULTISTATE_NULL;
|
||||
object_index =
|
||||
Multistate_Output_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Multistate_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
priority = wp_data->priority;
|
||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||
priority--;
|
||||
@@ -441,8 +441,8 @@ bool Multistate_Output_Write_Property(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
object_index =
|
||||
Multistate_Output_Instance_To_Index(wp_data->
|
||||
object_instance);
|
||||
Multistate_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
Multistate_Output_Out_Of_Service[object_index] =
|
||||
value.type.Boolean;
|
||||
}
|
||||
|
||||
@@ -438,8 +438,8 @@ int Multistate_Value_Read_Property(
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. */
|
||||
object_index =
|
||||
Multistate_Value_Instance_To_Index(rpdata->
|
||||
object_instance);
|
||||
Multistate_Value_Instance_To_Index
|
||||
(rpdata->object_instance);
|
||||
for (i = 1; i <= MULTISTATE_NUMBER_OF_STATES; i++) {
|
||||
characterstring_init_ansi(&char_string,
|
||||
Multistate_Value_State_Text(rpdata->object_instance,
|
||||
@@ -460,8 +460,8 @@ int Multistate_Value_Read_Property(
|
||||
}
|
||||
} else {
|
||||
object_index =
|
||||
Multistate_Value_Instance_To_Index(rpdata->
|
||||
object_instance);
|
||||
Multistate_Value_Instance_To_Index
|
||||
(rpdata->object_instance);
|
||||
if (rpdata->array_index <= MULTISTATE_NUMBER_OF_STATES) {
|
||||
characterstring_init_ansi(&char_string,
|
||||
Multistate_Value_State_Text(rpdata->object_instance,
|
||||
@@ -528,8 +528,8 @@ bool Multistate_Value_Write_Property(
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
status =
|
||||
Multistate_Value_Present_Value_Set(wp_data->
|
||||
object_instance, value.type.Unsigned_Int);
|
||||
Multistate_Value_Present_Value_Set
|
||||
(wp_data->object_instance, value.type.Unsigned_Int);
|
||||
if (!status) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
|
||||
@@ -189,8 +189,8 @@ int Notification_Class_Read_Property(
|
||||
|
||||
apdu = rpdata->application_data;
|
||||
CurrentNotify =
|
||||
&NC_Info[Notification_Class_Instance_To_Index
|
||||
(rpdata->object_instance)];
|
||||
&NC_Info[Notification_Class_Instance_To_Index(rpdata->
|
||||
object_instance)];
|
||||
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
@@ -400,8 +400,8 @@ bool Notification_Class_Write_Property(
|
||||
|
||||
|
||||
CurrentNotify =
|
||||
&NC_Info[Notification_Class_Instance_To_Index
|
||||
(wp_data->object_instance)];
|
||||
&NC_Info[Notification_Class_Instance_To_Index(wp_data->
|
||||
object_instance)];
|
||||
|
||||
/* decode the some of the request
|
||||
*/
|
||||
@@ -467,8 +467,9 @@ bool Notification_Class_Write_Property(
|
||||
while (iOffset < wp_data->application_data_len) {
|
||||
/* Decode Valid Days */
|
||||
len =
|
||||
bacapp_decode_application_data(&wp_data->application_data
|
||||
[iOffset], wp_data->application_data_len, &value);
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[iOffset], wp_data->application_data_len,
|
||||
&value);
|
||||
|
||||
if ((len == 0) ||
|
||||
(value.tag != BACNET_APPLICATION_TAG_BIT_STRING)) {
|
||||
@@ -491,8 +492,9 @@ bool Notification_Class_Write_Property(
|
||||
iOffset += len;
|
||||
/* Decode From Time */
|
||||
len =
|
||||
bacapp_decode_application_data(&wp_data->application_data
|
||||
[iOffset], wp_data->application_data_len, &value);
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[iOffset], wp_data->application_data_len,
|
||||
&value);
|
||||
|
||||
if ((len == 0) || (value.tag != BACNET_APPLICATION_TAG_TIME)) {
|
||||
/* Bad decode, wrong tag or following required parameter missing */
|
||||
@@ -506,8 +508,9 @@ bool Notification_Class_Write_Property(
|
||||
iOffset += len;
|
||||
/* Decode To Time */
|
||||
len =
|
||||
bacapp_decode_application_data(&wp_data->application_data
|
||||
[iOffset], wp_data->application_data_len, &value);
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[iOffset], wp_data->application_data_len,
|
||||
&value);
|
||||
|
||||
if ((len == 0) || (value.tag != BACNET_APPLICATION_TAG_TIME)) {
|
||||
/* Bad decode, wrong tag or following required parameter missing */
|
||||
@@ -526,8 +529,9 @@ bool Notification_Class_Write_Property(
|
||||
RECIPIENT_TYPE_DEVICE;
|
||||
/* Decode Network Number */
|
||||
len =
|
||||
bacapp_decode_context_data(&wp_data->application_data
|
||||
[iOffset], wp_data->application_data_len, &value,
|
||||
bacapp_decode_context_data(&wp_data->
|
||||
application_data[iOffset],
|
||||
wp_data->application_data_len, &value,
|
||||
PROP_RECIPIENT_LIST);
|
||||
|
||||
if ((len == 0) ||
|
||||
@@ -538,21 +542,21 @@ bool Notification_Class_Write_Property(
|
||||
return false;
|
||||
}
|
||||
/* store value */
|
||||
TmpNotify.Recipient_List[idx].Recipient.
|
||||
_.DeviceIdentifier = value.type.Object_Id.instance;
|
||||
TmpNotify.Recipient_List[idx].Recipient._.
|
||||
DeviceIdentifier = value.type.Object_Id.instance;
|
||||
|
||||
iOffset += len;
|
||||
}
|
||||
/* opening tag [1] - Recipient */
|
||||
else if (decode_is_opening_tag_number
|
||||
(&wp_data->application_data[iOffset], 1)) {
|
||||
else if (decode_is_opening_tag_number(&wp_data->
|
||||
application_data[iOffset], 1)) {
|
||||
iOffset++;
|
||||
TmpNotify.Recipient_List[idx].Recipient.RecipientType =
|
||||
RECIPIENT_TYPE_ADDRESS;
|
||||
/* Decode Network Number */
|
||||
len =
|
||||
bacapp_decode_application_data
|
||||
(&wp_data->application_data[iOffset],
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[iOffset],
|
||||
wp_data->application_data_len, &value);
|
||||
|
||||
if ((len == 0) ||
|
||||
@@ -569,8 +573,8 @@ bool Notification_Class_Write_Property(
|
||||
iOffset += len;
|
||||
/* Decode Address */
|
||||
len =
|
||||
bacapp_decode_application_data
|
||||
(&wp_data->application_data[iOffset],
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[iOffset],
|
||||
wp_data->application_data_len, &value);
|
||||
|
||||
if ((len == 0) ||
|
||||
@@ -581,16 +585,16 @@ bool Notification_Class_Write_Property(
|
||||
return false;
|
||||
}
|
||||
/* store value */
|
||||
if (TmpNotify.Recipient_List[idx].Recipient._.
|
||||
Address.net == 0) {
|
||||
memcpy(TmpNotify.Recipient_List[idx].Recipient.
|
||||
_.Address.mac, value.type.Octet_String.value,
|
||||
if (TmpNotify.Recipient_List[idx].Recipient._.Address.
|
||||
net == 0) {
|
||||
memcpy(TmpNotify.Recipient_List[idx].Recipient._.
|
||||
Address.mac, value.type.Octet_String.value,
|
||||
value.type.Octet_String.length);
|
||||
TmpNotify.Recipient_List[idx].Recipient._.
|
||||
Address.mac_len = value.type.Octet_String.length;
|
||||
TmpNotify.Recipient_List[idx].Recipient._.Address.
|
||||
mac_len = value.type.Octet_String.length;
|
||||
} else {
|
||||
memcpy(TmpNotify.Recipient_List[idx].Recipient.
|
||||
_.Address.adr, value.type.Octet_String.value,
|
||||
memcpy(TmpNotify.Recipient_List[idx].Recipient._.
|
||||
Address.adr, value.type.Octet_String.value,
|
||||
value.type.Octet_String.length);
|
||||
TmpNotify.Recipient_List[idx].Recipient._.Address.len =
|
||||
value.type.Octet_String.length;
|
||||
@@ -598,8 +602,8 @@ bool Notification_Class_Write_Property(
|
||||
|
||||
iOffset += len;
|
||||
/* closing tag [1] - Recipient */
|
||||
if (decode_is_closing_tag_number(&wp_data->application_data
|
||||
[iOffset], 1))
|
||||
if (decode_is_closing_tag_number(&wp_data->
|
||||
application_data[iOffset], 1))
|
||||
iOffset++;
|
||||
else {
|
||||
/* Bad decode, wrong tag or following required parameter missing */
|
||||
@@ -616,8 +620,9 @@ bool Notification_Class_Write_Property(
|
||||
|
||||
/* Process Identifier */
|
||||
len =
|
||||
bacapp_decode_application_data(&wp_data->application_data
|
||||
[iOffset], wp_data->application_data_len, &value);
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[iOffset], wp_data->application_data_len,
|
||||
&value);
|
||||
|
||||
if ((len == 0) ||
|
||||
(value.tag != BACNET_APPLICATION_TAG_UNSIGNED_INT)) {
|
||||
@@ -633,8 +638,9 @@ bool Notification_Class_Write_Property(
|
||||
iOffset += len;
|
||||
/* Issue Confirmed Notifications */
|
||||
len =
|
||||
bacapp_decode_application_data(&wp_data->application_data
|
||||
[iOffset], wp_data->application_data_len, &value);
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[iOffset], wp_data->application_data_len,
|
||||
&value);
|
||||
|
||||
if ((len == 0) ||
|
||||
(value.tag != BACNET_APPLICATION_TAG_BOOLEAN)) {
|
||||
@@ -650,8 +656,9 @@ bool Notification_Class_Write_Property(
|
||||
iOffset += len;
|
||||
/* Transitions */
|
||||
len =
|
||||
bacapp_decode_application_data(&wp_data->application_data
|
||||
[iOffset], wp_data->application_data_len, &value);
|
||||
bacapp_decode_application_data(&wp_data->
|
||||
application_data[iOffset], wp_data->application_data_len,
|
||||
&value);
|
||||
|
||||
if ((len == 0) ||
|
||||
(value.tag != BACNET_APPLICATION_TAG_BIT_STRING)) {
|
||||
@@ -692,16 +699,16 @@ bool Notification_Class_Write_Property(
|
||||
CurrentNotify->Recipient_List[idx] =
|
||||
TmpNotify.Recipient_List[idx];
|
||||
|
||||
if (CurrentNotify->Recipient_List[idx].
|
||||
Recipient.RecipientType == RECIPIENT_TYPE_DEVICE) {
|
||||
if (CurrentNotify->Recipient_List[idx].Recipient.
|
||||
RecipientType == RECIPIENT_TYPE_DEVICE) {
|
||||
/* copy Device_ID */
|
||||
DeviceID =
|
||||
CurrentNotify->Recipient_List[idx].Recipient.
|
||||
_.DeviceIdentifier;
|
||||
CurrentNotify->Recipient_List[idx].Recipient._.
|
||||
DeviceIdentifier;
|
||||
address_bind_request(DeviceID, &max_apdu, &src);
|
||||
|
||||
} else if (CurrentNotify->Recipient_List[idx].
|
||||
Recipient.RecipientType == RECIPIENT_TYPE_ADDRESS) {
|
||||
} else if (CurrentNotify->Recipient_List[idx].Recipient.
|
||||
RecipientType == RECIPIENT_TYPE_ADDRESS) {
|
||||
/* copy Address */
|
||||
/* src = CurrentNotify->Recipient_List[idx].Recipient._.Address; */
|
||||
/* address_bind_request(BACNET_MAX_INSTANCE, &max_apdu, &src); */
|
||||
@@ -824,16 +831,16 @@ void Notification_Class_common_reporting_function(
|
||||
event_data->priority =
|
||||
CurrentNotify->Priority[TRANSITION_TO_NORMAL];
|
||||
event_data->ackRequired =
|
||||
(CurrentNotify->Ack_Required & TRANSITION_TO_NORMAL_MASKED) ?
|
||||
true : false;
|
||||
(CurrentNotify->
|
||||
Ack_Required & TRANSITION_TO_NORMAL_MASKED) ? true : false;
|
||||
break;
|
||||
|
||||
case EVENT_STATE_FAULT:
|
||||
event_data->priority =
|
||||
CurrentNotify->Priority[TRANSITION_TO_FAULT];
|
||||
event_data->ackRequired =
|
||||
(CurrentNotify->Ack_Required & TRANSITION_TO_FAULT_MASKED) ?
|
||||
true : false;
|
||||
(CurrentNotify->
|
||||
Ack_Required & TRANSITION_TO_FAULT_MASKED) ? true : false;
|
||||
break;
|
||||
|
||||
case EVENT_STATE_OFFNORMAL:
|
||||
@@ -918,13 +925,13 @@ void Notification_Class_find_recipient(
|
||||
RECIPIENT_TYPE_DEVICE) {
|
||||
/* Device ID */
|
||||
DeviceID =
|
||||
CurrentNotify->Recipient_List[idx].Recipient.
|
||||
_.DeviceIdentifier;
|
||||
CurrentNotify->Recipient_List[idx].Recipient._.
|
||||
DeviceIdentifier;
|
||||
/* Send who_ is request only when address of device is unknown. */
|
||||
if (!address_bind_request(DeviceID, &max_apdu, &src))
|
||||
Send_WhoIs(DeviceID, DeviceID);
|
||||
} else if (CurrentNotify->Recipient_List[idx].
|
||||
Recipient.RecipientType == RECIPIENT_TYPE_ADDRESS) {
|
||||
} else if (CurrentNotify->Recipient_List[idx].Recipient.
|
||||
RecipientType == RECIPIENT_TYPE_ADDRESS) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,9 +743,9 @@ bool Trend_Log_Write_Property(
|
||||
if (wp_data->application_data_len != 0) {
|
||||
iOffset += len;
|
||||
len =
|
||||
bacapp_decode_context_data(&wp_data->
|
||||
application_data[iOffset], wp_data->application_data_len,
|
||||
&value, PROP_LOG_DEVICE_OBJECT_PROPERTY);
|
||||
bacapp_decode_context_data(&wp_data->application_data
|
||||
[iOffset], wp_data->application_data_len, &value,
|
||||
PROP_LOG_DEVICE_OBJECT_PROPERTY);
|
||||
if ((len == 0) || ((value.context_tag != 2) &&
|
||||
(value.context_tag != 3))) {
|
||||
/* Bad decode or wrong tag */
|
||||
@@ -762,8 +762,8 @@ bool Trend_Log_Write_Property(
|
||||
if (wp_data->application_data_len != 0) {
|
||||
iOffset += len;
|
||||
len =
|
||||
bacapp_decode_context_data(&wp_data->
|
||||
application_data[iOffset],
|
||||
bacapp_decode_context_data
|
||||
(&wp_data->application_data[iOffset],
|
||||
wp_data->application_data_len, &value,
|
||||
PROP_LOG_DEVICE_OBJECT_PROPERTY);
|
||||
if ((len == 0) || (value.context_tag != 3)) {
|
||||
@@ -1105,8 +1105,8 @@ int rr_trend_log_encode(
|
||||
pRequest->ItemCount = 0; /* Start out with nothing */
|
||||
|
||||
/* Bail out now if nowt - should never happen for a Trend Log but ... */
|
||||
if (LogInfo[Trend_Log_Instance_To_Index(pRequest->object_instance)].
|
||||
ulRecordCount == 0)
|
||||
if (LogInfo[Trend_Log_Instance_To_Index(pRequest->
|
||||
object_instance)].ulRecordCount == 0)
|
||||
return (0);
|
||||
|
||||
if ((pRequest->RequestType == RR_BY_POSITION) ||
|
||||
|
||||
@@ -223,10 +223,10 @@ void rpm_ack_extract_data(
|
||||
} else {
|
||||
/* AccessError */
|
||||
sprintf(ackString, "BACnet Error: %s: %s",
|
||||
bactext_error_class_name((int) listOfProperties->error.
|
||||
error_class),
|
||||
bactext_error_code_name((int) listOfProperties->error.
|
||||
error_code));
|
||||
bactext_error_class_name((int) listOfProperties->
|
||||
error.error_class),
|
||||
bactext_error_code_name((int) listOfProperties->
|
||||
error.error_code));
|
||||
LogError(ackString);
|
||||
}
|
||||
listOfProperties = listOfProperties->next;
|
||||
|
||||
@@ -126,16 +126,14 @@ int main(
|
||||
return 0;
|
||||
}
|
||||
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
||||
printf("Send a Read-Broadcast-Distribution-Table message to a BBMD.\r\n"
|
||||
"\r\n"
|
||||
"IP:\r\n"
|
||||
printf
|
||||
("Send a Read-Broadcast-Distribution-Table message to a BBMD.\r\n"
|
||||
"\r\n" "IP:\r\n"
|
||||
"IP address of the BBMD in dotted decimal notation\r\n"
|
||||
"[port]\r\n"
|
||||
"optional BACnet/IP port number (default=47808=0xBAC0)\r\n"
|
||||
"\r\n"
|
||||
"optional BACnet/IP port number (default=47808=0xBAC0)\r\n" "\r\n"
|
||||
"To send a Read-Broadcast-Distribution-Table message to a BBMD\r\n"
|
||||
"at 192.168.0.1 using port 47808:\r\n"
|
||||
"%s 192.168.0.1 47808\r\n",
|
||||
"at 192.168.0.1 using port 47808:\r\n" "%s 192.168.0.1 47808\r\n",
|
||||
filename_remove_path(argv[0]));
|
||||
return 0;
|
||||
}
|
||||
@@ -143,8 +141,7 @@ int main(
|
||||
if (argc > 1) {
|
||||
Target_BBMD_Address = inet_addr(argv[1]);
|
||||
if (Target_BBMD_Address == (-1)) {
|
||||
fprintf(stderr, "IP=%s - failed to convert address.\r\n",
|
||||
argv[1]);
|
||||
fprintf(stderr, "IP=%s - failed to convert address.\r\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +258,8 @@ int main(
|
||||
|
||||
/* at least one second has passed */
|
||||
if (current_seconds != last_seconds)
|
||||
tsm_timer_milliseconds((uint16_t)((current_seconds - last_seconds) * 1000));
|
||||
tsm_timer_milliseconds((uint16_t) ((current_seconds -
|
||||
last_seconds) * 1000));
|
||||
if (Error_Detected)
|
||||
break;
|
||||
/* wait until the device is bound, or timeout and quit */
|
||||
|
||||
+338
-311
@@ -21,9 +21,10 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
#include "bacint.h"
|
||||
|
||||
#ifdef TEST_PACKET
|
||||
uint8_t test_packet[]={0x81, 0x0a, 0x00, 0x16, /* BVLC header */
|
||||
0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */
|
||||
0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x19, 0x55}; /* APDU */
|
||||
uint8_t test_packet[] = { 0x81, 0x0a, 0x00, 0x16, /* BVLC header */
|
||||
0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */
|
||||
0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x19, 0x55
|
||||
}; /* APDU */
|
||||
#endif
|
||||
|
||||
extern int get_local_address_ioctl(
|
||||
@@ -31,345 +32,371 @@ extern int get_local_address_ioctl(
|
||||
struct in_addr *addr,
|
||||
int request);
|
||||
|
||||
void* dl_ip_thread(void *pArgs) {
|
||||
MSGBOX_ID msgboxid;
|
||||
BACMSG msg_storage, *bacmsg = NULL;
|
||||
MSG_DATA *msg_data;
|
||||
ROUTER_PORT *port = (ROUTER_PORT*)pArgs;
|
||||
IP_DATA ip_data; /* port specific parameters */
|
||||
BACNET_ADDRESS address = { 0 };
|
||||
int status;
|
||||
uint8_t shutdown = 0;
|
||||
|
||||
/* initialize router port */
|
||||
if (!dl_ip_init(port, &ip_data)) {
|
||||
port->state = INIT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate buffer */
|
||||
ip_data.max_buff = MAX_BIP_MPDU;
|
||||
ip_data.buff = (uint8_t*)malloc(ip_data.max_buff);
|
||||
|
||||
if (ip_data.buff == NULL) {
|
||||
port->state = INIT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msgboxid = create_msgbox();
|
||||
if (msgboxid == INVALID_MSGBOX_ID) {
|
||||
PRINT(ERROR, "Error: Failed to create message box");
|
||||
port->state = INIT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
port->port_id = msgboxid;
|
||||
port->state = RUNNING;
|
||||
|
||||
while (!shutdown) {
|
||||
|
||||
/* check for incoming messages */
|
||||
bacmsg = recv_from_msgbox(port->port_id, &msg_storage);
|
||||
|
||||
if (bacmsg) {
|
||||
switch(bacmsg->type) {
|
||||
case DATA: {
|
||||
msg_data = (MSG_DATA*)bacmsg->data;
|
||||
memmove(&address.net, &msg_data->dest.net, 2);
|
||||
memmove(&address.mac_len, &msg_data->dest.len, 1);
|
||||
memmove(&address.mac[0], &msg_data->dest.adr[0], MAX_MAC_LEN);
|
||||
|
||||
dl_ip_send(&ip_data, &address, msg_data->pdu, msg_data->pdu_len);
|
||||
|
||||
check_data(msg_data);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVICE: {
|
||||
switch(bacmsg->subtype) {
|
||||
case SHUTDOWN:
|
||||
del_msgbox(port->port_id);
|
||||
shutdown = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
status = dl_ip_recv(&ip_data, &msg_data, &address, 1000);
|
||||
if (status > 0) {
|
||||
memmove(&msg_data->src.len, &address.mac_len, 1);
|
||||
memmove(&msg_data->src.adr[0], &address.mac[0], MAX_MAC_LEN);
|
||||
msg_storage.origin = port->port_id;
|
||||
msg_storage.type = DATA;
|
||||
msg_storage.data = msg_data;
|
||||
|
||||
if (!send_to_msgbox(port->main_id, &msg_storage)) {
|
||||
free_data(msg_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup procedure */
|
||||
dl_ip_cleanup(&ip_data);
|
||||
port->state = FINISHED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool dl_ip_init(ROUTER_PORT *port,
|
||||
IP_DATA *ip_data) {
|
||||
struct sockaddr_in sin;
|
||||
int socket_opt = 0;
|
||||
int status = 0; /* for error checking */
|
||||
|
||||
/* setup port for later use */
|
||||
ip_data->port = htons(port->params.bip_params.port);
|
||||
|
||||
/* get local address */
|
||||
status = get_local_address_ioctl(port->iface, &ip_data->local_addr, SIOCGIFADDR);
|
||||
if (status < 0) {
|
||||
return false;
|
||||
}
|
||||
/* get broadcast address */
|
||||
status = get_local_address_ioctl(port->iface, &ip_data->broadcast_addr, SIOCGIFBRDADDR);
|
||||
if (status < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ip_data->socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (ip_data->socket < 0)
|
||||
return false;
|
||||
|
||||
/* setup socket options */
|
||||
|
||||
socket_opt = 1;
|
||||
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_REUSEADDR, &socket_opt, sizeof(socket_opt));
|
||||
if (status < 0) {
|
||||
close(ip_data->socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_BROADCAST, &socket_opt, sizeof(socket_opt));
|
||||
if (status < 0) {
|
||||
close(ip_data->socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* bind the socket to the local port number */
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
sin.sin_port = ip_data->port;
|
||||
|
||||
memset(&sin.sin_zero, '\0', sizeof(sin.sin_zero));
|
||||
|
||||
status = bind(ip_data->socket, (const struct sockaddr *) &sin, sizeof(struct sockaddr));
|
||||
if (status < 0) {
|
||||
close(ip_data->socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* add BIP address to router port structure */
|
||||
memcpy(&port->route_info.mac[0], &ip_data->local_addr.s_addr, 4);
|
||||
memcpy(&port->route_info.mac[4], &port->params.bip_params.port, 2);
|
||||
port->route_info.mac_len = 6;
|
||||
|
||||
PRINT(INFO, "Interface: %s\n", port->iface);
|
||||
PRINT(INFO, "IP Address: %s\n", inet_ntoa(ip_data->local_addr));
|
||||
PRINT(INFO, "IP Broadcast Address: %s\n", inet_ntoa(ip_data->broadcast_addr));
|
||||
PRINT(INFO, "UDP Port: 0x%04X [%hu]\n", (port->params.bip_params.port),
|
||||
(port->params.bip_params.port));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int dl_ip_send(IP_DATA *data,
|
||||
BACNET_ADDRESS *dest,
|
||||
uint8_t *pdu,
|
||||
unsigned pdu_len)
|
||||
void *dl_ip_thread(
|
||||
void *pArgs)
|
||||
{
|
||||
struct sockaddr_in bip_dest = { 0 };
|
||||
int buff_len = 0;
|
||||
int bytes_sent = 0;
|
||||
MSGBOX_ID msgboxid;
|
||||
BACMSG msg_storage, *bacmsg = NULL;
|
||||
MSG_DATA *msg_data;
|
||||
ROUTER_PORT *port = (ROUTER_PORT *) pArgs;
|
||||
IP_DATA ip_data; /* port specific parameters */
|
||||
BACNET_ADDRESS address = { 0 };
|
||||
int status;
|
||||
uint8_t shutdown = 0;
|
||||
|
||||
if (data->socket < 0)
|
||||
return -1;
|
||||
/* initialize router port */
|
||||
if (!dl_ip_init(port, &ip_data)) {
|
||||
port->state = INIT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->buff[0] = BVLL_TYPE_BACNET_IP;
|
||||
bip_dest.sin_family = AF_INET;
|
||||
if (dest->net == BACNET_BROADCAST_NETWORK) {
|
||||
/* broadcast */
|
||||
bip_dest.sin_addr.s_addr = data->broadcast_addr.s_addr;
|
||||
bip_dest.sin_port = data->port;
|
||||
data->buff[1] = BVLC_ORIGINAL_BROADCAST_NPDU;
|
||||
} else if (dest->mac_len == 6) {
|
||||
memcpy(&bip_dest.sin_addr.s_addr, &dest->mac[0], 4);
|
||||
memcpy(&bip_dest.sin_port, &dest->mac[4], 2);
|
||||
data->buff[1] = BVLC_ORIGINAL_UNICAST_NPDU;
|
||||
} else {
|
||||
/* invalid address */
|
||||
return -1;
|
||||
}
|
||||
/* allocate buffer */
|
||||
ip_data.max_buff = MAX_BIP_MPDU;
|
||||
ip_data.buff = (uint8_t *) malloc(ip_data.max_buff);
|
||||
|
||||
buff_len = 2;
|
||||
buff_len +=
|
||||
encode_unsigned16(&data->buff[buff_len],
|
||||
(uint16_t) (pdu_len + 4 /*inclusive*/ ));
|
||||
memcpy(&data->buff[buff_len], pdu, pdu_len);
|
||||
buff_len += pdu_len;
|
||||
if (ip_data.buff == NULL) {
|
||||
port->state = INIT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* send the packet */
|
||||
bytes_sent =
|
||||
sendto(data->socket, (char *) data->buff, buff_len, 0,
|
||||
(struct sockaddr *) &bip_dest, sizeof(struct sockaddr));
|
||||
msgboxid = create_msgbox();
|
||||
if (msgboxid == INVALID_MSGBOX_ID) {
|
||||
PRINT(ERROR, "Error: Failed to create message box");
|
||||
port->state = INIT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRINT(DEBUG, "send to %s\n", inet_ntoa(bip_dest.sin_addr));
|
||||
port->port_id = msgboxid;
|
||||
port->state = RUNNING;
|
||||
|
||||
return bytes_sent;
|
||||
while (!shutdown) {
|
||||
|
||||
/* check for incoming messages */
|
||||
bacmsg = recv_from_msgbox(port->port_id, &msg_storage);
|
||||
|
||||
if (bacmsg) {
|
||||
switch (bacmsg->type) {
|
||||
case DATA:{
|
||||
msg_data = (MSG_DATA *) bacmsg->data;
|
||||
memmove(&address.net, &msg_data->dest.net, 2);
|
||||
memmove(&address.mac_len, &msg_data->dest.len, 1);
|
||||
memmove(&address.mac[0], &msg_data->dest.adr[0],
|
||||
MAX_MAC_LEN);
|
||||
|
||||
dl_ip_send(&ip_data, &address, msg_data->pdu,
|
||||
msg_data->pdu_len);
|
||||
|
||||
check_data(msg_data);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SERVICE:{
|
||||
switch (bacmsg->subtype) {
|
||||
case SHUTDOWN:
|
||||
del_msgbox(port->port_id);
|
||||
shutdown = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
status = dl_ip_recv(&ip_data, &msg_data, &address, 1000);
|
||||
if (status > 0) {
|
||||
memmove(&msg_data->src.len, &address.mac_len, 1);
|
||||
memmove(&msg_data->src.adr[0], &address.mac[0], MAX_MAC_LEN);
|
||||
msg_storage.origin = port->port_id;
|
||||
msg_storage.type = DATA;
|
||||
msg_storage.data = msg_data;
|
||||
|
||||
if (!send_to_msgbox(port->main_id, &msg_storage)) {
|
||||
free_data(msg_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup procedure */
|
||||
dl_ip_cleanup(&ip_data);
|
||||
port->state = FINISHED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool dl_ip_init(
|
||||
ROUTER_PORT * port,
|
||||
IP_DATA * ip_data)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int socket_opt = 0;
|
||||
int status = 0; /* for error checking */
|
||||
|
||||
/* setup port for later use */
|
||||
ip_data->port = htons(port->params.bip_params.port);
|
||||
|
||||
/* get local address */
|
||||
status =
|
||||
get_local_address_ioctl(port->iface, &ip_data->local_addr,
|
||||
SIOCGIFADDR);
|
||||
if (status < 0) {
|
||||
return false;
|
||||
}
|
||||
/* get broadcast address */
|
||||
status =
|
||||
get_local_address_ioctl(port->iface, &ip_data->broadcast_addr,
|
||||
SIOCGIFBRDADDR);
|
||||
if (status < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ip_data->socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (ip_data->socket < 0)
|
||||
return false;
|
||||
|
||||
/* setup socket options */
|
||||
|
||||
socket_opt = 1;
|
||||
status =
|
||||
setsockopt(ip_data->socket, SOL_SOCKET, SO_REUSEADDR, &socket_opt,
|
||||
sizeof(socket_opt));
|
||||
if (status < 0) {
|
||||
close(ip_data->socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
status =
|
||||
setsockopt(ip_data->socket, SOL_SOCKET, SO_BROADCAST, &socket_opt,
|
||||
sizeof(socket_opt));
|
||||
if (status < 0) {
|
||||
close(ip_data->socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* bind the socket to the local port number */
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
sin.sin_port = ip_data->port;
|
||||
|
||||
memset(&sin.sin_zero, '\0', sizeof(sin.sin_zero));
|
||||
|
||||
status =
|
||||
bind(ip_data->socket, (const struct sockaddr *) &sin,
|
||||
sizeof(struct sockaddr));
|
||||
if (status < 0) {
|
||||
close(ip_data->socket);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* add BIP address to router port structure */
|
||||
memcpy(&port->route_info.mac[0], &ip_data->local_addr.s_addr, 4);
|
||||
memcpy(&port->route_info.mac[4], &port->params.bip_params.port, 2);
|
||||
port->route_info.mac_len = 6;
|
||||
|
||||
PRINT(INFO, "Interface: %s\n", port->iface);
|
||||
PRINT(INFO, "IP Address: %s\n", inet_ntoa(ip_data->local_addr));
|
||||
PRINT(INFO, "IP Broadcast Address: %s\n",
|
||||
inet_ntoa(ip_data->broadcast_addr));
|
||||
PRINT(INFO, "UDP Port: 0x%04X [%hu]\n", (port->params.bip_params.port),
|
||||
(port->params.bip_params.port));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int dl_ip_send(
|
||||
IP_DATA * data,
|
||||
BACNET_ADDRESS * dest,
|
||||
uint8_t * pdu,
|
||||
unsigned pdu_len)
|
||||
{
|
||||
struct sockaddr_in bip_dest = { 0 };
|
||||
int buff_len = 0;
|
||||
int bytes_sent = 0;
|
||||
|
||||
if (data->socket < 0)
|
||||
return -1;
|
||||
|
||||
data->buff[0] = BVLL_TYPE_BACNET_IP;
|
||||
bip_dest.sin_family = AF_INET;
|
||||
if (dest->net == BACNET_BROADCAST_NETWORK) {
|
||||
/* broadcast */
|
||||
bip_dest.sin_addr.s_addr = data->broadcast_addr.s_addr;
|
||||
bip_dest.sin_port = data->port;
|
||||
data->buff[1] = BVLC_ORIGINAL_BROADCAST_NPDU;
|
||||
} else if (dest->mac_len == 6) {
|
||||
memcpy(&bip_dest.sin_addr.s_addr, &dest->mac[0], 4);
|
||||
memcpy(&bip_dest.sin_port, &dest->mac[4], 2);
|
||||
data->buff[1] = BVLC_ORIGINAL_UNICAST_NPDU;
|
||||
} else {
|
||||
/* invalid address */
|
||||
return -1;
|
||||
}
|
||||
|
||||
buff_len = 2;
|
||||
buff_len +=
|
||||
encode_unsigned16(&data->buff[buff_len],
|
||||
(uint16_t) (pdu_len + 4 /*inclusive */ ));
|
||||
memcpy(&data->buff[buff_len], pdu, pdu_len);
|
||||
buff_len += pdu_len;
|
||||
|
||||
/* send the packet */
|
||||
bytes_sent =
|
||||
sendto(data->socket, (char *) data->buff, buff_len, 0,
|
||||
(struct sockaddr *) &bip_dest, sizeof(struct sockaddr));
|
||||
|
||||
PRINT(DEBUG, "send to %s\n", inet_ntoa(bip_dest.sin_addr));
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
int dl_ip_recv(
|
||||
IP_DATA *data,
|
||||
MSG_DATA **msg_data,
|
||||
BACNET_ADDRESS *src,
|
||||
unsigned timeout)
|
||||
IP_DATA * data,
|
||||
MSG_DATA ** msg_data,
|
||||
BACNET_ADDRESS * src,
|
||||
unsigned timeout)
|
||||
{
|
||||
int received_bytes = 0;
|
||||
uint16_t buff_len = 0; /* return value */
|
||||
fd_set read_fds;
|
||||
struct timeval select_timeout;
|
||||
struct sockaddr_in sin = { 0 };
|
||||
socklen_t sin_len = sizeof(sin);
|
||||
int received_bytes = 0;
|
||||
uint16_t buff_len = 0; /* return value */
|
||||
fd_set read_fds;
|
||||
struct timeval select_timeout;
|
||||
struct sockaddr_in sin = { 0 };
|
||||
socklen_t sin_len = sizeof(sin);
|
||||
|
||||
/* make sure the socket is open */
|
||||
if (data->socket < 0)
|
||||
return 0;
|
||||
/* make sure the socket is open */
|
||||
if (data->socket < 0)
|
||||
return 0;
|
||||
|
||||
if (timeout >= 1000) {
|
||||
select_timeout.tv_sec = timeout / 1000;
|
||||
select_timeout.tv_usec = 1000 * (timeout - select_timeout.tv_sec * 1000);
|
||||
} else {
|
||||
select_timeout.tv_sec = 0;
|
||||
select_timeout.tv_usec = 1000 * timeout;
|
||||
}
|
||||
if (timeout >= 1000) {
|
||||
select_timeout.tv_sec = timeout / 1000;
|
||||
select_timeout.tv_usec =
|
||||
1000 * (timeout - select_timeout.tv_sec * 1000);
|
||||
} else {
|
||||
select_timeout.tv_sec = 0;
|
||||
select_timeout.tv_usec = 1000 * timeout;
|
||||
}
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(data->socket, &read_fds);
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(data->socket, &read_fds);
|
||||
|
||||
#ifdef TEST_PACKET
|
||||
received_bytes = sizeof(test_packet);
|
||||
memmove(data->buff, &test_packet, received_bytes);
|
||||
sin.sin_addr.s_addr = 0x7E1D40A; sin.sin_port = 0xC0BA;
|
||||
received_bytes = sizeof(test_packet);
|
||||
memmove(data->buff, &test_packet, received_bytes);
|
||||
sin.sin_addr.s_addr = 0x7E1D40A;
|
||||
sin.sin_port = 0xC0BA;
|
||||
#else
|
||||
int ret = select(data->socket + 1, &read_fds, NULL, NULL, &select_timeout);
|
||||
/* see if there is a packet for us */
|
||||
if (ret > 0)
|
||||
received_bytes =
|
||||
recvfrom(data->socket, (char *) &data->buff[0], data->max_buff, 0,
|
||||
(struct sockaddr *) &sin, &sin_len);
|
||||
else
|
||||
return 0;
|
||||
int ret = select(data->socket + 1, &read_fds, NULL, NULL, &select_timeout);
|
||||
/* see if there is a packet for us */
|
||||
if (ret > 0)
|
||||
received_bytes =
|
||||
recvfrom(data->socket, (char *) &data->buff[0], data->max_buff, 0,
|
||||
(struct sockaddr *) &sin, &sin_len);
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
PRINT(DEBUG, "received from %s\n", inet_ntoa(sin.sin_addr));
|
||||
PRINT(DEBUG, "received from %s\n", inet_ntoa(sin.sin_addr));
|
||||
|
||||
/* check for errors */
|
||||
if (received_bytes <= 0) {
|
||||
return 0;
|
||||
}
|
||||
/* check for errors */
|
||||
if (received_bytes <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the signature of a BACnet/IP packet */
|
||||
if (data->buff[0] != BVLL_TYPE_BACNET_IP)
|
||||
return 0;
|
||||
/* the signature of a BACnet/IP packet */
|
||||
if (data->buff[0] != BVLL_TYPE_BACNET_IP)
|
||||
return 0;
|
||||
|
||||
switch (data->buff[1]) {
|
||||
case BVLC_ORIGINAL_UNICAST_NPDU:
|
||||
case BVLC_ORIGINAL_BROADCAST_NPDU: {
|
||||
if ((sin.sin_addr.s_addr == data->local_addr.s_addr) &&
|
||||
(sin.sin_port == data->port)) {
|
||||
buff_len = 0;
|
||||
switch (data->buff[1]) {
|
||||
case BVLC_ORIGINAL_UNICAST_NPDU:
|
||||
case BVLC_ORIGINAL_BROADCAST_NPDU:{
|
||||
if ((sin.sin_addr.s_addr == data->local_addr.s_addr) &&
|
||||
(sin.sin_port == data->port)) {
|
||||
buff_len = 0;
|
||||
|
||||
PRINT(DEBUG, "BIP: src is me. Discarded!\n");
|
||||
PRINT(DEBUG, "BIP: src is me. Discarded!\n");
|
||||
|
||||
} else {
|
||||
src->mac_len = 6;
|
||||
memcpy(&src->mac[0], &sin.sin_addr.s_addr, 4);
|
||||
memcpy(&src->mac[4], &sin.sin_port, 2);
|
||||
} else {
|
||||
src->mac_len = 6;
|
||||
memcpy(&src->mac[0], &sin.sin_addr.s_addr, 4);
|
||||
memcpy(&src->mac[4], &sin.sin_port, 2);
|
||||
|
||||
(void) decode_unsigned16(&data->buff[2], &buff_len);
|
||||
/* subtract off the BVLC header */
|
||||
buff_len -= 4;
|
||||
if (buff_len < data->max_buff) {
|
||||
/* allocate data message stucture */
|
||||
(*msg_data) = (MSG_DATA*)malloc(sizeof(MSG_DATA));
|
||||
(*msg_data)->pdu_len = buff_len;
|
||||
(*msg_data)->pdu = (uint8_t*)malloc((*msg_data)->pdu_len);
|
||||
/* fill up data message structure */
|
||||
memmove(&(*msg_data)->pdu[0], &data->buff[4], (*msg_data)->pdu_len);
|
||||
memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS));
|
||||
}
|
||||
/* ignore packets that are too large */
|
||||
else {
|
||||
buff_len = 0;
|
||||
(void) decode_unsigned16(&data->buff[2], &buff_len);
|
||||
/* subtract off the BVLC header */
|
||||
buff_len -= 4;
|
||||
if (buff_len < data->max_buff) {
|
||||
/* allocate data message stucture */
|
||||
(*msg_data) = (MSG_DATA *) malloc(sizeof(MSG_DATA));
|
||||
(*msg_data)->pdu_len = buff_len;
|
||||
(*msg_data)->pdu =
|
||||
(uint8_t *) malloc((*msg_data)->pdu_len);
|
||||
/* fill up data message structure */
|
||||
memmove(&(*msg_data)->pdu[0], &data->buff[4],
|
||||
(*msg_data)->pdu_len);
|
||||
memmove(&(*msg_data)->src, src,
|
||||
sizeof(BACNET_ADDRESS));
|
||||
}
|
||||
/* ignore packets that are too large */
|
||||
else {
|
||||
buff_len = 0;
|
||||
|
||||
PRINT(ERROR, "BIP: PDU too large. Discarded!.\n");
|
||||
PRINT(ERROR, "BIP: PDU too large. Discarded!.\n");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BVLC_FORWARDED_NPDU: {
|
||||
memcpy(&sin.sin_addr.s_addr, &data->buff[4], 4);
|
||||
memcpy(&sin.sin_port, &data->buff[8], 2);
|
||||
if ((sin.sin_addr.s_addr == data->local_addr.s_addr) &&
|
||||
(sin.sin_port == data->port)) {
|
||||
buff_len = 0;
|
||||
} else {
|
||||
src->mac_len = 6;
|
||||
memcpy(&src->mac[0], &sin.sin_addr.s_addr, 4);
|
||||
memcpy(&src->mac[4], &sin.sin_port, 2);
|
||||
case BVLC_FORWARDED_NPDU:{
|
||||
memcpy(&sin.sin_addr.s_addr, &data->buff[4], 4);
|
||||
memcpy(&sin.sin_port, &data->buff[8], 2);
|
||||
if ((sin.sin_addr.s_addr == data->local_addr.s_addr) &&
|
||||
(sin.sin_port == data->port)) {
|
||||
buff_len = 0;
|
||||
} else {
|
||||
src->mac_len = 6;
|
||||
memcpy(&src->mac[0], &sin.sin_addr.s_addr, 4);
|
||||
memcpy(&src->mac[4], &sin.sin_port, 2);
|
||||
|
||||
(void) decode_unsigned16(&data->buff[2], &buff_len);
|
||||
/* subtract off the BVLC header */
|
||||
buff_len -= 10;
|
||||
if (buff_len < data->max_buff) {
|
||||
/* allocate data message stucture */
|
||||
(*msg_data) = (MSG_DATA*)malloc(sizeof(MSG_DATA));
|
||||
(*msg_data)->pdu_len = buff_len;
|
||||
(*msg_data)->pdu = (uint8_t*)malloc((*msg_data)->pdu_len);
|
||||
/* fill up data message structure */
|
||||
memmove(&(*msg_data)->pdu, &data->buff[4+6], (*msg_data)->pdu_len);
|
||||
memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS));
|
||||
} else {
|
||||
/* ignore packets that are too large */
|
||||
buff_len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(void) decode_unsigned16(&data->buff[2], &buff_len);
|
||||
/* subtract off the BVLC header */
|
||||
buff_len -= 10;
|
||||
if (buff_len < data->max_buff) {
|
||||
/* allocate data message stucture */
|
||||
(*msg_data) = (MSG_DATA *) malloc(sizeof(MSG_DATA));
|
||||
(*msg_data)->pdu_len = buff_len;
|
||||
(*msg_data)->pdu =
|
||||
(uint8_t *) malloc((*msg_data)->pdu_len);
|
||||
/* fill up data message structure */
|
||||
memmove(&(*msg_data)->pdu, &data->buff[4 + 6],
|
||||
(*msg_data)->pdu_len);
|
||||
memmove(&(*msg_data)->src, src,
|
||||
sizeof(BACNET_ADDRESS));
|
||||
} else {
|
||||
/* ignore packets that are too large */
|
||||
buff_len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
PRINT(ERROR, "BIP: BVLC discarded!\n");
|
||||
PRINT(ERROR, "BIP: BVLC discarded!\n");
|
||||
|
||||
break;
|
||||
}
|
||||
return buff_len;
|
||||
break;
|
||||
}
|
||||
return buff_len;
|
||||
}
|
||||
|
||||
void dl_ip_cleanup(
|
||||
IP_DATA *ip_data) {
|
||||
/* free buffer */
|
||||
if (ip_data->buff)
|
||||
free(ip_data->buff);
|
||||
/* close socket */
|
||||
if (ip_data->socket > 0)
|
||||
close(ip_data->socket);
|
||||
return;
|
||||
IP_DATA * ip_data)
|
||||
{
|
||||
/* free buffer */
|
||||
if (ip_data->buff)
|
||||
free(ip_data->buff);
|
||||
/* close socket */
|
||||
if (ip_data->socket > 0)
|
||||
close(ip_data->socket);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,36 +26,36 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
#define MAX_BIP_PDU (MAX_NPDU + MAX_BIP_APDU)
|
||||
#define MAX_BIP_MPDU (MAX_HEADER + MAX_BIP_PDU)
|
||||
|
||||
typedef struct ip_data {
|
||||
int socket;
|
||||
uint16_t port;
|
||||
struct in_addr local_addr;
|
||||
struct in_addr broadcast_addr;
|
||||
uint8_t *buff;
|
||||
uint16_t max_buff;
|
||||
} IP_DATA;
|
||||
typedef struct ip_data {
|
||||
int socket;
|
||||
uint16_t port;
|
||||
struct in_addr local_addr;
|
||||
struct in_addr broadcast_addr;
|
||||
uint8_t *buff;
|
||||
uint16_t max_buff;
|
||||
} IP_DATA;
|
||||
|
||||
|
||||
void* dl_ip_thread(
|
||||
void *pArgs);
|
||||
void *dl_ip_thread(
|
||||
void *pArgs);
|
||||
|
||||
bool dl_ip_init(
|
||||
ROUTER_PORT *port,
|
||||
IP_DATA *data);
|
||||
ROUTER_PORT * port,
|
||||
IP_DATA * data);
|
||||
|
||||
int dl_ip_send(
|
||||
IP_DATA *data,
|
||||
BACNET_ADDRESS *dest,
|
||||
uint8_t *pdu,
|
||||
unsigned pdu_len);
|
||||
IP_DATA * data,
|
||||
BACNET_ADDRESS * dest,
|
||||
uint8_t * pdu,
|
||||
unsigned pdu_len);
|
||||
|
||||
int dl_ip_recv(
|
||||
IP_DATA *data,
|
||||
MSG_DATA **msg, /* on recieve fill up message */
|
||||
BACNET_ADDRESS *src,
|
||||
unsigned timeout);
|
||||
IP_DATA * data,
|
||||
MSG_DATA ** msg, /* on recieve fill up message */
|
||||
BACNET_ADDRESS * src,
|
||||
unsigned timeout);
|
||||
|
||||
void dl_ip_cleanup(
|
||||
IP_DATA *data);
|
||||
IP_DATA * data);
|
||||
|
||||
#endif /* end of UDPMODULE_H */
|
||||
|
||||
+695
-625
File diff suppressed because it is too large
Load Diff
@@ -23,73 +23,80 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
|
||||
pthread_mutex_t msg_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
MSGBOX_ID create_msgbox() {
|
||||
MSGBOX_ID msgboxid;
|
||||
MSGBOX_ID create_msgbox(
|
||||
)
|
||||
{
|
||||
MSGBOX_ID msgboxid;
|
||||
|
||||
msgboxid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
|
||||
if (msgboxid == INVALID_MSGBOX_ID) {
|
||||
return INVALID_MSGBOX_ID;
|
||||
}
|
||||
msgboxid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
|
||||
if (msgboxid == INVALID_MSGBOX_ID) {
|
||||
return INVALID_MSGBOX_ID;
|
||||
}
|
||||
|
||||
return msgboxid;
|
||||
return msgboxid;
|
||||
}
|
||||
|
||||
bool send_to_msgbox(
|
||||
MSGBOX_ID dest,
|
||||
BACMSG *msg) {
|
||||
MSGBOX_ID dest,
|
||||
BACMSG * msg)
|
||||
{
|
||||
|
||||
int err;
|
||||
int err;
|
||||
|
||||
err = msgsnd(dest, msg, sizeof(BACMSG), 0);
|
||||
if (err) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
err = msgsnd(dest, msg, sizeof(BACMSG), 0);
|
||||
if (err) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
BACMSG* recv_from_msgbox(
|
||||
MSGBOX_ID src,
|
||||
BACMSG *msg) {
|
||||
BACMSG *recv_from_msgbox(
|
||||
MSGBOX_ID src,
|
||||
BACMSG * msg)
|
||||
{
|
||||
|
||||
int recv_bytes;
|
||||
int recv_bytes;
|
||||
|
||||
recv_bytes = msgrcv(src, msg, sizeof(BACMSG), 0, IPC_NOWAIT);
|
||||
if (recv_bytes > 0) {
|
||||
return msg;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
recv_bytes = msgrcv(src, msg, sizeof(BACMSG), 0, IPC_NOWAIT);
|
||||
if (recv_bytes > 0) {
|
||||
return msg;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void del_msgbox(
|
||||
MSGBOX_ID msgboxid) {
|
||||
MSGBOX_ID msgboxid)
|
||||
{
|
||||
|
||||
if (msgboxid == INVALID_MSGBOX_ID)
|
||||
return;
|
||||
else
|
||||
msgctl(msgboxid, IPC_RMID, NULL);
|
||||
if (msgboxid == INVALID_MSGBOX_ID)
|
||||
return;
|
||||
else
|
||||
msgctl(msgboxid, IPC_RMID, NULL);
|
||||
}
|
||||
|
||||
void free_data(
|
||||
MSG_DATA *data) {
|
||||
MSG_DATA * data)
|
||||
{
|
||||
|
||||
if (data->pdu) {
|
||||
free(data->pdu);
|
||||
data->pdu = NULL;
|
||||
}
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
if (data->pdu) {
|
||||
free(data->pdu);
|
||||
data->pdu = NULL;
|
||||
}
|
||||
if (data) {
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void check_data(
|
||||
MSG_DATA *data) {
|
||||
MSG_DATA * data)
|
||||
{
|
||||
|
||||
/* lock and decrement messages reference count */
|
||||
pthread_mutex_lock(&msg_lock);
|
||||
if (--data->ref_count == 0) {
|
||||
free_data(data);
|
||||
}
|
||||
pthread_mutex_unlock(&msg_lock);
|
||||
/* lock and decrement messages reference count */
|
||||
pthread_mutex_lock(&msg_lock);
|
||||
if (--data->ref_count == 0) {
|
||||
free_data(data);
|
||||
}
|
||||
pthread_mutex_unlock(&msg_lock);
|
||||
}
|
||||
|
||||
@@ -32,54 +32,55 @@ extern pthread_mutex_t msg_lock;
|
||||
typedef int MSGBOX_ID;
|
||||
|
||||
typedef enum {
|
||||
DATA,
|
||||
SERVICE
|
||||
DATA,
|
||||
SERVICE
|
||||
} MSGTYPE;
|
||||
|
||||
typedef enum {
|
||||
SHUTDOWN,
|
||||
CHG_IP,
|
||||
CHG_MAC
|
||||
SHUTDOWN,
|
||||
CHG_IP,
|
||||
CHG_MAC
|
||||
} MSGSUBTYPE;
|
||||
|
||||
typedef struct _message {
|
||||
MSGBOX_ID origin;
|
||||
MSGTYPE type;
|
||||
MSGSUBTYPE subtype;
|
||||
void *data;
|
||||
/* add timestamp */
|
||||
MSGBOX_ID origin;
|
||||
MSGTYPE type;
|
||||
MSGSUBTYPE subtype;
|
||||
void *data;
|
||||
/* add timestamp */
|
||||
} BACMSG;
|
||||
|
||||
/* specific message type data structures */
|
||||
typedef struct _msg_data {
|
||||
BACNET_ADDRESS dest;
|
||||
BACNET_ADDRESS src;
|
||||
uint8_t *pdu;
|
||||
uint16_t pdu_len;
|
||||
uint8_t ref_count;
|
||||
BACNET_ADDRESS dest;
|
||||
BACNET_ADDRESS src;
|
||||
uint8_t *pdu;
|
||||
uint16_t pdu_len;
|
||||
uint8_t ref_count;
|
||||
} MSG_DATA;
|
||||
|
||||
MSGBOX_ID create_msgbox();
|
||||
MSGBOX_ID create_msgbox(
|
||||
);
|
||||
|
||||
/* returns sent byte count */
|
||||
bool send_to_msgbox(
|
||||
MSGBOX_ID dest,
|
||||
BACMSG *msg);
|
||||
MSGBOX_ID dest,
|
||||
BACMSG * msg);
|
||||
|
||||
/* returns received message */
|
||||
BACMSG* recv_from_msgbox(
|
||||
MSGBOX_ID src,
|
||||
BACMSG *msg);
|
||||
BACMSG *recv_from_msgbox(
|
||||
MSGBOX_ID src,
|
||||
BACMSG * msg);
|
||||
|
||||
void del_msgbox(
|
||||
MSGBOX_ID msgboxid);
|
||||
MSGBOX_ID msgboxid);
|
||||
|
||||
/* free message data structure */
|
||||
void free_data(
|
||||
MSG_DATA *data);
|
||||
MSG_DATA * data);
|
||||
|
||||
/* check message reference counter and delete data if needed */
|
||||
void check_data(
|
||||
MSG_DATA *data);
|
||||
MSG_DATA * data);
|
||||
|
||||
#endif /* end of MSGQUEUE_H */
|
||||
|
||||
@@ -29,140 +29,139 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
#define mstp_thread_debug(...)
|
||||
#endif
|
||||
|
||||
void* dl_mstp_thread(void* pArgs) {
|
||||
void *dl_mstp_thread(
|
||||
void *pArgs)
|
||||
{
|
||||
|
||||
ROUTER_PORT *port = (ROUTER_PORT*)pArgs;
|
||||
struct mstp_port_struct_t mstp_port = {(MSTP_RECEIVE_STATE)0};
|
||||
volatile SHARED_MSTP_DATA shared_port_data = {0};
|
||||
uint16_t pdu_len;
|
||||
uint8_t shutdown = 0;
|
||||
ROUTER_PORT *port = (ROUTER_PORT *) pArgs;
|
||||
struct mstp_port_struct_t mstp_port = { (MSTP_RECEIVE_STATE) 0 };
|
||||
volatile SHARED_MSTP_DATA shared_port_data = { 0 };
|
||||
uint16_t pdu_len;
|
||||
uint8_t shutdown = 0;
|
||||
|
||||
shared_port_data.Treply_timeout = 260;
|
||||
shared_port_data.MSTP_Packets = 0;
|
||||
shared_port_data.Tusage_timeout = 50;
|
||||
shared_port_data.RS485_Handle = -1;
|
||||
shared_port_data.RS485_Baud = B38400;
|
||||
shared_port_data.RS485MOD = 0;
|
||||
shared_port_data.Treply_timeout = 260;
|
||||
shared_port_data.MSTP_Packets = 0;
|
||||
shared_port_data.Tusage_timeout = 50;
|
||||
shared_port_data.RS485_Handle = -1;
|
||||
shared_port_data.RS485_Baud = B38400;
|
||||
shared_port_data.RS485MOD = 0;
|
||||
|
||||
switch(port->params.mstp_params.databits){
|
||||
case 5:
|
||||
shared_port_data.RS485MOD = CS5;
|
||||
break;
|
||||
case 6:
|
||||
shared_port_data.RS485MOD = CS6;
|
||||
break;
|
||||
case 7:
|
||||
shared_port_data.RS485MOD = CS7;
|
||||
break;
|
||||
default:
|
||||
shared_port_data.RS485MOD = CS8;
|
||||
break;
|
||||
}
|
||||
switch (port->params.mstp_params.databits) {
|
||||
case 5:
|
||||
shared_port_data.RS485MOD = CS5;
|
||||
break;
|
||||
case 6:
|
||||
shared_port_data.RS485MOD = CS6;
|
||||
break;
|
||||
case 7:
|
||||
shared_port_data.RS485MOD = CS7;
|
||||
break;
|
||||
default:
|
||||
shared_port_data.RS485MOD = CS8;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(port->params.mstp_params.parity){
|
||||
case PARITY_EVEN:
|
||||
shared_port_data.RS485MOD |= PARENB;
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
shared_port_data.RS485MOD |= PARENB | PARODD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (port->params.mstp_params.parity) {
|
||||
case PARITY_EVEN:
|
||||
shared_port_data.RS485MOD |= PARENB;
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
shared_port_data.RS485MOD |= PARENB | PARODD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(port->params.mstp_params.stopbits == 2)
|
||||
shared_port_data.RS485MOD |= CSTOPB;
|
||||
if (port->params.mstp_params.stopbits == 2)
|
||||
shared_port_data.RS485MOD |= CSTOPB;
|
||||
|
||||
mstp_port.UserData = (void*) &shared_port_data;
|
||||
dlmstp_set_baud_rate(&mstp_port, port->params.mstp_params.baudrate);
|
||||
dlmstp_set_mac_address(&mstp_port, port->route_info.mac[0]);
|
||||
dlmstp_set_max_info_frames(&mstp_port, port->params.mstp_params.max_frames);
|
||||
dlmstp_set_max_master(&mstp_port, port->params.mstp_params.max_master);
|
||||
if(!dlmstp_init(&mstp_port, port->iface))
|
||||
printf("MSTP %s init failed. Stop.\n", port->iface);
|
||||
mstp_port.UserData = (void *) &shared_port_data;
|
||||
dlmstp_set_baud_rate(&mstp_port, port->params.mstp_params.baudrate);
|
||||
dlmstp_set_mac_address(&mstp_port, port->route_info.mac[0]);
|
||||
dlmstp_set_max_info_frames(&mstp_port,
|
||||
port->params.mstp_params.max_frames);
|
||||
dlmstp_set_max_master(&mstp_port, port->params.mstp_params.max_master);
|
||||
if (!dlmstp_init(&mstp_port, port->iface))
|
||||
printf("MSTP %s init failed. Stop.\n", port->iface);
|
||||
|
||||
port->port_id = create_msgbox();
|
||||
if (port->port_id == INVALID_MSGBOX_ID) {
|
||||
port->state = INIT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
port->port_id = create_msgbox();
|
||||
if (port->port_id == INVALID_MSGBOX_ID) {
|
||||
port->state = INIT_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
port->state = RUNNING;
|
||||
port->state = RUNNING;
|
||||
|
||||
while (!shutdown) {
|
||||
/* message loop */
|
||||
BACMSG msg_storage, * bacmsg;
|
||||
MSG_DATA * msg_data;
|
||||
while (!shutdown) {
|
||||
/* message loop */
|
||||
BACMSG msg_storage, *bacmsg;
|
||||
MSG_DATA *msg_data;
|
||||
|
||||
bacmsg = recv_from_msgbox(port->port_id, &msg_storage);
|
||||
bacmsg = recv_from_msgbox(port->port_id, &msg_storage);
|
||||
|
||||
if(bacmsg)
|
||||
{
|
||||
switch(bacmsg->type)
|
||||
{
|
||||
case DATA:
|
||||
msg_data = (MSG_DATA*) bacmsg->data;
|
||||
if (bacmsg) {
|
||||
switch (bacmsg->type) {
|
||||
case DATA:
|
||||
msg_data = (MSG_DATA *) bacmsg->data;
|
||||
|
||||
if(msg_data->dest.net == BACNET_BROADCAST_NETWORK)
|
||||
{
|
||||
dlmstp_get_broadcast_address(&(msg_data->dest));
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_data->dest.mac[0] = msg_data->dest.adr[0];
|
||||
msg_data->dest.mac_len = 1;
|
||||
}
|
||||
if (msg_data->dest.net == BACNET_BROADCAST_NETWORK) {
|
||||
dlmstp_get_broadcast_address(&(msg_data->dest));
|
||||
} else {
|
||||
msg_data->dest.mac[0] = msg_data->dest.adr[0];
|
||||
msg_data->dest.mac_len = 1;
|
||||
}
|
||||
|
||||
dlmstp_send_pdu(&mstp_port, &(msg_data->dest), msg_data->pdu, msg_data->pdu_len);
|
||||
dlmstp_send_pdu(&mstp_port, &(msg_data->dest),
|
||||
msg_data->pdu, msg_data->pdu_len);
|
||||
|
||||
check_data(msg_data);
|
||||
check_data(msg_data);
|
||||
|
||||
|
||||
break;
|
||||
case SERVICE:
|
||||
switch(bacmsg->subtype) {
|
||||
case SHUTDOWN:
|
||||
shutdown = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pdu_len = dlmstp_receive(&mstp_port, NULL, NULL, 0, 1000);
|
||||
break;
|
||||
case SERVICE:
|
||||
switch (bacmsg->subtype) {
|
||||
case SHUTDOWN:
|
||||
shutdown = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
pdu_len = dlmstp_receive(&mstp_port, NULL, NULL, 0, 1000);
|
||||
|
||||
if(pdu_len > 0)
|
||||
{
|
||||
msg_data = (MSG_DATA*)malloc(sizeof(MSG_DATA));
|
||||
memmove(&(msg_data->src), (const void*)&(shared_port_data.Receive_Packet.address), sizeof(shared_port_data.Receive_Packet.address));
|
||||
msg_data->src.adr[0] = msg_data->src.mac[0];
|
||||
msg_data->src.len = 1;
|
||||
msg_data->pdu = (uint8_t*)malloc(pdu_len);
|
||||
memmove(msg_data->pdu, (const void*)&(shared_port_data.Receive_Packet.pdu), pdu_len);
|
||||
msg_data->pdu_len = pdu_len;
|
||||
if (pdu_len > 0) {
|
||||
msg_data = (MSG_DATA *) malloc(sizeof(MSG_DATA));
|
||||
memmove(&(msg_data->src),
|
||||
(const void *) &(shared_port_data.Receive_Packet.address),
|
||||
sizeof(shared_port_data.Receive_Packet.address));
|
||||
msg_data->src.adr[0] = msg_data->src.mac[0];
|
||||
msg_data->src.len = 1;
|
||||
msg_data->pdu = (uint8_t *) malloc(pdu_len);
|
||||
memmove(msg_data->pdu,
|
||||
(const void *) &(shared_port_data.Receive_Packet.pdu),
|
||||
pdu_len);
|
||||
msg_data->pdu_len = pdu_len;
|
||||
|
||||
msg_storage.type = DATA;
|
||||
msg_storage.subtype = (MSGSUBTYPE)0;
|
||||
msg_storage.origin = port->port_id;
|
||||
msg_storage.data = msg_data;
|
||||
msg_storage.type = DATA;
|
||||
msg_storage.subtype = (MSGSUBTYPE) 0;
|
||||
msg_storage.origin = port->port_id;
|
||||
msg_storage.data = msg_data;
|
||||
|
||||
if(!send_to_msgbox(port->main_id, &msg_storage))
|
||||
{
|
||||
free_data(msg_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!send_to_msgbox(port->main_id, &msg_storage)) {
|
||||
free_data(msg_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dlmstp_cleanup(&mstp_port);
|
||||
port->state = FINISHED;
|
||||
dlmstp_cleanup(&mstp_port);
|
||||
port->state = FINISHED;
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
|
||||
#include "portthread.h"
|
||||
|
||||
void* dl_mstp_thread(
|
||||
void* pArgs);
|
||||
void *dl_mstp_thread(
|
||||
void *pArgs);
|
||||
|
||||
#endif /* end of MSTPMODULE_H */
|
||||
|
||||
@@ -21,291 +21,307 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
#include "bacint.h"
|
||||
|
||||
uint16_t process_network_message(
|
||||
BACMSG *msg,
|
||||
MSG_DATA *data,
|
||||
uint8_t **buff) {
|
||||
BACMSG * msg,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff)
|
||||
{
|
||||
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
ROUTER_PORT *srcport;
|
||||
ROUTER_PORT *destport;
|
||||
uint16_t net;
|
||||
uint8_t error_code;
|
||||
int16_t buff_len = 0;
|
||||
int apdu_offset;
|
||||
int apdu_len;
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
ROUTER_PORT *srcport;
|
||||
ROUTER_PORT *destport;
|
||||
uint16_t net;
|
||||
uint8_t error_code;
|
||||
int16_t buff_len = 0;
|
||||
int apdu_offset;
|
||||
int apdu_len;
|
||||
|
||||
memmove(data, msg->data, sizeof(MSG_DATA));
|
||||
memmove(data, msg->data, sizeof(MSG_DATA));
|
||||
|
||||
apdu_offset = npdu_decode(data->pdu, &data->dest, NULL, &npdu_data);
|
||||
apdu_len = data->pdu_len - apdu_offset;
|
||||
apdu_offset = npdu_decode(data->pdu, &data->dest, NULL, &npdu_data);
|
||||
apdu_len = data->pdu_len - apdu_offset;
|
||||
|
||||
srcport = find_snet(msg->origin);
|
||||
data->src.net = srcport->route_info.net;
|
||||
srcport = find_snet(msg->origin);
|
||||
data->src.net = srcport->route_info.net;
|
||||
|
||||
switch (npdu_data.network_message_type) {
|
||||
switch (npdu_data.network_message_type) {
|
||||
|
||||
case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
|
||||
PRINT(INFO, "Recieved Who-Is-Router-To-Network message\n");
|
||||
if (apdu_len) {
|
||||
/* if NET specified */
|
||||
decode_unsigned16(&data->pdu[apdu_offset], &net);
|
||||
if (srcport->route_info.net == net) {
|
||||
PRINT(INFO, "Message discarded: NET directly connected\n");
|
||||
return -2;
|
||||
}
|
||||
case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
|
||||
PRINT(INFO, "Recieved Who-Is-Router-To-Network message\n");
|
||||
if (apdu_len) {
|
||||
/* if NET specified */
|
||||
decode_unsigned16(&data->pdu[apdu_offset], &net);
|
||||
if (srcport->route_info.net == net) {
|
||||
PRINT(INFO, "Message discarded: NET directly connected\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
destport = find_dnet(net, NULL); /* see if NET can be reached */
|
||||
if (destport) {
|
||||
/* if TRUE send reply */
|
||||
PRINT(INFO, "Sending I-Am-Router-To-Network message\n");
|
||||
buff_len = create_network_message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK,
|
||||
data, buff, &net);
|
||||
} else {
|
||||
data->dest.net = net; /* NET to look for */
|
||||
return -1; /* else initiate NET search procedure */
|
||||
}
|
||||
} else {
|
||||
/* if NET is omitted (message sent with -1) */
|
||||
PRINT(INFO, "Sending I-Am-Router-To-Network message\n");
|
||||
buff_len = create_network_message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK,
|
||||
data, buff, NULL);
|
||||
}
|
||||
destport = find_dnet(net, NULL); /* see if NET can be reached */
|
||||
if (destport) {
|
||||
/* if TRUE send reply */
|
||||
PRINT(INFO, "Sending I-Am-Router-To-Network message\n");
|
||||
buff_len =
|
||||
create_network_message
|
||||
(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, data, buff,
|
||||
&net);
|
||||
} else {
|
||||
data->dest.net = net; /* NET to look for */
|
||||
return -1; /* else initiate NET search procedure */
|
||||
}
|
||||
} else {
|
||||
/* if NET is omitted (message sent with -1) */
|
||||
PRINT(INFO, "Sending I-Am-Router-To-Network message\n");
|
||||
buff_len =
|
||||
create_network_message
|
||||
(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, data, buff, NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK:
|
||||
{
|
||||
PRINT(INFO, "Recieved I-Am-Router-To-Network message\n");
|
||||
int net_count = apdu_len / 2;
|
||||
int i;
|
||||
for (i = 0; i < net_count; i++) {
|
||||
decode_unsigned16(&data->pdu[apdu_offset+2*i], &net); /* decode received NET values */
|
||||
add_dnet(&srcport->route_info, net, data->src); /* and update routing table */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK:
|
||||
{
|
||||
/* first octet of the message contains rejection reason */
|
||||
/* next two octets contain NET (can be decoded for additional info on error) */
|
||||
error_code = data->pdu[apdu_offset];
|
||||
switch (error_code) {
|
||||
case 0:
|
||||
PRINT(ERROR, "Error!\n");
|
||||
break;
|
||||
case 1:
|
||||
PRINT(ERROR, "Error: Network unreachable\n");
|
||||
break;
|
||||
case 2:
|
||||
PRINT(ERROR, "Error: Network is busy\n");
|
||||
break;
|
||||
case 3:
|
||||
PRINT(ERROR, "Error: Unknown network message type\n");
|
||||
break;
|
||||
case 4:
|
||||
PRINT(ERROR, "Error: Message too long\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NETWORK_MESSAGE_INIT_RT_TABLE:
|
||||
PRINT(INFO, "Recieved Initialize-Routing-Table message\n");
|
||||
if (data->pdu[apdu_offset] > 0) {
|
||||
int net_count = data->pdu[apdu_offset];
|
||||
while (net_count--) {
|
||||
int i = 1;
|
||||
decode_unsigned16(&data->pdu[apdu_offset+i], &net); /* decode received NET values */
|
||||
add_dnet(&srcport->route_info, net, data->src); /* and update routing table */
|
||||
if (data->pdu[apdu_offset+i+3] > 0) /* find next NET value */
|
||||
i = data->pdu[apdu_offset+i+3] + 4;
|
||||
else
|
||||
i = i + 4;
|
||||
}
|
||||
buff_len = create_network_message(NETWORK_MESSAGE_INIT_RT_TABLE_ACK, data, buff, NULL);
|
||||
} else
|
||||
buff_len = create_network_message(NETWORK_MESSAGE_INIT_RT_TABLE_ACK, data, buff, &buff);
|
||||
break;
|
||||
case NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK:
|
||||
{
|
||||
PRINT(INFO, "Recieved I-Am-Router-To-Network message\n");
|
||||
int net_count = apdu_len / 2;
|
||||
int i;
|
||||
for (i = 0; i < net_count; i++) {
|
||||
decode_unsigned16(&data->pdu[apdu_offset + 2 * i], &net); /* decode received NET values */
|
||||
add_dnet(&srcport->route_info, net, data->src); /* and update routing table */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK:
|
||||
{
|
||||
/* first octet of the message contains rejection reason */
|
||||
/* next two octets contain NET (can be decoded for additional info on error) */
|
||||
error_code = data->pdu[apdu_offset];
|
||||
switch (error_code) {
|
||||
case 0:
|
||||
PRINT(ERROR, "Error!\n");
|
||||
break;
|
||||
case 1:
|
||||
PRINT(ERROR, "Error: Network unreachable\n");
|
||||
break;
|
||||
case 2:
|
||||
PRINT(ERROR, "Error: Network is busy\n");
|
||||
break;
|
||||
case 3:
|
||||
PRINT(ERROR, "Error: Unknown network message type\n");
|
||||
break;
|
||||
case 4:
|
||||
PRINT(ERROR, "Error: Message too long\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NETWORK_MESSAGE_INIT_RT_TABLE:
|
||||
PRINT(INFO, "Recieved Initialize-Routing-Table message\n");
|
||||
if (data->pdu[apdu_offset] > 0) {
|
||||
int net_count = data->pdu[apdu_offset];
|
||||
while (net_count--) {
|
||||
int i = 1;
|
||||
decode_unsigned16(&data->pdu[apdu_offset + i], &net); /* decode received NET values */
|
||||
add_dnet(&srcport->route_info, net, data->src); /* and update routing table */
|
||||
if (data->pdu[apdu_offset + i + 3] > 0) /* find next NET value */
|
||||
i = data->pdu[apdu_offset + i + 3] + 4;
|
||||
else
|
||||
i = i + 4;
|
||||
}
|
||||
buff_len =
|
||||
create_network_message(NETWORK_MESSAGE_INIT_RT_TABLE_ACK,
|
||||
data, buff, NULL);
|
||||
} else
|
||||
buff_len =
|
||||
create_network_message(NETWORK_MESSAGE_INIT_RT_TABLE_ACK,
|
||||
data, buff, &buff);
|
||||
break;
|
||||
|
||||
case NETWORK_MESSAGE_INIT_RT_TABLE_ACK:
|
||||
PRINT(INFO, "Recieved Initialize-Routing-Table-Ack message\n");
|
||||
if (data->pdu[apdu_offset] > 0) {
|
||||
int net_count = data->pdu[apdu_offset];
|
||||
while (net_count--) {
|
||||
int i = 1;
|
||||
decode_unsigned16(&data->pdu[apdu_offset+i], &net); /* decode received NET values */
|
||||
add_dnet(&srcport->route_info, net, data->src); /* and update routing table */
|
||||
if (data->pdu[apdu_offset+i+3] > 0) /* find next NET value */
|
||||
i = data->pdu[apdu_offset+i+3] + 4;
|
||||
else
|
||||
i = i + 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NETWORK_MESSAGE_INIT_RT_TABLE_ACK:
|
||||
PRINT(INFO, "Recieved Initialize-Routing-Table-Ack message\n");
|
||||
if (data->pdu[apdu_offset] > 0) {
|
||||
int net_count = data->pdu[apdu_offset];
|
||||
while (net_count--) {
|
||||
int i = 1;
|
||||
decode_unsigned16(&data->pdu[apdu_offset + i], &net); /* decode received NET values */
|
||||
add_dnet(&srcport->route_info, net, data->src); /* and update routing table */
|
||||
if (data->pdu[apdu_offset + i + 3] > 0) /* find next NET value */
|
||||
i = data->pdu[apdu_offset + i + 3] + 4;
|
||||
else
|
||||
i = i + 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NETWORK_MESSAGE_INVALID:
|
||||
case NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK:
|
||||
/* hell if I know what to do with these messages */
|
||||
break;
|
||||
case NETWORK_MESSAGE_INVALID:
|
||||
case NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK:
|
||||
/* hell if I know what to do with these messages */
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINT(ERROR, "Error: Message unsupported\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PRINT(ERROR, "Error: Message unsupported\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return buff_len;
|
||||
return buff_len;
|
||||
}
|
||||
|
||||
uint16_t create_network_message(
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA *data,
|
||||
uint8_t **buff,
|
||||
void *val) {
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff,
|
||||
void *val)
|
||||
{
|
||||
|
||||
int16_t buff_len;
|
||||
bool data_expecting_reply = false;
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
int16_t buff_len;
|
||||
bool data_expecting_reply = false;
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
|
||||
if (network_message_type == NETWORK_MESSAGE_INIT_RT_TABLE)
|
||||
data_expecting_reply = true;
|
||||
init_npdu(&npdu_data, network_message_type, data_expecting_reply);
|
||||
if (network_message_type == NETWORK_MESSAGE_INIT_RT_TABLE)
|
||||
data_expecting_reply = true;
|
||||
init_npdu(&npdu_data, network_message_type, data_expecting_reply);
|
||||
|
||||
*buff = (uint8_t*)malloc(128); /* resolve different length */
|
||||
*buff = (uint8_t *) malloc(128); /* resolve different length */
|
||||
|
||||
/* manual destination setup for Init-RT-Table-Ack message */
|
||||
data->dest.net = BACNET_BROADCAST_NETWORK;
|
||||
buff_len = npdu_encode_pdu(*buff, &data->dest, NULL, &npdu_data);
|
||||
/* manual destination setup for Init-RT-Table-Ack message */
|
||||
data->dest.net = BACNET_BROADCAST_NETWORK;
|
||||
buff_len = npdu_encode_pdu(*buff, &data->dest, NULL, &npdu_data);
|
||||
|
||||
switch (network_message_type) {
|
||||
switch (network_message_type) {
|
||||
|
||||
case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
|
||||
if (val != NULL) {
|
||||
uint8_t * valptr = (uint8_t*)val;
|
||||
uint16_t val16 = (valptr[0]) + (valptr[1] << 8);
|
||||
buff_len += encode_unsigned16(*buff+buff_len, val16);
|
||||
}
|
||||
break;
|
||||
case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
|
||||
if (val != NULL) {
|
||||
uint8_t *valptr = (uint8_t *) val;
|
||||
uint16_t val16 = (valptr[0]) + (valptr[1] << 8);
|
||||
buff_len += encode_unsigned16(*buff + buff_len, val16);
|
||||
}
|
||||
break;
|
||||
|
||||
case NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK:
|
||||
if (val != NULL) {
|
||||
uint8_t * valptr = (uint8_t*)val;
|
||||
uint16_t val16 = (valptr[0]) + (valptr[1] << 8);
|
||||
buff_len += encode_unsigned16(*buff+buff_len, val16);
|
||||
}
|
||||
else {
|
||||
ROUTER_PORT *port = head;
|
||||
DNET *dnet;
|
||||
while (port != NULL) {
|
||||
if (port->route_info.net != data->src.net) {
|
||||
buff_len += encode_unsigned16(*buff+buff_len, port->route_info.net);
|
||||
dnet = port->route_info.dnets;
|
||||
while (dnet != NULL) {
|
||||
buff_len += encode_unsigned16(*buff+buff_len, dnet->net);
|
||||
dnet = dnet->next;
|
||||
}
|
||||
port = port->next;
|
||||
} else {
|
||||
dnet = port->route_info.dnets;
|
||||
while (dnet != NULL) {
|
||||
buff_len += encode_unsigned16(*buff+buff_len, dnet->net);
|
||||
dnet = dnet->next;
|
||||
}
|
||||
port = port->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK:
|
||||
if (val != NULL) {
|
||||
uint8_t *valptr = (uint8_t *) val;
|
||||
uint16_t val16 = (valptr[0]) + (valptr[1] << 8);
|
||||
buff_len += encode_unsigned16(*buff + buff_len, val16);
|
||||
} else {
|
||||
ROUTER_PORT *port = head;
|
||||
DNET *dnet;
|
||||
while (port != NULL) {
|
||||
if (port->route_info.net != data->src.net) {
|
||||
buff_len +=
|
||||
encode_unsigned16(*buff + buff_len,
|
||||
port->route_info.net);
|
||||
dnet = port->route_info.dnets;
|
||||
while (dnet != NULL) {
|
||||
buff_len +=
|
||||
encode_unsigned16(*buff + buff_len, dnet->net);
|
||||
dnet = dnet->next;
|
||||
}
|
||||
port = port->next;
|
||||
} else {
|
||||
dnet = port->route_info.dnets;
|
||||
while (dnet != NULL) {
|
||||
buff_len +=
|
||||
encode_unsigned16(*buff + buff_len, dnet->net);
|
||||
dnet = dnet->next;
|
||||
}
|
||||
port = port->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK:
|
||||
{
|
||||
uint8_t * valptr = (uint8_t*)val;
|
||||
uint16_t val16 = (valptr[0]) + (valptr[1] << 8);
|
||||
buff_len += encode_unsigned16(*buff + buff_len, val16);
|
||||
break;
|
||||
}
|
||||
case NETWORK_MESSAGE_INIT_RT_TABLE:
|
||||
case NETWORK_MESSAGE_INIT_RT_TABLE_ACK:
|
||||
if ((uint8_t*)val) {
|
||||
(*buff)[buff_len++] = (uint8_t) port_count;
|
||||
case NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK:
|
||||
{
|
||||
uint8_t *valptr = (uint8_t *) val;
|
||||
uint16_t val16 = (valptr[0]) + (valptr[1] << 8);
|
||||
buff_len += encode_unsigned16(*buff + buff_len, val16);
|
||||
break;
|
||||
}
|
||||
case NETWORK_MESSAGE_INIT_RT_TABLE:
|
||||
case NETWORK_MESSAGE_INIT_RT_TABLE_ACK:
|
||||
if ((uint8_t *) val) {
|
||||
(*buff)[buff_len++] = (uint8_t) port_count;
|
||||
|
||||
if (port_count > 0) {
|
||||
ROUTER_PORT *port = head;
|
||||
uint8_t portID = 1;
|
||||
if (port_count > 0) {
|
||||
ROUTER_PORT *port = head;
|
||||
uint8_t portID = 1;
|
||||
|
||||
while (port != NULL) {
|
||||
buff_len += encode_unsigned16(*buff+buff_len, port->route_info.net);
|
||||
(*buff)[buff_len++] = portID++;
|
||||
(*buff)[buff_len++] = 0;
|
||||
port = port->next;
|
||||
}
|
||||
}
|
||||
} else
|
||||
(*buff)[buff_len++] = (uint8_t) 0;
|
||||
break;
|
||||
while (port != NULL) {
|
||||
buff_len +=
|
||||
encode_unsigned16(*buff + buff_len,
|
||||
port->route_info.net);
|
||||
(*buff)[buff_len++] = portID++;
|
||||
(*buff)[buff_len++] = 0;
|
||||
port = port->next;
|
||||
}
|
||||
}
|
||||
} else
|
||||
(*buff)[buff_len++] = (uint8_t) 0;
|
||||
break;
|
||||
|
||||
case NETWORK_MESSAGE_INVALID:
|
||||
case NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK:
|
||||
/* hell if I know what to do with these messages */
|
||||
break;
|
||||
}
|
||||
case NETWORK_MESSAGE_INVALID:
|
||||
case NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK:
|
||||
case NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK:
|
||||
/* hell if I know what to do with these messages */
|
||||
break;
|
||||
}
|
||||
|
||||
return buff_len;
|
||||
return buff_len;
|
||||
}
|
||||
|
||||
void send_network_message(
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA *data,
|
||||
uint8_t **buff,
|
||||
void *val) {
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff,
|
||||
void *val)
|
||||
{
|
||||
|
||||
BACMSG msg;
|
||||
ROUTER_PORT *port = head;
|
||||
int16_t buff_len;
|
||||
BACMSG msg;
|
||||
ROUTER_PORT *port = head;
|
||||
int16_t buff_len;
|
||||
|
||||
if (!data) {
|
||||
data = (MSG_DATA*)malloc(sizeof(MSG_DATA));
|
||||
data->dest.net = BACNET_BROADCAST_NETWORK;
|
||||
}
|
||||
if (!data) {
|
||||
data = (MSG_DATA *) malloc(sizeof(MSG_DATA));
|
||||
data->dest.net = BACNET_BROADCAST_NETWORK;
|
||||
}
|
||||
|
||||
buff_len = create_network_message(network_message_type, data, buff, val);
|
||||
buff_len = create_network_message(network_message_type, data, buff, val);
|
||||
|
||||
/* form network message */
|
||||
data->pdu = *buff;
|
||||
data->pdu_len = buff_len;
|
||||
msg.origin = head->main_id;
|
||||
msg.type = DATA;
|
||||
msg.data = data;
|
||||
/* form network message */
|
||||
data->pdu = *buff;
|
||||
data->pdu_len = buff_len;
|
||||
msg.origin = head->main_id;
|
||||
msg.type = DATA;
|
||||
msg.data = data;
|
||||
|
||||
data->ref_count = port_count;
|
||||
while (port != NULL) {
|
||||
if (port->state == FINISHED) {
|
||||
port = port->next;
|
||||
continue;
|
||||
}
|
||||
send_to_msgbox(port->port_id, &msg);
|
||||
port = port->next;
|
||||
}
|
||||
data->ref_count = port_count;
|
||||
while (port != NULL) {
|
||||
if (port->state == FINISHED) {
|
||||
port = port->next;
|
||||
continue;
|
||||
}
|
||||
send_to_msgbox(port->port_id, &msg);
|
||||
port = port->next;
|
||||
}
|
||||
}
|
||||
|
||||
void init_npdu(
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
bool data_expecting_reply) {
|
||||
BACNET_NPDU_DATA * npdu_data,
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
bool data_expecting_reply)
|
||||
{
|
||||
|
||||
if (npdu_data) {
|
||||
npdu_data->data_expecting_reply = data_expecting_reply;
|
||||
npdu_data->protocol_version = BACNET_PROTOCOL_VERSION;
|
||||
npdu_data->network_layer_message = true;
|
||||
npdu_data->network_message_type = network_message_type;
|
||||
npdu_data->vendor_id = 0;
|
||||
npdu_data->priority = MESSAGE_PRIORITY_NORMAL;
|
||||
npdu_data->hop_count = HOP_COUNT_DEFAULT;
|
||||
}
|
||||
if (npdu_data) {
|
||||
npdu_data->data_expecting_reply = data_expecting_reply;
|
||||
npdu_data->protocol_version = BACNET_PROTOCOL_VERSION;
|
||||
npdu_data->network_layer_message = true;
|
||||
npdu_data->network_message_type = network_message_type;
|
||||
npdu_data->vendor_id = 0;
|
||||
npdu_data->priority = MESSAGE_PRIORITY_NORMAL;
|
||||
npdu_data->hop_count = HOP_COUNT_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,25 +29,25 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
#include "portthread.h"
|
||||
|
||||
uint16_t process_network_message(
|
||||
BACMSG *msg,
|
||||
MSG_DATA *data,
|
||||
uint8_t **buff);
|
||||
BACMSG * msg,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff);
|
||||
|
||||
uint16_t create_network_message(
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA *data,
|
||||
uint8_t **buff,
|
||||
void *val);
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff,
|
||||
void *val);
|
||||
|
||||
void send_network_message(
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA *data,
|
||||
uint8_t **buff,
|
||||
void *val);
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff,
|
||||
void *val);
|
||||
|
||||
void init_npdu(
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
bool data_expecting_reply);
|
||||
BACNET_NPDU_DATA * npdu_data,
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
bool data_expecting_reply);
|
||||
|
||||
#endif /* end of NETWORK_LAYER_H */
|
||||
|
||||
@@ -19,98 +19,102 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
#include <string.h>
|
||||
#include "portthread.h"
|
||||
|
||||
ROUTER_PORT* find_snet(
|
||||
MSGBOX_ID id) {
|
||||
ROUTER_PORT *find_snet(
|
||||
MSGBOX_ID id)
|
||||
{
|
||||
|
||||
ROUTER_PORT *port = head;
|
||||
ROUTER_PORT *port = head;
|
||||
|
||||
while (port != NULL) {
|
||||
if (port->port_id == id)
|
||||
return port;
|
||||
port = port->next;
|
||||
}
|
||||
while (port != NULL) {
|
||||
if (port->port_id == id)
|
||||
return port;
|
||||
port = port->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ROUTER_PORT* find_dnet(
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS *addr) {
|
||||
ROUTER_PORT *find_dnet(
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS * addr)
|
||||
{
|
||||
|
||||
ROUTER_PORT *port = head;
|
||||
DNET *dnet;
|
||||
ROUTER_PORT *port = head;
|
||||
DNET *dnet;
|
||||
|
||||
/* for broadcast messages no search is needed */
|
||||
if (net == BACNET_BROADCAST_NETWORK)
|
||||
return port;
|
||||
/* for broadcast messages no search is needed */
|
||||
if (net == BACNET_BROADCAST_NETWORK)
|
||||
return port;
|
||||
|
||||
while(port != NULL) {
|
||||
while (port != NULL) {
|
||||
|
||||
/* check if DNET is directly connected to the router */
|
||||
if (net == port->route_info.net)
|
||||
return port;
|
||||
/* check if DNET is directly connected to the router */
|
||||
if (net == port->route_info.net)
|
||||
return port;
|
||||
|
||||
/* else search router ports DNET list */
|
||||
else if (port->route_info.dnets) {
|
||||
dnet = port->route_info.dnets;
|
||||
while (dnet != NULL) {
|
||||
if (net == dnet->net) {
|
||||
if (addr) {
|
||||
memmove(&addr->len, &dnet->mac_len, 1);
|
||||
memmove(&addr->adr[0], &dnet->mac[0], MAX_MAC_LEN);
|
||||
}
|
||||
return port;
|
||||
}
|
||||
dnet = dnet->next;
|
||||
}
|
||||
}
|
||||
port = port->next;
|
||||
}
|
||||
/* else search router ports DNET list */
|
||||
else if (port->route_info.dnets) {
|
||||
dnet = port->route_info.dnets;
|
||||
while (dnet != NULL) {
|
||||
if (net == dnet->net) {
|
||||
if (addr) {
|
||||
memmove(&addr->len, &dnet->mac_len, 1);
|
||||
memmove(&addr->adr[0], &dnet->mac[0], MAX_MAC_LEN);
|
||||
}
|
||||
return port;
|
||||
}
|
||||
dnet = dnet->next;
|
||||
}
|
||||
}
|
||||
port = port->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void add_dnet(
|
||||
RT_ENTRY *route_info,
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS addr) {
|
||||
RT_ENTRY * route_info,
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS addr)
|
||||
{
|
||||
|
||||
DNET *dnet = route_info->dnets;
|
||||
DNET *tmp;
|
||||
DNET *dnet = route_info->dnets;
|
||||
DNET *tmp;
|
||||
|
||||
if (dnet == NULL) {
|
||||
route_info->dnets = (DNET*)malloc(sizeof(DNET));
|
||||
memmove(&route_info->dnets->mac_len, &addr.len, 1);
|
||||
memmove(&route_info->dnets->mac[0], &addr.adr[0], MAX_MAC_LEN);
|
||||
route_info->dnets->net = net;
|
||||
route_info->dnets->state = true;
|
||||
route_info->dnets->next = NULL;
|
||||
} else {
|
||||
if (dnet == NULL) {
|
||||
route_info->dnets = (DNET *) malloc(sizeof(DNET));
|
||||
memmove(&route_info->dnets->mac_len, &addr.len, 1);
|
||||
memmove(&route_info->dnets->mac[0], &addr.adr[0], MAX_MAC_LEN);
|
||||
route_info->dnets->net = net;
|
||||
route_info->dnets->state = true;
|
||||
route_info->dnets->next = NULL;
|
||||
} else {
|
||||
|
||||
while (dnet != NULL) {
|
||||
if (dnet->net == net) /* make sure NETs are not repeated */
|
||||
return;
|
||||
tmp = dnet;
|
||||
dnet = dnet->next;
|
||||
}
|
||||
while (dnet != NULL) {
|
||||
if (dnet->net == net) /* make sure NETs are not repeated */
|
||||
return;
|
||||
tmp = dnet;
|
||||
dnet = dnet->next;
|
||||
}
|
||||
|
||||
dnet = (DNET*)malloc(sizeof(DNET));
|
||||
memmove(&dnet->mac_len, &addr.len, 1);
|
||||
memmove(&dnet->mac[0], &addr.adr[0], MAX_MAC_LEN);
|
||||
dnet->net = net;
|
||||
dnet->state = true;
|
||||
dnet->next = NULL;
|
||||
tmp->next = dnet;
|
||||
}
|
||||
dnet = (DNET *) malloc(sizeof(DNET));
|
||||
memmove(&dnet->mac_len, &addr.len, 1);
|
||||
memmove(&dnet->mac[0], &addr.adr[0], MAX_MAC_LEN);
|
||||
dnet->net = net;
|
||||
dnet->state = true;
|
||||
dnet->next = NULL;
|
||||
tmp->next = dnet;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup_dnets(
|
||||
DNET *dnets) {
|
||||
DNET * dnets)
|
||||
{
|
||||
|
||||
DNET *dnet = dnets;
|
||||
while(dnet != NULL) {
|
||||
dnet = dnet->next;
|
||||
free(dnets);
|
||||
dnets = dnet;
|
||||
}
|
||||
DNET *dnet = dnets;
|
||||
while (dnet != NULL) {
|
||||
dnet = dnet->next;
|
||||
free(dnets);
|
||||
dnets = dnet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,90 +36,91 @@ Copyright (C) 2012 Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
BIP = 1,
|
||||
MSTP = 2
|
||||
BIP = 1,
|
||||
MSTP = 2
|
||||
} DL_TYPE;
|
||||
|
||||
typedef enum {
|
||||
INIT,
|
||||
INIT_FAILED,
|
||||
RUNNING,
|
||||
FINISHED
|
||||
INIT,
|
||||
INIT_FAILED,
|
||||
RUNNING,
|
||||
FINISHED
|
||||
} PORT_STATE;
|
||||
|
||||
/* router port thread function */
|
||||
typedef void* (*PORT_FUNC)(
|
||||
void*);
|
||||
typedef void *(
|
||||
*PORT_FUNC) (
|
||||
void *);
|
||||
|
||||
typedef enum {
|
||||
PARITY_NONE,
|
||||
PARITY_EVEN,
|
||||
PARITY_ODD
|
||||
}PARITY;
|
||||
PARITY_NONE,
|
||||
PARITY_EVEN,
|
||||
PARITY_ODD
|
||||
} PARITY;
|
||||
|
||||
/* port specific parameters */
|
||||
typedef union _port_params {
|
||||
struct {
|
||||
uint16_t port;
|
||||
} bip_params;
|
||||
struct {
|
||||
uint32_t baudrate;
|
||||
PARITY parity;
|
||||
uint8_t databits;
|
||||
uint8_t stopbits;
|
||||
uint8_t max_master;
|
||||
uint8_t max_frames;
|
||||
} mstp_params;
|
||||
struct {
|
||||
uint16_t port;
|
||||
} bip_params;
|
||||
struct {
|
||||
uint32_t baudrate;
|
||||
PARITY parity;
|
||||
uint8_t databits;
|
||||
uint8_t stopbits;
|
||||
uint8_t max_master;
|
||||
uint8_t max_frames;
|
||||
} mstp_params;
|
||||
} PORT_PARAMS;
|
||||
|
||||
/* list node for reacheble networks */
|
||||
typedef struct _dnet {
|
||||
uint8_t mac[MAX_MAC_LEN];
|
||||
uint8_t mac_len;
|
||||
uint16_t net;
|
||||
bool state; /* enabled or disabled */
|
||||
struct _dnet *next;
|
||||
uint8_t mac[MAX_MAC_LEN];
|
||||
uint8_t mac_len;
|
||||
uint16_t net;
|
||||
bool state; /* enabled or disabled */
|
||||
struct _dnet *next;
|
||||
} DNET;
|
||||
|
||||
/* information for routing table */
|
||||
typedef struct _routing_table_entry {
|
||||
uint8_t mac[MAX_MAC_LEN];
|
||||
uint8_t mac_len;
|
||||
uint16_t net;
|
||||
DNET *dnets;
|
||||
uint8_t mac[MAX_MAC_LEN];
|
||||
uint8_t mac_len;
|
||||
uint16_t net;
|
||||
DNET *dnets;
|
||||
} RT_ENTRY;
|
||||
|
||||
typedef struct _port {
|
||||
DL_TYPE type;
|
||||
PORT_STATE state;
|
||||
MSGBOX_ID main_id; /* same for every router port */
|
||||
MSGBOX_ID port_id; /* different for every router port */
|
||||
char *iface;
|
||||
PORT_FUNC func;
|
||||
RT_ENTRY route_info;
|
||||
PORT_PARAMS params;
|
||||
struct _port *next; /* pointer to next list node */
|
||||
DL_TYPE type;
|
||||
PORT_STATE state;
|
||||
MSGBOX_ID main_id; /* same for every router port */
|
||||
MSGBOX_ID port_id; /* different for every router port */
|
||||
char *iface;
|
||||
PORT_FUNC func;
|
||||
RT_ENTRY route_info;
|
||||
PORT_PARAMS params;
|
||||
struct _port *next; /* pointer to next list node */
|
||||
} ROUTER_PORT;
|
||||
|
||||
extern ROUTER_PORT *head;
|
||||
extern int port_count;
|
||||
|
||||
/* get recieving router port */
|
||||
ROUTER_PORT* find_snet(
|
||||
MSGBOX_ID id);
|
||||
ROUTER_PORT *find_snet(
|
||||
MSGBOX_ID id);
|
||||
|
||||
/* get sending router port */
|
||||
ROUTER_PORT* find_dnet(
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS *addr);
|
||||
ROUTER_PORT *find_dnet(
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS * addr);
|
||||
|
||||
/* add reacheble network for specified router port */
|
||||
void add_dnet(
|
||||
RT_ENTRY *route_info,
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS addr);
|
||||
RT_ENTRY * route_info,
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS addr);
|
||||
|
||||
void cleanup_dnets(
|
||||
DNET *dnets);
|
||||
DNET * dnets);
|
||||
|
||||
#endif /* end of PORTTHREAD_H */
|
||||
|
||||
@@ -151,7 +151,7 @@ int main(
|
||||
0
|
||||
}; /* address where message came from */
|
||||
uint16_t pdu_len = 0;
|
||||
unsigned timeout = 1; /* milliseconds */
|
||||
unsigned timeout = 1; /* milliseconds */
|
||||
time_t last_seconds = 0;
|
||||
time_t current_seconds = 0;
|
||||
uint32_t elapsed_seconds = 0;
|
||||
@@ -188,7 +188,7 @@ int main(
|
||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||
}
|
||||
/* at least one second has passed */
|
||||
elapsed_seconds = (uint32_t)(current_seconds - last_seconds);
|
||||
elapsed_seconds = (uint32_t) (current_seconds - last_seconds);
|
||||
if (elapsed_seconds) {
|
||||
last_seconds = current_seconds;
|
||||
dcc_timer_seconds(elapsed_seconds);
|
||||
|
||||
@@ -152,7 +152,7 @@ int main(
|
||||
0
|
||||
}; /* address where message came from */
|
||||
uint16_t pdu_len = 0;
|
||||
unsigned timeout = 10; /* milliseconds */
|
||||
unsigned timeout = 10; /* milliseconds */
|
||||
unsigned max_apdu = 0;
|
||||
time_t elapsed_seconds = 0;
|
||||
time_t last_seconds = 0;
|
||||
@@ -213,7 +213,7 @@ int main(
|
||||
if (strcmp(argv[1], "broadcast") == 0) {
|
||||
Target_Broadcast = true;
|
||||
Target_DNET = BACNET_BROADCAST_NETWORK;
|
||||
} else if (strncmp(argv[1],"dnet=",5) == 0) {
|
||||
} else if (strncmp(argv[1], "dnet=", 5) == 0) {
|
||||
Target_Broadcast = true;
|
||||
Target_DNET = strtol(&argv[1][5], NULL, 0);
|
||||
} else {
|
||||
|
||||
@@ -113,8 +113,7 @@ static void print_usage(
|
||||
char *filename)
|
||||
{
|
||||
printf("Usage: %s [device-instance-min device-instance-min] "
|
||||
"<object-type object-instance | object-name> [--help]\r\n",
|
||||
filename);
|
||||
"<object-type object-instance | object-name> [--help]\r\n", filename);
|
||||
}
|
||||
|
||||
static void print_help(
|
||||
@@ -123,12 +122,12 @@ static void print_help(
|
||||
print_usage(filename);
|
||||
printf("Send BACnet WhoHas request to devices, \r\n"
|
||||
"and wait %u milliseconds (BACNET_APDU_TIMEOUT) for responses.\r\n"
|
||||
"The device-instance-min or max can be 0 to %d.\r\n"
|
||||
"\r\n" "Use either:\r\n" "The object-type can be 0 to %d.\r\n"
|
||||
"The device-instance-min or max can be 0 to %d.\r\n" "\r\n"
|
||||
"Use either:\r\n" "The object-type can be 0 to %d.\r\n"
|
||||
"The object-instance can be 0 to %d.\r\n" "or:\r\n"
|
||||
"The object-name can be any string of characters.\r\n",
|
||||
BACNET_MAX_INSTANCE, (unsigned)apdu_timeout(),
|
||||
BACNET_MAX_OBJECT, BACNET_MAX_INSTANCE);
|
||||
BACNET_MAX_INSTANCE, (unsigned) apdu_timeout(), BACNET_MAX_OBJECT,
|
||||
BACNET_MAX_INSTANCE);
|
||||
}
|
||||
|
||||
int main(
|
||||
@@ -144,32 +143,29 @@ int main(
|
||||
time_t last_seconds = 0;
|
||||
time_t current_seconds = 0;
|
||||
time_t timeout_seconds = 0;
|
||||
int argi = 0;
|
||||
int argi = 0;
|
||||
bool by_name = false;
|
||||
|
||||
if (argc < 2) {
|
||||
print_usage(filename_remove_path(argv[0]));
|
||||
return 0;
|
||||
}
|
||||
/* print help if requested */
|
||||
for (argi = 1; argi < argc; argi++)
|
||||
{
|
||||
if (strcmp(argv[argi], "--help") == 0) {
|
||||
print_help(filename_remove_path(argv[0]));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* print help if requested */
|
||||
for (argi = 1; argi < argc; argi++) {
|
||||
if (strcmp(argv[argi], "--help") == 0) {
|
||||
print_help(filename_remove_path(argv[0]));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* decode the command line parameters */
|
||||
if (argc < 3) {
|
||||
/* bacwh "name" */
|
||||
Target_Object_Instance_Min =
|
||||
Target_Object_Instance_Max = -1;
|
||||
Target_Object_Instance_Min = Target_Object_Instance_Max = -1;
|
||||
Target_Object_Name = argv[1];
|
||||
by_name = true;
|
||||
} else if (argc < 4) {
|
||||
/* bacwh 8 1234 */
|
||||
Target_Object_Instance_Min =
|
||||
Target_Object_Instance_Max = -1;
|
||||
Target_Object_Instance_Min = Target_Object_Instance_Max = -1;
|
||||
Target_Object_Type = strtol(argv[1], NULL, 0);
|
||||
Target_Object_Instance = strtol(argv[2], NULL, 0);
|
||||
} else if (argc < 5) {
|
||||
@@ -212,14 +208,12 @@ int main(
|
||||
}
|
||||
}
|
||||
if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) {
|
||||
fprintf(stderr,
|
||||
"object-instance-min=%u - it must be less than %u\r\n",
|
||||
fprintf(stderr, "object-instance-min=%u - it must be less than %u\r\n",
|
||||
Target_Object_Instance_Min, BACNET_MAX_INSTANCE + 1);
|
||||
return 1;
|
||||
}
|
||||
if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) {
|
||||
fprintf(stderr,
|
||||
"object-instance-max=%u - it must be less than %u\r\n",
|
||||
fprintf(stderr, "object-instance-max=%u - it must be less than %u\r\n",
|
||||
Target_Object_Instance_Max, BACNET_MAX_INSTANCE + 1);
|
||||
return 1;
|
||||
}
|
||||
@@ -233,15 +227,11 @@ int main(
|
||||
timeout_seconds = apdu_timeout() / 1000;
|
||||
/* send the request */
|
||||
if (by_name) {
|
||||
Send_WhoHas_Name(
|
||||
Target_Object_Instance_Min,
|
||||
Target_Object_Instance_Max,
|
||||
Target_Object_Name);
|
||||
Send_WhoHas_Name(Target_Object_Instance_Min,
|
||||
Target_Object_Instance_Max, Target_Object_Name);
|
||||
} else {
|
||||
Send_WhoHas_Object(
|
||||
Target_Object_Instance_Min,
|
||||
Target_Object_Instance_Max,
|
||||
Target_Object_Type,
|
||||
Send_WhoHas_Object(Target_Object_Instance_Min,
|
||||
Target_Object_Instance_Max, Target_Object_Type,
|
||||
Target_Object_Instance);
|
||||
}
|
||||
/* loop forever */
|
||||
|
||||
+190
-218
@@ -63,7 +63,7 @@ static bool Error_Detected = false;
|
||||
#define BAC_ADDRESS_MULT 1
|
||||
|
||||
struct address_entry {
|
||||
struct address_entry * next;
|
||||
struct address_entry *next;
|
||||
uint8_t Flags;
|
||||
uint32_t device_id;
|
||||
unsigned max_apdu;
|
||||
@@ -71,38 +71,41 @@ struct address_entry {
|
||||
};
|
||||
|
||||
static struct address_table {
|
||||
struct address_entry * first;
|
||||
struct address_entry * last;
|
||||
} Address_Table = {0};
|
||||
struct address_entry *first;
|
||||
struct address_entry *last;
|
||||
} Address_Table = {
|
||||
0};
|
||||
|
||||
|
||||
struct address_entry * alloc_address_entry(void)
|
||||
struct address_entry *alloc_address_entry(
|
||||
void)
|
||||
{
|
||||
struct address_entry * rval;
|
||||
rval = (struct address_entry *)calloc(1, sizeof(struct address_entry));
|
||||
if(Address_Table.first == 0)
|
||||
{
|
||||
Address_Table.first = Address_Table.last = rval;
|
||||
}
|
||||
else
|
||||
{
|
||||
Address_Table.last->next = rval;
|
||||
Address_Table.last = rval;
|
||||
}
|
||||
return rval;
|
||||
struct address_entry *rval;
|
||||
rval = (struct address_entry *) calloc(1, sizeof(struct address_entry));
|
||||
if (Address_Table.first == 0) {
|
||||
Address_Table.first = Address_Table.last = rval;
|
||||
} else {
|
||||
Address_Table.last->next = rval;
|
||||
Address_Table.last = rval;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool bacnet_address_matches(BACNET_ADDRESS * a1, BACNET_ADDRESS * a2)
|
||||
bool bacnet_address_matches(
|
||||
BACNET_ADDRESS * a1,
|
||||
BACNET_ADDRESS * a2)
|
||||
{
|
||||
int i = 0;
|
||||
if(a1->net != a2->net) return false;
|
||||
if(a1->len != a2->len) return false;
|
||||
for(;i<a1->len;i++)
|
||||
if(a1->adr[i]!=a2->adr[i])
|
||||
return false;
|
||||
return true;
|
||||
int i = 0;
|
||||
if (a1->net != a2->net)
|
||||
return false;
|
||||
if (a1->len != a2->len)
|
||||
return false;
|
||||
for (; i < a1->len; i++)
|
||||
if (a1->adr[i] != a2->adr[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void address_table_add(
|
||||
@@ -111,21 +114,20 @@ void address_table_add(
|
||||
BACNET_ADDRESS * src)
|
||||
{
|
||||
struct address_entry *pMatch;
|
||||
uint8_t flags = 0;
|
||||
uint8_t flags = 0;
|
||||
|
||||
pMatch = Address_Table.first;
|
||||
pMatch = Address_Table.first;
|
||||
while (pMatch) {
|
||||
if (pMatch->device_id == device_id)
|
||||
{
|
||||
if (pMatch->device_id == device_id) {
|
||||
if (bacnet_address_matches(&pMatch->address, src))
|
||||
return;
|
||||
flags |= BAC_ADDRESS_MULT;
|
||||
pMatch->Flags |= BAC_ADDRESS_MULT;
|
||||
return;
|
||||
flags |= BAC_ADDRESS_MULT;
|
||||
pMatch->Flags |= BAC_ADDRESS_MULT;
|
||||
}
|
||||
pMatch = pMatch->next;
|
||||
}
|
||||
|
||||
pMatch = alloc_address_entry();
|
||||
pMatch = alloc_address_entry();
|
||||
|
||||
pMatch->Flags = flags;
|
||||
pMatch->device_id = device_id;
|
||||
@@ -219,124 +221,107 @@ static void init_service_handlers(
|
||||
apdu_set_reject_handler(MyRejectHandler);
|
||||
}
|
||||
|
||||
void print_macaddr(uint8_t * addr, int len)
|
||||
void print_macaddr(
|
||||
uint8_t * addr,
|
||||
int len)
|
||||
{
|
||||
int j = 0;
|
||||
int j = 0;
|
||||
|
||||
while(j < len)
|
||||
{
|
||||
if (j != 0) {
|
||||
printf(":");
|
||||
}
|
||||
printf("%02X", addr[j]);
|
||||
j++;
|
||||
}
|
||||
while(j < MAX_MAC_LEN)
|
||||
{
|
||||
printf(" ");
|
||||
j++;
|
||||
}
|
||||
while (j < len) {
|
||||
if (j != 0) {
|
||||
printf(":");
|
||||
}
|
||||
printf("%02X", addr[j]);
|
||||
j++;
|
||||
}
|
||||
while (j < MAX_MAC_LEN) {
|
||||
printf(" ");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
static void print_address_cache(
|
||||
void)
|
||||
void)
|
||||
{
|
||||
BACNET_ADDRESS address;
|
||||
unsigned total_addresses = 0;
|
||||
unsigned dup_addresses = 0;
|
||||
struct address_entry *addr;
|
||||
uint8_t local_sadr = 0;
|
||||
BACNET_ADDRESS address;
|
||||
unsigned total_addresses = 0;
|
||||
unsigned dup_addresses = 0;
|
||||
struct address_entry *addr;
|
||||
uint8_t local_sadr = 0;
|
||||
|
||||
/* NOTE: this string format is parsed by src/address.c,
|
||||
so these must be compatible. */
|
||||
/* NOTE: this string format is parsed by src/address.c,
|
||||
so these must be compatible. */
|
||||
|
||||
printf(";%-7s %-20s %-5s %-20s %-4s\n",
|
||||
"Device", "MAC (hex)", "SNET", "SADR (hex)", "APDU");
|
||||
printf(";-------- -------------------- ----- -------------------- ----\n");
|
||||
printf(";%-7s %-20s %-5s %-20s %-4s\n", "Device", "MAC (hex)", "SNET",
|
||||
"SADR (hex)", "APDU");
|
||||
printf(";-------- -------------------- ----- -------------------- ----\n");
|
||||
|
||||
|
||||
addr = Address_Table.first;
|
||||
while (addr)
|
||||
{
|
||||
bacnet_address_copy(&address, &addr->address);
|
||||
total_addresses++;
|
||||
if(addr->Flags & BAC_ADDRESS_MULT)
|
||||
{
|
||||
dup_addresses++;
|
||||
printf(";");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
printf(" %-7u ", addr->device_id);
|
||||
print_macaddr(address.mac, address.mac_len);
|
||||
printf(" %-5hu ", address.net);
|
||||
if (address.net) {
|
||||
print_macaddr(address.adr, address.len);
|
||||
} else {
|
||||
print_macaddr(&local_sadr, 1);
|
||||
}
|
||||
printf(" %-4hu ", addr->max_apdu);
|
||||
printf("\n");
|
||||
addr = Address_Table.first;
|
||||
while (addr) {
|
||||
bacnet_address_copy(&address, &addr->address);
|
||||
total_addresses++;
|
||||
if (addr->Flags & BAC_ADDRESS_MULT) {
|
||||
dup_addresses++;
|
||||
printf(";");
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
printf(" %-7u ", addr->device_id);
|
||||
print_macaddr(address.mac, address.mac_len);
|
||||
printf(" %-5hu ", address.net);
|
||||
if (address.net) {
|
||||
print_macaddr(address.adr, address.len);
|
||||
} else {
|
||||
print_macaddr(&local_sadr, 1);
|
||||
}
|
||||
printf(" %-4hu ", addr->max_apdu);
|
||||
printf("\n");
|
||||
|
||||
addr = addr->next;
|
||||
}
|
||||
printf(";\n; Total Devices: %u\n", total_addresses);
|
||||
if (dup_addresses) {
|
||||
printf("; * Duplicate Devices: %u\n", dup_addresses);
|
||||
}
|
||||
addr = addr->next;
|
||||
}
|
||||
printf(";\n; Total Devices: %u\n", total_addresses);
|
||||
if (dup_addresses) {
|
||||
printf("; * Duplicate Devices: %u\n", dup_addresses);
|
||||
}
|
||||
}
|
||||
|
||||
static int print_usage(char* exe_name){
|
||||
printf(
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
"%s [[network]:[address]] "
|
||||
"[device-instance-min [device-instance-max]] [--help]\n" ,
|
||||
exe_name);
|
||||
return 1;
|
||||
static int print_usage(
|
||||
char *exe_name)
|
||||
{
|
||||
printf("Usage:\n" "\n" "%s [[network]:[address]] "
|
||||
"[device-instance-min [device-instance-max]] [--help]\n", exe_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int print_help(char* exe_name){
|
||||
printf(
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
"%s [[network]:[address]] "
|
||||
"[device-instance-min [device-instance-max]] [--help]\n"
|
||||
"\n"
|
||||
" Send BACnet WhoIs service request to a device or multiple devices, and wait\n"
|
||||
" for responses. Displays any devices found and their network information.\n"
|
||||
"\n"
|
||||
"device-instance:\r\n"
|
||||
" BACnet Device Object Instance number that you are trying to send a Who-Is\n"
|
||||
" service request. The value should be in the range of 0 to 4194303. A range\n"
|
||||
" of values can also be specified by using a minimum value and a maximum value.\n"
|
||||
"\n"
|
||||
"network:\n"
|
||||
" BACnet network number for directed requests. Valid range is from 0 to 65535\n"
|
||||
" where 0 is the local connection and 65535 is network broadcast.\n"
|
||||
"\n"
|
||||
"address:\n"
|
||||
" BACnet mac address number. Valid ranges are from 0 to 255 or a IP connection \n"
|
||||
" string including port number like 10.1.2.3:47808.\n"
|
||||
"\n"
|
||||
"Examples:\n\n"
|
||||
"To send a WhoIs request to Network 123:\n"
|
||||
"%s 123:\n\n"
|
||||
"To send a WhoIs request to Network 123 Address 5:\n"
|
||||
"%s 123:5\n\n"
|
||||
"To send a WhoIs request to Device 123:\n"
|
||||
"%s 123\n\n"
|
||||
"To send a WhoIs request to Devices from 1000 to 9000:\n"
|
||||
"%s 1000 9000\n\n"
|
||||
"To send a WhoIs request to Devices from 1000 to 9000 on Network 123:\n"
|
||||
"%s 123: 1000 9000\n\n"
|
||||
"To send a WhoIs request to all devices:\n"
|
||||
"%s\n\n",
|
||||
exe_name,exe_name,exe_name,exe_name,exe_name,exe_name,exe_name);
|
||||
return 1;
|
||||
static int print_help(
|
||||
char *exe_name)
|
||||
{
|
||||
printf("Usage:\n" "\n" "%s [[network]:[address]] "
|
||||
"[device-instance-min [device-instance-max]] [--help]\n" "\n"
|
||||
" Send BACnet WhoIs service request to a device or multiple devices, and wait\n"
|
||||
" for responses. Displays any devices found and their network information.\n"
|
||||
"\n" "device-instance:\r\n"
|
||||
" BACnet Device Object Instance number that you are trying to send a Who-Is\n"
|
||||
" service request. The value should be in the range of 0 to 4194303. A range\n"
|
||||
" of values can also be specified by using a minimum value and a maximum value.\n"
|
||||
"\n" "network:\n"
|
||||
" BACnet network number for directed requests. Valid range is from 0 to 65535\n"
|
||||
" where 0 is the local connection and 65535 is network broadcast.\n"
|
||||
"\n" "address:\n"
|
||||
" BACnet mac address number. Valid ranges are from 0 to 255 or a IP connection \n"
|
||||
" string including port number like 10.1.2.3:47808.\n" "\n"
|
||||
"Examples:\n\n" "To send a WhoIs request to Network 123:\n"
|
||||
"%s 123:\n\n" "To send a WhoIs request to Network 123 Address 5:\n"
|
||||
"%s 123:5\n\n" "To send a WhoIs request to Device 123:\n" "%s 123\n\n"
|
||||
"To send a WhoIs request to Devices from 1000 to 9000:\n"
|
||||
"%s 1000 9000\n\n"
|
||||
"To send a WhoIs request to Devices from 1000 to 9000 on Network 123:\n"
|
||||
"%s 123: 1000 9000\n\n" "To send a WhoIs request to all devices:\n"
|
||||
"%s\n\n", exe_name, exe_name, exe_name, exe_name, exe_name, exe_name,
|
||||
exe_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -345,47 +330,39 @@ static int print_help(char* exe_name){
|
||||
** @return length of address parsed in bytes
|
||||
*/
|
||||
static int parse_bac_address(
|
||||
BACNET_ADDRESS *dest, /* [out] BACNET Address*/
|
||||
char *src /* [in] nul terminated string to parse */
|
||||
)
|
||||
BACNET_ADDRESS * dest, /* [out] BACNET Address */
|
||||
char *src /* [in] nul terminated string to parse */
|
||||
)
|
||||
{
|
||||
int i = 0;
|
||||
uint16_t s;
|
||||
int a[4],p;
|
||||
int c = sscanf(src,"%u.%u.%u.%u:%u",&a[0],&a[1],&a[2],&a[3],&p);
|
||||
int i = 0;
|
||||
uint16_t s;
|
||||
int a[4], p;
|
||||
int c = sscanf(src, "%u.%u.%u.%u:%u", &a[0], &a[1], &a[2], &a[3], &p);
|
||||
|
||||
dest->len = 0;
|
||||
dest->len = 0;
|
||||
|
||||
if (c==1)
|
||||
{
|
||||
if( a[0] < 256 ) /* mstp */
|
||||
{
|
||||
dest->adr[0] = a[0];
|
||||
dest->len = 1;
|
||||
}
|
||||
else if ( a[0] < 0x0FFFF ) /* lon */
|
||||
{
|
||||
s = htons((uint16_t)a[0]);
|
||||
memcpy(&dest->adr[0], &s, 2);
|
||||
dest->len = 2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else if (c==5) /* ip address */
|
||||
{
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
if(a[i] == 0 || a[i] > 255)
|
||||
return 0;
|
||||
if (c == 1) {
|
||||
if (a[0] < 256) { /* mstp */
|
||||
dest->adr[0] = a[0];
|
||||
dest->len = 1;
|
||||
} else if (a[0] < 0x0FFFF) { /* lon */
|
||||
s = htons((uint16_t) a[0]);
|
||||
memcpy(&dest->adr[0], &s, 2);
|
||||
dest->len = 2;
|
||||
} else
|
||||
return 0;
|
||||
} else if (c == 5) { /* ip address */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (a[i] == 0 || a[i] > 255)
|
||||
return 0;
|
||||
|
||||
dest->adr[i] = a[i];
|
||||
}
|
||||
s = htons((uint16_t)p);
|
||||
memcpy(&dest->adr[i], &s, 2);
|
||||
dest->len = 6;
|
||||
}
|
||||
return dest->len;
|
||||
dest->adr[i] = a[i];
|
||||
}
|
||||
s = htons((uint16_t) p);
|
||||
memcpy(&dest->adr[i], &s, 2);
|
||||
dest->len = 6;
|
||||
}
|
||||
return dest->len;
|
||||
}
|
||||
|
||||
|
||||
@@ -404,68 +381,62 @@ int main(
|
||||
time_t last_seconds = 0;
|
||||
time_t current_seconds = 0;
|
||||
time_t timeout_seconds = 0;
|
||||
BACNET_ADDRESS dest;
|
||||
int argi;
|
||||
BACNET_ADDRESS dest;
|
||||
int argi;
|
||||
|
||||
/* print help if requested */
|
||||
for (argi = 1; argi < argc; argi++)
|
||||
{
|
||||
if (strcmp(argv[argi], "--help") == 0) {
|
||||
print_help(filename_remove_path(argv[0]));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
datalink_get_broadcast_address(&dest);
|
||||
|
||||
/* decode the command line parameters */
|
||||
if (argc >= 2) {
|
||||
char *s;
|
||||
long v = strtol(argv[1], &s, 0);
|
||||
if(*s++ == ':')
|
||||
{
|
||||
if(argv[1][0] != ':')
|
||||
dest.net = (uint16_t) v;
|
||||
dest.mac_len = 0;
|
||||
if(isdigit(*s))
|
||||
parse_bac_address(&dest,s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Target_Object_Instance_Min = Target_Object_Instance_Max = v;
|
||||
}
|
||||
/* print help if requested */
|
||||
for (argi = 1; argi < argc; argi++) {
|
||||
if (strcmp(argv[argi], "--help") == 0) {
|
||||
print_help(filename_remove_path(argv[0]));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= 2){
|
||||
/* empty */
|
||||
} else if (argc == 3){
|
||||
if(Target_Object_Instance_Min == -1)
|
||||
Target_Object_Instance_Min =
|
||||
Target_Object_Instance_Max = strtol(argv[2], NULL, 0);
|
||||
else
|
||||
Target_Object_Instance_Max = strtol(argv[2], NULL, 0);
|
||||
} else if (argc == 4){
|
||||
datalink_get_broadcast_address(&dest);
|
||||
|
||||
/* decode the command line parameters */
|
||||
if (argc >= 2) {
|
||||
char *s;
|
||||
long v = strtol(argv[1], &s, 0);
|
||||
if (*s++ == ':') {
|
||||
if (argv[1][0] != ':')
|
||||
dest.net = (uint16_t) v;
|
||||
dest.mac_len = 0;
|
||||
if (isdigit(*s))
|
||||
parse_bac_address(&dest, s);
|
||||
} else {
|
||||
Target_Object_Instance_Min = Target_Object_Instance_Max = v;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= 2) {
|
||||
/* empty */
|
||||
} else if (argc == 3) {
|
||||
if (Target_Object_Instance_Min == -1)
|
||||
Target_Object_Instance_Min = Target_Object_Instance_Max =
|
||||
strtol(argv[2], NULL, 0);
|
||||
else
|
||||
Target_Object_Instance_Max = strtol(argv[2], NULL, 0);
|
||||
} else if (argc == 4) {
|
||||
Target_Object_Instance_Min = strtol(argv[2], NULL, 0);
|
||||
Target_Object_Instance_Max = strtol(argv[3], NULL, 0);
|
||||
} else {
|
||||
print_usage(filename_remove_path(argv[0]));
|
||||
print_usage(filename_remove_path(argv[0]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) {
|
||||
fprintf(stderr,
|
||||
"device-instance-min=%u - it must be less than %u\r\n",
|
||||
fprintf(stderr, "device-instance-min=%u - it must be less than %u\r\n",
|
||||
Target_Object_Instance_Min, BACNET_MAX_INSTANCE + 1);
|
||||
return 1;
|
||||
}
|
||||
if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) {
|
||||
fprintf(stderr,
|
||||
"device-instance-max=%u - it must be less than %u\r\n",
|
||||
fprintf(stderr, "device-instance-max=%u - it must be less than %u\r\n",
|
||||
Target_Object_Instance_Max, BACNET_MAX_INSTANCE + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* setup my info */
|
||||
/* setup my info */
|
||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||
init_service_handlers();
|
||||
address_init();
|
||||
@@ -475,8 +446,9 @@ int main(
|
||||
last_seconds = time(NULL);
|
||||
timeout_seconds = apdu_timeout() / 1000;
|
||||
/* send the request */
|
||||
Send_WhoIs_To_Network(&dest,Target_Object_Instance_Min, Target_Object_Instance_Max);
|
||||
/* loop forever */
|
||||
Send_WhoIs_To_Network(&dest, Target_Object_Instance_Min,
|
||||
Target_Object_Instance_Max);
|
||||
/* loop forever */
|
||||
for (;;) {
|
||||
/* increment timer - exit if timed out */
|
||||
current_seconds = time(NULL);
|
||||
|
||||
@@ -180,7 +180,8 @@ int main(
|
||||
|
||||
if (argc < 4) {
|
||||
/* FIXME: what about access method - record or stream? */
|
||||
printf("%s device-instance file-instance local-name [octet count] [pad value]\r\n",
|
||||
printf
|
||||
("%s device-instance file-instance local-name [octet count] [pad value]\r\n",
|
||||
filename_remove_path(argv[0]));
|
||||
return 0;
|
||||
}
|
||||
@@ -281,8 +282,8 @@ int main(
|
||||
if (len < requestedOctetCount) {
|
||||
End_Of_File_Detected = true;
|
||||
if (pad_byte) {
|
||||
memset(octetstring_value(&fileData)+len+1,
|
||||
(int)Target_File_Requested_Octet_Pad_Byte,
|
||||
memset(octetstring_value(&fileData) + len + 1,
|
||||
(int) Target_File_Requested_Octet_Pad_Byte,
|
||||
requestedOctetCount - len);
|
||||
len = requestedOctetCount;
|
||||
}
|
||||
|
||||
@@ -345,7 +345,8 @@ int main(
|
||||
|
||||
/* at least one second has passed */
|
||||
if (current_seconds != last_seconds)
|
||||
tsm_timer_milliseconds((uint16_t)((current_seconds - last_seconds) * 1000));
|
||||
tsm_timer_milliseconds((uint16_t) ((current_seconds -
|
||||
last_seconds) * 1000));
|
||||
if (Error_Detected)
|
||||
break;
|
||||
/* wait until the device is bound, or timeout and quit */
|
||||
|
||||
Reference in New Issue
Block a user