1
0
mirror of https://github.com/stargieg/bacnet-stack synced 2025-10-26 23:35:52 +08:00

add ao and ai uci loop

This commit is contained in:
Patrick Grimm 2014-02-24 22:38:53 +01:00
parent 4a586ffa8d
commit 7a159b9afa
6 changed files with 1279 additions and 377 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com> * Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
* Copyright (C) 2013 Patrick Grimm <patrick@lunatiki.de>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
@ -29,25 +30,38 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "bacdef.h" #include "bacdef.h"
#include "rp.h" #include "cov.h"
#include "bacerror.h"
#include "wp.h" #include "wp.h"
#include "rp.h"
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
#include "nc.h" #include "nc.h"
#include "getevent.h"
#include "alarm_ack.h" #include "alarm_ack.h"
#include "getevent.h"
#include "get_alarm_sum.h" #include "get_alarm_sum.h"
#endif #endif /* INTRINSIC_REPORTING */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
typedef struct analog_input_descr { typedef struct analog_input_descr {
uint32_t Instance;
char Object_Name[64];
char Object_Description[64];
//uint8_t Present_Value;
unsigned Event_State:3; unsigned Event_State:3;
float Present_Value;
BACNET_RELIABILITY Reliability;
bool Out_Of_Service; bool Out_Of_Service;
bool Change_Of_Value;
uint8_t Reliability;
float COV_Increment;
bool Disable;
uint8_t Units; uint8_t Units;
/* Here is our Priority Array. They are supposed to be Real, but */
/* we don't have that kind of memory, so we will use a single byte */
/* and load a Real for returning the value when asked. */
float Priority_Array[BACNET_MAX_PRIORITY];
float Relinquish_Default;
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
uint32_t Time_Delay; uint32_t Time_Delay;
uint32_t Notification_Class; uint32_t Notification_Class;
@ -63,9 +77,29 @@ extern "C" {
uint32_t Remaining_Time_Delay; uint32_t Remaining_Time_Delay;
/* AckNotification informations */ /* AckNotification informations */
ACK_NOTIFICATION Ack_notify_data; ACK_NOTIFICATION Ack_notify_data;
#endif #endif /* INTRINSIC_REPORTING */
} ANALOG_INPUT_DESCR; } ANALOG_INPUT_DESCR;
/* value/name tuples */
struct ai_inst_tuple {
char idx[18];
struct ai_inst_tuple *next;
};
typedef struct ai_inst_tuple ai_inst_tuple_t;
/* structure to hold tuple-list and uci context during iteration */
struct ai_inst_itr_ctx {
struct ai_inst_tuple *list;
struct uci_context *ctx;
char *section;
};
void Analog_Input_Load_UCI_List(
const char *sec_idx,
struct ai_inst_itr_ctx *itr);
void Analog_Input_Property_Lists( void Analog_Input_Property_Lists(
const int **pRequired, const int **pRequired,
const int **pOptional, const int **pOptional,
@ -73,50 +107,72 @@ extern "C" {
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(
uint32_t object_instance); uint32_t object_instance);
unsigned Analog_Input_Count( unsigned Analog_Input_Count(
void); void);
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(
unsigned index); unsigned index);
unsigned Analog_Input_Instance_To_Index( unsigned Analog_Input_Instance_To_Index(
uint32_t instance); uint32_t object_instance);
int Analog_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata);
bool Analog_Input_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data);
/* optional API */
bool Analog_Input_Object_Instance_Add( bool Analog_Input_Object_Instance_Add(
uint32_t instance); uint32_t instance);
bool Analog_Input_Object_Name( bool Analog_Input_Object_Name(
uint32_t object_instance, uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name); BACNET_CHARACTER_STRING * object_name);
bool Analog_Input_Name_Set( bool Analog_Input_Name_Set(
uint32_t object_instance, uint32_t object_instance,
char *new_name); char *new_name);
char *Analog_Input_Description( bool Analog_Input_Present_Value_Set(
uint32_t instance); uint32_t object_instance,
bool Analog_Input_Description_Set( float value,
uint32_t instance, uint8_t priority);
char *new_name);
bool Analog_Input_Units_Set(
uint32_t instance,
uint16_t units);
uint16_t Analog_Input_Units(
uint32_t instance);
int Analog_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata);
bool Analog_Input_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data);
float Analog_Input_Present_Value( float Analog_Input_Present_Value(
uint32_t object_instance); uint32_t object_instance);
void Analog_Input_Present_Value_Set(
uint32_t object_instance, unsigned Analog_Input_Present_Value_Priority(
float value); uint32_t object_instance);
bool Analog_Input_Out_Of_Service( bool Analog_Input_Out_Of_Service(
uint32_t object_instance); uint32_t object_instance);
void Analog_Input_Out_Of_Service_Set( void Analog_Input_Out_Of_Service_Set(
uint32_t object_instance, uint32_t object_instance,
bool oos_flag); bool value);
uint8_t Analog_Input_Reliability(
uint32_t object_instance);
void Analog_Input_Reliability_Set(
uint32_t object_instance,
uint8_t value);
bool Analog_Input_Encode_Value_List(
uint32_t object_instance,
BACNET_PROPERTY_VALUE * value_list);
bool Analog_Input_Change_Of_Value(
uint32_t instance);
void Analog_Input_Change_Of_Value_Clear(
uint32_t instance);
bool Analog_Input_Description_Set(
uint32_t object_instance,
char *text_string);
/* note: header of Intrinsic_Reporting function is required /* note: header of Intrinsic_Reporting function is required
even when INTRINSIC_REPORTING is not defined */ even when INTRINSIC_REPORTING is not defined */
@ -142,7 +198,7 @@ extern "C" {
#ifdef TEST #ifdef TEST
#include "ctest.h" #include "ctest.h"
void testAnalogInput( void testAnalog_Input(
Test * pTest); Test * pTest);
#endif #endif

View File

@ -25,7 +25,7 @@
* *
*********************************************************************/ *********************************************************************/
/* Analog Value Objects - customize for your use */ /* Analog Output Objects - customize for your use */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@ -46,8 +46,7 @@
/* number of demo objects */ /* number of demo objects */
#ifndef MAX_ANALOG_OUTPUTS #ifndef MAX_ANALOG_OUTPUTS
//#define MAX_ANALOG_OUTPUTS 65535 #define MAX_ANALOG_OUTPUTS 65535
#define MAX_ANALOG_OUTPUTS 512
#endif #endif
unsigned max_analog_outputs_int = 0; unsigned max_analog_outputs_int = 0;
@ -60,11 +59,8 @@ unsigned max_analog_outputs_int = 0;
/* will be relinquished (i.e. set to the NULL level). */ /* will be relinquished (i.e. set to the NULL level). */
#define ANALOG_LEVEL_NULL 255 #define ANALOG_LEVEL_NULL 255
ANALOG_OUTPUT_DESCR AO_Descr[MAX_ANALOG_OUTPUTS]; ANALOG_OUTPUT_DESCR AO_Descr[MAX_ANALOG_OUTPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Output_Properties_Required[] = { static const int Analog_Output_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER,
@ -119,6 +115,26 @@ void Analog_Output_Property_Lists(
return; return;
} }
void Analog_Output_Load_UCI_List(const char *sec_idx,
struct ao_inst_itr_ctx *itr)
{
ao_inst_tuple_t *t = malloc(sizeof(ao_inst_tuple_t));
bool disable;
disable = ucix_get_option_int(itr->ctx, itr->section, sec_idx,
"disable", 0);
if (strcmp(sec_idx,"default") == 0)
return;
if (disable)
return;
if( (t = (ao_inst_tuple_t *)malloc(sizeof(ao_inst_tuple_t))) != NULL ) {
strncpy(t->idx, sec_idx, sizeof(t->idx));
t->next = itr->list;
itr->list = t;
}
return;
}
void Analog_Output_Init( void Analog_Output_Init(
void) void)
{ {
@ -158,12 +174,29 @@ void Analog_Output_Init(
const char *ucicov_increment; const char *ucicov_increment;
const char *ucicov_increment_default; const char *ucicov_increment_default;
const char *sec = "bacnet_ao"; const char *sec = "bacnet_ao";
char *section;
char *type;
struct ao_inst_itr_ctx itr_m;
section = "bacnet_ao";
#if PRINT_ENABLED
fprintf(stderr, "Analog_Output_Init\n"); fprintf(stderr, "Analog_Output_Init\n");
#endif
if (!initialized) { if (!initialized) {
initialized = true; initialized = true;
ctx = ucix_init(sec); ctx = ucix_init(sec);
#if PRINT_ENABLED
if(!ctx) if(!ctx)
fprintf(stderr, "Failed to load config file bacnet_ao\n"); fprintf(stderr, "Failed to load config file bacnet_ao\n");
#endif
type = "ao";
ao_inst_tuple_t *cur = malloc(sizeof (ao_inst_tuple_t));
itr_m.list = NULL;
itr_m.section = section;
itr_m.ctx = ctx;
ucix_for_each_section_type(ctx, section, type,
(void *)Analog_Output_Load_UCI_List, &itr_m);
ucidescription_default = ucix_get_option(ctx, sec, "default", ucidescription_default = ucix_get_option(ctx, sec, "default",
"description"); "description");
@ -187,21 +220,21 @@ void Analog_Output_Init(
"dead_limit"); "dead_limit");
ucicov_increment_default = ucix_get_option(ctx, sec, "default", ucicov_increment_default = ucix_get_option(ctx, sec, "default",
"cov_increment"); "cov_increment");
i = 0;
for (i = 0; i < MAX_ANALOG_OUTPUTS; i++) { for( cur = itr_m.list; cur; cur = cur->next ) {
memset(&AO_Descr[i], 0x00, sizeof(ANALOG_OUTPUT_DESCR)); strncpy(idx_cc, cur->idx, sizeof(idx_cc));
/* initialize all the analog output priority arrays to NULL */
for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
AO_Descr[i].Priority_Array[j] = ANALOG_LEVEL_NULL;
}
sprintf(idx_cc,"%d",i);
idx_c = idx_cc; idx_c = idx_cc;
uciname = ucix_get_option(ctx, "bacnet_ao", idx_c, "name"); uciname = ucix_get_option(ctx, "bacnet_ao", idx_c, "name");
ucidisable = ucix_get_option_int(ctx, "bacnet_ao", idx_c, ucidisable = ucix_get_option_int(ctx, "bacnet_ao", idx_c,
"disable", 0); "disable", 0);
if ((uciname != 0) && (ucidisable == 0)) { if ((uciname != 0) && (ucidisable == 0)) {
memset(&AO_Descr[i], 0x00, sizeof(ANALOG_OUTPUT_DESCR));
/* initialize all the analog output priority arrays to NULL */
for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
AO_Descr[i].Priority_Array[j] = ANALOG_LEVEL_NULL;
}
AO_Descr[i].Instance=atoi(idx_cc);
AO_Descr[i].Disable=false; AO_Descr[i].Disable=false;
max_analog_outputs_int = i+1;
sprintf(name, "%s", uciname); sprintf(name, "%s", uciname);
ucix_string_copy(AO_Descr[i].Object_Name, ucix_string_copy(AO_Descr[i].Object_Name,
sizeof(AO_Descr[i].Object_Name), name); sizeof(AO_Descr[i].Object_Name), name);
@ -312,7 +345,7 @@ void Analog_Output_Init(
AO_Descr[i].Event_State = EVENT_STATE_NORMAL; AO_Descr[i].Event_State = EVENT_STATE_NORMAL;
/* notification class not connected */ /* notification class not connected */
if (ucinc > -1) AO_Descr[i].Notification_Class = ucinc; if (ucinc > -1) AO_Descr[i].Notification_Class = ucinc;
else AO_Descr[i].Notification_Class = BACNET_MAX_INSTANCE; else AO_Descr[i].Notification_Class = 0;
if (ucievent > -1) AO_Descr[i].Event_Enable = ucievent; if (ucievent > -1) AO_Descr[i].Event_Enable = ucievent;
else AO_Descr[i].Event_Enable = 0; else AO_Descr[i].Event_Enable = 0;
if (ucitime_delay > -1) AO_Descr[i].Time_Delay = ucitime_delay; if (ucitime_delay > -1) AO_Descr[i].Time_Delay = ucitime_delay;
@ -339,11 +372,13 @@ void Analog_Output_Init(
handler_get_alarm_summary_set(OBJECT_ANALOG_OUTPUT, handler_get_alarm_summary_set(OBJECT_ANALOG_OUTPUT,
Analog_Output_Alarm_Summary); Analog_Output_Alarm_Summary);
#endif #endif
} else { i++;
AO_Descr[i].Disable=true; max_analog_outputs_int = i;
} }
} }
#if PRINT_ENABLED
fprintf(stderr, "max_analog_outputs %i\n", max_analog_outputs_int); fprintf(stderr, "max_analog_outputs %i\n", max_analog_outputs_int);
#endif
if(ctx) if(ctx)
ucix_cleanup(ctx); ucix_cleanup(ctx);
} }
@ -356,12 +391,17 @@ void Analog_Output_Init(
unsigned Analog_Output_Instance_To_Index( unsigned Analog_Output_Instance_To_Index(
uint32_t object_instance) uint32_t object_instance)
{ {
unsigned index = max_analog_outputs_int; ANALOG_OUTPUT_DESCR *CurrentAO;
int index,instance,i;
if (object_instance < max_analog_outputs_int) index = max_analog_outputs_int;
index = object_instance; for (i = 0; i < index; i++) {
CurrentAO = &AO_Descr[i];
return index; instance = CurrentAO->Instance;
if (CurrentAO->Instance == object_instance) {
return i;
}
}
return MAX_ANALOG_OUTPUTS;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
@ -371,16 +411,10 @@ uint32_t Analog_Output_Index_To_Instance(
unsigned index) unsigned index)
{ {
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
if (index < max_analog_outputs_int) { uint32_t instance;
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
if (CurrentAO->Disable == false) { instance = CurrentAO->Instance;
return index; return instance;
} else {
return false;
}
} else {
return false;
}
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
@ -400,14 +434,15 @@ bool Analog_Output_Valid_Instance(
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
index = Analog_Output_Instance_To_Index(object_instance); index = Analog_Output_Instance_To_Index(object_instance);
if (index < max_analog_outputs_int) { if (index == MAX_ANALOG_OUTPUTS) {
CurrentAO = &AO_Descr[index]; #if PRINT_ENABLED
if (CurrentAO->Disable == false) { fprintf(stderr, "Analog_Output_Valid_Instance %i invalid\n",object_instance);
return true; #endif
} else { return false;
return false;
}
} }
CurrentAO = &AO_Descr[index];
if (CurrentAO->Disable == false)
return true;
return false; return false;
} }
@ -417,10 +452,10 @@ bool Analog_Output_Change_Of_Value(
{ {
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
bool status = false; bool status = false;
unsigned index; unsigned index = 0;
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
status = CurrentAO->Change_Of_Value; status = CurrentAO->Change_Of_Value;
} }
@ -432,10 +467,10 @@ void Analog_Output_Change_Of_Value_Clear(
uint32_t object_instance) uint32_t object_instance)
{ {
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
unsigned index; unsigned index = 0;
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
CurrentAO->Change_Of_Value = false; CurrentAO->Change_Of_Value = false;
} }
@ -495,8 +530,8 @@ float Analog_Output_Present_Value(
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
unsigned i = 0; unsigned i = 0;
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
/* When all the priorities are level null, the present value returns */ /* When all the priorities are level null, the present value returns */
/* the Relinquish Default value */ /* the Relinquish Default value */
@ -520,8 +555,8 @@ unsigned Analog_Output_Present_Value_Priority(
unsigned i = 0; /* loop counter */ unsigned i = 0; /* loop counter */
unsigned priority = 0; /* return value */ unsigned priority = 0; /* return value */
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
for (i = 0; i < BACNET_MAX_PRIORITY; i++) { for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
if (CurrentAO->Priority_Array[priority] != ANALOG_LEVEL_NULL) { if (CurrentAO->Priority_Array[priority] != ANALOG_LEVEL_NULL) {
@ -534,7 +569,6 @@ unsigned Analog_Output_Present_Value_Priority(
return priority; return priority;
} }
bool Analog_Output_Present_Value_Set( bool Analog_Output_Present_Value_Set(
uint32_t object_instance, uint32_t object_instance,
float value, float value,
@ -544,8 +578,8 @@ bool Analog_Output_Present_Value_Set(
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
bool status = false; bool status = false;
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
if (priority && (priority <= BACNET_MAX_PRIORITY) && if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) ) { (priority != 6 /* reserved */ ) ) {
@ -566,7 +600,6 @@ bool Analog_Output_Present_Value_Set(
return status; return status;
} }
bool Analog_Output_Present_Value_Relinquish( bool Analog_Output_Present_Value_Relinquish(
uint32_t object_instance, uint32_t object_instance,
unsigned priority) unsigned priority)
@ -601,8 +634,8 @@ bool Analog_Output_Out_Of_Service(
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
bool value = false; bool value = false;
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
value = CurrentAO->Out_Of_Service; value = CurrentAO->Out_Of_Service;
} }
@ -617,8 +650,8 @@ void Analog_Output_Out_Of_Service_Set(
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
unsigned index = 0; unsigned index = 0;
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
CurrentAO->Out_Of_Service = value; CurrentAO->Out_Of_Service = value;
} }
@ -633,8 +666,8 @@ void Analog_Output_Reliability_Set(
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
unsigned index = 0; unsigned index = 0;
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
CurrentAO->Reliability = value; CurrentAO->Reliability = value;
} }
@ -649,8 +682,8 @@ uint8_t Analog_Output_Reliability(
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
uint8_t value = 0; uint8_t value = 0;
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
value = CurrentAO->Reliability; value = CurrentAO->Reliability;
} }
@ -665,8 +698,8 @@ static char *Analog_Output_Description(
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
char *pName = NULL; /* return value */ char *pName = NULL; /* return value */
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
pName = CurrentAO->Object_Description; pName = CurrentAO->Object_Description;
} }
@ -683,8 +716,8 @@ bool Analog_Output_Description_Set(
size_t i = 0; /* loop counter */ size_t i = 0; /* loop counter */
bool status = false; /* return value */ bool status = false; /* return value */
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
status = true; status = true;
if (new_name) { if (new_name) {
@ -718,8 +751,8 @@ static bool Analog_Output_Description_Write(
const char *idx_c; const char *idx_c;
char idx_cc[64]; char idx_cc[64];
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
length = characterstring_length(char_string); length = characterstring_length(char_string);
if (length <= sizeof(CurrentAO->Object_Description)) { if (length <= sizeof(CurrentAO->Object_Description)) {
@ -733,14 +766,16 @@ static bool Analog_Output_Description_Write(
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else { } else {
sprintf(idx_cc,"%d",index); sprintf(idx_cc,"%d",CurrentAO->Instance);
idx_c = idx_cc; idx_c = idx_cc;
if(ctx) { if(ctx) {
ucix_add_option(ctx, "bacnet_ao", idx_c, ucix_add_option(ctx, "bacnet_ao", idx_c,
"description", char_string->value); "description", char_string->value);
#if PRINT_ENABLED
} else { } else {
fprintf(stderr, fprintf(stderr,
"Failed to open config file bacnet_ao\n"); "Failed to open config file bacnet_ao\n");
#endif
} }
} }
} else { } else {
@ -764,10 +799,8 @@ bool Analog_Output_Object_Name(
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
bool status = false; bool status = false;
if (Analog_Output_Valid_Instance(object_instance)) {
index = Analog_Output_Instance_To_Index(object_instance); index = Analog_Output_Instance_To_Index(object_instance);
if (index < max_analog_outputs_int) {
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
status = characterstring_init_ansi(object_name, CurrentAO->Object_Name); status = characterstring_init_ansi(object_name, CurrentAO->Object_Name);
} }
@ -789,8 +822,8 @@ static bool Analog_Output_Object_Name_Write(
const char *idx_c; const char *idx_c;
char idx_cc[64]; char idx_cc[64];
index = Analog_Output_Instance_To_Index(object_instance); if (Analog_Output_Valid_Instance(object_instance)) {
if (index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(object_instance);
CurrentAO = &AO_Descr[index]; CurrentAO = &AO_Descr[index];
length = characterstring_length(char_string); length = characterstring_length(char_string);
if (length <= sizeof(CurrentAO->Object_Name)) { if (length <= sizeof(CurrentAO->Object_Name)) {
@ -804,14 +837,16 @@ static bool Analog_Output_Object_Name_Write(
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else { } else {
sprintf(idx_cc,"%d",index); sprintf(idx_cc,"%d",CurrentAO->Instance);
idx_c = idx_cc; idx_c = idx_cc;
if(ctx) { if(ctx) {
ucix_add_option(ctx, "bacnet_ao", idx_c, ucix_add_option(ctx, "bacnet_ao", idx_c,
"name", char_string->value); "name", char_string->value);
#if PRINT_ENABLED
} else { } else {
fprintf(stderr, fprintf(stderr,
"Failed to open config file bacnet_ao\n"); "Failed to open config file bacnet_ao\n");
#endif
} }
} }
} else { } else {
@ -837,7 +872,7 @@ int Analog_Output_Read_Property(
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
float present_value = 0; float present_value = 0;
unsigned object_index = 0; unsigned index = 0;
unsigned i = 0; unsigned i = 0;
uint8_t *apdu = NULL; uint8_t *apdu = NULL;
@ -848,10 +883,10 @@ int Analog_Output_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
object_index = Analog_Output_Instance_To_Index(rpdata->object_instance); if (Analog_Output_Valid_Instance(rpdata->object_instance)) {
if (object_index < max_analog_outputs_int) index = Analog_Output_Instance_To_Index(rpdata->object_instance);
CurrentAO = &AO_Descr[object_index]; CurrentAO = &AO_Descr[index];
else } else
return BACNET_STATUS_ERROR; return BACNET_STATUS_ERROR;
switch (rpdata->object_property) { switch (rpdata->object_property) {
@ -1136,7 +1171,7 @@ bool Analog_Output_Write_Property(
{ {
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned index = 0;
int object_type = 0; int object_type = 0;
uint32_t object_instance = 0; uint32_t object_instance = 0;
unsigned int priority = 0; unsigned int priority = 0;
@ -1171,10 +1206,10 @@ bool Analog_Output_Write_Property(
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false; return false;
} }
object_index = Analog_Output_Instance_To_Index(wp_data->object_instance); if (Analog_Output_Valid_Instance(wp_data->object_instance)) {
if (object_index < max_analog_outputs_int) { index = Analog_Output_Instance_To_Index(wp_data->object_instance);
CurrentAO = &AO_Descr[object_index]; CurrentAO = &AO_Descr[index];
sprintf(idx_cc,"%d",object_index); sprintf(idx_cc,"%d",CurrentAO->Instance);
idx_c = idx_cc; idx_c = idx_cc;
} else } else
return false; return false;
@ -1482,18 +1517,17 @@ void Analog_Output_Intrinsic_Reporting(
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
BACNET_EVENT_NOTIFICATION_DATA event_data; BACNET_EVENT_NOTIFICATION_DATA event_data;
BACNET_CHARACTER_STRING msgText; BACNET_CHARACTER_STRING msgText;
unsigned int object_index; unsigned index = 0;
uint8_t FromState = 0; uint8_t FromState = 0;
uint8_t ToState; uint8_t ToState;
float ExceededLimit = 0.0f; float ExceededLimit = 0.0f;
float PresentVal = 0.0f; float PresentVal = 0.0f;
bool SendNotify = false; bool SendNotify = false;
if (Analog_Output_Valid_Instance(object_instance)) {
object_index = Analog_Output_Instance_To_Index(object_instance); index = Analog_Output_Instance_To_Index(object_instance);
if (object_index < max_analog_outputs_int) CurrentAO = &AO_Descr[index];
CurrentAO = &AO_Descr[object_index]; } else
else
return; return;
/* check limits */ /* check limits */
@ -1785,7 +1819,7 @@ int Analog_Output_Event_Information(
/* check index */ /* check index */
if (index < max_analog_outputs_int) { if (Analog_Output_Valid_Instance(index)) {
/* Event_State not equal to NORMAL */ /* Event_State not equal to NORMAL */
IsActiveEvent = (AO_Descr[index].Event_State != EVENT_STATE_NORMAL); IsActiveEvent = (AO_Descr[index].Event_State != EVENT_STATE_NORMAL);
@ -1853,16 +1887,15 @@ int Analog_Output_Alarm_Ack(
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
ANALOG_OUTPUT_DESCR *CurrentAO; ANALOG_OUTPUT_DESCR *CurrentAO;
unsigned int object_index; unsigned index = 0;
if (Analog_Output_Valid_Instance(alarmack_data->eventObjectIdentifier.
object_index = instance)) {
Analog_Output_Instance_To_Index(alarmack_data->eventObjectIdentifier. index =
instance); Analog_Output_Instance_To_Index(alarmack_data->eventObjectIdentifier.
instance);
if (object_index < max_analog_outputs_int) CurrentAO = &AO_Descr[index];
CurrentAO = &AO_Descr[object_index]; } else {
else {
*error_code = ERROR_CODE_UNKNOWN_OBJECT; *error_code = ERROR_CODE_UNKNOWN_OBJECT;
return -1; return -1;
} }
@ -2048,7 +2081,7 @@ int main(
Test *pTest; Test *pTest;
bool rc; bool rc;
pTest = ct_create("BACnet Analog Value", NULL); pTest = ct_create("BACnet Analog Output", NULL);
/* individual tests */ /* individual tests */
rc = ct_addTestFunction(pTest, testAnalog_Output); rc = ct_addTestFunction(pTest, testAnalog_Output);
assert(rc); assert(rc);

View File

@ -31,6 +31,7 @@
#include <stdint.h> #include <stdint.h>
#include "bacdef.h" #include "bacdef.h"
#include "cov.h" #include "cov.h"
#include "bacerror.h"
#include "wp.h" #include "wp.h"
#include "rp.h" #include "rp.h"
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@ -44,10 +45,8 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
int max_analog_outputs;
typedef struct analog_output_descr { typedef struct analog_output_descr {
unsigned Object_ID; uint32_t Instance;
char Object_Name[64]; char Object_Name[64];
char Object_Description[64]; char Object_Description[64];
//uint8_t Present_Value; //uint8_t Present_Value;
@ -81,6 +80,25 @@ int max_analog_outputs;
#endif /* INTRINSIC_REPORTING */ #endif /* INTRINSIC_REPORTING */
} ANALOG_OUTPUT_DESCR; } ANALOG_OUTPUT_DESCR;
/* value/name tuples */
struct ao_inst_tuple {
char idx[18];
struct ao_inst_tuple *next;
};
typedef struct ao_inst_tuple ao_inst_tuple_t;
/* structure to hold tuple-list and uci context during iteration */
struct ao_inst_itr_ctx {
struct ao_inst_tuple *list;
struct uci_context *ctx;
char *section;
};
void Analog_Output_Load_UCI_List(
const char *sec_idx,
struct ao_inst_itr_ctx *itr);
void Analog_Output_Property_Lists( void Analog_Output_Property_Lists(
const int **pRequired, const int **pRequired,

View File

@ -471,7 +471,7 @@ void Binary_Value_Out_Of_Service_Set(
return; return;
} }
uint8_t Binary_Value_Reliabvlity( uint8_t Binary_Value_Reliability(
uint32_t object_instance) uint32_t object_instance)
{ {
BINARY_VALUE_DESCR *CurrentBV; BINARY_VALUE_DESCR *CurrentBV;
@ -481,13 +481,13 @@ uint8_t Binary_Value_Reliabvlity(
if (Binary_Value_Valid_Instance(object_instance)) { if (Binary_Value_Valid_Instance(object_instance)) {
index = Binary_Value_Instance_To_Index(object_instance); index = Binary_Value_Instance_To_Index(object_instance);
CurrentBV = &BV_Descr[index]; CurrentBV = &BV_Descr[index];
value = CurrentBV->Reliabvlity; value = CurrentBV->Reliability;
} }
return value; return value;
} }
void Binary_Value_Reliabvlity_Set( void Binary_Value_Reliability_Set(
uint32_t object_instance, uint32_t object_instance,
uint8_t value) uint8_t value)
{ {
@ -497,7 +497,7 @@ void Binary_Value_Reliabvlity_Set(
if (Binary_Value_Valid_Instance(object_instance)) { if (Binary_Value_Valid_Instance(object_instance)) {
index = Binary_Value_Instance_To_Index(object_instance); index = Binary_Value_Instance_To_Index(object_instance);
CurrentBV = &BV_Descr[index]; CurrentBV = &BV_Descr[index];
CurrentBV->Reliabvlity = value; CurrentBV->Reliability = value;
} }
return; return;
@ -1054,7 +1054,7 @@ int Binary_Value_Read_Property(
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = encode_application_enumerated(&apdu[0], apdu_len = encode_application_enumerated(&apdu[0],
CurrentBV->Reliabvlity); CurrentBV->Reliability);
break; break;
case PROP_PRIORITY_ARRAY: case PROP_PRIORITY_ARRAY:
@ -1416,7 +1416,7 @@ bool Binary_Value_Write_Property(
WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED, WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
CurrentBV->Reliabvlity = value.type.Enumerated; CurrentBV->Reliability = value.type.Enumerated;
} }
break; break;

View File

@ -107,7 +107,6 @@ static object_functions_t My_Object_Table[] = {
NULL /* COV */ , NULL /* COV */ ,
NULL /* COV Clear */ , NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }, NULL /* Intrinsic Reporting */ },
#if 0
{OBJECT_ANALOG_INPUT, {OBJECT_ANALOG_INPUT,
Analog_Input_Init, Analog_Input_Init,
Analog_Input_Count, Analog_Input_Count,
@ -119,9 +118,9 @@ static object_functions_t My_Object_Table[] = {
Analog_Input_Property_Lists, Analog_Input_Property_Lists,
NULL /* ReadRangeInfo */ , NULL /* ReadRangeInfo */ ,
NULL /* Iterator */ , NULL /* Iterator */ ,
NULL /* Value_Lists */ , Analog_Input_Encode_Value_List ,
NULL /* COV */ , Analog_Input_Change_Of_Value,
NULL /* COV Clear */ , Analog_Input_Change_Of_Value_Clear,
Analog_Input_Intrinsic_Reporting}, Analog_Input_Intrinsic_Reporting},
{OBJECT_ANALOG_OUTPUT, {OBJECT_ANALOG_OUTPUT,
Analog_Output_Init, Analog_Output_Init,
@ -137,8 +136,7 @@ static object_functions_t My_Object_Table[] = {
Analog_Output_Encode_Value_List , Analog_Output_Encode_Value_List ,
Analog_Output_Change_Of_Value, Analog_Output_Change_Of_Value,
Analog_Output_Change_Of_Value_Clear, Analog_Output_Change_Of_Value_Clear,
Analog_Value_Intrinsic_Reporting}, Analog_Output_Intrinsic_Reporting},
#endif
{OBJECT_ANALOG_VALUE, {OBJECT_ANALOG_VALUE,
Analog_Value_Init, Analog_Value_Init,
Analog_Value_Count, Analog_Value_Count,