mirror of
https://github.com/stargieg/bacnet-stack
synced 2025-10-19 23:25:23 +08:00
[r3164] esp32 support
This commit is contained in:
parent
1172adba2c
commit
fcded70c49
36
ports/esp32/lib/readme.txt
Normal file
36
ports/esp32/lib/readme.txt
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
This directory is intended for the project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link to executable file.
|
||||
|
||||
The source code of each library should be placed in separate directory, like
|
||||
"lib/private_lib/[here are source files]".
|
||||
|
||||
For example, see how can be organized `Foo` and `Bar` libraries:
|
||||
|
||||
|--lib
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |- readme.txt --> THIS FILE
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
Then in `src/main.c` you should use:
|
||||
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
// rest H/C/CPP code
|
||||
|
||||
PlatformIO will find your libraries automatically, configure preprocessor's
|
||||
include paths and build them.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- http://docs.platformio.org/page/librarymanager/ldf.html
|
||||
19
ports/esp32/platformio.ini
Normal file
19
ports/esp32/platformio.ini
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp32thing]
|
||||
platform = espressif32
|
||||
board = esp32thing
|
||||
framework = espidf
|
||||
|
||||
upload_port = COM7
|
||||
upload_speed = 1152000
|
||||
|
||||
monitor_baud = 115200
|
||||
66
ports/esp32/readme.txt
Normal file
66
ports/esp32/readme.txt
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
Bacnet Server for Espressif ESP32
|
||||
Steve Karg Bacnet stack using PlatformIO open source ecosystem for IoT development on VSCode or Atom
|
||||
F. Chaxel 2017
|
||||
|
||||
TODO list :
|
||||
|
||||
(Install VSCode or Atom and add the PlatformIO extension)
|
||||
|
||||
Edit platformio.ini to adjust board, Com Port, ...
|
||||
|
||||
Goto lib/stack and copy the requested files from Steve code :
|
||||
|
||||
all .h from include directory (not all required by it's simple)
|
||||
|
||||
these .c files from src or demo/handlers
|
||||
abort.c
|
||||
address.c
|
||||
apdu.c
|
||||
bacaddr.c
|
||||
bacapp.c
|
||||
bacdcode.c
|
||||
bacerror.c
|
||||
bacint.c
|
||||
bacreal.c
|
||||
bacstr.c
|
||||
bip.c
|
||||
bvlc.c
|
||||
cov.c
|
||||
datetime.c
|
||||
bacdevobjpropref.c
|
||||
dcc.c
|
||||
debug.c
|
||||
h_cov.c
|
||||
h_ucov.c
|
||||
h_npdu.c
|
||||
h_rp.c
|
||||
h_rpm.c
|
||||
h_whois.c
|
||||
h_wp.c
|
||||
iam.c
|
||||
lighting.c
|
||||
memcopy.c
|
||||
noserv.c
|
||||
npdu.c
|
||||
proplist.c
|
||||
reject.c
|
||||
rp.c
|
||||
rpm.c
|
||||
s_iam.c
|
||||
tsm.c
|
||||
whois.c
|
||||
wp.c
|
||||
|
||||
Modify
|
||||
in config.h
|
||||
MAX_TSM_TRANSACTIONS 255, set the value to 10 for instances
|
||||
in main.c
|
||||
wifi_config to fit your wifi network
|
||||
BACNET_LED 5, set another IO number depending of your board
|
||||
|
||||
A lot of Warning will be issued at compile time due to the redefinition of BIT macros.
|
||||
Could be removes by placing a #ifndef #BIT0 .. #endif arround the BIT macro in bits.h,
|
||||
and moving to the top of include list
|
||||
#include "datalink.h" in tsm.c, s_iam and in device.c
|
||||
#include "net.h" in bip.c and in bip.h (redondant include in bip.c)
|
||||
#include "bvlc.h" in bvlc.c
|
||||
1472
ports/esp32/src/ai.c
Normal file
1472
ports/esp32/src/ai.c
Normal file
File diff suppressed because it is too large
Load Diff
174
ports/esp32/src/ai.h
Normal file
174
ports/esp32/src/ai.h
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
* Copyright (C) 2011 Krzysztof Malorny <malornykrzysztof@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef AI_H
|
||||
#define AI_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "rp.h"
|
||||
#include "wp.h"
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
#include "nc.h"
|
||||
#include "getevent.h"
|
||||
#include "alarm_ack.h"
|
||||
#include "get_alarm_sum.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct analog_input_descr {
|
||||
unsigned Event_State:3;
|
||||
float Present_Value;
|
||||
BACNET_RELIABILITY Reliability;
|
||||
bool Out_Of_Service;
|
||||
uint8_t Units;
|
||||
float Prior_Value;
|
||||
float COV_Increment;
|
||||
bool Changed;
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
uint32_t Time_Delay;
|
||||
uint32_t Notification_Class;
|
||||
float High_Limit;
|
||||
float Low_Limit;
|
||||
float Deadband;
|
||||
unsigned Limit_Enable:2;
|
||||
unsigned Event_Enable:3;
|
||||
unsigned Notify_Type:1;
|
||||
ACKED_INFO Acked_Transitions[MAX_BACNET_EVENT_TRANSITION];
|
||||
BACNET_DATE_TIME Event_Time_Stamps[MAX_BACNET_EVENT_TRANSITION];
|
||||
/* time to generate event notification */
|
||||
uint32_t Remaining_Time_Delay;
|
||||
/* AckNotification informations */
|
||||
ACK_NOTIFICATION Ack_notify_data;
|
||||
#endif
|
||||
} ANALOG_INPUT_DESCR;
|
||||
|
||||
void Analog_Input_Property_Lists(
|
||||
const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
|
||||
bool Analog_Input_Valid_Instance(
|
||||
uint32_t object_instance);
|
||||
unsigned Analog_Input_Count(
|
||||
void);
|
||||
uint32_t Analog_Input_Index_To_Instance(
|
||||
unsigned index);
|
||||
unsigned Analog_Input_Instance_To_Index(
|
||||
uint32_t instance);
|
||||
bool Analog_Input_Object_Instance_Add(
|
||||
uint32_t instance);
|
||||
|
||||
bool Analog_Input_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name);
|
||||
bool Analog_Input_Name_Set(
|
||||
uint32_t object_instance,
|
||||
char *new_name);
|
||||
|
||||
char *Analog_Input_Description(
|
||||
uint32_t instance);
|
||||
bool Analog_Input_Description_Set(
|
||||
uint32_t instance,
|
||||
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(
|
||||
uint32_t object_instance);
|
||||
void Analog_Input_Present_Value_Set(
|
||||
uint32_t object_instance,
|
||||
float value);
|
||||
|
||||
bool Analog_Input_Out_Of_Service(
|
||||
uint32_t object_instance);
|
||||
void Analog_Input_Out_Of_Service_Set(
|
||||
uint32_t object_instance,
|
||||
bool oos_flag);
|
||||
|
||||
bool Analog_Input_Change_Of_Value(
|
||||
uint32_t instance);
|
||||
void Analog_Input_Change_Of_Value_Clear(
|
||||
uint32_t instance);
|
||||
bool Analog_Input_Encode_Value_List(
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_VALUE * value_list);
|
||||
float Analog_Input_COV_Increment(
|
||||
uint32_t instance);
|
||||
void Analog_Input_COV_Increment_Set(
|
||||
uint32_t instance,
|
||||
float value);
|
||||
|
||||
/* note: header of Intrinsic_Reporting function is required
|
||||
even when INTRINSIC_REPORTING is not defined */
|
||||
void Analog_Input_Intrinsic_Reporting(
|
||||
uint32_t object_instance);
|
||||
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
int Analog_Input_Event_Information(
|
||||
unsigned index,
|
||||
BACNET_GET_EVENT_INFORMATION_DATA * getevent_data);
|
||||
|
||||
int Analog_Input_Alarm_Ack(
|
||||
BACNET_ALARM_ACK_DATA * alarmack_data,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
|
||||
int Analog_Input_Alarm_Summary(
|
||||
unsigned index,
|
||||
BACNET_GET_ALARM_SUMMARY_DATA * getalarm_data);
|
||||
#endif
|
||||
|
||||
bool Analog_Input_Create(
|
||||
uint32_t object_instance);
|
||||
bool Analog_Input_Delete(
|
||||
uint32_t object_instance);
|
||||
void Analog_Input_Cleanup(
|
||||
void);
|
||||
void Analog_Input_Init(
|
||||
void);
|
||||
|
||||
#ifdef TEST
|
||||
#include "ctest.h"
|
||||
void testAnalogInput(
|
||||
Test * pTest);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
57
ports/esp32/src/bip_init.c
Normal file
57
ports/esp32/src/bip_init.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// Copyleft F.Chaxel 2017
|
||||
//
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/netdb.h"
|
||||
|
||||
#include "bip.h"
|
||||
|
||||
long bip_getaddrbyname(
|
||||
const char *host_name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bip_set_interface(char *ifname)
|
||||
{
|
||||
}
|
||||
|
||||
void bip_cleanup (void)
|
||||
{
|
||||
close(bip_socket());
|
||||
bip_set_socket(-1);
|
||||
}
|
||||
|
||||
bool bip_init(char *ifname)
|
||||
{
|
||||
|
||||
tcpip_adapter_ip_info_t ip_info = { 0 };
|
||||
|
||||
int value = 1;
|
||||
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
|
||||
|
||||
bip_set_interface(ifname);
|
||||
bip_set_port(htons(0xBAC0));
|
||||
bip_set_addr(ip_info.ip.addr);
|
||||
bip_set_broadcast_addr((ip_info.ip.addr&ip_info.netmask.addr)|(~ip_info.netmask.addr));
|
||||
|
||||
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
struct sockaddr_in saddr = { 0 };
|
||||
|
||||
saddr.sin_family = PF_INET;
|
||||
saddr.sin_port = htons(0xBAC0);
|
||||
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
|
||||
|
||||
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &value, sizeof(value));
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &value, sizeof(value));
|
||||
|
||||
bip_set_socket(sock);
|
||||
|
||||
return true;
|
||||
}
|
||||
556
ports/esp32/src/bo.c
Normal file
556
ports/esp32/src/bo.c
Normal file
|
|
@ -0,0 +1,556 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/* Binary Output Objects - customize for your use */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "bacapp.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "rp.h"
|
||||
#include "wp.h"
|
||||
#include "bo.h"
|
||||
#include "handlers.h"
|
||||
|
||||
#ifndef MAX_BINARY_OUTPUTS
|
||||
#define MAX_BINARY_OUTPUTS 1
|
||||
#endif
|
||||
|
||||
/* When all the priorities are level null, the present value returns */
|
||||
/* the Relinquish Default value */
|
||||
#define RELINQUISH_DEFAULT BINARY_INACTIVE
|
||||
/* Here is our Priority Array.*/
|
||||
static BACNET_BINARY_PV
|
||||
Binary_Output_Level[MAX_BINARY_OUTPUTS][BACNET_MAX_PRIORITY];
|
||||
/* Writable out-of-service allows others to play with our Present Value */
|
||||
/* without changing the physical output */
|
||||
static bool Out_Of_Service[MAX_BINARY_OUTPUTS];
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Binary_Output_Properties_Required[] = {
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_PRESENT_VALUE,
|
||||
PROP_STATUS_FLAGS,
|
||||
PROP_EVENT_STATE,
|
||||
PROP_OUT_OF_SERVICE,
|
||||
PROP_POLARITY,
|
||||
PROP_PRIORITY_ARRAY,
|
||||
PROP_RELINQUISH_DEFAULT,
|
||||
-1
|
||||
};
|
||||
|
||||
static const int Binary_Output_Properties_Optional[] = {
|
||||
PROP_DESCRIPTION,
|
||||
PROP_ACTIVE_TEXT,
|
||||
PROP_INACTIVE_TEXT,
|
||||
-1
|
||||
};
|
||||
|
||||
static const int Binary_Output_Properties_Proprietary[] = {
|
||||
-1
|
||||
};
|
||||
|
||||
void Binary_Output_Property_Lists(
|
||||
const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary)
|
||||
{
|
||||
if (pRequired)
|
||||
*pRequired = Binary_Output_Properties_Required;
|
||||
if (pOptional)
|
||||
*pOptional = Binary_Output_Properties_Optional;
|
||||
if (pProprietary)
|
||||
*pProprietary = Binary_Output_Properties_Proprietary;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Binary_Output_Init(
|
||||
void)
|
||||
{
|
||||
unsigned i, j;
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
|
||||
/* initialize all the analog output priority arrays to NULL */
|
||||
for (i = 0; i < MAX_BINARY_OUTPUTS; i++) {
|
||||
for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
|
||||
Binary_Output_Level[i][j] = BINARY_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then you need validate that the */
|
||||
/* given instance exists */
|
||||
bool Binary_Output_Valid_Instance(
|
||||
uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_BINARY_OUTPUTS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then count how many you have */
|
||||
unsigned Binary_Output_Count(
|
||||
void)
|
||||
{
|
||||
return MAX_BINARY_OUTPUTS;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then you need to return the instance */
|
||||
/* that correlates to the correct index */
|
||||
uint32_t Binary_Output_Index_To_Instance(
|
||||
unsigned index)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. Yours might be */
|
||||
/* more complex, and then you need to return the index */
|
||||
/* that correlates to the correct instance number */
|
||||
unsigned Binary_Output_Instance_To_Index(
|
||||
uint32_t object_instance)
|
||||
{
|
||||
unsigned index = MAX_BINARY_OUTPUTS;
|
||||
|
||||
if (object_instance < MAX_BINARY_OUTPUTS)
|
||||
index = object_instance;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
BACNET_BINARY_PV Binary_Output_Present_Value(
|
||||
uint32_t object_instance)
|
||||
{
|
||||
BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
|
||||
unsigned index = 0;
|
||||
unsigned i = 0;
|
||||
|
||||
index = Binary_Output_Instance_To_Index(object_instance);
|
||||
if (index < MAX_BINARY_OUTPUTS) {
|
||||
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
|
||||
if (Binary_Output_Level[index][i] != BINARY_NULL) {
|
||||
value = Binary_Output_Level[index][i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool Binary_Output_Out_Of_Service(
|
||||
uint32_t object_instance)
|
||||
{
|
||||
bool value = false;
|
||||
unsigned index = 0;
|
||||
|
||||
index = Binary_Output_Instance_To_Index(object_instance);
|
||||
if (index < MAX_BINARY_OUTPUTS) {
|
||||
value = Out_Of_Service[index];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* note: the object name must be unique within this device */
|
||||
|
||||
bool Binary_Output_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name)
|
||||
{
|
||||
static char text_string[32] = "";
|
||||
bool status = false;
|
||||
|
||||
if (object_instance==0)
|
||||
status=characterstring_init_ansi(object_name, "Led");
|
||||
else
|
||||
{
|
||||
if (object_instance < MAX_BINARY_OUTPUTS) {
|
||||
sprintf(text_string, "BINARY OUTPUT %lu",
|
||||
(unsigned long) object_instance);
|
||||
status = characterstring_init_ansi(object_name, text_string);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||
int Binary_Output_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
{
|
||||
int len = 0;
|
||||
int apdu_len = 0; /* return value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
|
||||
BACNET_POLARITY polarity = POLARITY_NORMAL;
|
||||
unsigned object_index = 0;
|
||||
unsigned i = 0;
|
||||
bool state = false;
|
||||
uint8_t *apdu = NULL;
|
||||
|
||||
if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
|
||||
(rpdata->application_data_len == 0)) {
|
||||
return 0;
|
||||
}
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT,
|
||||
rpdata->object_instance);
|
||||
break;
|
||||
/* note: Name and Description don't have to be the same.
|
||||
You could make Description writable and different */
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_DESCRIPTION:
|
||||
Binary_Output_Object_Name(rpdata->object_instance, &char_string);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_OBJECT_TYPE:
|
||||
apdu_len =
|
||||
encode_application_enumerated(&apdu[0], OBJECT_BINARY_OUTPUT);
|
||||
break;
|
||||
case PROP_PRESENT_VALUE:
|
||||
present_value =
|
||||
Binary_Output_Present_Value(rpdata->object_instance);
|
||||
apdu_len = encode_application_enumerated(&apdu[0], present_value);
|
||||
break;
|
||||
case PROP_STATUS_FLAGS:
|
||||
/* note: see the details in the standard on how to use these */
|
||||
bitstring_init(&bit_string);
|
||||
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
|
||||
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
|
||||
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
|
||||
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
case PROP_EVENT_STATE:
|
||||
/* note: see the details in the standard on how to use this */
|
||||
apdu_len =
|
||||
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
object_index =
|
||||
Binary_Output_Instance_To_Index(rpdata->object_instance);
|
||||
state = Out_Of_Service[object_index];
|
||||
apdu_len = encode_application_boolean(&apdu[0], state);
|
||||
break;
|
||||
case PROP_POLARITY:
|
||||
apdu_len = encode_application_enumerated(&apdu[0], polarity);
|
||||
break;
|
||||
case PROP_PRIORITY_ARRAY:
|
||||
/* Array element zero is the number of elements in the array */
|
||||
if (rpdata->array_index == 0)
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. */
|
||||
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
object_index =
|
||||
Binary_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 (Binary_Output_Level[object_index][i] == BINARY_NULL)
|
||||
len = encode_application_null(&apdu[apdu_len]);
|
||||
else {
|
||||
present_value = Binary_Output_Level[object_index][i];
|
||||
len =
|
||||
encode_application_enumerated(&apdu[apdu_len],
|
||||
present_value);
|
||||
}
|
||||
/* add it if we have room */
|
||||
if ((apdu_len + len) < MAX_APDU)
|
||||
apdu_len += len;
|
||||
else {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
apdu_len = BACNET_STATUS_ABORT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
object_index =
|
||||
Binary_Output_Instance_To_Index(rpdata->object_instance);
|
||||
if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
|
||||
if (Binary_Output_Level[object_index][rpdata->array_index -
|
||||
1] == BINARY_NULL)
|
||||
apdu_len = encode_application_null(&apdu[apdu_len]);
|
||||
else {
|
||||
present_value = Binary_Output_Level[object_index]
|
||||
[rpdata->array_index - 1];
|
||||
apdu_len =
|
||||
encode_application_enumerated(&apdu[apdu_len],
|
||||
present_value);
|
||||
}
|
||||
} else {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case PROP_RELINQUISH_DEFAULT:
|
||||
present_value = RELINQUISH_DEFAULT;
|
||||
apdu_len = encode_application_enumerated(&apdu[0], present_value);
|
||||
break;
|
||||
case PROP_ACTIVE_TEXT:
|
||||
characterstring_init_ansi(&char_string, "on");
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_INACTIVE_TEXT:
|
||||
characterstring_init_ansi(&char_string, "off");
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
default:
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
break;
|
||||
}
|
||||
/* only array properties can have array options */
|
||||
if ((apdu_len >= 0) && (rpdata->object_property != PROP_PRIORITY_ARRAY) &&
|
||||
(rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/* returns true if successful */
|
||||
bool Binary_Output_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
unsigned int object_index = 0;
|
||||
unsigned int priority = 0;
|
||||
BACNET_BINARY_PV level = BINARY_NULL;
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
|
||||
/* decode the some of the request */
|
||||
len =
|
||||
bacapp_decode_application_data(wp_data->application_data,
|
||||
wp_data->application_data_len, &value);
|
||||
/* FIXME: len < application_data_len: more data? */
|
||||
if (len < 0) {
|
||||
/* error while decoding - a value larger than we can handle */
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
if ((wp_data->object_property != PROP_PRIORITY_ARRAY) &&
|
||||
(wp_data->array_index != BACNET_ARRAY_ALL)) {
|
||||
/* only array properties can have array options */
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
return false;
|
||||
}
|
||||
switch (wp_data->object_property) {
|
||||
case PROP_PRESENT_VALUE:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
|
||||
priority = wp_data->priority;
|
||||
/* Command priority 6 is reserved for use by Minimum On/Off
|
||||
algorithm and may not be used for other purposes in any
|
||||
object. */
|
||||
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
|
||||
(priority != 6 /* reserved */ ) &&
|
||||
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
||||
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
||||
object_index =
|
||||
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
|
||||
are the highest priority.
|
||||
However, if Out of Service is TRUE, then don't set the
|
||||
physical output. This comment may apply to the
|
||||
main loop (i.e. check out of service before changing output) */
|
||||
status = true;
|
||||
} else if (priority == 6) {
|
||||
/* Command priority 6 is reserved for use by Minimum On/Off
|
||||
algorithm and may not be used for other purposes in any
|
||||
object. */
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
} else {
|
||||
status =
|
||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
level = BINARY_NULL;
|
||||
object_index =
|
||||
Binary_Output_Instance_To_Index
|
||||
(wp_data->object_instance);
|
||||
priority = wp_data->priority;
|
||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||
priority--;
|
||||
Binary_Output_Level[object_index][priority] = level;
|
||||
/* Note: you could set the physical output here to the next
|
||||
highest priority, or to the relinquish default if no
|
||||
priorities are set.
|
||||
However, if Out of Service is TRUE, then don't set the
|
||||
physical output. This comment may apply to the
|
||||
main loop (i.e. check out of service before changing output) */
|
||||
} else {
|
||||
status = false;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
status =
|
||||
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
|
||||
&wp_data->error_class, &wp_data->error_code);
|
||||
if (status) {
|
||||
object_index =
|
||||
Binary_Output_Instance_To_Index(wp_data->object_instance);
|
||||
Out_Of_Service[object_index] =
|
||||
value.type.Boolean;
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
case PROP_OBJECT_NAME:
|
||||
case PROP_OBJECT_TYPE:
|
||||
case PROP_STATUS_FLAGS:
|
||||
case PROP_RELIABILITY:
|
||||
case PROP_EVENT_STATE:
|
||||
case PROP_POLARITY:
|
||||
case PROP_PRIORITY_ARRAY:
|
||||
case PROP_RELINQUISH_DEFAULT:
|
||||
case PROP_ACTIVE_TEXT:
|
||||
case PROP_INACTIVE_TEXT:
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
default:
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "ctest.h"
|
||||
|
||||
bool WPValidateArgType(
|
||||
BACNET_APPLICATION_DATA_VALUE * pValue,
|
||||
uint8_t ucExpectedTag,
|
||||
BACNET_ERROR_CLASS * pErrorClass,
|
||||
BACNET_ERROR_CODE * pErrorCode)
|
||||
{
|
||||
pValue = pValue;
|
||||
ucExpectedTag = ucExpectedTag;
|
||||
pErrorClass = pErrorClass;
|
||||
pErrorCode = pErrorCode;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void testBinaryOutput(
|
||||
Test * pTest)
|
||||
{
|
||||
uint8_t apdu[MAX_APDU] = { 0 };
|
||||
int len = 0;
|
||||
uint32_t len_value = 0;
|
||||
uint8_t tag_number = 0;
|
||||
uint16_t decoded_type = 0;
|
||||
uint32_t decoded_instance = 0;
|
||||
BACNET_READ_PROPERTY_DATA rpdata;
|
||||
|
||||
Binary_Output_Init();
|
||||
rpdata.application_data = &apdu[0];
|
||||
rpdata.application_data_len = sizeof(apdu);
|
||||
rpdata.object_type = OBJECT_BINARY_OUTPUT;
|
||||
rpdata.object_instance = 1;
|
||||
rpdata.object_property = PROP_OBJECT_IDENTIFIER;
|
||||
rpdata.array_index = BACNET_ARRAY_ALL;
|
||||
len = Binary_Output_Read_Property(&rpdata);
|
||||
ct_test(pTest, len != 0);
|
||||
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
|
||||
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
|
||||
len = decode_object_id(&apdu[len], &decoded_type, &decoded_instance);
|
||||
ct_test(pTest, decoded_type == rpdata.object_type);
|
||||
ct_test(pTest, decoded_instance == rpdata.object_instance);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TEST_BINARY_OUTPUT
|
||||
int main(
|
||||
void)
|
||||
{
|
||||
Test *pTest;
|
||||
bool rc;
|
||||
|
||||
pTest = ct_create("BACnet Binary Output", NULL);
|
||||
/* individual tests */
|
||||
rc = ct_addTestFunction(pTest, testBinaryOutput);
|
||||
assert(rc);
|
||||
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void) ct_report(pTest);
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* TEST_BINARY_INPUT */
|
||||
#endif /* TEST */
|
||||
141
ports/esp32/src/bo.h
Normal file
141
ports/esp32/src/bo.h
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BO_H
|
||||
#define BO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacerror.h"
|
||||
#include "rp.h"
|
||||
#include "wp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void Binary_Output_Init(
|
||||
void);
|
||||
|
||||
void Binary_Output_Property_Lists(
|
||||
const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
|
||||
bool Binary_Output_Valid_Instance(
|
||||
uint32_t object_instance);
|
||||
unsigned Binary_Output_Count(
|
||||
void);
|
||||
uint32_t Binary_Output_Index_To_Instance(
|
||||
unsigned index);
|
||||
unsigned Binary_Output_Instance_To_Index(
|
||||
uint32_t instance);
|
||||
bool Binary_Output_Object_Instance_Add(
|
||||
uint32_t instance);
|
||||
|
||||
bool Binary_Output_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name);
|
||||
bool Binary_Output_Name_Set(
|
||||
uint32_t object_instance,
|
||||
char *new_name);
|
||||
|
||||
char *Binary_Output_Description(
|
||||
uint32_t instance);
|
||||
bool Binary_Output_Description_Set(
|
||||
uint32_t instance,
|
||||
char *new_name);
|
||||
|
||||
char *Binary_Output_Inactive_Text(
|
||||
uint32_t instance);
|
||||
bool Binary_Output_Inactive_Text_Set(
|
||||
uint32_t instance,
|
||||
char *new_name);
|
||||
char *Binary_Output_Active_Text(
|
||||
uint32_t instance);
|
||||
bool Binary_Output_Active_Text_Set(
|
||||
uint32_t instance,
|
||||
char *new_name);
|
||||
|
||||
BACNET_BINARY_PV Binary_Output_Present_Value(
|
||||
uint32_t instance);
|
||||
bool Binary_Output_Present_Value_Set(
|
||||
uint32_t instance,
|
||||
BACNET_BINARY_PV binary_value,
|
||||
unsigned priority);
|
||||
bool Binary_Output_Present_Value_Relinquish(
|
||||
uint32_t instance,
|
||||
unsigned priority);
|
||||
unsigned Binary_Output_Present_Value_Priority(
|
||||
uint32_t object_instance);
|
||||
|
||||
BACNET_POLARITY Binary_Output_Polarity(
|
||||
uint32_t instance);
|
||||
bool Binary_Output_Polarity_Set(
|
||||
uint32_t object_instance,
|
||||
BACNET_POLARITY polarity);
|
||||
|
||||
bool Binary_Output_Out_Of_Service(
|
||||
uint32_t instance);
|
||||
void Binary_Output_Out_Of_Service_Set(
|
||||
uint32_t object_instance,
|
||||
bool value);
|
||||
|
||||
BACNET_BINARY_PV Binary_Output_Relinquish_Default(
|
||||
uint32_t object_instance);
|
||||
bool Binary_Output_Relinquish_Default_Set(
|
||||
uint32_t object_instance,
|
||||
BACNET_BINARY_PV value);
|
||||
|
||||
bool Binary_Output_Encode_Value_List(
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_VALUE * value_list);
|
||||
bool Binary_Output_Change_Of_Value(
|
||||
uint32_t instance);
|
||||
void Binary_Output_Change_Of_Value_Clear(
|
||||
uint32_t instance);
|
||||
|
||||
int Binary_Output_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata);
|
||||
bool Binary_Output_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data);
|
||||
|
||||
bool Binary_Output_Create(
|
||||
uint32_t object_instance);
|
||||
bool Binary_Output_Delete(
|
||||
uint32_t object_instance);
|
||||
void Binary_Output_Cleanup(
|
||||
void);
|
||||
|
||||
#ifdef TEST
|
||||
#include "ctest.h"
|
||||
void testBinaryOutput(
|
||||
Test * pTest);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
2020
ports/esp32/src/device.c
Normal file
2020
ports/esp32/src/device.c
Normal file
File diff suppressed because it is too large
Load Diff
476
ports/esp32/src/device.h
Normal file
476
ports/esp32/src/device.h
Normal file
|
|
@ -0,0 +1,476 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/** @file device.h Defines functions for handling all BACnet objects belonging
|
||||
* to a BACnet device, as well as Device-specific properties. */
|
||||
|
||||
#ifndef DEVICE_H
|
||||
#define DEVICE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacenum.h"
|
||||
#include "wp.h"
|
||||
#include "rd.h"
|
||||
#include "rp.h"
|
||||
#include "rpm.h"
|
||||
#include "readrange.h"
|
||||
|
||||
/** Called so a BACnet object can perform any necessary initialization.
|
||||
* @ingroup ObjHelpers
|
||||
*/
|
||||
typedef void (
|
||||
*object_init_function) (
|
||||
void);
|
||||
|
||||
/** Counts the number of objects of this type.
|
||||
* @ingroup ObjHelpers
|
||||
* @return Count of implemented objects of this type.
|
||||
*/
|
||||
typedef unsigned (
|
||||
*object_count_function) (
|
||||
void);
|
||||
|
||||
/** Maps an object index position to its corresponding BACnet object instance number.
|
||||
* @ingroup ObjHelpers
|
||||
* @param index [in] The index of the object, in the array of objects of its type.
|
||||
* @return The BACnet object instance number to be used in a BACNET_OBJECT_ID.
|
||||
*/
|
||||
typedef uint32_t(
|
||||
*object_index_to_instance_function)
|
||||
(
|
||||
unsigned index);
|
||||
|
||||
/** Provides the BACnet Object_Name for a given object instance of this type.
|
||||
* @ingroup ObjHelpers
|
||||
* @param object_instance [in] The object instance number to be looked up.
|
||||
* @param object_name [in,out] Pointer to a character_string structure that
|
||||
* will hold a copy of the object name if this is a valid object_instance.
|
||||
* @return True if the object_instance is valid and object_name has been
|
||||
* filled with a copy of the Object's name.
|
||||
*/
|
||||
typedef bool(
|
||||
*object_name_function)
|
||||
(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name);
|
||||
|
||||
/** Look in the table of objects of this type, and see if this is a valid
|
||||
* instance number.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] The object instance number to be looked up.
|
||||
* @return True if the object instance refers to a valid object of this type.
|
||||
*/
|
||||
typedef bool(
|
||||
*object_valid_instance_function) (
|
||||
uint32_t object_instance);
|
||||
|
||||
/** Helper function to step through an array of objects and find either the
|
||||
* first one or the next one of a given type. Used to step through an array
|
||||
* of objects which is not necessarily contiguious for each type i.e. the
|
||||
* index for the 'n'th object of a given type is not necessarily 'n'.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] The index of the current object or a value of ~0 to indicate
|
||||
* start at the beginning.
|
||||
* @return The index of the next object of the required type or ~0 (all bits
|
||||
* == 1) to indicate no more objects found.
|
||||
*/
|
||||
typedef unsigned (
|
||||
*object_iterate_function) (
|
||||
unsigned current_index);
|
||||
|
||||
/** Look in the table of objects of this type, and get the COV Value List.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] The object instance number to be looked up.
|
||||
* @param [out] The value list
|
||||
* @return True if the object instance supports this feature, and has changed.
|
||||
*/
|
||||
typedef bool(
|
||||
*object_value_list_function) (
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_VALUE * value_list);
|
||||
|
||||
/** Look in the table of objects for this instance to see if value changed.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] The object instance number to be looked up.
|
||||
* @return True if the object instance has changed.
|
||||
*/
|
||||
typedef bool(
|
||||
*object_cov_function) (
|
||||
uint32_t object_instance);
|
||||
|
||||
/** Look in the table of objects for this instance to clear the changed flag.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] The object instance number to be looked up.
|
||||
*/
|
||||
typedef void (
|
||||
*object_cov_clear_function) (
|
||||
uint32_t object_instance);
|
||||
|
||||
/** Intrinsic Reporting funcionality.
|
||||
* @ingroup ObjHelpers
|
||||
* @param [in] Object instance.
|
||||
*/
|
||||
typedef void (
|
||||
*object_intrinsic_reporting_function) (
|
||||
uint32_t object_instance);
|
||||
|
||||
|
||||
/** Defines the group of object helper functions for any supported Object.
|
||||
* @ingroup ObjHelpers
|
||||
* Each Object must provide some implementation of each of these helpers
|
||||
* in order to properly support the handlers. Eg, the ReadProperty handler
|
||||
* handler_read_property() relies on the instance of Object_Read_Property
|
||||
* for each Object type, or configure the function as NULL.
|
||||
* In both appearance and operation, this group of functions acts like
|
||||
* they are member functions of a C++ Object base class.
|
||||
*/
|
||||
typedef struct object_functions {
|
||||
BACNET_OBJECT_TYPE Object_Type;
|
||||
object_init_function Object_Init;
|
||||
object_count_function Object_Count;
|
||||
object_index_to_instance_function Object_Index_To_Instance;
|
||||
object_valid_instance_function Object_Valid_Instance;
|
||||
object_name_function Object_Name;
|
||||
read_property_function Object_Read_Property;
|
||||
write_property_function Object_Write_Property;
|
||||
rpm_property_lists_function Object_RPM_List;
|
||||
rr_info_function Object_RR_Info;
|
||||
object_iterate_function Object_Iterator;
|
||||
object_value_list_function Object_Value_List;
|
||||
object_cov_function Object_COV;
|
||||
object_cov_clear_function Object_COV_Clear;
|
||||
object_intrinsic_reporting_function Object_Intrinsic_Reporting;
|
||||
} object_functions_t;
|
||||
|
||||
/* String Lengths - excluding any nul terminator */
|
||||
#define MAX_DEV_NAME_LEN 32
|
||||
#define MAX_DEV_LOC_LEN 64
|
||||
#define MAX_DEV_MOD_LEN 32
|
||||
#define MAX_DEV_VER_LEN 16
|
||||
#define MAX_DEV_DESC_LEN 64
|
||||
|
||||
/** Structure to define the Object Properties common to all Objects. */
|
||||
typedef struct commonBacObj_s {
|
||||
|
||||
/** The BACnet type of this object (ie, what class is this object from?).
|
||||
* This property, of type BACnetObjectType, indicates membership in a
|
||||
* particular object type class. Each inherited class will be of one type.
|
||||
*/
|
||||
BACNET_OBJECT_TYPE mObject_Type;
|
||||
|
||||
/** The instance number for this class instance. */
|
||||
uint32_t Object_Instance_Number;
|
||||
|
||||
/** Object Name; must be unique.
|
||||
* This property, of type CharacterString, shall represent a name for
|
||||
* the object that is unique within the BACnet Device that maintains it.
|
||||
*/
|
||||
char Object_Name[MAX_DEV_NAME_LEN];
|
||||
|
||||
} COMMON_BAC_OBJECT;
|
||||
|
||||
|
||||
/** Structure to define the Properties of Device Objects which distinguish
|
||||
* one instance from another.
|
||||
* This structure only defines fields for properties that are unique to
|
||||
* a given Device object. The rest may be fixed in device.c or hard-coded
|
||||
* into the read-property encoding.
|
||||
* This may be useful for implementations which manage multiple Devices,
|
||||
* eg, a Gateway.
|
||||
*/
|
||||
typedef struct devObj_s {
|
||||
/** The BACnet Device Address for this device; ->len depends on DLL type. */
|
||||
BACNET_ADDRESS bacDevAddr;
|
||||
|
||||
/** Structure for the Object Properties common to all Objects. */
|
||||
COMMON_BAC_OBJECT bacObj;
|
||||
|
||||
/** Device Description. */
|
||||
char Description[MAX_DEV_DESC_LEN];
|
||||
|
||||
/** The upcounter that shows if the Device ID or object structure has changed. */
|
||||
uint32_t Database_Revision;
|
||||
} DEVICE_OBJECT_DATA;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void Device_Init(
|
||||
object_functions_t * object_table);
|
||||
|
||||
bool Device_Reinitialize(
|
||||
BACNET_REINITIALIZE_DEVICE_DATA * rd_data);
|
||||
bool Device_Reinitialize_State_Set(BACNET_REINITIALIZED_STATE state);
|
||||
BACNET_REINITIALIZED_STATE Device_Reinitialized_State(
|
||||
void);
|
||||
|
||||
rr_info_function Device_Objects_RR_Info(
|
||||
BACNET_OBJECT_TYPE object_type);
|
||||
|
||||
void Device_getCurrentDateTime(
|
||||
BACNET_DATE_TIME * DateTime);
|
||||
|
||||
int32_t Device_UTC_Offset(void);
|
||||
void Device_UTC_Offset_Set(int16_t offset);
|
||||
|
||||
bool Device_Daylight_Savings_Status(void);
|
||||
bool Device_Align_Intervals(void);
|
||||
bool Device_Align_Intervals_Set(bool flag);
|
||||
uint32_t Device_Time_Sync_Interval(void);
|
||||
bool Device_Time_Sync_Interval_Set(uint32_t value);
|
||||
uint32_t Device_Interval_Offset(void);
|
||||
bool Device_Interval_Offset_Set(uint32_t value);
|
||||
|
||||
void Device_Property_Lists(
|
||||
const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
void Device_Objects_Property_List(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
struct special_property_list_t *pPropertyList);
|
||||
/* functions to support COV */
|
||||
bool Device_Encode_Value_List(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_VALUE * value_list);
|
||||
bool Device_Value_List_Supported(
|
||||
BACNET_OBJECT_TYPE object_type);
|
||||
bool Device_COV(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance);
|
||||
void Device_COV_Clear(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance);
|
||||
|
||||
uint32_t Device_Object_Instance_Number(
|
||||
void);
|
||||
bool Device_Set_Object_Instance_Number(
|
||||
uint32_t object_id);
|
||||
bool Device_Valid_Object_Instance_Number(
|
||||
uint32_t object_id);
|
||||
unsigned Device_Object_List_Count(
|
||||
void);
|
||||
bool Device_Object_List_Identifier(
|
||||
uint32_t array_index,
|
||||
int *object_type,
|
||||
uint32_t * instance);
|
||||
|
||||
unsigned Device_Count(
|
||||
void);
|
||||
uint32_t Device_Index_To_Instance(
|
||||
unsigned index);
|
||||
|
||||
bool Device_Object_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name);
|
||||
bool Device_Set_Object_Name(
|
||||
BACNET_CHARACTER_STRING * object_name);
|
||||
/* Copy a child object name, given its ID. */
|
||||
bool Device_Object_Name_Copy(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name);
|
||||
bool Device_Object_Name_ANSI_Init(const char * object_name);
|
||||
char * Device_Object_Name_ANSI(void);
|
||||
|
||||
BACNET_DEVICE_STATUS Device_System_Status(
|
||||
void);
|
||||
int Device_Set_System_Status(
|
||||
BACNET_DEVICE_STATUS status,
|
||||
bool local);
|
||||
|
||||
const char *Device_Vendor_Name(
|
||||
void);
|
||||
|
||||
uint16_t Device_Vendor_Identifier(
|
||||
void);
|
||||
void Device_Set_Vendor_Identifier(
|
||||
uint16_t vendor_id);
|
||||
|
||||
const char *Device_Model_Name(
|
||||
void);
|
||||
bool Device_Set_Model_Name(
|
||||
const char *name,
|
||||
size_t length);
|
||||
|
||||
const char *Device_Firmware_Revision(
|
||||
void);
|
||||
|
||||
const char *Device_Application_Software_Version(
|
||||
void);
|
||||
bool Device_Set_Application_Software_Version(
|
||||
const char *name,
|
||||
size_t length);
|
||||
|
||||
const char *Device_Description(
|
||||
void);
|
||||
bool Device_Set_Description(
|
||||
const char *name,
|
||||
size_t length);
|
||||
|
||||
const char *Device_Location(
|
||||
void);
|
||||
bool Device_Set_Location(
|
||||
const char *name,
|
||||
size_t length);
|
||||
|
||||
/* some stack-centric constant values - no set methods */
|
||||
uint8_t Device_Protocol_Version(
|
||||
void);
|
||||
uint8_t Device_Protocol_Revision(
|
||||
void);
|
||||
BACNET_SEGMENTATION Device_Segmentation_Supported(
|
||||
void);
|
||||
|
||||
uint32_t Device_Database_Revision(
|
||||
void);
|
||||
void Device_Set_Database_Revision(
|
||||
uint32_t revision);
|
||||
void Device_Inc_Database_Revision(
|
||||
void);
|
||||
|
||||
bool Device_Valid_Object_Name(
|
||||
BACNET_CHARACTER_STRING * object_name,
|
||||
int *object_type,
|
||||
uint32_t * object_instance);
|
||||
bool Device_Valid_Object_Id(
|
||||
int object_type,
|
||||
uint32_t object_instance);
|
||||
|
||||
int Device_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata);
|
||||
bool Device_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data);
|
||||
|
||||
bool DeviceGetRRInfo(
|
||||
BACNET_READ_RANGE_DATA * pRequest, /* Info on the request */
|
||||
RR_PROP_INFO * pInfo); /* Where to put the information */
|
||||
|
||||
int Device_Read_Property_Local(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata);
|
||||
bool Device_Write_Property_Local(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data);
|
||||
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
void Device_local_reporting(
|
||||
void);
|
||||
#endif
|
||||
|
||||
/* Prototypes for Routing functionality in the Device Object.
|
||||
* Enable by defining BAC_ROUTING in config.h and including gw_device.c
|
||||
* in the build (lib/Makefile).
|
||||
*/
|
||||
void Routing_Device_Init(
|
||||
uint32_t first_object_instance);
|
||||
|
||||
uint16_t Add_Routed_Device(
|
||||
uint32_t Object_Instance,
|
||||
BACNET_CHARACTER_STRING * Object_Name,
|
||||
const char *Description);
|
||||
DEVICE_OBJECT_DATA *Get_Routed_Device_Object(
|
||||
int idx);
|
||||
BACNET_ADDRESS *Get_Routed_Device_Address(
|
||||
int idx);
|
||||
|
||||
void routed_get_my_address(
|
||||
BACNET_ADDRESS * my_address);
|
||||
|
||||
bool Routed_Device_Address_Lookup(
|
||||
int idx,
|
||||
uint8_t address_len,
|
||||
uint8_t * mac_adress);
|
||||
bool Routed_Device_GetNext(
|
||||
BACNET_ADDRESS * dest,
|
||||
int *DNET_list,
|
||||
int *cursor);
|
||||
bool Routed_Device_Is_Valid_Network(
|
||||
uint16_t dest_net,
|
||||
int *DNET_list);
|
||||
|
||||
uint32_t Routed_Device_Index_To_Instance(
|
||||
unsigned index);
|
||||
bool Routed_Device_Valid_Object_Instance_Number(
|
||||
uint32_t object_id);
|
||||
bool Routed_Device_Name(
|
||||
uint32_t object_instance,
|
||||
BACNET_CHARACTER_STRING * object_name);
|
||||
uint32_t Routed_Device_Object_Instance_Number(
|
||||
void);
|
||||
bool Routed_Device_Set_Object_Instance_Number(
|
||||
uint32_t object_id);
|
||||
bool Routed_Device_Set_Object_Name(
|
||||
uint8_t encoding,
|
||||
const char *value,
|
||||
size_t length);
|
||||
bool Routed_Device_Set_Description(
|
||||
const char *name,
|
||||
size_t length);
|
||||
void Routed_Device_Inc_Database_Revision(
|
||||
void);
|
||||
int Routed_Device_Service_Approval(
|
||||
BACNET_CONFIRMED_SERVICE service,
|
||||
int service_argument,
|
||||
uint8_t * apdu_buff,
|
||||
uint8_t invoke_id);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
/** @defgroup ObjFrmwk Object Framework
|
||||
* The modules in this section describe the BACnet-stack's framework for
|
||||
* BACnet-defined Objects (Device, Analog Input, etc). There are two submodules
|
||||
* to describe this arrangement:
|
||||
* - The "object helper functions" which provide C++-like common functionality
|
||||
* to all supported object types.
|
||||
* - 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
|
||||
* @ingroup ObjFrmwk
|
||||
* This section describes the function templates for the helper functions that
|
||||
* provide common object support.
|
||||
*//** @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
|
||||
* situated in the Device Object, which "knows" how to reach its child Objects.
|
||||
*
|
||||
* Most of these calls have a common operation:
|
||||
* -# Call Device_Objects_Find_Functions( for the desired Object_Type )
|
||||
* - Gets a pointer to the object_functions for this Type of Object.
|
||||
* -# Call the Object's Object_Valid_Instance( for the desired object_instance )
|
||||
* to make sure there is such an instance.
|
||||
* -# Call the Object helper function needed by the handler,
|
||||
* eg Object_Read_Property() for the RP handler.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
215
ports/esp32/src/main.c
Normal file
215
ports/esp32/src/main.c
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
//
|
||||
// Copyleft F.Chaxel 2017
|
||||
//
|
||||
|
||||
#include "config.h"
|
||||
#include "txbuf.h"
|
||||
#include "client.h"
|
||||
|
||||
#include "handlers.h"
|
||||
#include "datalink.h"
|
||||
#include "dcc.h"
|
||||
#include "tsm.h"
|
||||
// conflict filename address.h with another file in default include paths
|
||||
#include "../lib/stack/address.h"
|
||||
#include "bip.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "ai.h"
|
||||
#include "bo.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/netdb.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
// hidden function not in any .h files
|
||||
extern uint8_t temprature_sens_read();
|
||||
extern uint32_t hall_sens_read();
|
||||
|
||||
// Wifi params
|
||||
wifi_config_t wifi_config = {
|
||||
.sta = {
|
||||
.ssid = "myWifi",
|
||||
.password = "myPass",
|
||||
},
|
||||
};
|
||||
|
||||
// GPIO 5 has a Led on Sparkfun ESP32 board
|
||||
#define BACNET_LED 5
|
||||
|
||||
uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 };
|
||||
uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||
|
||||
EventGroupHandle_t wifi_event_group;
|
||||
const static int CONNECTED_BIT = BIT0;
|
||||
|
||||
/* BACnet handler, stack init, IAm */
|
||||
void StartBACnet()
|
||||
{
|
||||
/* we need to handle who-is to support dynamic device binding */
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||
|
||||
/* set the handler for all the services we don't implement */
|
||||
/* It is required to send the proper reject message... */
|
||||
apdu_set_unrecognized_service_handler_handler
|
||||
(handler_unrecognized_service);
|
||||
/* Set the handlers for any confirmed services that we support. */
|
||||
/* We must implement read property - it's required! */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
handler_read_property);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
||||
handler_read_property_multiple);
|
||||
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
handler_write_property);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
|
||||
handler_cov_subscribe);
|
||||
|
||||
address_init();
|
||||
bip_init(NULL);
|
||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
||||
}
|
||||
|
||||
/* wifi events handler : start & stop bacnet with an event */
|
||||
esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
|
||||
{
|
||||
switch(event->event_id) {
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
esp_wifi_connect();
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_CONNECTED:
|
||||
break ;
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
if (xEventGroupGetBits(wifi_event_group)!=CONNECTED_BIT)
|
||||
{
|
||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||
StartBACnet();
|
||||
}
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
/* This is a workaround as ESP32 WiFi libs don't currently
|
||||
auto-reassociate. */
|
||||
esp_wifi_connect();
|
||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||
bip_cleanup();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* tcpip & wifi station start */
|
||||
|
||||
void wifi_init_station(void)
|
||||
{
|
||||
tcpip_adapter_init();
|
||||
wifi_event_group = xEventGroupCreate();
|
||||
esp_event_loop_init(wifi_event_handler, NULL);
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
esp_wifi_init(&cfg);
|
||||
|
||||
esp_wifi_set_storage(WIFI_STORAGE_RAM);
|
||||
esp_wifi_set_mode(WIFI_MODE_STA);
|
||||
|
||||
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
|
||||
|
||||
esp_wifi_start() ;
|
||||
}
|
||||
|
||||
/* setup gpio & nv flash, call wifi init code */
|
||||
void setup()
|
||||
{
|
||||
gpio_pad_select_gpio(BACNET_LED);
|
||||
gpio_set_direction(BACNET_LED, GPIO_MODE_OUTPUT);
|
||||
|
||||
gpio_set_level(BACNET_LED,0);
|
||||
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES)
|
||||
{
|
||||
nvs_flash_erase();
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
wifi_init_station();
|
||||
}
|
||||
|
||||
/* Bacnet Task */
|
||||
void BACnetTask(void *pvParameters)
|
||||
{
|
||||
uint16_t pdu_len = 0;
|
||||
BACNET_ADDRESS src = {
|
||||
0
|
||||
};
|
||||
unsigned timeout = 1;
|
||||
|
||||
// Init Bacnet objets dictionnary
|
||||
Device_Init(NULL);
|
||||
Device_Set_Object_Instance_Number(12);
|
||||
|
||||
setup();
|
||||
|
||||
uint32_t tickcount=xTaskGetTickCount();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS); // could be remove to speed the code
|
||||
|
||||
// do nothing if not connected to wifi
|
||||
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
|
||||
{
|
||||
uint32_t newtick=xTaskGetTickCount();
|
||||
|
||||
// one second elapse at least (maybe much more if Wifi was deconnected for a long)
|
||||
if ((newtick<tickcount)||((newtick-tickcount)>=configTICK_RATE_HZ))
|
||||
{
|
||||
tickcount=newtick;
|
||||
dcc_timer_seconds(1);
|
||||
bvlc_maintenance_timer(1);
|
||||
handler_cov_timer_seconds(1);
|
||||
tsm_timer_milliseconds(1000);
|
||||
|
||||
// Read analog values from internal sensors
|
||||
Analog_Input_Present_Value_Set(0,temprature_sens_read());
|
||||
Analog_Input_Present_Value_Set(1,hall_sens_read());
|
||||
|
||||
}
|
||||
|
||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||
if (pdu_len)
|
||||
{
|
||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||
|
||||
if(Binary_Output_Present_Value(0)==BINARY_ACTIVE)
|
||||
gpio_set_level(BACNET_LED,1);
|
||||
else
|
||||
gpio_set_level(BACNET_LED,0);
|
||||
}
|
||||
|
||||
handler_cov_task();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Entry point */
|
||||
void app_main()
|
||||
{
|
||||
// Cannot run BACnet code here, the default stack size is to small : 4096 byte
|
||||
xTaskCreate(
|
||||
BACnetTask, /* Function to implement the task */
|
||||
"BACnetTask", /* Name of the task */
|
||||
10000, /* Stack size in words */
|
||||
NULL, /* Task input parameter */
|
||||
20, /* Priority of the task */
|
||||
NULL); /* Task handle. */
|
||||
}
|
||||
125
ports/esp32/src/sdkconfig.h
Normal file
125
ports/esp32/src/sdkconfig.h
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
*
|
||||
* Automatically generated file; DO NOT EDIT.
|
||||
* Espressif IoT Development Framework Configuration
|
||||
*
|
||||
*/
|
||||
#define CONFIG_GATTC_ENABLE 1
|
||||
#define CONFIG_ESP32_PHY_MAX_TX_POWER 20
|
||||
#define CONFIG_PHY_ENABLED 1
|
||||
#define CONFIG_TRACEMEM_RESERVE_DRAM 0x0
|
||||
#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16
|
||||
#define CONFIG_BLE_SMP_ENABLE 1
|
||||
#define CONFIG_IPC_TASK_STACK_SIZE 1024
|
||||
#define CONFIG_ESPTOOLPY_FLASHFREQ "40m"
|
||||
#define CONFIG_NEWLIB_STDOUT_ADDCR 1
|
||||
#define CONFIG_TASK_WDT_CHECK_IDLE_TASK 1
|
||||
#define CONFIG_ESPTOOLPY_FLASHSIZE "2MB"
|
||||
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER 1
|
||||
#define CONFIG_ETHERNET 1
|
||||
#define CONFIG_INT_WDT 1
|
||||
#define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1
|
||||
#define CONFIG_LOG_BOOTLOADER_LEVEL_INFO 1
|
||||
#define CONFIG_ESPTOOLPY_FLASHSIZE_2MB 1
|
||||
#define CONFIG_AWS_IOT_MQTT_PORT 8883
|
||||
#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1
|
||||
#define CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM 10
|
||||
#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1
|
||||
#define CONFIG_BT_RESERVE_DRAM 0x10000
|
||||
#define CONFIG_ESP32_PANIC_PRINT_REBOOT 1
|
||||
#define CONFIG_CONSOLE_UART_BAUDRATE 115200
|
||||
#define CONFIG_LWIP_MAX_SOCKETS 10
|
||||
#define CONFIG_EMAC_TASK_PRIORITY 20
|
||||
#define CONFIG_TIMER_TASK_STACK_DEPTH 2048
|
||||
#define CONFIG_FATFS_CODEPAGE 1
|
||||
#define CONFIG_ESP32_DEFAULT_CPU_FREQ_160 1
|
||||
#define CONFIG_ULP_COPROC_RESERVE_MEM 0
|
||||
#define CONFIG_ESPTOOLPY_BAUD 115200
|
||||
#define CONFIG_INT_WDT_CHECK_CPU1 1
|
||||
#define CONFIG_FLASHMODE_DIO 1
|
||||
#define CONFIG_ESPTOOLPY_AFTER_RESET 1
|
||||
#define CONFIG_TOOLPREFIX "xtensa-esp32-elf-"
|
||||
#define CONFIG_FREERTOS_IDLE_TASK_STACKSIZE 1024
|
||||
#define CONFIG_ESP32_WIFI_AMPDU_ENABLED 1
|
||||
#define CONFIG_CONSOLE_UART_NUM 0
|
||||
#define CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC 1
|
||||
#define CONFIG_ESPTOOLPY_BAUD_115200B 1
|
||||
#define CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX 0
|
||||
#define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS 1
|
||||
#define CONFIG_CONSOLE_UART_DEFAULT 1
|
||||
#define CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN 16384
|
||||
#define CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS 4
|
||||
#define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1
|
||||
#define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1
|
||||
#define CONFIG_BTDM_CONTROLLER_RUN_CPU 0
|
||||
#define CONFIG_TCPIP_TASK_STACK_SIZE 2560
|
||||
#define CONFIG_TASK_WDT 1
|
||||
#define CONFIG_MAIN_TASK_STACK_SIZE 4096
|
||||
#define CONFIG_TASK_WDT_TIMEOUT_S 5
|
||||
#define CONFIG_INT_WDT_TIMEOUT_MS 300
|
||||
#define CONFIG_ESPTOOLPY_FLASHMODE "dio"
|
||||
#define CONFIG_BTC_TASK_STACK_SIZE 3072
|
||||
#define CONFIG_BLUEDROID_ENABLED 1
|
||||
#define CONFIG_ESPTOOLPY_BEFORE "default_reset"
|
||||
#define CONFIG_LOG_DEFAULT_LEVEL 3
|
||||
#define CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION 1
|
||||
#define CONFIG_TIMER_QUEUE_LENGTH 10
|
||||
#define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 32
|
||||
#define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER 20
|
||||
#define CONFIG_ESP32_RTC_CLK_CAL_CYCLES 1024
|
||||
#define CONFIG_ESP32_WIFI_NVS_ENABLED 1
|
||||
#define CONFIG_AWS_IOT_SDK 1
|
||||
#define CONFIG_DMA_RX_BUF_NUM 10
|
||||
#define CONFIG_TCP_SYNMAXRTX 6
|
||||
#define CONFIG_PYTHON "python"
|
||||
#define CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 1
|
||||
#define CONFIG_ESPTOOLPY_COMPRESSED 1
|
||||
#define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv"
|
||||
#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1
|
||||
#define CONFIG_PARTITION_TABLE_SINGLE_APP 1
|
||||
#define CONFIG_WIFI_ENABLED 1
|
||||
#define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1
|
||||
#define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE 4096
|
||||
#define CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY 2000
|
||||
#define CONFIG_ESP32_APPTRACE_DEST_NONE 1
|
||||
#define CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET 0x10000
|
||||
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32
|
||||
#define CONFIG_FATFS_CODEPAGE_ASCII 1
|
||||
#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 1
|
||||
#define CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ 160
|
||||
#define CONFIG_FREERTOS_HZ 100
|
||||
#define CONFIG_LOG_COLORS 1
|
||||
#define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE 1
|
||||
#define CONFIG_FREERTOS_ASSERT_FAIL_ABORT 1
|
||||
#define CONFIG_ESP32_XTAL_FREQ 0
|
||||
#define CONFIG_MONITOR_BAUD_115200B 1
|
||||
#define CONFIG_LOG_BOOTLOADER_LEVEL 3
|
||||
#define CONFIG_SMP_ENABLE 1
|
||||
#define CONFIG_ESPTOOLPY_BEFORE_RESET 1
|
||||
#define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200
|
||||
#define CONFIG_ESP32_XTAL_FREQ_AUTO 1
|
||||
#define CONFIG_TCP_MAXRTX 12
|
||||
#define CONFIG_ESPTOOLPY_AFTER "hard_reset"
|
||||
#define CONFIG_DMA_TX_BUF_NUM 10
|
||||
#define CONFIG_ESP32_DEBUG_OCDAWARE 1
|
||||
#define CONFIG_TIMER_TASK_PRIORITY 1
|
||||
#define CONFIG_BT_ENABLED 1
|
||||
#define CONFIG_MONITOR_BAUD 115200
|
||||
#define CONFIG_FREERTOS_CORETIMER_0 1
|
||||
#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv"
|
||||
#define CONFIG_MBEDTLS_HAVE_TIME 1
|
||||
#define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY 1
|
||||
#define CONFIG_GATTS_ENABLE 1
|
||||
#define CONFIG_FREERTOS_ISR_STACKSIZE 1536
|
||||
#define CONFIG_OPENSSL_ASSERT_DO_NOTHING 1
|
||||
#define CONFIG_AWS_IOT_MQTT_HOST ""
|
||||
#define CONFIG_SYSTEM_EVENT_QUEUE_SIZE 32
|
||||
#define CONFIG_BT_ACL_CONNECTIONS 4
|
||||
#define CONFIG_FATFS_MAX_LFN 255
|
||||
#define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1
|
||||
#define CONFIG_APP_OFFSET 0x10000
|
||||
#define CONFIG_MEMMAP_SMP 1
|
||||
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
|
||||
#define CONFIG_MONITOR_BAUD_OTHER_VAL 115200
|
||||
#define CONFIG_ESPTOOLPY_PORT "/dev/ttyUSB0"
|
||||
#define CONFIG_OPTIMIZATION_LEVEL_RELEASE 1
|
||||
Loading…
Reference in New Issue
Block a user