Initial commit
commit
9c23deac0e
|
|
@ -0,0 +1,2 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# Gitignore settings for ESPHome
|
||||
# This is an example and may include too much for your use-case.
|
||||
# You can modify this file to suit your needs.
|
||||
/.esphome/
|
||||
/secrets.yaml
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2025 Tomer27cz
|
||||
|
||||
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.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# xt211
|
||||
ESPHome component for ČEZ Sagecom XT211 AMM
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef ARDUINO_IGNORE_H
|
||||
#define ARDUINO_IGNORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Use UTC time zone. Read more: https://www.gurux.fi/Gurux.DLMS.Objects.GXDLMSClock
|
||||
//#define DLMS_USE_UTC_TIME_ZONE
|
||||
|
||||
/* Uncomment defines to ignore non-needed parts to make image size smaller. */
|
||||
|
||||
// #define DLMS_IGNORE_HDLC
|
||||
// #define DLMS_IGNORE_WRAPPER
|
||||
#define DLMS_IGNORE_PLC
|
||||
#define DLMS_IGNORE_SERVER
|
||||
#define GX_DLMS_MICROCONTROLLER
|
||||
#define DLMS_IGNORE_HIGH_SHA256
|
||||
#define DLMS_IGNORE_HIGH_SHA1
|
||||
#define DLMS_IGNORE_HIGH_MD5
|
||||
// #define DLMS_IGNORE_AES
|
||||
// #define DLMS_IGNORE_HIGH_GMAC
|
||||
// #define DLMS_IGNORE_DATA
|
||||
// #define DLMS_IGNORE_REGISTER
|
||||
// #define DLMS_IGNORE_EXTENDED_REGISTER
|
||||
// #define DLMS_IGNORE_DEMAND_REGISTER
|
||||
// #define DLMS_IGNORE_REGISTER_ACTIVATION
|
||||
// #define DLMS_IGNORE_PROFILE_GENERIC
|
||||
// #define DLMS_IGNORE_CLOCK
|
||||
// #define DLMS_IGNORE_SCRIPT_TABLE
|
||||
// #define DLMS_IGNORE_SCHEDULE
|
||||
// #define DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
||||
// #define DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
// #define DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
||||
// #define DLMS_IGNORE_SAP_ASSIGNMENT
|
||||
// #define DLMS_IGNORE_IMAGE_TRANSFER
|
||||
// #define DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
// #define DLMS_IGNORE_ACTIVITY_CALENDAR
|
||||
// #define DLMS_IGNORE_REGISTER_MONITOR
|
||||
// #define DLMS_IGNORE_ACTION_SCHEDULE
|
||||
// #define DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
// #define DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
||||
// #define DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
||||
// #define DLMS_IGNORE_UTILITY_TABLES
|
||||
// #define DLMS_IGNORE_MODEM_CONFIGURATION
|
||||
// #define DLMS_IGNORE_AUTO_ANSWER
|
||||
// #define DLMS_IGNORE_AUTO_CONNECT
|
||||
// #define DLMS_IGNORE_TCP_UDP_SETUP
|
||||
// #define DLMS_IGNORE_IP4_SETUP
|
||||
// #define DLMS_IGNORE_IP6_SETUP
|
||||
// #define DLMS_IGNORE_MAC_ADDRESS_SETUP
|
||||
// #define DLMS_IGNORE_PPP_SETUP
|
||||
// #define DLMS_IGNORE_GPRS_SETUP
|
||||
// #define DLMS_IGNORE_SMTP_SETUP
|
||||
// #define DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
// #define DLMS_IGNORE_REGISTER_TABLE
|
||||
// #define DLMS_IGNORE_STATUS_MAPPING
|
||||
// #define DLMS_IGNORE_SECURITY_SETUP
|
||||
// #define DLMS_IGNORE_DISCONNECT_CONTROL
|
||||
// #define DLMS_IGNORE_LIMITER
|
||||
#define DLMS_IGNORE_MBUS_CLIENT
|
||||
// #define DLMS_IGNORE_PUSH_SETUP
|
||||
#define DLMS_IGNORE_PARAMETER_MONITOR
|
||||
#define DLMS_IGNORE_WIRELESS_MODE_Q_CHANNEL
|
||||
#define DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
||||
#define DLMS_IGNORE_ZIG_BEE_SAS_STARTUP
|
||||
#define DLMS_IGNORE_ZIG_BEE_SAS_JOIN
|
||||
#define DLMS_IGNORE_ZIG_BEE_SAS_APS_FRAGMENTATION
|
||||
#define DLMS_IGNORE_ZIG_BEE_NETWORK_CONTROL
|
||||
#define DLMS_IGNORE_DATA_PROTECTION
|
||||
// #define DLMS_IGNORE_ACCOUNT
|
||||
// #define DLMS_IGNORE_CREDIT
|
||||
// #define DLMS_IGNORE_CHARGE
|
||||
#define DLMS_IGNORE_TOKEN_GATEWAY
|
||||
#define DLMS_IGNORE_COMPACT_DATA
|
||||
#define DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
#define DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
#define DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
#define DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
#define DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
#define DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
#define DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
#define DLMS_IGNORE_ARBITRATOR
|
||||
#define DLMS_IGNORE_SERIALIZER
|
||||
|
||||
// #define DLMS_IGNORE_FLOAT32
|
||||
// #define DLMS_IGNORE_FLOAT64
|
||||
|
||||
// #define DLMS_ITALIAN_STANDARD
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//Arduino client spesific settings.
|
||||
|
||||
//Use EPOCH time. This can be used to improve memory usage.
|
||||
#define DLMS_USE_EPOCH_TIME
|
||||
#define DLMS_IGNORE_NOTIFY
|
||||
#define DLMS_IGNORE_SERVER
|
||||
#define DLMS_IGNORE_NOTIFY
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //ARDUINO_IGNORE_H
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import re
|
||||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import uart, binary_sensor
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_BAUD_RATE,
|
||||
CONF_RECEIVE_TIMEOUT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
DEFAULTS_BAUD_RATE_SESSION = 9600
|
||||
DEFAULTS_RECEIVE_TIMEOUT = "2000ms"
|
||||
|
||||
CONF_XT211_ID = "xt211_id"
|
||||
CONF_OBIS_CODE = "obis_code"
|
||||
CONF_DONT_PUBLISH = "dont_publish"
|
||||
CONF_CLASS = "class"
|
||||
|
||||
CONF_PUSH_SHOW_LOG = "push_show_log"
|
||||
CONF_PUSH_CUSTOM_PATTERN = "push_custom_pattern"
|
||||
|
||||
|
||||
xt211_ns = cg.esphome_ns.namespace("xt211")
|
||||
XT211 = xt211_ns.class_(
|
||||
"XT211Component", cg.Component, uart.UARTDevice
|
||||
)
|
||||
|
||||
BAUD_RATES = [300, 600, 1200, 2400, 4800, 9600, 19200]
|
||||
|
||||
def obis_code(value):
|
||||
value = cv.string(value)
|
||||
# match = re.match(r"^\d{1,3}-\d{1,3}:\d{1,3}\.\d{1,3}\.\d{1,3}$", value)
|
||||
match = re.match(r"^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\.\d{1,3}\.\d{1,3}$", value)
|
||||
if match is None:
|
||||
raise cv.Invalid(f"{value} is not a valid OBIS code")
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(XT211),
|
||||
cv.Optional(CONF_BAUD_RATE, default=DEFAULTS_BAUD_RATE_SESSION): cv.one_of(
|
||||
*BAUD_RATES
|
||||
),
|
||||
cv.Optional(
|
||||
CONF_RECEIVE_TIMEOUT, default=DEFAULTS_RECEIVE_TIMEOUT
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_PUSH_SHOW_LOG, default=False): cv.boolean,
|
||||
cv.Optional(CONF_PUSH_CUSTOM_PATTERN, default=""): cv.string,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await uart.register_uart_device(var, config)
|
||||
|
||||
cg.add(var.set_baud_rate(config[CONF_BAUD_RATE]))
|
||||
cg.add(var.set_receive_timeout_ms(config[CONF_RECEIVE_TIMEOUT]))
|
||||
|
||||
cg.add(var.set_push_show_log(config[CONF_PUSH_SHOW_LOG]))
|
||||
cg.add(var.set_push_custom_pattern_dsl(config[CONF_PUSH_CUSTOM_PATTERN]))
|
||||
|
||||
cg.add_build_flag("-Wno-error=implicit-function-declaration")
|
||||
# cg.add_library("GuruxDLMS", None, "https://github.com/latonita/GuruxDLMS.c#platformio")
|
||||
# cg.add_library("GuruxDLMS", None, "https://github.com/Gurux/GuruxDLMS.c#platformio")
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef APDU_H
|
||||
#define APDU_H
|
||||
|
||||
#include "dlmssettings.h"
|
||||
#include "bytebuffer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifndef DLMS_IGNORE_CLIENT
|
||||
/**
|
||||
* Generates Aarq.
|
||||
*/
|
||||
int apdu_generateAarq(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data);
|
||||
#endif //DLMS_IGNORE_CLIENT
|
||||
|
||||
/**
|
||||
* Parse APDU.
|
||||
*/
|
||||
int apdu_parsePDU(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* buff,
|
||||
DLMS_ASSOCIATION_RESULT* result,
|
||||
unsigned char* diagnostic,
|
||||
unsigned char* command);
|
||||
|
||||
#ifndef DLMS_IGNORE_SERVER
|
||||
/**
|
||||
* Server generates AARE message.
|
||||
*/
|
||||
int apdu_generateAARE(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data,
|
||||
DLMS_ASSOCIATION_RESULT result,
|
||||
unsigned char diagnostic,
|
||||
gxByteBuffer* errorData,
|
||||
gxByteBuffer* encryptedData,
|
||||
unsigned char command);
|
||||
#endif //DLMS_IGNORE_SERVER
|
||||
|
||||
/**
|
||||
* Generate user information.
|
||||
*
|
||||
* @param settings
|
||||
* DLMS settings
|
||||
* @param cipher
|
||||
* @param data
|
||||
* Generated user information.
|
||||
*/
|
||||
int apdu_generateUserInformation(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data);
|
||||
|
||||
int apdu_getUserInformation(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data,
|
||||
unsigned char command);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //APDU_H
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
# import esphome.codegen as cg
|
||||
# import esphome.config_validation as cv
|
||||
# from esphome.components import binary_sensor
|
||||
# from esphome.const import (
|
||||
# DEVICE_CLASS_CONNECTIVITY,
|
||||
# ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
# )
|
||||
# from . import (
|
||||
# XT211,
|
||||
# xt211_ns,
|
||||
# CONF_XT211_ID,
|
||||
# )
|
||||
#
|
||||
# AUTO_LOAD = ["xt211"]
|
||||
#
|
||||
# CONF_TRANSMISSION = "transmission"
|
||||
# CONF_SESSION = "session"
|
||||
# CONF_CONNECTION = "connection"
|
||||
#
|
||||
# ICON_TRANSMISSION = "mdi:swap-horizontal"
|
||||
# ICON_CONNECTION = "mdi:lan-connect"
|
||||
# ICON_SESSION = "mdi:sync"
|
||||
#
|
||||
# CONFIG_SCHEMA = cv.Schema(
|
||||
# {
|
||||
# cv.GenerateID(CONF_XT211_ID): cv.use_id(XT211),
|
||||
# cv.Optional(CONF_TRANSMISSION): binary_sensor.binary_sensor_schema(
|
||||
# device_class=DEVICE_CLASS_CONNECTIVITY,
|
||||
# entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
# icon=ICON_TRANSMISSION,
|
||||
# ),
|
||||
# cv.Optional(CONF_SESSION): binary_sensor.binary_sensor_schema(
|
||||
# device_class=DEVICE_CLASS_CONNECTIVITY,
|
||||
# entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
# icon=ICON_SESSION,
|
||||
# ),
|
||||
# cv.Optional(CONF_CONNECTION): binary_sensor.binary_sensor_schema(
|
||||
# device_class=DEVICE_CLASS_CONNECTIVITY,
|
||||
# entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
# icon=ICON_CONNECTION,
|
||||
# ),
|
||||
# }
|
||||
# )
|
||||
#
|
||||
# async def to_code(config):
|
||||
# hub = await cg.get_variable(config[CONF_XT211_ID])
|
||||
#
|
||||
# if conf := config.get(CONF_TRANSMISSION):
|
||||
# sensor = await binary_sensor.new_binary_sensor(config[CONF_TRANSMISSION])
|
||||
# cg.add(hub.set_transmission_binary_sensor(sensor))
|
||||
#
|
||||
# if conf := config.get(CONF_SESSION):
|
||||
# sensor = await binary_sensor.new_binary_sensor(config[CONF_SESSION])
|
||||
# cg.add(hub.set_session_binary_sensor(sensor))
|
||||
#
|
||||
# if conf := config.get(CONF_CONNECTION):
|
||||
# sensor = await binary_sensor.new_binary_sensor(config[CONF_CONNECTION])
|
||||
# cg.add(hub.set_connection_binary_sensor(sensor))
|
||||
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from . import (
|
||||
XT211,
|
||||
xt211_ns,
|
||||
obis_code,
|
||||
CONF_XT211_ID,
|
||||
CONF_OBIS_CODE,
|
||||
CONF_DONT_PUBLISH,
|
||||
CONF_CLASS,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ["xt211"]
|
||||
|
||||
XT211BinarySensor = xt211_ns.class_(
|
||||
"XT211BinarySensor", binary_sensor.BinarySensor
|
||||
)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
binary_sensor.binary_sensor_schema(
|
||||
XT211BinarySensor,
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(CONF_XT211_ID): cv.use_id(XT211),
|
||||
cv.Required(CONF_OBIS_CODE): obis_code,
|
||||
cv.Optional(CONF_DONT_PUBLISH, default=False): cv.boolean,
|
||||
cv.Optional(CONF_CLASS, default=1): cv.int_,
|
||||
}
|
||||
),
|
||||
cv.has_exactly_one_key(CONF_OBIS_CODE),
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
component = await cg.get_variable(config[CONF_XT211_ID])
|
||||
var = await binary_sensor.new_binary_sensor(config)
|
||||
cg.add(var.set_obis_code(config[CONF_OBIS_CODE]))
|
||||
cg.add(var.set_dont_publish(config.get(CONF_DONT_PUBLISH)))
|
||||
cg.add(var.set_obis_class(config[CONF_CLASS]))
|
||||
|
||||
cg.add(component.register_sensor(var))
|
||||
|
|
@ -0,0 +1,344 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxmem.h"
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "errorcodes.h"
|
||||
#include "bitarray.h"
|
||||
#include "helpers.h"
|
||||
|
||||
//Returs needed amount of bytes to store bits.
|
||||
uint16_t ba_getByteCount(uint16_t bitCount)
|
||||
{
|
||||
double d = bitCount;
|
||||
if (bitCount != 0)
|
||||
{
|
||||
d /= 8;
|
||||
if (bitCount == 0 || (bitCount % 8) != 0)
|
||||
{
|
||||
++d;
|
||||
}
|
||||
}
|
||||
return (uint16_t)d;
|
||||
}
|
||||
|
||||
//Return byte index where bit is saved.
|
||||
int getByteIndex(int bitCount)
|
||||
{
|
||||
double d = bitCount;
|
||||
d /= 8;
|
||||
return (int)d;
|
||||
}
|
||||
|
||||
//Initialize bit array.
|
||||
void ba_init(bitArray* arr)
|
||||
{
|
||||
arr->capacity = 0;
|
||||
arr->data = NULL;
|
||||
#ifndef GX_DLMS_MICROCONTROLLER
|
||||
arr->position = 0;
|
||||
#endif //GX_DLMS_MICROCONTROLLER
|
||||
arr->size = 0;
|
||||
}
|
||||
|
||||
|
||||
char ba_isAttached(bitArray* arr)
|
||||
{
|
||||
return (arr->capacity & 0x8000) == 0x8000;
|
||||
}
|
||||
|
||||
uint16_t ba_getCapacity(bitArray* arr)
|
||||
{
|
||||
return arr->capacity & 0x7FFF;
|
||||
}
|
||||
|
||||
uint16_t ba_size(bitArray* bb)
|
||||
{
|
||||
return bb != 0 ? bb->size : 0;
|
||||
}
|
||||
|
||||
void ba_attach(
|
||||
bitArray* arr,
|
||||
unsigned char* value,
|
||||
uint16_t count,
|
||||
uint16_t capacity)
|
||||
{
|
||||
arr->data = value;
|
||||
arr->capacity = (uint16_t)(0x8000 | capacity);
|
||||
arr->size = count;
|
||||
#ifndef GX_DLMS_MICROCONTROLLER
|
||||
arr->position = 0;
|
||||
#endif //GX_DLMS_MICROCONTROLLER
|
||||
}
|
||||
|
||||
//Allocate new size for the array in bytes.
|
||||
int ba_capacity(bitArray* arr, uint16_t capacity)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (!ba_isAttached(arr))
|
||||
{
|
||||
arr->capacity = capacity;
|
||||
if (capacity == 0)
|
||||
{
|
||||
if (arr->data != NULL)
|
||||
{
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = (unsigned char*)gxmalloc(ba_getByteCount(arr->capacity));
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef gxrealloc
|
||||
//If compiler supports realloc.
|
||||
unsigned char* tmp = (unsigned char*)gxrealloc(arr->data, ba_getByteCount(arr->capacity));
|
||||
//If not enought memory available.
|
||||
if (tmp == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
arr->data = tmp;
|
||||
#else
|
||||
//If compiler doesn't support realloc.
|
||||
unsigned char* old = arr->data;
|
||||
arr->data = (unsigned char*)gxmalloc(ba_getByteCount(arr->capacity));
|
||||
//If not enought memory available.
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = old;
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(arr->data, old, ba_getByteCount(arr->size));
|
||||
gxfree(old);
|
||||
#endif // gxrealloc
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
if (ba_getCapacity(arr) < capacity)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Push new data to the bit array.
|
||||
int ba_set(bitArray* arr, unsigned char item)
|
||||
{
|
||||
int ret = ba_setByIndex(arr, arr->size, item);
|
||||
if (ret == 0)
|
||||
{
|
||||
++arr->size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Set bit by index.
|
||||
int ba_setByIndex(bitArray* arr, uint16_t index, unsigned char item)
|
||||
{
|
||||
int ret;
|
||||
unsigned char newItem = 0;
|
||||
int byteIndex;
|
||||
item = item == 0 ? 0 : 1;
|
||||
if (!ba_isAttached(arr))
|
||||
{
|
||||
if (index >= arr->capacity)
|
||||
{
|
||||
if ((ret = ba_capacity(arr, arr->capacity + BIT_ARRAY_CAPACITY)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
//If we are adding a bit to the higher than next byte.
|
||||
if (index >= arr->capacity)
|
||||
{
|
||||
return ba_setByIndex(arr, index, item);
|
||||
}
|
||||
newItem = 1;
|
||||
}
|
||||
}
|
||||
if (index >= arr->capacity)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
byteIndex = getByteIndex(index);
|
||||
if (index % 8 == 0 || newItem)
|
||||
{
|
||||
arr->data[byteIndex] = (unsigned char)(item << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
arr->data[byteIndex] |= (item << (7 - (index % 8)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ba_copy(
|
||||
bitArray* target,
|
||||
unsigned char* source,
|
||||
uint16_t count)
|
||||
{
|
||||
int ret = 0;
|
||||
ba_clear(target);
|
||||
if (count != 0)
|
||||
{
|
||||
if ((ret = ba_capacity(target, count)) == 0)
|
||||
{
|
||||
memcpy(target->data, source, ba_getByteCount(count));
|
||||
target->size = count;
|
||||
#ifndef GX_DLMS_MICROCONTROLLER
|
||||
target->position = 0;
|
||||
#endif //GX_DLMS_MICROCONTROLLER
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ba_clear(bitArray* arr)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (!ba_isAttached(arr))
|
||||
{
|
||||
if (arr->data != NULL)
|
||||
{
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
}
|
||||
arr->capacity = 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
arr->size = 0;
|
||||
#ifndef GX_DLMS_MICROCONTROLLER
|
||||
arr->position = 0;
|
||||
#endif //GX_DLMS_MICROCONTROLLER
|
||||
}
|
||||
|
||||
#ifndef GX_DLMS_MICROCONTROLLER
|
||||
int ba_get(bitArray* arr, unsigned char* value)
|
||||
{
|
||||
int ret = ba_getByIndex(arr, arr->position, value);
|
||||
if (ret == 0)
|
||||
{
|
||||
++arr->position;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif //GX_DLMS_MICROCONTROLLER
|
||||
|
||||
int ba_getByIndex(bitArray* arr, int index, unsigned char* value)
|
||||
{
|
||||
char ch;
|
||||
if (index >= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
ch = arr->data[getByteIndex(index)];
|
||||
*value = (ch & (1 << (7 - (index % 8)))) != 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ba_toInteger(bitArray* arr, uint32_t* value)
|
||||
{
|
||||
*value = 0;
|
||||
unsigned char ch;
|
||||
int pos, ret;
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
if ((ret = ba_getByIndex(arr, pos, &ch)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
*value |= ch << pos;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
char* ba_toString(bitArray* arr)
|
||||
{
|
||||
unsigned char ch;
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
int pos, ret;
|
||||
#else
|
||||
int pos;
|
||||
#endif
|
||||
char* buff = (char*)gxmalloc(arr->size + 1);
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
ret = ba_getByIndex(arr, pos, &ch);
|
||||
assert(ret == 0);
|
||||
#else
|
||||
ba_getByIndex(arr, pos, &ch);
|
||||
#endif
|
||||
buff[pos] = ch == 0 ? '0' : '1';
|
||||
}
|
||||
*(buff + arr->size) = 0;
|
||||
return buff;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
int ba_toString2(
|
||||
gxByteBuffer* bb,
|
||||
bitArray* ba)
|
||||
{
|
||||
unsigned char ch;
|
||||
int pos, ret = 0;
|
||||
if ((ret = bb_capacity(bb, bb->size + ba->size)) == 0)
|
||||
{
|
||||
for (pos = 0; pos != ba->size; ++pos)
|
||||
{
|
||||
if ((ret = ba_getByIndex(ba, pos, &ch)) != 0 ||
|
||||
(ret = bb_setInt8(bb, ch == 0 ? '0' : '1')) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef BIT_ARRAY_H
|
||||
#define BIT_ARRAY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxignore.h"
|
||||
#include "bytebuffer.h"
|
||||
|
||||
#define BIT_ARRAY_CAPACITY 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char* data;
|
||||
uint16_t capacity;
|
||||
uint16_t size;
|
||||
#ifndef GX_DLMS_MICROCONTROLLER
|
||||
uint16_t position;
|
||||
#endif //GX_DLMS_MICROCONTROLLER
|
||||
} bitArray;
|
||||
|
||||
//Initialize gxByteBuffer.
|
||||
void ba_init(
|
||||
bitArray* arr);
|
||||
|
||||
//Attach bit array.
|
||||
void ba_attach(
|
||||
bitArray* arr,
|
||||
unsigned char* value,
|
||||
uint16_t count,
|
||||
uint16_t capacity);
|
||||
|
||||
/*
|
||||
* Is static buffer used.
|
||||
*/
|
||||
char ba_isAttached(
|
||||
bitArray* arr);
|
||||
|
||||
//Bit array capacity.
|
||||
uint16_t ba_getCapacity(
|
||||
bitArray* arr);
|
||||
|
||||
/*
|
||||
* Get size.
|
||||
*/
|
||||
uint16_t ba_size(bitArray* bb);
|
||||
|
||||
//How many bytes bit array will take.
|
||||
uint16_t ba_getByteCount(
|
||||
uint16_t bitCount);
|
||||
|
||||
//Allocate new size for the array in bits.
|
||||
int ba_capacity(
|
||||
bitArray* arr,
|
||||
uint16_t capacity);
|
||||
|
||||
//Push new data to the bit array.
|
||||
int ba_set(
|
||||
bitArray* arr,
|
||||
unsigned char item);
|
||||
|
||||
//Push new data to the bit array.
|
||||
int ba_setByIndex(
|
||||
bitArray* arr,
|
||||
uint16_t index,
|
||||
unsigned char item);
|
||||
|
||||
//Copy bit array.
|
||||
int ba_copy(
|
||||
bitArray* target,
|
||||
unsigned char* source,
|
||||
uint16_t count);
|
||||
|
||||
//Clear bit array.
|
||||
void ba_clear(
|
||||
bitArray* arr);
|
||||
|
||||
//Get bit value.
|
||||
int ba_get(
|
||||
bitArray* arr,
|
||||
unsigned char* value);
|
||||
|
||||
//Get bit value by index.
|
||||
int ba_getByIndex(
|
||||
bitArray* arr,
|
||||
int index,
|
||||
unsigned char* value);
|
||||
|
||||
//Convert bit array to integer.
|
||||
int ba_toInteger(
|
||||
bitArray* arr,
|
||||
uint32_t* value);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Get bit array as a string.
|
||||
char* ba_toString(
|
||||
bitArray* arr);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Add bit array as a string.
|
||||
int ba_toString2(
|
||||
gxByteBuffer* bb,
|
||||
bitArray* ba);
|
||||
|
||||
#define BIT_ATTACH(X, V, S) ba_attach(&X, V, S, 8 * sizeof(V)/sizeof(V[0]))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //BYTE_ARRAY_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,541 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef BYTE_BUFFER_H
|
||||
#define BYTE_BUFFER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxint.h"
|
||||
#include "gxignore.h"
|
||||
|
||||
//Arduino DOIT ESP32 uses bb_init. bb_Init is used instead.
|
||||
#ifndef ESP_PLATFORM
|
||||
#define BYTE_BUFFER_INIT bb_init
|
||||
#else
|
||||
#define BYTE_BUFFER_INIT bb_Init
|
||||
#endif //DESP_PLATFORM
|
||||
|
||||
#define VECTOR_CAPACITY 50
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
unsigned char* data;
|
||||
uint32_t capacity;
|
||||
uint32_t size;
|
||||
uint32_t position;
|
||||
#else
|
||||
unsigned char* data;
|
||||
uint16_t capacity;
|
||||
uint16_t size;
|
||||
uint16_t position;
|
||||
#endif
|
||||
} gxByteBuffer;
|
||||
|
||||
/*
|
||||
* Is static buffer used.
|
||||
*/
|
||||
char bb_isAttached(
|
||||
gxByteBuffer* arr);
|
||||
|
||||
/*Get maximum buffer size.*/
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
uint32_t bb_getCapacity(
|
||||
gxByteBuffer* arr);
|
||||
#else
|
||||
uint16_t bb_getCapacity(
|
||||
gxByteBuffer* arr);
|
||||
#endif
|
||||
|
||||
/*Returns amount of the available bytes.*/
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
uint32_t bb_available(gxByteBuffer* arr);
|
||||
#else
|
||||
uint16_t bb_available(gxByteBuffer* arr);
|
||||
#endif
|
||||
/*
|
||||
* Initialize gxByteBuffer.
|
||||
*/
|
||||
int BYTE_BUFFER_INIT(
|
||||
gxByteBuffer* bb);
|
||||
|
||||
/*
|
||||
* Allocate new size for the array in bytes.
|
||||
*/
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_capacity(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t capacity);
|
||||
#else
|
||||
int bb_capacity(
|
||||
gxByteBuffer* bb,
|
||||
uint16_t capacity);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get size.
|
||||
*/
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
uint32_t bb_size(
|
||||
gxByteBuffer* bb);
|
||||
#else
|
||||
uint16_t bb_size(
|
||||
gxByteBuffer* bb);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Fill buffer it with zeros.
|
||||
*/
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_zero(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t index,
|
||||
uint32_t count);
|
||||
#else
|
||||
int bb_zero(
|
||||
gxByteBuffer* bb,
|
||||
uint16_t index,
|
||||
uint16_t count);
|
||||
#endif
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_insertUInt8(
|
||||
gxByteBuffer* arr,
|
||||
uint32_t index,
|
||||
unsigned char item);
|
||||
#else
|
||||
int bb_insertUInt8(
|
||||
gxByteBuffer* arr,
|
||||
uint16_t index,
|
||||
unsigned char item);
|
||||
#endif
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_allocate(
|
||||
gxByteBuffer* arr,
|
||||
uint32_t index,
|
||||
uint32_t dataSize);
|
||||
#else
|
||||
int bb_allocate(
|
||||
gxByteBuffer* arr,
|
||||
uint16_t index,
|
||||
uint16_t dataSize);
|
||||
#endif
|
||||
//Set new data to the gxByteBuffer.
|
||||
int bb_setUInt8(
|
||||
gxByteBuffer* bb,
|
||||
unsigned char item);
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_setUInt8ByIndex(
|
||||
gxByteBuffer* arr,
|
||||
uint32_t index,
|
||||
unsigned char item);
|
||||
#else
|
||||
int bb_setUInt8ByIndex(
|
||||
gxByteBuffer* arr,
|
||||
uint16_t index,
|
||||
unsigned char item);
|
||||
#endif
|
||||
|
||||
int bb_setUInt16(
|
||||
gxByteBuffer* bb,
|
||||
uint16_t item);
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_setUInt16ByIndex(
|
||||
gxByteBuffer* arr,
|
||||
uint32_t index,
|
||||
uint16_t item);
|
||||
#else
|
||||
int bb_setUInt16ByIndex(
|
||||
gxByteBuffer* arr,
|
||||
uint16_t index,
|
||||
uint16_t item);
|
||||
#endif
|
||||
|
||||
int bb_setUInt32(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t item);
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_setUInt32ByIndex(
|
||||
gxByteBuffer* arr,
|
||||
uint32_t index,
|
||||
uint32_t item);
|
||||
#else
|
||||
int bb_setUInt32ByIndex(
|
||||
gxByteBuffer* arr,
|
||||
uint16_t index,
|
||||
uint32_t item);
|
||||
#endif //!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__))
|
||||
|
||||
int bb_setUInt64(
|
||||
gxByteBuffer* bb,
|
||||
uint64_t item);
|
||||
|
||||
#ifndef DLMS_IGNORE_FLOAT32
|
||||
int bb_setFloat(
|
||||
gxByteBuffer* arr,
|
||||
float value);
|
||||
#endif //DLMS_IGNORE_FLOAT32
|
||||
|
||||
#ifndef DLMS_IGNORE_FLOAT64
|
||||
int bb_setDouble(
|
||||
gxByteBuffer* arr,
|
||||
double value);
|
||||
#endif //DLMS_IGNORE_FLOAT64
|
||||
|
||||
int bb_setInt8(
|
||||
gxByteBuffer* bb,
|
||||
char item);
|
||||
|
||||
int bb_setInt16(
|
||||
gxByteBuffer* bb,
|
||||
int16_t item);
|
||||
|
||||
int bb_setInt32(
|
||||
gxByteBuffer* bb,
|
||||
int32_t item);
|
||||
|
||||
int bb_setInt64(
|
||||
gxByteBuffer* bb,
|
||||
int64_t item);
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_insert(
|
||||
const unsigned char* src,
|
||||
uint32_t count,
|
||||
gxByteBuffer* target,
|
||||
uint32_t index);
|
||||
|
||||
#else
|
||||
int bb_insert(
|
||||
const unsigned char* src,
|
||||
uint16_t count,
|
||||
gxByteBuffer* target,
|
||||
uint16_t index);
|
||||
#endif
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_set(
|
||||
gxByteBuffer* bb,
|
||||
const unsigned char* pSource,
|
||||
uint32_t count);
|
||||
#else
|
||||
int bb_set(
|
||||
gxByteBuffer* bb,
|
||||
const unsigned char* pSource,
|
||||
uint16_t count);
|
||||
#endif
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_set2(
|
||||
gxByteBuffer* bb,
|
||||
gxByteBuffer* data,
|
||||
uint32_t index,
|
||||
uint32_t count);
|
||||
#else
|
||||
int bb_set2(
|
||||
gxByteBuffer* bb,
|
||||
gxByteBuffer* data,
|
||||
uint16_t index,
|
||||
uint16_t count);
|
||||
#endif
|
||||
|
||||
int bb_addString(
|
||||
gxByteBuffer* bb,
|
||||
const char* value);
|
||||
|
||||
int bb_attachString(
|
||||
gxByteBuffer* bb,
|
||||
char* value);
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_attach(
|
||||
gxByteBuffer* arr,
|
||||
unsigned char* value,
|
||||
uint32_t count,
|
||||
uint32_t capacity);
|
||||
int bb_attachString2(
|
||||
gxByteBuffer* arr,
|
||||
char* value,
|
||||
uint32_t count,
|
||||
uint32_t capacity);
|
||||
#else
|
||||
int bb_attach(
|
||||
gxByteBuffer* arr,
|
||||
unsigned char* value,
|
||||
uint16_t count,
|
||||
uint16_t capacity);
|
||||
int bb_attachString2(
|
||||
gxByteBuffer* arr,
|
||||
char* value,
|
||||
uint16_t count,
|
||||
uint16_t capacity);
|
||||
#endif
|
||||
//Clean byte buffer and release allocated memory.
|
||||
int bb_clear(
|
||||
gxByteBuffer* bb);
|
||||
|
||||
//Set size and position to zero. Allocated memory is not released.
|
||||
int bb_empty(
|
||||
gxByteBuffer* bb);
|
||||
|
||||
int bb_getUInt8(
|
||||
gxByteBuffer* bb,
|
||||
unsigned char* value);
|
||||
|
||||
int bb_getUInt8ByIndex(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t index,
|
||||
unsigned char* value);
|
||||
|
||||
int bb_getUInt16(
|
||||
gxByteBuffer* bb,
|
||||
uint16_t* value);
|
||||
|
||||
int bb_getUInt24(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t* value);
|
||||
|
||||
int bb_getUInt32(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t* value);
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_get(
|
||||
gxByteBuffer* bb,
|
||||
unsigned char* value,
|
||||
uint32_t count);
|
||||
#else
|
||||
int bb_get(
|
||||
gxByteBuffer* bb,
|
||||
unsigned char* value,
|
||||
uint16_t count);
|
||||
#endif
|
||||
|
||||
int bb_getInt8(
|
||||
gxByteBuffer* arr,
|
||||
signed char* value);
|
||||
|
||||
int bb_getInt16(
|
||||
gxByteBuffer* bb,
|
||||
int16_t* value);
|
||||
|
||||
int bb_getInt32(
|
||||
gxByteBuffer* bb,
|
||||
int32_t* value);
|
||||
|
||||
int bb_getInt64(
|
||||
gxByteBuffer* bb,
|
||||
int64_t* value);
|
||||
|
||||
int bb_getUInt64(
|
||||
gxByteBuffer* bb,
|
||||
uint64_t* value);
|
||||
|
||||
#ifndef DLMS_IGNORE_FLOAT32
|
||||
int bb_getFloat(
|
||||
gxByteBuffer* bb,
|
||||
float* value);
|
||||
#endif //DLMS_IGNORE_FLOAT32
|
||||
|
||||
#ifndef DLMS_IGNORE_FLOAT64
|
||||
int bb_getDouble(
|
||||
gxByteBuffer* bb,
|
||||
double* value);
|
||||
#endif //DLMS_IGNORE_FLOAT64
|
||||
|
||||
int bb_getUInt16ByIndex(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t index,
|
||||
uint16_t* value);
|
||||
|
||||
int bb_getUInt24ByIndex(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t index,
|
||||
uint32_t* value);
|
||||
|
||||
int bb_getUInt32ByIndex(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t index,
|
||||
uint32_t* value);
|
||||
|
||||
int bb_getUInt64ByIndex(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t index,
|
||||
uint64_t* value);
|
||||
|
||||
int bb_getUInt128ByIndex(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t index,
|
||||
unsigned char* value);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Add hex string to byte buffer.
|
||||
int bb_addHexString(
|
||||
gxByteBuffer* arr,
|
||||
const char* str);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Add hex string to byte buffer.
|
||||
int bb_addHexString2(
|
||||
gxByteBuffer* arr,
|
||||
const char* str);
|
||||
|
||||
//Add hex string to byte buffer.
|
||||
int bb_addLogicalName(
|
||||
gxByteBuffer* arr,
|
||||
const unsigned char* str);
|
||||
|
||||
//Get byte array as hex string.
|
||||
int bb_toHexString2(
|
||||
gxByteBuffer* arr,
|
||||
char* buffer,
|
||||
uint16_t size);
|
||||
|
||||
#if !(defined(DLMS_IGNORE_STRING_CONVERTER) || defined(DLMS_IGNORE_MALLOC))
|
||||
//Get byte array as a string.
|
||||
char* bb_toString(
|
||||
gxByteBuffer* bb);
|
||||
|
||||
//Get byte array as hex string.
|
||||
char* bb_toHexString(
|
||||
gxByteBuffer* bb);
|
||||
|
||||
//Add double value to byte array as a string.
|
||||
int bb_addDoubleAsString(
|
||||
gxByteBuffer* ba,
|
||||
double value);
|
||||
#endif //!(defined(DLMS_IGNORE_STRING_CONVERTER) || defined(DLMS_IGNORE_MALLOC))
|
||||
|
||||
//Add integer value to byte array as a string.
|
||||
int bb_addIntAsString(
|
||||
gxByteBuffer* ba,
|
||||
int value);
|
||||
|
||||
//Add integer value to byte array as a string.
|
||||
int bb_addIntAsString2(
|
||||
gxByteBuffer* ba,
|
||||
int value,
|
||||
unsigned char digits);
|
||||
|
||||
/**
|
||||
* Returns data as byte array.
|
||||
*
|
||||
* @param bb Byte buffer as a byte array.
|
||||
*/
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
int bb_subArray(
|
||||
gxByteBuffer* bb,
|
||||
uint32_t index,
|
||||
uint32_t count,
|
||||
gxByteBuffer* target);
|
||||
#else
|
||||
int bb_subArray(
|
||||
gxByteBuffer* bb,
|
||||
uint16_t index,
|
||||
uint16_t count,
|
||||
gxByteBuffer* target);
|
||||
#endif
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
//Move data insize byte array.
|
||||
int bb_move(
|
||||
gxByteBuffer* ba,
|
||||
uint32_t srcPos,
|
||||
uint32_t destPos,
|
||||
uint32_t count);
|
||||
#else
|
||||
//Move data insize byte array.
|
||||
int bb_move(
|
||||
gxByteBuffer* ba,
|
||||
uint16_t srcPos,
|
||||
uint16_t destPos,
|
||||
uint16_t count);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Remove handled bytes. This can be used in debugging to remove handled
|
||||
* bytes.
|
||||
*/
|
||||
int bb_trim(
|
||||
gxByteBuffer* bb);
|
||||
|
||||
/**
|
||||
* Compares, whether two given arrays are similar starting from current
|
||||
* position.
|
||||
*
|
||||
* @param bb
|
||||
* Bytebuffer to compare.
|
||||
* @param arr
|
||||
* Array to compare.
|
||||
* @param length
|
||||
* Array length.
|
||||
* @return True, if arrays are similar. False, if the arrays differ.
|
||||
*/
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
unsigned char bb_compare(
|
||||
gxByteBuffer* bb,
|
||||
unsigned char* buff,
|
||||
uint32_t length);
|
||||
#else
|
||||
unsigned char bb_compare(
|
||||
gxByteBuffer* bb,
|
||||
unsigned char* buff,
|
||||
uint16_t length);
|
||||
#endif
|
||||
|
||||
//Find index of given char.
|
||||
uint32_t bb_indexOf(
|
||||
gxByteBuffer* bb,
|
||||
char ch);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
//Print content of byte buffer to cout.
|
||||
int bb_print(gxByteBuffer* bb);
|
||||
#endif //defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
|
||||
#define BB_ATTACH(X, V, S) bb_attach(&X, V, S, sizeof(V))
|
||||
|
||||
#define BB_ATTACH_STR(X, V, S) bb_attachString2(&X, V, S, sizeof(V))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //BYTE_BUFFER_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,177 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef CHIPPERING_H
|
||||
#define CHIPPERING_H
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_HIGH_GMAC
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "bytebuffer.h"
|
||||
#include "enums.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Used security.
|
||||
*/
|
||||
DLMS_SECURITY security;
|
||||
DLMS_SECURITY_SUITE suite;
|
||||
|
||||
/**
|
||||
* Is data encrypted.
|
||||
*/
|
||||
unsigned char encrypt;
|
||||
|
||||
/**
|
||||
* Block cipher key.
|
||||
*/
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer blockCipherKey;
|
||||
#else
|
||||
unsigned char blockCipherKey[32];
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
/**
|
||||
* Broadcast block cipher key.
|
||||
*/
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer broadcastBlockCipherKey;
|
||||
#else
|
||||
unsigned char broadcastBlockCipherKey[32];
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
/**
|
||||
* System title.
|
||||
*/
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer systemTitle;
|
||||
#else
|
||||
unsigned char systemTitle[8];
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
/**
|
||||
* Invocation (Frame) counter.
|
||||
*/
|
||||
uint32_t invocationCounter;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer authenticationKey;
|
||||
#else
|
||||
unsigned char authenticationKey[32];
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Dedicated key.
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer* dedicatedKey;
|
||||
#else
|
||||
unsigned char dedicatedKey[32];
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
//Is data send as a broadcast or unicast.
|
||||
unsigned char broacast;
|
||||
} ciphering;
|
||||
|
||||
|
||||
void cip_init(ciphering* target);
|
||||
void cip_clear(ciphering* target);
|
||||
/**
|
||||
* Encrypt data.
|
||||
*/
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int cip_encrypt(
|
||||
ciphering* settings,
|
||||
DLMS_SECURITY security,
|
||||
DLMS_COUNT_TYPE type,
|
||||
uint32_t frameCounter,
|
||||
unsigned char tag,
|
||||
unsigned char* systemTitle,
|
||||
gxByteBuffer* key,
|
||||
gxByteBuffer* input);
|
||||
#else
|
||||
int cip_encrypt(
|
||||
ciphering* settings,
|
||||
DLMS_SECURITY security,
|
||||
DLMS_COUNT_TYPE type,
|
||||
uint32_t frameCounter,
|
||||
unsigned char tag,
|
||||
unsigned char* systemTitle,
|
||||
unsigned char* key,
|
||||
gxByteBuffer* input);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
/**
|
||||
* Decrypt data.
|
||||
*/
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int cip_decrypt(
|
||||
ciphering* settings,
|
||||
unsigned char* title,
|
||||
gxByteBuffer* key,
|
||||
gxByteBuffer* data,
|
||||
DLMS_SECURITY* security,
|
||||
DLMS_SECURITY_SUITE* suite,
|
||||
uint64_t* invocationCounter);
|
||||
#else
|
||||
int cip_decrypt(
|
||||
ciphering* settings,
|
||||
unsigned char* title,
|
||||
unsigned char* key,
|
||||
gxByteBuffer* data,
|
||||
DLMS_SECURITY* security,
|
||||
DLMS_SECURITY_SUITE* suite,
|
||||
uint64_t* invocationCounter);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
// Encrypt data using AES RFC3394.
|
||||
int cip_encryptKey(
|
||||
unsigned char* kek,
|
||||
//KEK size.
|
||||
unsigned char size,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* output);
|
||||
|
||||
// Decrypt data using AES RFC3394.
|
||||
//Returns DLMS_ERROR_CODE_FALSE if data is not encrypted with the key.
|
||||
int cip_decryptKey(
|
||||
unsigned char* kek,
|
||||
//KEK size.
|
||||
unsigned char size,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DLMS_IGNORE_HIGH_GMAC
|
||||
#endif //CHIPPERING_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,446 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxignore.h"
|
||||
#if !(defined(DLMS_IGNORE_CLIENT) && defined(DLMS_IGNORE_MALLOC))
|
||||
#ifdef DLMS_DEBUG
|
||||
#include "serverevents.h"
|
||||
#endif //DLMS_DEBUG
|
||||
|
||||
#include "dlms.h"
|
||||
|
||||
int cl_getData(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* reply,
|
||||
gxReplyData* data);
|
||||
|
||||
int cl_getData2(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* reply,
|
||||
gxReplyData* data,
|
||||
gxReplyData* notify,
|
||||
unsigned char* isNotify);
|
||||
|
||||
// Get size of the frame.
|
||||
// size: Size of received bytes on the frame.
|
||||
// Returns: Zero if succeeded, or rccurred error code.
|
||||
int cl_getFrameSize(dlmsSettings* settings, gxByteBuffer* data, uint32_t* size);
|
||||
|
||||
#ifndef DLMS_IGNORE_HDLC
|
||||
int cl_snrmRequest(
|
||||
dlmsSettings* settings,
|
||||
message* messages);
|
||||
|
||||
int cl_parseUAResponse(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data);
|
||||
|
||||
// Returns the number of bytes to read before the frame is complete.
|
||||
// When WRAPPER is used this method can be used to check how many bytes we need to read.
|
||||
// data: Received data.
|
||||
// size: Size of received bytes on the frame.
|
||||
// Returns: Zero if succeeded, or rccurred error code.
|
||||
int cl_getRemainingFrameSize(dlmsSettings* settings, gxByteBuffer* data, uint32_t* size);
|
||||
#endif //DLMS_IGNORE_HDLC
|
||||
|
||||
int cl_aarqRequest(
|
||||
dlmsSettings* settings,
|
||||
message* messages);
|
||||
|
||||
int cl_parseAAREResponse(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data);
|
||||
|
||||
int cl_getApplicationAssociationRequest(
|
||||
dlmsSettings* settings,
|
||||
message* messages);
|
||||
|
||||
int cl_parseApplicationAssociationResponse(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
/*Read association view. Association view is not available if malloc is not used.*/
|
||||
int cl_getObjectsRequest(
|
||||
dlmsSettings* settings,
|
||||
message* messages);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
/*Parse association view. Association view is not available if malloc is not used.*/
|
||||
int cl_parseObjects(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Get objects count in association view.
|
||||
int cl_parseObjectCount(
|
||||
gxByteBuffer* data,
|
||||
uint16_t* count);
|
||||
|
||||
/*Parse next association view object.
|
||||
This method can be used when malloc is not used or there is a limited amount of the memory in use.*/
|
||||
int cl_parseNextObject(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data,
|
||||
gxObject* object);
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
int cl_readSN(
|
||||
dlmsSettings* settings,
|
||||
uint16_t address,
|
||||
unsigned char attributeOrdinal,
|
||||
gxByteBuffer* data,
|
||||
message* messages);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
int cl_readLN(
|
||||
dlmsSettings* settings,
|
||||
const unsigned char* name,
|
||||
DLMS_OBJECT_TYPE interfaceClass,
|
||||
unsigned char attributeOrdinal,
|
||||
gxByteBuffer* data,
|
||||
message* messages);
|
||||
|
||||
/*This method is used to read list of objects.*/
|
||||
int cl_readList(
|
||||
dlmsSettings* settings,
|
||||
gxArray* list,
|
||||
message* messages);
|
||||
|
||||
int cl_read(
|
||||
dlmsSettings* settings,
|
||||
gxObject* object,
|
||||
unsigned char attributeOrdinal,
|
||||
message* messages);
|
||||
|
||||
int cl_getKeepAlive(
|
||||
dlmsSettings* settings,
|
||||
message* messages);
|
||||
|
||||
#ifndef DLMS_IGNORE_PROFILE_GENERIC
|
||||
int cl_readRowsByEntry(
|
||||
dlmsSettings* settings,
|
||||
gxProfileGeneric* object,
|
||||
uint32_t index,
|
||||
uint32_t count,
|
||||
message* messages);
|
||||
|
||||
int cl_readRowsByEntry2(
|
||||
dlmsSettings* settings,
|
||||
gxProfileGeneric* object,
|
||||
uint32_t index,
|
||||
uint32_t count,
|
||||
uint16_t colStart,
|
||||
uint16_t colEnd,
|
||||
message* messages);
|
||||
|
||||
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
int cl_readRowsByRange(
|
||||
dlmsSettings* settings,
|
||||
gxProfileGeneric* object,
|
||||
uint32_t start,
|
||||
uint32_t end,
|
||||
message* messages);
|
||||
#else
|
||||
int cl_readRowsByRange(
|
||||
dlmsSettings* settings,
|
||||
gxProfileGeneric* object,
|
||||
struct tm* start,
|
||||
struct tm* end,
|
||||
message* messages);
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//Read profile generic using start and end times.
|
||||
int cl_readRowsByRange2(
|
||||
dlmsSettings* settings,
|
||||
gxProfileGeneric* object,
|
||||
gxtime* start,
|
||||
gxtime* end,
|
||||
message* messages);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//Read profile generic using Indonesia standard.
|
||||
#ifdef DLMS_INDONESIA_STANDARD
|
||||
int cl_readRowsByRange3(
|
||||
dlmsSettings* settings,
|
||||
gxProfileGeneric* object,
|
||||
gxtime* start,
|
||||
gxtime* end,
|
||||
unsigned char startRegister,
|
||||
unsigned char numberOfRegisters,
|
||||
message* messages)
|
||||
#endif //DLMS_INDONESIA_STANDARD
|
||||
|
||||
#endif //DLMS_IGNORE_PROFILE_GENERIC
|
||||
|
||||
/*This method is used to write object.*/
|
||||
int cl_write(
|
||||
dlmsSettings* settings,
|
||||
gxObject* object,
|
||||
unsigned char index,
|
||||
message* messages);
|
||||
|
||||
/*This method is used to write list of objects.*/
|
||||
int cl_writeList(
|
||||
dlmsSettings* settings,
|
||||
gxArray* list,
|
||||
message* messages);
|
||||
|
||||
int cl_writeLN(
|
||||
dlmsSettings* settings,
|
||||
const unsigned char* name,
|
||||
DLMS_OBJECT_TYPE interfaceClass,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* data,
|
||||
unsigned char byteArray,
|
||||
message* messages);
|
||||
|
||||
int cl_writeSN(
|
||||
dlmsSettings* settings,
|
||||
uint16_t address,
|
||||
int index,
|
||||
dlmsVARIANT* data,
|
||||
message* messages);
|
||||
|
||||
int cl_changeType(
|
||||
gxByteBuffer* value,
|
||||
DLMS_DATA_TYPE type,
|
||||
dlmsVARIANT* newValue);
|
||||
|
||||
int cl_updateValue(
|
||||
dlmsSettings* settings,
|
||||
gxObject* object,
|
||||
unsigned char attributeOrdinal,
|
||||
dlmsVARIANT* value);
|
||||
|
||||
/**
|
||||
* Update list of values.
|
||||
*
|
||||
* @param list
|
||||
* read objects.
|
||||
* @param data
|
||||
* Received reply from the meter.
|
||||
*/
|
||||
int cl_updateValues(
|
||||
dlmsSettings* settings,
|
||||
gxArray* list,
|
||||
gxByteBuffer* data);
|
||||
|
||||
int cl_receiverReady(
|
||||
dlmsSettings* settings,
|
||||
DLMS_DATA_REQUEST_TYPES type,
|
||||
gxByteBuffer* message);
|
||||
|
||||
|
||||
/**
|
||||
* Generates a release request.
|
||||
*
|
||||
* @return Release request, as byte array.
|
||||
*/
|
||||
int cl_releaseRequest(
|
||||
dlmsSettings* settings,
|
||||
message* packets);
|
||||
|
||||
/**
|
||||
* Generates a release request.
|
||||
*
|
||||
* @return Release request, as byte array.
|
||||
*/
|
||||
int cl_releaseRequest2(
|
||||
dlmsSettings* settings,
|
||||
message* packets,
|
||||
unsigned char useProtectedRelease);
|
||||
|
||||
|
||||
int cl_disconnectRequest(
|
||||
dlmsSettings* settings,
|
||||
message* messages);
|
||||
|
||||
/**
|
||||
* Generate Method (Action) request.
|
||||
*
|
||||
* @param object
|
||||
* Method object.
|
||||
* @param index
|
||||
* Method index.
|
||||
* @param data
|
||||
* Method data.
|
||||
* @param messages DLMS action messages.
|
||||
*/
|
||||
int cl_method(
|
||||
dlmsSettings* settings,
|
||||
gxObject* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* data,
|
||||
message* messages);
|
||||
|
||||
/**
|
||||
* Generate Method (Action) request.
|
||||
*
|
||||
* @param object
|
||||
* Method object.
|
||||
* @param index
|
||||
* Method index.
|
||||
* @param data
|
||||
* Method data.
|
||||
* @param bytearray
|
||||
* Is data bytearray.
|
||||
* @param messages DLMS action messages.
|
||||
*/
|
||||
int cl_method2(
|
||||
dlmsSettings* settings,
|
||||
gxObject* object,
|
||||
unsigned char index,
|
||||
unsigned char* value,
|
||||
uint32_t length,
|
||||
message* messages);
|
||||
|
||||
/**
|
||||
* Generate Method (Action) request..
|
||||
*
|
||||
* @param name
|
||||
* Method object short name or Logical Name.
|
||||
* @param objectType
|
||||
* Object type.
|
||||
* @param index
|
||||
* Method index.
|
||||
* @param value
|
||||
* Method data.
|
||||
* @param dataType
|
||||
* Data type.
|
||||
* @return DLMS action message.
|
||||
*/
|
||||
int cl_methodLN(
|
||||
dlmsSettings* settings,
|
||||
const unsigned char* name,
|
||||
DLMS_OBJECT_TYPE objectType,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* data,
|
||||
message* messages);
|
||||
|
||||
/**
|
||||
* Generate Method (Action) request..
|
||||
*
|
||||
* @param name
|
||||
* Method object short name or Logical Name.
|
||||
* @param objectType
|
||||
* Object type.
|
||||
* @param index
|
||||
* Method index.
|
||||
* @param value
|
||||
* byte array.
|
||||
* @param length
|
||||
* Length of byte array.
|
||||
* @return DLMS action message.
|
||||
*/
|
||||
int cl_methodLN2(
|
||||
dlmsSettings* settings,
|
||||
unsigned char* name,
|
||||
DLMS_OBJECT_TYPE objectType,
|
||||
unsigned char index,
|
||||
unsigned char* value,
|
||||
uint32_t length,
|
||||
message* messages);
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
/**
|
||||
* Generate Method (Action) request.
|
||||
*
|
||||
* @param name
|
||||
* Method object short name or Logical Name.
|
||||
* @param objectType
|
||||
* Object type.
|
||||
* @param index
|
||||
* Method index.
|
||||
* @param value
|
||||
* Method data.
|
||||
* @param dataType
|
||||
* Data type.
|
||||
* @return DLMS action message.
|
||||
*/
|
||||
int cl_methodSN(
|
||||
dlmsSettings* settings,
|
||||
uint16_t address,
|
||||
DLMS_OBJECT_TYPE objectType,
|
||||
int index,
|
||||
dlmsVARIANT* data,
|
||||
message* messages);
|
||||
|
||||
|
||||
/**
|
||||
* Generate Method (Action) request.
|
||||
*
|
||||
* @param name
|
||||
* Method object short name or Logical Name.
|
||||
* @param objectType
|
||||
* Object type.
|
||||
* @param index
|
||||
* Method index.
|
||||
* @param value
|
||||
* byte array.
|
||||
* @param lenght
|
||||
* Length of the byte array.
|
||||
* @return DLMS action message.
|
||||
*/
|
||||
int cl_methodSN2(
|
||||
dlmsSettings* settings,
|
||||
uint16_t address,
|
||||
DLMS_OBJECT_TYPE objectType,
|
||||
int index,
|
||||
unsigned char* value,
|
||||
uint32_t length,
|
||||
message* messages);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Convert physical address and logical address to server address.
|
||||
// logicalAddress: Server logical address.
|
||||
// physicalAddress: Server physical address.
|
||||
// addressSize: Address size in bytes.
|
||||
// Returns Server address.
|
||||
uint16_t cl_getServerAddress(
|
||||
uint16_t logicalAddress,
|
||||
uint16_t physicalAddress,
|
||||
unsigned char addressSize);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //!defined(DLMS_IGNORE_CLIENT) && !defined(DLMS_IGNORE_MALLOC)
|
||||
#endif //CLIENT_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef CONVERTERRS_H
|
||||
#define CONVERTERRS_H
|
||||
#include "gxignore.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
#include "errorcodes.h"
|
||||
#include "variant.h"
|
||||
#include "gxarray.h"
|
||||
#include "gxobjects.h"
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#include "enums.h"
|
||||
|
||||
//Get object type as string.
|
||||
int obj_typeToString(
|
||||
DLMS_OBJECT_TYPE type,
|
||||
char* buff);
|
||||
|
||||
//Get object type as string.
|
||||
const char* obj_typeToString2(
|
||||
DLMS_OBJECT_TYPE type);
|
||||
|
||||
//Get object type as string.
|
||||
const char* obj_typeToString2(
|
||||
DLMS_OBJECT_TYPE type);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
#ifndef DLMS_IGNORE_STRING_CONVERTER
|
||||
|
||||
const char* obj_getUnitAsString(
|
||||
unsigned char unit);
|
||||
|
||||
int obj_rowsToString(
|
||||
gxByteBuffer* ba,
|
||||
gxArray* buffer);
|
||||
|
||||
//Convert object's attributes to string.
|
||||
//This can be used in debugging purposes.
|
||||
int obj_toString(
|
||||
gxObject* object,
|
||||
char** buff);
|
||||
#endif //DLMS_IGNORE_STRING_CONVERTER
|
||||
const char* err_toString(int err);
|
||||
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //CONVERTERRS_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,229 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef COSEM_H
|
||||
#define COSEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxobjects.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int cosem_createObject(
|
||||
DLMS_OBJECT_TYPE type,
|
||||
gxObject** object);
|
||||
|
||||
int cosem_createObject2(
|
||||
DLMS_OBJECT_TYPE type,
|
||||
const char* ln,
|
||||
gxObject** object);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
int cosem_setLogicalName(
|
||||
gxObject* object,
|
||||
const unsigned char* value);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int cosem_init(
|
||||
gxObject* object,
|
||||
DLMS_OBJECT_TYPE type,
|
||||
const char* logicalNameString);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
int cosem_init2(
|
||||
gxObject* object,
|
||||
DLMS_OBJECT_TYPE type,
|
||||
const unsigned char* ln);
|
||||
|
||||
//This initialize method will also check the size of the object type and compare it with the expected size.
|
||||
int cosem_init3(
|
||||
gxObject* object,
|
||||
const uint16_t expectedSize,
|
||||
DLMS_OBJECT_TYPE type,
|
||||
const unsigned char* ln);
|
||||
|
||||
//This initialize method will also check the size of the object type and compare it with the expected size.
|
||||
int cosem_init4(
|
||||
void* object,
|
||||
const uint16_t expectedSize,
|
||||
DLMS_OBJECT_TYPE type,
|
||||
const unsigned char* ln);
|
||||
|
||||
int cosem_checkStructure(gxByteBuffer* bb, uint16_t expectedItemCount);
|
||||
|
||||
int cosem_getStructure(gxByteBuffer* bb, uint16_t* count);
|
||||
|
||||
int cosem_checkArray(gxByteBuffer* bb, uint16_t* count);
|
||||
|
||||
int cosem_checkArray2(gxByteBuffer* bb, uint16_t* count, unsigned char checkDataType);
|
||||
|
||||
int cosem_getUInt8(gxByteBuffer* bb, unsigned char* value);
|
||||
|
||||
int cosem_getUInt16(gxByteBuffer* bb, uint16_t* value);
|
||||
|
||||
int cosem_getUInt32(gxByteBuffer* bb, uint32_t* value);
|
||||
|
||||
int cosem_getInt8(gxByteBuffer* bb, signed char* value);
|
||||
|
||||
int cosem_getInt16(gxByteBuffer* bb, int16_t* value);
|
||||
|
||||
int cosem_getInt32(gxByteBuffer* bb, int32_t* value);
|
||||
|
||||
int cosem_getOctetString(gxByteBuffer* bb, gxByteBuffer* value);
|
||||
|
||||
|
||||
int cosem_getString(gxByteBuffer* bb, gxByteBuffer* value);
|
||||
|
||||
int cosem_getOctetString2(gxByteBuffer* bb, unsigned char* value, uint16_t capacity, uint16_t* size);
|
||||
|
||||
int cosem_getOctetString3(gxByteBuffer* bb, gxByteBuffer* value, unsigned char exact);
|
||||
|
||||
int cosem_getString2(gxByteBuffer* bb, char* value, uint16_t capacity);
|
||||
|
||||
//Get date-time value from the octet-string.
|
||||
int cosem_getDateTimeFromOctetString(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
//Get date-time value from the octet-string.
|
||||
int cosem_getDateFromOctetString(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
//Get date-time value from the octet-string.
|
||||
int cosem_getTimeFromOctetString(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
//Get date-time value from the octet-string.
|
||||
int cosem_getDateTimeFromOctetString2(gxByteBuffer* bb, gxtime* value, unsigned char checkDataType);
|
||||
|
||||
//Get date-time value from the octet-string.
|
||||
int cosem_getDateFromOctetString2(gxByteBuffer* bb, gxtime* value, unsigned char checkDataType);
|
||||
|
||||
//Get date-time value from the octet-string.
|
||||
int cosem_getTimeFromOctetString2(gxByteBuffer* bb, gxtime* value, unsigned char checkDataType);
|
||||
|
||||
//Get date-time value from the byte array.
|
||||
int cosem_getDateTime(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
//Get date value from the byte array.
|
||||
int cosem_getDate(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
//Get time value from the byte array.
|
||||
int cosem_getTime(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
//Get date-time value from the byte array.
|
||||
int cosem_getDateTime2(gxByteBuffer* bb, gxtime* value, unsigned char checkDataType);
|
||||
|
||||
//Get date value from the byte array.
|
||||
int cosem_getDate2(gxByteBuffer* bb, gxtime* value, unsigned char checkDataType);
|
||||
|
||||
//Get time value from the byte array.
|
||||
int cosem_getTime2(gxByteBuffer* bb, gxtime* value, unsigned char checkDataType);
|
||||
|
||||
//Get get bit string from the byte array.
|
||||
int cosem_getBitString(gxByteBuffer* bb, bitArray* value);
|
||||
//Get get bit string from the byte array.
|
||||
int cosem_getBitString2(gxByteBuffer* bb, unsigned char* value, uint16_t capacity, uint16_t* size);
|
||||
|
||||
//Get integer value from bit string.
|
||||
int cosem_getIntegerFromBitString(gxByteBuffer* bb, uint32_t* value);
|
||||
|
||||
int cosem_getVariant(gxByteBuffer* bb, dlmsVARIANT* value);
|
||||
|
||||
int cosem_getEnum(gxByteBuffer* bb, unsigned char* value);
|
||||
|
||||
int cosem_getBoolean(gxByteBuffer* bb, unsigned char* value);
|
||||
|
||||
int cosem_getUtf8String(gxByteBuffer* bb, gxByteBuffer* value);
|
||||
|
||||
int cosem_getUtf8String2(gxByteBuffer* bb, char* value, uint16_t capacity, uint16_t* size);
|
||||
|
||||
int cosem_setDateTimeAsOctetString(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
int cosem_setDateAsOctetString(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
int cosem_setBitString(gxByteBuffer* bb, uint32_t value, uint16_t count);
|
||||
|
||||
int cosem_setTimeAsOctetString(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
int cosem_setDateTime(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
int cosem_setDate(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
int cosem_setTime(gxByteBuffer* bb, gxtime* value);
|
||||
|
||||
int cosem_setOctetString(gxByteBuffer* bb, gxByteBuffer* value);
|
||||
|
||||
int cosem_setString(gxByteBuffer* bb, const char* value, uint16_t len);
|
||||
|
||||
int cosem_setString2(gxByteBuffer* bb, gxByteBuffer* value);
|
||||
|
||||
int cosem_setOctetString2(
|
||||
gxByteBuffer* bb,
|
||||
const unsigned char* value,
|
||||
uint16_t size);
|
||||
|
||||
int cosem_setUInt8(gxByteBuffer* bb, unsigned char value);
|
||||
int cosem_setUInt16(gxByteBuffer* bb, uint16_t value);
|
||||
int cosem_setUInt32(gxByteBuffer* bb, uint32_t value);
|
||||
int cosem_setUInt64(gxByteBuffer* bb, uint64_t* value);
|
||||
|
||||
int cosem_setInt8(gxByteBuffer* bb, char value);
|
||||
int cosem_setInt16(gxByteBuffer* bb, int16_t value);
|
||||
int cosem_setInt32(gxByteBuffer* bb, int32_t value);
|
||||
int cosem_setInt64(gxByteBuffer* bb, int64_t* value);
|
||||
int cosem_setVariant(gxByteBuffer* bb, dlmsVARIANT* value);
|
||||
|
||||
int cosem_setStructure(gxByteBuffer* bb, uint16_t count);
|
||||
int cosem_setArray(gxByteBuffer* bb, uint16_t count);
|
||||
int cosem_setEnum(gxByteBuffer* bb, unsigned char value);
|
||||
int cosem_setBoolean(gxByteBuffer* bb, unsigned char value);
|
||||
|
||||
#ifndef DLMS_IGNORE_PROFILE_GENERIC
|
||||
int cosem_getColumns(
|
||||
gxArray* captureObjects,
|
||||
unsigned char selector,
|
||||
dlmsVARIANT* parameters,
|
||||
gxArray* columns);
|
||||
#endif //DLMS_IGNORE_PROFILE_GENERIC
|
||||
|
||||
//Find object from settings object and create if not found.
|
||||
int cosem_findObjectByLN(
|
||||
dlmsSettings* settings,
|
||||
DLMS_OBJECT_TYPE ot,
|
||||
const unsigned char* ln,
|
||||
gxObject** object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //COSEM_H
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef CRC_H
|
||||
#define CRC_H
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_HDLC
|
||||
#if defined(USE_AVR) || defined(ARDUINO_ARCH_AVR)
|
||||
//If AVR is used.
|
||||
#include <avr/pgmspace.h>
|
||||
#endif //#if defined(USE_AVR) || defined(ARDUINO_ARCH_AVR)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
//CRC table.
|
||||
#ifndef USE_PROGMEM
|
||||
static const uint16_t FCS16Table[] = {
|
||||
#else
|
||||
const uint16_t FCS16Table[] PROGMEM = {
|
||||
#endif //USE_PROGMEM
|
||||
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
|
||||
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
|
||||
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
|
||||
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
|
||||
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
|
||||
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
|
||||
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
|
||||
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
|
||||
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
|
||||
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
|
||||
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
|
||||
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
|
||||
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
|
||||
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
|
||||
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
|
||||
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
|
||||
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
|
||||
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
|
||||
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
|
||||
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
|
||||
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
|
||||
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
|
||||
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
|
||||
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
|
||||
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
|
||||
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
|
||||
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
|
||||
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
|
||||
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
|
||||
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
|
||||
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
|
||||
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
|
||||
};
|
||||
|
||||
static uint16_t countCRC(gxByteBuffer* Buff, uint32_t index, uint32_t count)
|
||||
{
|
||||
uint16_t tmp;
|
||||
uint16_t FCS16 = 0xFFFF;
|
||||
uint16_t pos;
|
||||
for (pos = 0; pos < count; ++pos)
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
//If Arduino is used data is read from flash like this.
|
||||
tmp = (FCS16 ^ Buff->data[index + pos]) & 0xFF;
|
||||
FCS16 = (FCS16 >> 8) ^ pgm_read_word_near(FCS16Table + tmp);
|
||||
#else
|
||||
FCS16 = (FCS16 >> 8) ^ FCS16Table[(FCS16 ^ ((unsigned char*)Buff->data)[index + pos]) & 0xFF];
|
||||
#endif //ARDUINO_ARCH_AVR
|
||||
}
|
||||
FCS16 = ~FCS16;
|
||||
//CRC is in big endian byte order.
|
||||
tmp = FCS16;
|
||||
FCS16 = tmp >> 8;
|
||||
FCS16 |= tmp << 8;
|
||||
return FCS16;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DLMS_IGNORE_HDLC
|
||||
#endif //CRC_H
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "datainfo.h"
|
||||
|
||||
void di_init(gxDataInfo *info)
|
||||
{
|
||||
info->index = 0;
|
||||
info->count = 0;
|
||||
info->type = DLMS_DATA_TYPE_NONE;
|
||||
info->complete = 1;
|
||||
#ifdef DLMS_ITALIAN_STANDARD
|
||||
//Some meters require that there is a array count in data.
|
||||
info->appendAA = 0;
|
||||
#endif //DLMS_ITALIAN_STANDARD
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef GXDATA_INFO_H
|
||||
#define GXDATA_INFO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxint.h"
|
||||
#include "enums.h"
|
||||
#include "gxignore.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Last array index.
|
||||
uint16_t index;
|
||||
|
||||
// Items count in array.
|
||||
uint16_t count;
|
||||
// Object data type.
|
||||
DLMS_DATA_TYPE type;
|
||||
// Is data parsed to the end.
|
||||
unsigned char complete;
|
||||
#ifdef DLMS_ITALIAN_STANDARD
|
||||
//Some meters require that there is a array count in data.
|
||||
unsigned char appendAA;
|
||||
#endif //DLMS_ITALIAN_STANDARD
|
||||
} gxDataInfo;
|
||||
|
||||
void di_init(gxDataInfo *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXDATA_INFO_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,380 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef DATE_H
|
||||
#define DATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "enums.h"
|
||||
|
||||
#include "bytebuffer.h"
|
||||
|
||||
#ifndef DLMS_USE_EPOCH_TIME
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifndef DLMS_USE_EPOCH_TIME
|
||||
//Get UTC offset in minutes.
|
||||
void time_getUtcOffset(short* hours, short* minutes);
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
|
||||
// DataType enumerates skipped fields from date time.
|
||||
typedef enum
|
||||
{
|
||||
// Nothing is skipped from date time.
|
||||
DATETIME_SKIPS_NONE = 0x0,
|
||||
// Year part of date time is skipped.
|
||||
DATETIME_SKIPS_YEAR = 0x1,
|
||||
// Month part of date time is skipped.
|
||||
DATETIME_SKIPS_MONTH = 0x2,
|
||||
// Day part is skipped.
|
||||
DATETIME_SKIPS_DAY = 0x4,
|
||||
// Day of week part of date time is skipped.
|
||||
DATETIME_SKIPS_DAYOFWEEK = 0x8,
|
||||
// Hours part of date time is skipped.
|
||||
DATETIME_SKIPS_HOUR = 0x10,
|
||||
// Minute part of date time is skipped.
|
||||
DATETIME_SKIPS_MINUTE = 0x20,
|
||||
// Seconds part of date time is skipped.
|
||||
DATETIME_SKIPS_SECOND = 0x40,
|
||||
// Hundreds of seconds part of date time is skipped.
|
||||
DATETIME_SKIPS_MS = 0x80,
|
||||
//Devitation is skipped.
|
||||
DATETIME_SKIPS_DEVITATION = 0x100,
|
||||
//Status is skipped.
|
||||
DATETIME_SKIPS_STATUS = 0x200
|
||||
} DATETIME_SKIPS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t value;
|
||||
#else
|
||||
struct tm value;
|
||||
#endif
|
||||
int16_t deviation;
|
||||
DATETIME_SKIPS skip : 16;
|
||||
DLMS_DATE_TIME_EXTRA_INFO extraInfo : 8;
|
||||
DLMS_CLOCK_STATUS status : 8;
|
||||
} gxtime;
|
||||
|
||||
// Constructor.
|
||||
void time_init(
|
||||
gxtime* time,
|
||||
uint16_t year,
|
||||
unsigned char month,
|
||||
unsigned char day,
|
||||
unsigned char hour,
|
||||
unsigned char minute,
|
||||
unsigned char second,
|
||||
uint16_t millisecond,
|
||||
int16_t devitation);
|
||||
|
||||
#ifndef DLMS_USE_EPOCH_TIME
|
||||
void time_init2(
|
||||
gxtime* time,
|
||||
struct tm* value);
|
||||
|
||||
// Constructor.
|
||||
void time_init3(
|
||||
gxtime* time,
|
||||
int year,
|
||||
int month,
|
||||
int day,
|
||||
int hour,
|
||||
int minute,
|
||||
int second,
|
||||
int millisecond);
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
|
||||
//Constructor from Unix time.
|
||||
void time_initUnix(
|
||||
gxtime* time,
|
||||
uint32_t value);
|
||||
|
||||
void time_clear(
|
||||
gxtime* time);
|
||||
|
||||
void time_copy(
|
||||
gxtime* trg,
|
||||
gxtime* src);
|
||||
|
||||
//Returns the approximate processor time in ms.
|
||||
extern uint32_t time_elapsed(void);
|
||||
|
||||
/*
|
||||
Get years from time.
|
||||
*/
|
||||
uint16_t time_getYears(
|
||||
const gxtime* value);
|
||||
/*
|
||||
Get months from time.
|
||||
*/
|
||||
unsigned char time_getMonths(
|
||||
const gxtime* value);
|
||||
/*
|
||||
Get days from time.
|
||||
*/
|
||||
unsigned char time_getDays(
|
||||
const gxtime* value);
|
||||
|
||||
/*
|
||||
Get hours from time.
|
||||
*/
|
||||
unsigned char time_getHours(
|
||||
const gxtime* value);
|
||||
|
||||
/*
|
||||
Get minutes from time.
|
||||
*/
|
||||
unsigned char time_getMinutes(
|
||||
const gxtime* value);
|
||||
|
||||
/*
|
||||
Get seconds from time.
|
||||
*/
|
||||
unsigned char time_getSeconds(
|
||||
const gxtime* value);
|
||||
|
||||
/*
|
||||
Get years from time.
|
||||
*/
|
||||
uint16_t time_getYears2(
|
||||
uint32_t value);
|
||||
/*
|
||||
Get months from time.
|
||||
*/
|
||||
unsigned char time_getMonths2(
|
||||
uint32_t value);
|
||||
/*
|
||||
Get days from time.
|
||||
*/
|
||||
unsigned char time_getDays2(
|
||||
uint32_t value);
|
||||
|
||||
/*
|
||||
Get hours from time.
|
||||
*/
|
||||
unsigned char time_getHours2(
|
||||
uint32_t value);
|
||||
|
||||
/*
|
||||
Get minutes from time.
|
||||
*/
|
||||
unsigned char time_getMinutes2(
|
||||
uint32_t value);
|
||||
|
||||
/*
|
||||
Get seconds from time.
|
||||
*/
|
||||
unsigned char time_getSeconds2(
|
||||
uint32_t value);
|
||||
|
||||
/*
|
||||
Adds amount of days to current time.
|
||||
*/
|
||||
void time_addDays(
|
||||
gxtime* value,
|
||||
int days);
|
||||
|
||||
/*
|
||||
Adds amount of hours to current time.
|
||||
*/
|
||||
void time_addHours(
|
||||
gxtime* value,
|
||||
int hours);
|
||||
|
||||
/*
|
||||
Adds amount of minutes to current time.
|
||||
*/
|
||||
void time_addMinutes(
|
||||
gxtime* value,
|
||||
int minutes);
|
||||
|
||||
/*
|
||||
Adds amount of seconds to current time.
|
||||
*/
|
||||
void time_addSeconds(
|
||||
gxtime* value,
|
||||
int seconds);
|
||||
|
||||
/*
|
||||
Clears date part.
|
||||
*/
|
||||
void time_clearDate(
|
||||
gxtime* value);
|
||||
|
||||
/*
|
||||
Clears time part.
|
||||
*/
|
||||
void time_clearTime(
|
||||
gxtime* value);
|
||||
|
||||
/*
|
||||
Clears hours.
|
||||
*/
|
||||
void time_clearHours(
|
||||
gxtime* value);
|
||||
|
||||
/*
|
||||
Clears minutes.
|
||||
*/
|
||||
void time_clearMinutes(
|
||||
gxtime* value);
|
||||
|
||||
/*
|
||||
Clears seconds.
|
||||
*/
|
||||
void time_clearSeconds(
|
||||
gxtime* value);
|
||||
|
||||
unsigned char date_daysInMonth(
|
||||
uint16_t year,
|
||||
uint8_t month);
|
||||
|
||||
#if !defined(DLMS_IGNORE_STRING_CONVERTER) && !defined(DLMS_IGNORE_MALLOC)
|
||||
//Print time to cout.
|
||||
int time_print(
|
||||
//Format.
|
||||
const char* format,
|
||||
gxtime* time);
|
||||
#endif //!defined(DLMS_IGNORE_STRING_CONVERTER) && !defined(DLMS_IGNORE_MALLOC)
|
||||
|
||||
//Save time to char buffer.
|
||||
int time_toString2(
|
||||
const gxtime* time,
|
||||
char* buff,
|
||||
uint16_t len);
|
||||
|
||||
//Save time to bytebuffer.
|
||||
int time_toString(
|
||||
const gxtime* time,
|
||||
gxByteBuffer* arr);
|
||||
|
||||
void time_addTime(
|
||||
gxtime* time,
|
||||
int hours,
|
||||
int minutes,
|
||||
int seconds);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Compare times.
|
||||
//
|
||||
// if Return value < 0 then it indicates value1 is less than value2.
|
||||
// if Return value > 0 then it indicates value2 is less than value1.
|
||||
// if Return value = 0 then it indicates value1 is equal to value2.
|
||||
int time_compare(
|
||||
gxtime* value1,
|
||||
gxtime* value2);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Compare time and EPOCH time.
|
||||
//
|
||||
// if Return value < 0 then it indicates value1 is less than value2.
|
||||
// if Return value > 0 then it indicates value2 is less than value1.
|
||||
// if Return value = 0 then it indicates value1 is equal to value2.
|
||||
int time_compare2(
|
||||
gxtime* value1,
|
||||
uint32_t value2);
|
||||
|
||||
|
||||
int time_compareWithDiff(
|
||||
gxtime* value1,
|
||||
uint32_t value2,
|
||||
short deviationDiff);
|
||||
|
||||
#ifndef DLMS_USE_EPOCH_TIME
|
||||
//Get date-time from EPOCH time.
|
||||
int time_fromUnixTime(
|
||||
uint32_t epoch,
|
||||
struct tm* time);
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
|
||||
//Get date-time from EPOCH time.
|
||||
int time_fromUnixTime2(
|
||||
uint32_t epoch,
|
||||
uint16_t* year,
|
||||
unsigned char* month,
|
||||
unsigned char* day,
|
||||
unsigned char* hour,
|
||||
unsigned char* minute,
|
||||
unsigned char* second,
|
||||
unsigned char* dayOfWeek);
|
||||
|
||||
//Get date-time from EPOCH time.
|
||||
int time_fromUnixTime3(
|
||||
const gxtime* time,
|
||||
uint16_t* year,
|
||||
unsigned char* month,
|
||||
unsigned char* day,
|
||||
unsigned char* hour,
|
||||
unsigned char* minute,
|
||||
unsigned char* second,
|
||||
unsigned char* dayOfWeek);
|
||||
|
||||
#ifndef DLMS_USE_EPOCH_TIME
|
||||
// Convert date time to Epoch time.
|
||||
uint32_t time_toUnixTime(
|
||||
struct tm* time);
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
|
||||
// Convert date time to Epoch time.
|
||||
uint32_t time_toUnixTime2(
|
||||
gxtime* time);
|
||||
|
||||
//Get day of week.
|
||||
unsigned char time_dayOfWeek(
|
||||
uint16_t year,
|
||||
unsigned char month,
|
||||
unsigned char day);
|
||||
|
||||
//Get deviation.
|
||||
int time_getDeviation(
|
||||
gxtime* value1);
|
||||
|
||||
//Convert date time to UTC date time.
|
||||
int time_toUTC(gxtime* value);
|
||||
|
||||
// Get next scheduled date in UTC time.
|
||||
uint32_t time_getNextScheduledDate(
|
||||
//Start time.
|
||||
uint32_t start,
|
||||
//Compared time.
|
||||
gxtime* value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //DATE_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,314 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef DLMS_H
|
||||
#define DLMS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "errorcodes.h"
|
||||
#include "bytebuffer.h"
|
||||
#include "message.h"
|
||||
#include "helpers.h"
|
||||
#include "dlmssettings.h"
|
||||
#include "apdu.h"
|
||||
#include "variant.h"
|
||||
#include "objectarray.h"
|
||||
#include "replydata.h"
|
||||
#include "datainfo.h"
|
||||
#include "parameters.h"
|
||||
|
||||
//Makes sure that the basic settings are set.
|
||||
int dlms_checkInit(
|
||||
dlmsSettings* settings);
|
||||
|
||||
#ifndef DLMS_IGNORE_HDLC
|
||||
//Is HDLC framing used.
|
||||
unsigned char dlms_useHdlc(DLMS_INTERFACE_TYPE type);
|
||||
|
||||
/**
|
||||
* Get PDU as HDLC frame.
|
||||
*/
|
||||
int dlms_getHdlcFrame(
|
||||
dlmsSettings* settings,
|
||||
int frame,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
#endif //DLMS_IGNORE_HDLC
|
||||
|
||||
#ifndef DLMS_IGNORE_PLC
|
||||
int dlms_getMacHdlcFrame(
|
||||
dlmsSettings* settings,
|
||||
unsigned char frame,
|
||||
unsigned char creditFields,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* reply);
|
||||
#endif //DLMS_IGNORE_HDLC
|
||||
|
||||
#ifndef DLMS_IGNORE_WRAPPER
|
||||
/**
|
||||
* Split DLMS PDU to wrapper frames.
|
||||
*
|
||||
* @param settings
|
||||
* DLMS settings.
|
||||
* @param data
|
||||
* Wrapped data.
|
||||
* @return Wrapper frames.
|
||||
*/
|
||||
int dlms_getWrapperFrame(
|
||||
dlmsSettings* settings,
|
||||
DLMS_COMMAND command,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* reply);
|
||||
#endif //DLMS_IGNORE_WRAPPER
|
||||
|
||||
#ifndef DLMS_IGNORE_HIGH_GMAC
|
||||
unsigned char dlms_useDedicatedKey(dlmsSettings* settings);
|
||||
#endif //DLMS_IGNORE_HIGH_GMAC
|
||||
|
||||
//Set data from DLMS Varuant to DLMS byte stream.
|
||||
int dlms_setData(
|
||||
gxByteBuffer* data,
|
||||
DLMS_DATA_TYPE type,
|
||||
dlmsVARIANT *value);
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
//Set data from DLMS Varuant to DLMS byte stream.
|
||||
int dlms_setData2(
|
||||
unsigned char *buff,
|
||||
uint32_t length,
|
||||
DLMS_DATA_TYPE type,
|
||||
dlmsVARIANT *value);
|
||||
#else
|
||||
//Set data from DLMS Varuant to DLMS byte stream.
|
||||
int dlms_setData2(
|
||||
unsigned char *buff,
|
||||
uint16_t length,
|
||||
DLMS_DATA_TYPE type,
|
||||
dlmsVARIANT *value);
|
||||
#endif
|
||||
|
||||
int dlms_receiverReady(
|
||||
dlmsSettings* settings,
|
||||
DLMS_DATA_REQUEST_TYPES type,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
/**
|
||||
* Get next logical name PDU.
|
||||
*
|
||||
* @param p
|
||||
* LN parameters.
|
||||
* @param reply
|
||||
* Generated message.
|
||||
*/
|
||||
int dlms_getLNPdu(
|
||||
gxLNParameters* p,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
//Get value from DLMS byte stream.
|
||||
int dlms_getData(
|
||||
gxByteBuffer* data,
|
||||
gxDataInfo* info,
|
||||
dlmsVARIANT *value);
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
/**
|
||||
* Get next short name PDU.
|
||||
* @param p SN parameters.
|
||||
* @param reply Generated message.
|
||||
*/
|
||||
int dlms_getSNPdu(
|
||||
gxSNParameters* p,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
#ifndef DLMS_IGNORE_HDLC
|
||||
//Return DLMS_ERROR_CODE_FALSE if LLC bytes are not included.
|
||||
int dlms_checkLLCBytes(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data);
|
||||
|
||||
int dlms_getHdlcData(
|
||||
unsigned char server,
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* reply,
|
||||
gxReplyData* data,
|
||||
unsigned char* frame,
|
||||
unsigned char preEstablished,
|
||||
unsigned char first);
|
||||
#endif //DLMS_IGNORE_HDLC
|
||||
|
||||
#ifndef DLMS_IGNORE_WRAPPER
|
||||
int dlms_getTcpData(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* buff,
|
||||
gxReplyData* data,
|
||||
gxReplyData* notify,
|
||||
unsigned char* isNotify);
|
||||
#endif //DLMS_IGNORE_WRAPPER
|
||||
|
||||
int dlms_changeType2(
|
||||
dlmsVARIANT *value,
|
||||
DLMS_DATA_TYPE type,
|
||||
dlmsVARIANT *newValue);
|
||||
|
||||
int dlms_changeType(
|
||||
gxByteBuffer* value,
|
||||
DLMS_DATA_TYPE type,
|
||||
dlmsVARIANT *newValue);
|
||||
|
||||
|
||||
int dlms_getPdu(
|
||||
dlmsSettings* settings,
|
||||
gxReplyData* data,
|
||||
unsigned char first);
|
||||
|
||||
int dlms_getData2(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* reply,
|
||||
gxReplyData* data,
|
||||
unsigned char first);
|
||||
|
||||
int dlms_getData3(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* reply,
|
||||
gxReplyData* data,
|
||||
gxReplyData* notify,
|
||||
unsigned char first,
|
||||
unsigned char* isNotify);
|
||||
|
||||
/**
|
||||
* Get all Logical name messages. Client uses this to generate messages.
|
||||
*
|
||||
* @param p
|
||||
* LN settings.
|
||||
* @param reply
|
||||
* Generated messages.
|
||||
* @return Status code.
|
||||
*/
|
||||
int dlms_getLnMessages(
|
||||
gxLNParameters *p,
|
||||
message* reply);
|
||||
|
||||
#ifndef DLMS_IGNORE_HDLC
|
||||
/**
|
||||
* Add LLC bytes to generated message.
|
||||
*
|
||||
* @param settings
|
||||
* DLMS settings.
|
||||
* @param data
|
||||
* Data where bytes are added.
|
||||
*/
|
||||
int dlms_addLLCBytes(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data);
|
||||
#endif //DLMS_IGNORE_HDLC
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
/**
|
||||
* Get all Short Name messages. Client uses this to generate messages.
|
||||
*
|
||||
* @param p
|
||||
* DLMS SN parameters.
|
||||
* @param reply
|
||||
* Generated messages.
|
||||
* @return Status code.
|
||||
*/
|
||||
int dlms_getSnMessages(
|
||||
gxSNParameters *p,
|
||||
message* reply);
|
||||
|
||||
int dlms_getActionInfo(
|
||||
DLMS_OBJECT_TYPE objectType,
|
||||
unsigned char *value,
|
||||
unsigned char *count);
|
||||
#endif // DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
int dlms_generateChallenge(
|
||||
gxByteBuffer* challenge);
|
||||
|
||||
/**
|
||||
* Chipher text.
|
||||
*
|
||||
* @param auth
|
||||
* Authentication level.
|
||||
* @param data
|
||||
* Text to chipher.
|
||||
* @param secret
|
||||
* Secret.
|
||||
* @return Chiphered text.
|
||||
*/
|
||||
int dlms_secure(
|
||||
dlmsSettings* settings,
|
||||
int32_t ic,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* secret,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
int dlms_parseSnrmUaResponse(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data);
|
||||
|
||||
// Add HDLC parameter.
|
||||
int dlms_appendHdlcParameter(
|
||||
gxByteBuffer* data,
|
||||
uint16_t value);
|
||||
|
||||
//Is it possible to add more data to the PDU before it's full.
|
||||
int dlms_isPduFull(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* data,
|
||||
uint16_t* size);
|
||||
|
||||
int dlms_getMacFrame(
|
||||
dlmsSettings* settings,
|
||||
unsigned char frame,
|
||||
unsigned char creditFields,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
/**
|
||||
* This function returns true, if pre-established connection is used.
|
||||
*/
|
||||
unsigned char dlms_usePreEstablishedConnection(dlmsSettings* settings);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //DLMS_H
|
||||
|
|
@ -0,0 +1,478 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxmem.h"
|
||||
#include "dlmssettings.h"
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
// Server sender frame sequence starting number.
|
||||
static const unsigned char SERVER_START_SENDER_FRAME_SEQUENCE = 0x1E;
|
||||
// Server receiver frame sequence starting number.
|
||||
static const unsigned char SERVER_START_RECEIVER_FRAME_SEQUENCE = 0xFE;
|
||||
// Client sender frame sequence starting number.
|
||||
static const unsigned char CLIENT_START_SENDER_FRAME_SEQUENCE = 0xFE;
|
||||
// Client receiver frame sequence starting number.
|
||||
static const unsigned char CLIENT_START_RCEIVER_FRAME_SEQUENCE = 0xE;
|
||||
|
||||
//Initialize server.
|
||||
void svr_init(
|
||||
dlmsServerSettings* settings,
|
||||
unsigned char useLogicalNameReferencing,
|
||||
DLMS_INTERFACE_TYPE interfaceType,
|
||||
uint16_t frameSize,
|
||||
uint16_t pduSize,
|
||||
unsigned char* frameBuffer,
|
||||
uint16_t frameBufferSize,
|
||||
unsigned char* pduBuffer,
|
||||
uint16_t pduBufferSize)
|
||||
{
|
||||
cl_init(&settings->base, useLogicalNameReferencing, 0, 0, DLMS_AUTHENTICATION_NONE, NULL, interfaceType);
|
||||
settings->base.proposedConformance |= DLMS_CONFORMANCE_GENERAL_PROTECTION;
|
||||
bb_attach(&settings->receivedData, frameBuffer, 0, frameBufferSize);
|
||||
reply_init(&settings->info);
|
||||
bb_attach(&settings->info.data, pduBuffer, 0, pduBufferSize);
|
||||
settings->base.maxInfoRX = settings->base.maxInfoTX = frameSize;
|
||||
settings->base.maxServerPDUSize = pduSize;
|
||||
settings->base.server = 1;
|
||||
settings->initialized = 0;
|
||||
trans_init(&settings->transaction);
|
||||
#ifndef DLMS_IGNORE_TCP_UDP_SETUP
|
||||
settings->wrapper = NULL;
|
||||
#endif // DLMS_IGNORE_TCP_UDP_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
settings->hdlc = NULL;
|
||||
#endif //DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
settings->localPortSetup = NULL;
|
||||
#endif //DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
#ifndef DLMS_IGNORE_CLOCK
|
||||
settings->defaultClock = NULL;
|
||||
#endif //DLMS_IGNORE_CLOCK
|
||||
settings->dataReceived = 0;
|
||||
settings->frameReceived = 0;
|
||||
resetFrameSequence(&settings->base);
|
||||
settings->pushClientAddress = 0;
|
||||
}
|
||||
|
||||
//Initialize client.
|
||||
void cl_init(
|
||||
dlmsSettings* settings,
|
||||
unsigned char useLogicalNameReferencing,
|
||||
uint16_t clientAddress,
|
||||
uint32_t serverAddress,
|
||||
DLMS_AUTHENTICATION authentication,
|
||||
const char* password,
|
||||
DLMS_INTERFACE_TYPE interfaceType)
|
||||
{
|
||||
settings->autoIncreaseInvokeID = 0;
|
||||
settings->qualityOfService = 0;
|
||||
settings->protocolVersion = 0;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
settings->preEstablishedSystemTitle = NULL;
|
||||
#else
|
||||
memset(settings->preEstablishedSystemTitle, 0, 8);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
settings->blockIndex = 1;
|
||||
settings->clientAddress = clientAddress;
|
||||
settings->serverAddress = serverAddress;
|
||||
settings->dlmsVersionNumber = 6;
|
||||
settings->useLogicalNameReferencing = useLogicalNameReferencing;
|
||||
settings->interfaceType = interfaceType;
|
||||
settings->authentication = authentication;
|
||||
BYTE_BUFFER_INIT(&settings->password);
|
||||
bb_addString(&settings->password, password);
|
||||
memset(settings->sourceSystemTitle, 0, sizeof(settings->sourceSystemTitle));
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
memset(settings->kek, 0, sizeof(settings->kek));
|
||||
#else
|
||||
BYTE_BUFFER_INIT(&settings->kek);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
settings->maxServerPDUSize = 1024;
|
||||
settings->maxPduSize = 0xFFFF;
|
||||
settings->server = 0;
|
||||
if (useLogicalNameReferencing)
|
||||
{
|
||||
settings->proposedConformance = (DLMS_CONFORMANCE)
|
||||
(DLMS_CONFORMANCE_BLOCK_TRANSFER_WITH_ACTION |
|
||||
DLMS_CONFORMANCE_BLOCK_TRANSFER_WITH_SET_OR_WRITE |
|
||||
DLMS_CONFORMANCE_BLOCK_TRANSFER_WITH_GET_OR_READ |
|
||||
DLMS_CONFORMANCE_SET |
|
||||
DLMS_CONFORMANCE_SELECTIVE_ACCESS |
|
||||
DLMS_CONFORMANCE_ACTION |
|
||||
DLMS_CONFORMANCE_MULTIPLE_REFERENCES |
|
||||
DLMS_CONFORMANCE_GET |
|
||||
DLMS_CONFORMANCE_GENERAL_PROTECTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->proposedConformance = (DLMS_CONFORMANCE)(DLMS_CONFORMANCE_INFORMATION_REPORT |
|
||||
DLMS_CONFORMANCE_READ | DLMS_CONFORMANCE_UN_CONFIRMED_WRITE |
|
||||
DLMS_CONFORMANCE_WRITE | DLMS_CONFORMANCE_PARAMETERIZED_ACCESS |
|
||||
DLMS_CONFORMANCE_MULTIPLE_REFERENCES);
|
||||
}
|
||||
settings->longInvokeID = 0;
|
||||
settings->maxInfoTX = settings->maxInfoRX = 0x80;
|
||||
settings->windowSizeTX = settings->windowSizeRX = 1;
|
||||
settings->connected = DLMS_CONNECTION_STATE_NONE;
|
||||
oa_init(&settings->objects);
|
||||
settings->connected = DLMS_CONNECTION_STATE_NONE;
|
||||
settings->customChallenges = 0;
|
||||
settings->invokeID = 1;
|
||||
BYTE_BUFFER_INIT(&settings->ctoSChallenge);
|
||||
BYTE_BUFFER_INIT(&settings->stoCChallenge);
|
||||
settings->priority = DLMS_PRIORITY_HIGH;
|
||||
settings->serviceClass = DLMS_SERVICE_CLASS_CONFIRMED;
|
||||
#ifndef DLMS_IGNORE_HIGH_GMAC
|
||||
cip_init(&settings->cipher);
|
||||
#endif //DLMS_IGNORE_HIGH_GMAC
|
||||
settings->userId = -1;
|
||||
resetFrameSequence(settings);
|
||||
settings->serializedPdu = NULL;
|
||||
oa_init(&settings->releasedObjects);
|
||||
settings->expectedSecurityPolicy = 0xFF;
|
||||
settings->expectedSecuritySuite = 0xFF;
|
||||
settings->expectedInvocationCounter = NULL;
|
||||
settings->expectedClientSystemTitle = NULL;
|
||||
#ifndef DLMS_IGNORE_PLC
|
||||
plc_reset(settings);
|
||||
#endif //DLMS_IGNORE_PLC
|
||||
oa_init(&settings->internalObjects);
|
||||
}
|
||||
|
||||
void cl_clear(
|
||||
dlmsSettings* settings)
|
||||
{
|
||||
settings->protocolVersion = 0;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (settings->preEstablishedSystemTitle != NULL)
|
||||
{
|
||||
bb_clear(settings->preEstablishedSystemTitle);
|
||||
gxfree(settings->preEstablishedSystemTitle);
|
||||
settings->preEstablishedSystemTitle = NULL;
|
||||
}
|
||||
#else
|
||||
memset(settings->preEstablishedSystemTitle, 0, 8);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
memset(settings->sourceSystemTitle, 0, sizeof(settings->sourceSystemTitle));
|
||||
bb_clear(&settings->password);
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
memset(settings->kek, 0, sizeof(settings->kek));
|
||||
#else
|
||||
bb_clear(&settings->kek);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
oa_clear(&settings->objects, !settings->server);
|
||||
settings->connected = DLMS_CONNECTION_STATE_NONE;
|
||||
settings->customChallenges = 0;
|
||||
settings->invokeID = 1;
|
||||
bb_clear(&settings->ctoSChallenge);
|
||||
bb_clear(&settings->stoCChallenge);
|
||||
settings->priority = DLMS_PRIORITY_HIGH;
|
||||
settings->serviceClass = DLMS_SERVICE_CLASS_CONFIRMED;
|
||||
#ifndef DLMS_IGNORE_HIGH_GMAC
|
||||
cip_clear(&settings->cipher);
|
||||
#endif //DLMS_IGNORE_HIGH_GMAC
|
||||
settings->maxPduSize = 0xFFFF;
|
||||
settings->userId = -1;
|
||||
oa_clear(&settings->releasedObjects, 1);
|
||||
oa_clear(&settings->internalObjects, 0);
|
||||
resetFrameSequence(settings);
|
||||
settings->expectedInvocationCounter = NULL;
|
||||
}
|
||||
|
||||
void svr_clear(
|
||||
dlmsServerSettings* settings)
|
||||
{
|
||||
cl_clear(&settings->base);
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_PLC
|
||||
void plc_reset(
|
||||
dlmsSettings* settings)
|
||||
{
|
||||
settings->plcSettings.initialCredit = 7;
|
||||
settings->plcSettings.currentCredit = 7;
|
||||
settings->plcSettings.deltaCredit = 0;
|
||||
//New device addresses are used.
|
||||
if (settings->interfaceType == DLMS_INTERFACE_TYPE_PLC)
|
||||
{
|
||||
if (settings->server)
|
||||
{
|
||||
settings->plcSettings.macSourceAddress = DLMS_PLC_SOURCE_ADDRESS_NEW;
|
||||
settings->plcSettings.macDestinationAddress = DLMS_PLC_SOURCE_ADDRESS_INITIATOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->plcSettings.macSourceAddress = DLMS_PLC_SOURCE_ADDRESS_INITIATOR;
|
||||
settings->plcSettings.macDestinationAddress = DLMS_PLC_DESTINATION_ADDRESS_ALL_PHYSICAL;
|
||||
}
|
||||
settings->plcSettings.allowedTimeSlots = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (settings->server)
|
||||
{
|
||||
settings->plcSettings.macSourceAddress = DLMS_PLC_SOURCE_ADDRESS_NEW;
|
||||
settings->plcSettings.macDestinationAddress = DLMS_PLC_HDLC_SOURCE_ADDRESS_INITIATOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->plcSettings.macSourceAddress = DLMS_PLC_HDLC_SOURCE_ADDRESS_INITIATOR;
|
||||
settings->plcSettings.macDestinationAddress = DLMS_PLC_DESTINATION_ADDRESS_ALL_PHYSICAL;
|
||||
}
|
||||
settings->plcSettings.allowedTimeSlots = 0x14;
|
||||
}
|
||||
settings->plcSettings.responseProbability = 100;
|
||||
}
|
||||
#endif //DLMS_IGNORE_PLC
|
||||
|
||||
void resetBlockIndex(
|
||||
dlmsSettings* settings)
|
||||
{
|
||||
settings->blockIndex = 1;
|
||||
}
|
||||
|
||||
void resetFrameSequence(
|
||||
dlmsSettings* settings)
|
||||
{
|
||||
if (settings->server)
|
||||
{
|
||||
settings->senderFrame = SERVER_START_SENDER_FRAME_SEQUENCE;
|
||||
settings->receiverFrame = SERVER_START_RECEIVER_FRAME_SEQUENCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->senderFrame = CLIENT_START_SENDER_FRAME_SEQUENCE;
|
||||
settings->receiverFrame = CLIENT_START_RCEIVER_FRAME_SEQUENCE;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char increaseReceiverSequence(
|
||||
unsigned char value)
|
||||
{
|
||||
return ((value + 0x20) | 0x10 | (value & 0xE));
|
||||
}
|
||||
|
||||
// Increase sender sequence.
|
||||
//
|
||||
// @param value
|
||||
// Frame value.
|
||||
// Increased sender frame sequence.
|
||||
unsigned char increaseSendSequence(
|
||||
unsigned char value)
|
||||
{
|
||||
return (unsigned char)((value & 0xF0) | ((value + 0x2) & 0xE));
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_HDLC_CHECK
|
||||
unsigned char checkFrame(
|
||||
dlmsSettings* settings,
|
||||
unsigned char frame)
|
||||
{
|
||||
//If notify
|
||||
if (frame == 0x13)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
// If U frame.
|
||||
if ((frame & 0x3) == 3)
|
||||
{
|
||||
if (frame == 0x93)
|
||||
{
|
||||
unsigned char isEcho = !settings->server && frame == 0x93 &&
|
||||
(settings->senderFrame == 0x10 || settings->senderFrame == 0xfe) &&
|
||||
settings->receiverFrame == 0xE;
|
||||
resetFrameSequence(settings);
|
||||
return !isEcho;
|
||||
}
|
||||
if (frame == 0x73 && !settings->server)
|
||||
{
|
||||
return settings->senderFrame == 0xFE && settings->receiverFrame == 0xE;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// If S -frame
|
||||
if ((frame & 0x1) == 1)
|
||||
{
|
||||
//If echo.
|
||||
if (frame == (settings->senderFrame & 0xF1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
settings->receiverFrame = increaseReceiverSequence(settings->receiverFrame);
|
||||
return 1;
|
||||
}
|
||||
//Handle I-frame.
|
||||
unsigned char expected;
|
||||
if ((settings->senderFrame & 0x1) == 0)
|
||||
{
|
||||
expected = increaseReceiverSequence(increaseSendSequence(settings->receiverFrame));
|
||||
if (frame == expected)
|
||||
{
|
||||
settings->receiverFrame = frame;
|
||||
return 1;
|
||||
}
|
||||
//If the final bit is not set.
|
||||
if (frame == (expected & ~0x10) && settings->windowSizeRX != 1)
|
||||
{
|
||||
settings->receiverFrame = frame;
|
||||
return 1;
|
||||
}
|
||||
//If Final bit is not set for the previous message.
|
||||
if ((settings->receiverFrame & 0x10) == 0 && settings->windowSizeRX != 1)
|
||||
{
|
||||
expected = (unsigned char)(0x10 | increaseSendSequence(settings->receiverFrame));
|
||||
if (frame == expected)
|
||||
{
|
||||
settings->receiverFrame = frame;
|
||||
return 1;
|
||||
}
|
||||
//If the final bit is not set.
|
||||
if (frame == (expected & ~0x10))
|
||||
{
|
||||
settings->receiverFrame = frame;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//If answer for RR.
|
||||
else
|
||||
{
|
||||
expected = increaseSendSequence(settings->receiverFrame);
|
||||
if (frame == expected)
|
||||
{
|
||||
settings->receiverFrame = frame;
|
||||
return 1;
|
||||
}
|
||||
if (frame == (expected & ~0x10))
|
||||
{
|
||||
settings->receiverFrame = frame;
|
||||
return 1;
|
||||
}
|
||||
if (settings->windowSizeRX != 1)
|
||||
{
|
||||
//If HDLC window size is bigger than one.
|
||||
if (frame == (expected | 0x10))
|
||||
{
|
||||
settings->receiverFrame = frame;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Pre-established connections needs this.
|
||||
if ((!settings->server && settings->receiverFrame == SERVER_START_RECEIVER_FRAME_SEQUENCE) ||
|
||||
(settings->server && settings->receiverFrame == CLIENT_START_RCEIVER_FRAME_SEQUENCE))
|
||||
{
|
||||
settings->receiverFrame = frame;
|
||||
return 1;
|
||||
}
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)//If Windows or Linux
|
||||
printf("Invalid frame %X. Expected %X.\r\n", frame, expected);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_HDLC_CHECK
|
||||
|
||||
unsigned char getNextSend(
|
||||
dlmsSettings* settings, unsigned char first)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
settings->senderFrame = increaseReceiverSequence(increaseSendSequence((unsigned char)settings->senderFrame));
|
||||
}
|
||||
else
|
||||
{
|
||||
settings->senderFrame = increaseSendSequence((unsigned char)settings->senderFrame);
|
||||
}
|
||||
return (unsigned char)settings->senderFrame;
|
||||
}
|
||||
|
||||
unsigned char getReceiverReady(
|
||||
dlmsSettings* settings)
|
||||
{
|
||||
settings->senderFrame = increaseReceiverSequence((unsigned char)(settings->senderFrame | 1));
|
||||
return (unsigned char)(settings->senderFrame & 0xF1);
|
||||
}
|
||||
|
||||
unsigned char getKeepAlive(
|
||||
dlmsSettings* settings)
|
||||
{
|
||||
settings->senderFrame = (unsigned char)(settings->senderFrame | 1);
|
||||
return (unsigned char)(settings->senderFrame & 0xF1);
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_HIGH_GMAC
|
||||
unsigned char isCiphered(
|
||||
ciphering* cipher)
|
||||
{
|
||||
return cipher->security != DLMS_SECURITY_NONE;
|
||||
}
|
||||
#endif //DLMS_IGNORE_HIGH_GMAC
|
||||
|
||||
void trans_init(gxLongTransaction* trans)
|
||||
{
|
||||
trans->command = DLMS_COMMAND_NONE;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
BYTE_BUFFER_INIT(&trans->data);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
vec_init(&trans->targets);
|
||||
}
|
||||
|
||||
void trans_clear(gxLongTransaction* trans)
|
||||
{
|
||||
trans->command = DLMS_COMMAND_NONE;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
bb_clear(&trans->data);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
vec_clear(&trans->targets);
|
||||
}
|
||||
|
||||
void updateInvokeId(
|
||||
dlmsServerSettings* settings,
|
||||
unsigned char value)
|
||||
{
|
||||
if ((value & 0x80) != 0) {
|
||||
settings->base.priority = DLMS_PRIORITY_HIGH;
|
||||
}
|
||||
else {
|
||||
settings->base.priority = DLMS_PRIORITY_NORMAL;
|
||||
}
|
||||
if ((value & 0x40) != 0) {
|
||||
settings->base.serviceClass = DLMS_SERVICE_CLASS_CONFIRMED;
|
||||
}
|
||||
else {
|
||||
settings->base.serviceClass = DLMS_SERVICE_CLASS_UN_CONFIRMED;
|
||||
}
|
||||
settings->base.invokeID = (unsigned char)(value & 0xF);
|
||||
}
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef DLMS_SETTINGS_H
|
||||
#define DLMS_SETTINGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "enums.h"
|
||||
#include "variant.h"
|
||||
#include "objectarray.h"
|
||||
#include "message.h"
|
||||
#include "gxvalueeventargs.h"
|
||||
#include "replydata.h"
|
||||
#include "ciphering.h"
|
||||
|
||||
#ifndef DLMS_IGNORE_PLC
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char responseProbability;
|
||||
uint16_t allowedTimeSlots;
|
||||
unsigned char discoverReportInitialCredit;
|
||||
unsigned char icEqualCredit;
|
||||
}gxPlcRegister;
|
||||
|
||||
// PLC communication settings.
|
||||
typedef struct
|
||||
{
|
||||
gxByteBuffer systemTitle;
|
||||
|
||||
/**
|
||||
* Initial credit (IC) tells how many times the frame must be repeated.
|
||||
* Maximum value is 7.
|
||||
*/
|
||||
unsigned char initialCredit;
|
||||
/**
|
||||
* The current credit (CC) initial value equal to IC and automatically
|
||||
* decremented by the MAC layer after each repetition. Maximum value is 7.
|
||||
*/
|
||||
unsigned char currentCredit;
|
||||
|
||||
/**
|
||||
* Delta credit (DC) is used by the system management application entity
|
||||
* (SMAE) of the Client for credit management, while it has no meaning for a
|
||||
* Server or a REPEATER. It represents the difference(IC-CC) of the last
|
||||
* communication originated by the system identified by the DA address to
|
||||
* the system identified by the SA address. Maximum value is 3.
|
||||
*/
|
||||
unsigned char deltaCredit;
|
||||
/**
|
||||
* Source MAC address.
|
||||
*/
|
||||
uint16_t macSourceAddress;
|
||||
/**
|
||||
* Destination MAC address.
|
||||
*/
|
||||
uint16_t macDestinationAddress;
|
||||
/**
|
||||
* Response probability.
|
||||
*/
|
||||
unsigned char responseProbability;
|
||||
/**
|
||||
* Allowed time slots.
|
||||
*/
|
||||
uint16_t allowedTimeSlots;
|
||||
/**
|
||||
* Server saves client system title.
|
||||
*/
|
||||
gxByteBuffer clientSystemTitle;
|
||||
}gxPlcSettings;
|
||||
#endif //DLMS_IGNORE_PLC
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Is custom challenges used. If custom challenge is used new challenge is
|
||||
// not generated if it is Set. This is for debugging purposes.
|
||||
unsigned char customChallenges;
|
||||
|
||||
// Client to server challenge.
|
||||
gxByteBuffer ctoSChallenge;
|
||||
|
||||
// Server to Client challenge.
|
||||
gxByteBuffer stoCChallenge;
|
||||
|
||||
unsigned char sourceSystemTitle[8];
|
||||
|
||||
// Invoke ID.
|
||||
unsigned char invokeID;
|
||||
|
||||
//Long Invoke ID.
|
||||
int longInvokeID;
|
||||
|
||||
// Priority.
|
||||
DLMS_PRIORITY priority;
|
||||
|
||||
// Service class.
|
||||
DLMS_SERVICE_CLASS serviceClass;
|
||||
|
||||
// Client address.
|
||||
uint16_t clientAddress;
|
||||
//Server address.
|
||||
uint32_t serverAddress;
|
||||
|
||||
unsigned char useLogicalNameReferencing;
|
||||
DLMS_INTERFACE_TYPE interfaceType;
|
||||
DLMS_AUTHENTICATION authentication;
|
||||
gxByteBuffer password;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer kek;
|
||||
#else
|
||||
unsigned char kek[16];
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
/**
|
||||
* DLMS version number.
|
||||
*/
|
||||
unsigned char dlmsVersionNumber;
|
||||
|
||||
/**
|
||||
* Max PDU size used in communicating.
|
||||
*/
|
||||
uint16_t maxPduSize;
|
||||
|
||||
/**
|
||||
* Max PDU size that server uses. Client can ask anything, but server will decide.
|
||||
*/
|
||||
uint16_t maxServerPDUSize;
|
||||
|
||||
/**
|
||||
* HDLC sender frame sequence number.
|
||||
*/
|
||||
unsigned char senderFrame;
|
||||
|
||||
/**
|
||||
* HDLC receiver block sequence number.
|
||||
*/
|
||||
unsigned char receiverFrame;
|
||||
/**
|
||||
* Server functionality is not supported at the moment in ANSI C version.
|
||||
*/
|
||||
unsigned char server;
|
||||
unsigned char isAuthenticationRequired;
|
||||
|
||||
//When connection is made client tells what kind of services it want's to use.
|
||||
DLMS_CONFORMANCE proposedConformance;
|
||||
|
||||
// Functionality what server can offer.
|
||||
DLMS_CONFORMANCE negotiatedConformance;
|
||||
|
||||
//Used max info TX.
|
||||
uint16_t maxInfoTX;
|
||||
//Used max info RX.
|
||||
uint16_t maxInfoRX;
|
||||
//Used max window size in TX.
|
||||
unsigned char windowSizeTX;
|
||||
//Used max window size in RX.
|
||||
unsigned char windowSizeRX;
|
||||
|
||||
// Initialize PDU size that is restored after the connection is closed.
|
||||
uint16_t initializePduSize;
|
||||
//Initialized max info TX.
|
||||
uint16_t initializeMaxInfoTX;
|
||||
//Initialized max info RX.
|
||||
uint16_t initializeMaxInfoRX;
|
||||
//Initialized max window size in TX.
|
||||
unsigned char initializeWindowSizeTX;
|
||||
//Initialized max window size in RX.
|
||||
unsigned char initializeWindowSizeRX;
|
||||
#ifndef DLMS_IGNORE_PLC
|
||||
//PLC settings.
|
||||
gxPlcSettings plcSettings;
|
||||
#endif //DLMS_IGNORE_PLC
|
||||
|
||||
//List of internal COSEM objects.
|
||||
//Objects in this list are not added to assocaition view.
|
||||
//Objects can be used to save internal data.
|
||||
objectArray internalObjects;
|
||||
|
||||
//List of COSEM objects.
|
||||
objectArray objects;
|
||||
|
||||
// Block packet index.
|
||||
uint32_t blockIndex;
|
||||
//Is connected to the meter.
|
||||
DLMS_CONNECTION_STATE connected;
|
||||
|
||||
#ifndef DLMS_IGNORE_HIGH_GMAC
|
||||
ciphering cipher;
|
||||
#endif //DLMS_IGNORE_HIGH_GMAC
|
||||
|
||||
int16_t userId;
|
||||
|
||||
/**
|
||||
* Protocol version.
|
||||
*/
|
||||
unsigned char protocolVersion;
|
||||
|
||||
unsigned char qualityOfService;
|
||||
//Pre-established Application Associations system title.
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer* preEstablishedSystemTitle;
|
||||
#else
|
||||
unsigned char preEstablishedSystemTitle[8];
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Client serializes data to this PDU when malloc is not used or heap size is limited.
|
||||
gxByteBuffer* serializedPdu;
|
||||
//Auto increase Invoke ID.
|
||||
unsigned char autoIncreaseInvokeID;
|
||||
//Client adds objects that are not found from the association view here so they are released when client is clear.
|
||||
objectArray releasedObjects;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Expected security suite.
|
||||
// If Expected security suite is set client can't connect with other security suite.
|
||||
unsigned char expectedSecuritySuite;
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Expected security policy.
|
||||
// If Expected security policy is set client can't connect with other security policies.
|
||||
unsigned char expectedSecurityPolicy;
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Expected Invocation(Frame) counter value.
|
||||
// Expected Invocation counter is not check if value is zero.
|
||||
#ifdef DLMS_COSEM_INVOCATION_COUNTER_SIZE64
|
||||
uint64_t* expectedInvocationCounter;
|
||||
#else
|
||||
uint32_t* expectedInvocationCounter;
|
||||
#endif //DLMS_COSEM_INVOCATION_COUNTER_SIZE64
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Expected client system title.
|
||||
unsigned char* expectedClientSystemTitle;
|
||||
} dlmsSettings;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Executed command.
|
||||
*/
|
||||
DLMS_COMMAND command;
|
||||
|
||||
/**
|
||||
* Targets.
|
||||
*/
|
||||
gxValueEventCollection targets;
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
/**
|
||||
* Extra data from PDU.
|
||||
*/
|
||||
gxByteBuffer data;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
} gxLongTransaction;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dlmsSettings base;
|
||||
|
||||
gxReplyData info;
|
||||
/**
|
||||
* Received data frame.
|
||||
*/
|
||||
gxByteBuffer receivedData;
|
||||
|
||||
/**
|
||||
* Long get or read transaction information.
|
||||
*/
|
||||
gxLongTransaction transaction;
|
||||
|
||||
/**
|
||||
* Is server initialized.
|
||||
*/
|
||||
unsigned char initialized;
|
||||
#ifndef DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
gxIecHdlcSetup* hdlc;
|
||||
#endif //DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
gxLocalPortSetup* localPortSetup;
|
||||
#endif //DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_TCP_UDP_SETUP
|
||||
gxTcpUdpSetup* wrapper;
|
||||
#endif //DLMS_IGNORE_TCP_UDP_SETUP
|
||||
#ifndef DLMS_IGNORE_CLOCK
|
||||
gxClock* defaultClock;
|
||||
#endif //DLMS_IGNORE_CLOCK
|
||||
|
||||
//Time when last frame was received. HDLC framing is using this.
|
||||
uint32_t dataReceived;
|
||||
//Time when last byte was received. HDLC framing is using this.
|
||||
uint32_t frameReceived;
|
||||
//Server is using push client address when sending push messages. Client address is used if PushAddress is zero.
|
||||
uint16_t pushClientAddress;
|
||||
#ifndef DLMS_IGNORE_IEC
|
||||
/*Flag ID is used when server is operating using optical probe.*/
|
||||
unsigned char flagId[3];
|
||||
#endif //DLMS_IGNORE_IEC
|
||||
} dlmsServerSettings;
|
||||
|
||||
//Initialize server.
|
||||
void svr_init(
|
||||
dlmsServerSettings* settings,
|
||||
unsigned char useLogicalNameReferencing,
|
||||
DLMS_INTERFACE_TYPE interfaceType,
|
||||
//Max frame size.
|
||||
uint16_t frameSize,
|
||||
//Max PDU size.
|
||||
uint16_t pduSize,
|
||||
//Buffer where received frames are saved.
|
||||
unsigned char* frameBuffer,
|
||||
//Size of frame buffer.
|
||||
uint16_t frameBufferSize,
|
||||
//PDU Buffer.
|
||||
unsigned char* pduBuffer,
|
||||
//Size of PDU buffer.
|
||||
uint16_t pduBufferSize);
|
||||
|
||||
//Initialize client.
|
||||
void cl_init(
|
||||
dlmsSettings* settings,
|
||||
unsigned char useLogicalNameReferencing,
|
||||
uint16_t clientAddress,
|
||||
uint32_t serverAddress,
|
||||
DLMS_AUTHENTICATION authentication,
|
||||
const char* password,
|
||||
DLMS_INTERFACE_TYPE interfaceType);
|
||||
|
||||
//Clear DLMS settings.
|
||||
void cl_clear(
|
||||
dlmsSettings* settings);
|
||||
|
||||
void svr_clear(
|
||||
dlmsServerSettings* settings);
|
||||
|
||||
#ifndef DLMS_IGNORE_PLC
|
||||
// Set default values for PLC.
|
||||
void plc_reset(
|
||||
dlmsSettings* settings);
|
||||
#endif //DLMS_IGNORE_PLC
|
||||
|
||||
//Reset block index.
|
||||
void resetBlockIndex(
|
||||
dlmsSettings* settings);
|
||||
|
||||
void resetFrameSequence(
|
||||
dlmsSettings* settings);
|
||||
|
||||
#ifndef DLMS_IGNORE_HDLC_CHECK
|
||||
unsigned char checkFrame(
|
||||
dlmsSettings* settings,
|
||||
unsigned char frame);
|
||||
#endif //DLMS_IGNORE_HDLC_CHECK
|
||||
|
||||
void updateInvokeId(
|
||||
dlmsServerSettings* settings, unsigned char value);
|
||||
|
||||
// Increase receiver sequence.
|
||||
//
|
||||
// value: Frame value.
|
||||
// Increased receiver frame sequence.
|
||||
unsigned char increaseReceiverSequence(
|
||||
unsigned char value);
|
||||
|
||||
// Increase sender sequence.
|
||||
//
|
||||
// value : Frame value.
|
||||
// Increased sender frame sequence.
|
||||
unsigned char increaseSendSequence(
|
||||
unsigned char value);
|
||||
|
||||
unsigned char getNextSend(
|
||||
dlmsSettings* settings, unsigned char first);
|
||||
|
||||
unsigned char getReceiverReady(
|
||||
dlmsSettings* settings);
|
||||
|
||||
unsigned char getKeepAlive(
|
||||
dlmsSettings* settings);
|
||||
|
||||
#ifndef DLMS_IGNORE_HIGH_GMAC
|
||||
unsigned char isCiphered(
|
||||
ciphering* cipher);
|
||||
#endif //DLMS_IGNORE_HIGH_GMAC
|
||||
|
||||
void trans_init(gxLongTransaction* trans);
|
||||
|
||||
void trans_clear(gxLongTransaction* trans);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //DLMS_SETTINGS_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,167 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef DLMS_ERROR_CODE_H
|
||||
#define DLMS_ERROR_CODE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DLMS_ERROR_TYPE_EXCEPTION_RESPONSE = 0x80000000,
|
||||
DLMS_ERROR_TYPE_CONFIRMED_SERVICE_ERROR = 0x40000000,
|
||||
DLMS_ERROR_TYPE_COMMUNICATION_ERROR = 0x20000000
|
||||
}DLMS_ERROR_TYPE;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Enumerates all DLMS error codes.
|
||||
// https://www.gurux.fi/Gurux.DLMS.ErrorCodes
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
typedef enum
|
||||
{
|
||||
//Meter is not accept frame.
|
||||
DLMS_ERROR_CODE_UNACCEPTABLE_FRAME = -3,
|
||||
//Meter rejects send packet.
|
||||
DLMS_ERROR_CODE_REJECTED = -2,
|
||||
DLMS_ERROR_CODE_FALSE = -1,
|
||||
//////////////////////////////////////////
|
||||
//DLMS Standard error codes start here.
|
||||
DLMS_ERROR_CODE_OK = 0,
|
||||
//Access Error : Device reports a hardware fault
|
||||
DLMS_ERROR_CODE_HARDWARE_FAULT = 1,
|
||||
//Access Error : Device reports a temporary failure
|
||||
DLMS_ERROR_CODE_TEMPORARY_FAILURE = 2,
|
||||
// Access Error : Device reports Read-Write denied
|
||||
DLMS_ERROR_CODE_READ_WRITE_DENIED = 3,
|
||||
// Access Error : Device reports a undefined object
|
||||
DLMS_ERROR_CODE_UNDEFINED_OBJECT = 4,
|
||||
// Access Error : Device reports a inconsistent Class or Object
|
||||
DLMS_ERROR_CODE_INCONSISTENT_CLASS_OR_OBJECT = 9,
|
||||
// Access Error : Device reports a unavailable object
|
||||
DLMS_ERROR_CODE_UNAVAILABLE_OBJECT = 11,
|
||||
// Access Error : Device reports a unmatched type
|
||||
DLMS_ERROR_CODE_UNMATCH_TYPE = 12,
|
||||
// Access Error : Device reports scope of access violated
|
||||
DLMS_ERROR_CODE_ACCESS_VIOLATED = 13,
|
||||
// Access Error : Data Block Unavailable.
|
||||
DLMS_ERROR_CODE_DATA_BLOCK_UNAVAILABLE = 14,
|
||||
// Access Error : Long Get Or Read Aborted.
|
||||
DLMS_ERROR_CODE_LONG_GET_OR_READ_ABORTED = 15,
|
||||
// Access Error : No Long Get Or Read In Progress.
|
||||
DLMS_ERROR_CODE_NO_LONG_GET_OR_READ_IN_PROGRESS = 16,
|
||||
// Access Error : Long Set Or Write Aborted.
|
||||
DLMS_ERROR_CODE_LONG_SET_OR_WRITE_ABORTED = 17,
|
||||
// Access Error : No Long Set Or Write In Progress.
|
||||
DLMS_ERROR_CODE_NO_LONG_SET_OR_WRITE_IN_PROGRESS = 18,
|
||||
// Access Error : Data Block Number Invalid.
|
||||
DLMS_ERROR_CODE_DATA_BLOCK_NUMBER_INVALID = 19,
|
||||
// Access Error : Other Reason.
|
||||
DLMS_ERROR_CODE_OTHER_REASON = 250,
|
||||
//DLMS Standard error codes end here.
|
||||
//////////////////////////////////////////
|
||||
|
||||
//Unknown error.
|
||||
DLMS_ERROR_CODE_UNKNOWN,
|
||||
//Data send failed.
|
||||
DLMS_ERROR_CODE_SEND_FAILED,
|
||||
//Data receive failed.
|
||||
DLMS_ERROR_CODE_RECEIVE_FAILED,
|
||||
DLMS_ERROR_CODE_NOT_IMPLEMENTED,
|
||||
//Secure connection is not supported.
|
||||
DLMS_ERROR_CODE_DLMS_SECURITY_NOT_IMPLEMENTED,
|
||||
//Invalid DLMS command.
|
||||
DLMS_ERROR_CODE_INVALID_COMMAND,
|
||||
//Invalid Block number.
|
||||
DLMS_ERROR_CODE_INVALID_BLOCK_NUMBER,
|
||||
//Invalid parameter.
|
||||
DLMS_ERROR_CODE_INVALID_PARAMETER,
|
||||
//Server is not initialized.
|
||||
DLMS_ERROR_CODE_NOT_INITIALIZED,
|
||||
//Not enough memory available.
|
||||
DLMS_ERROR_CODE_OUTOFMEMORY,
|
||||
//Packet is not a reply for a send packet.
|
||||
DLMS_ERROR_CODE_NOT_REPLY,
|
||||
//Invalid Logical Name
|
||||
DLMS_ERROR_CODE_INVALID_LOGICAL_NAME,
|
||||
//Client HDLC Address is not set.
|
||||
DLMS_ERROR_CODE_INVALID_CLIENT_ADDRESS,
|
||||
//Server HDLC Address is not set.
|
||||
DLMS_ERROR_CODE_INVALID_SERVER_ADDRESS,
|
||||
//Not a HDLC frame.
|
||||
DLMS_ERROR_CODE_INVALID_DATA_FORMAT,
|
||||
//Invalid DLMS version number.
|
||||
DLMS_ERROR_CODE_INVALID_VERSION_NUMBER,
|
||||
//Client addresses do not match
|
||||
DLMS_ERROR_CODE_CLIENT_ADDRESS_NO_NOT_MATCH,
|
||||
//Server addresses do not match
|
||||
DLMS_ERROR_CODE_SERVER_ADDRESS_NO_NOT_MATCH,
|
||||
//CRC do not match.
|
||||
DLMS_ERROR_CODE_WRONG_CRC,
|
||||
//Invalid response
|
||||
DLMS_ERROR_CODE_INVALID_RESPONSE,
|
||||
//Invalid Tag.
|
||||
DLMS_ERROR_CODE_INVALID_TAG,
|
||||
//Encoding failed. Not enough data.
|
||||
DLMS_ERROR_CODE_ENCODING_FAILED,
|
||||
DLMS_ERROR_CODE_REJECTED_PERMAMENT,
|
||||
DLMS_ERROR_CODE_REJECTED_TRANSIENT,
|
||||
DLMS_ERROR_CODE_NO_REASON_GIVEN,
|
||||
DLMS_ERROR_CODE_APPLICATION_CONTEXT_NAME_NOT_SUPPORTED,
|
||||
DLMS_ERROR_CODE_AUTHENTICATION_MECHANISM_NAME_NOT_RECOGNISED,
|
||||
DLMS_ERROR_CODE_AUTHENTICATION_MECHANISM_NAME_REQUIRED,
|
||||
DLMS_ERROR_CODE_AUTHENTICATION_FAILURE,
|
||||
DLMS_ERROR_CODE_AUTHENTICATION_REQUIRED,
|
||||
//Invalid frame number.
|
||||
DLMS_ERROR_CODE_INVALID_FRAME_NUMBER,
|
||||
DLMS_ERROR_CODE_INVALID_DATE_TIME,
|
||||
DLMS_ERROR_CODE_INVALID_INVOKE_ID,
|
||||
//Invocation counter value is too small.
|
||||
DLMS_ERROR_CODE_INVOCATION_COUNTER_TOO_SMALL,
|
||||
//Client try to connect with wrong security.
|
||||
DLMS_ERROR_CODE_INVALID_DECIPHERING_ERROR,
|
||||
//Client try to connect with wrong security suite.
|
||||
DLMS_ERROR_CODE_INVALID_SECURITY_SUITE,
|
||||
//Serialization load failed.
|
||||
DLMS_ERROR_CODE_SERIALIZATION_LOAD_FAILURE,
|
||||
//Serialization save failed.
|
||||
DLMS_ERROR_CODE_SERIALIZATION_SAVE_FAILURE,
|
||||
//Serialization count failed.
|
||||
DLMS_ERROR_CODE_SERIALIZATION_COUNT_FAILURE
|
||||
}DLMS_ERROR_CODE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //DLMS_ERROR_CODE_H
|
||||
|
|
@ -0,0 +1,603 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_AES
|
||||
#include <string.h> // CBC mode, for memset
|
||||
#include <stdint.h>
|
||||
#include "gxaes.h"
|
||||
|
||||
#if defined(USE_AVR) || defined(ARDUINO_ARCH_AVR)
|
||||
//If AVR is used.
|
||||
#include <avr/pgmspace.h>
|
||||
#endif //#if defined(USE_AVR) || defined(ARDUINO_ARCH_AVR)
|
||||
|
||||
#define Nb 4
|
||||
#define BLOCKLEN 16 //Block length in bytes AES is 128b block only
|
||||
|
||||
#if defined(AES256) && (AES256 == 1)
|
||||
#define Nk 8
|
||||
#define KEYLEN 32
|
||||
#define Nr 14
|
||||
#define keyExpSize 240
|
||||
#elif defined(AES192) && (AES192 == 1)
|
||||
#define Nk 6
|
||||
#define KEYLEN 24
|
||||
#define Nr 12
|
||||
#define keyExpSize 208
|
||||
#else
|
||||
#define Nk 4 // The number of 32 bit words in a key.
|
||||
#define KEYLEN 16 // Key length in bytes
|
||||
#define Nr 10 // The number of rounds in AES Cipher.
|
||||
#define keyExpSize 176
|
||||
#endif
|
||||
|
||||
#ifndef MULTIPLY_AS_A_FUNCTION
|
||||
#define MULTIPLY_AS_A_FUNCTION 0
|
||||
#endif
|
||||
|
||||
// state - array holding the intermediate results during decryption.
|
||||
typedef unsigned char state_t[4][4];
|
||||
static state_t* state;
|
||||
|
||||
// The array that stores the round keys.
|
||||
static unsigned char RoundKey[keyExpSize];
|
||||
|
||||
// The Key input to the AES Program
|
||||
static const unsigned char* Key;
|
||||
|
||||
#if defined(CBC) && CBC
|
||||
// Initial Vector used only for CBC mode
|
||||
static unsigned char* Iv;
|
||||
#endif
|
||||
|
||||
#ifndef USE_PROGMEM
|
||||
static const unsigned char __SBOX[256] = {
|
||||
#else
|
||||
static const unsigned char __SBOX[256] PROGMEM = {
|
||||
#endif //#if defined(_WIN32) || defined(_WIN64)
|
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
|
||||
|
||||
#ifndef USE_PROGMEM
|
||||
static const unsigned char __RS_BOX[256] = {
|
||||
#else
|
||||
static const unsigned char __RS_BOX[256] PROGMEM = {
|
||||
#endif //#if defined(_WIN32) || defined(_WIN64)
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
|
||||
|
||||
// The round constant word array, Rcon[i], contains the values given by
|
||||
// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
|
||||
#ifndef USE_PROGMEM
|
||||
static const unsigned char __R_CON[11] = {
|
||||
#else
|
||||
static const unsigned char __R_CON[11] PROGMEM = {
|
||||
#endif //#if defined(_WIN32) || defined(_WIN64)
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
|
||||
|
||||
#if 0
|
||||
#ifndef USE_PROGMEM
|
||||
static const unsigned char __R_CON[256] = {
|
||||
#else
|
||||
static const unsigned char __R_CON[256] PROGMEM = {
|
||||
#endif //#if defined(_WIN32) || defined(_WIN64)
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
|
||||
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
|
||||
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
|
||||
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
|
||||
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
|
||||
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
|
||||
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
|
||||
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
|
||||
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
|
||||
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
|
||||
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
|
||||
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
|
||||
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
|
||||
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
|
||||
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
|
||||
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d };
|
||||
#endif
|
||||
|
||||
static unsigned char getSBoxValue(unsigned char offset)
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
//If Arduino is used data is read from flash like this.
|
||||
return pgm_read_byte_near(__SBOX + offset);
|
||||
#else
|
||||
return __SBOX[offset];
|
||||
#endif //ARDUINO_ARCH_AVR
|
||||
}
|
||||
|
||||
static unsigned char getSBoxInvert(unsigned char offset)
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
//If Arduino is used data is read from flash like this.
|
||||
return pgm_read_byte_near(__RS_BOX + offset);
|
||||
#else
|
||||
return __RS_BOX[offset];
|
||||
#endif //ARDUINO_ARCH_AVR
|
||||
}
|
||||
|
||||
static unsigned char getRCon(unsigned char offset)
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
//If Arduino is used data is read from flash like this.
|
||||
return pgm_read_byte_near(__R_CON + offset);
|
||||
#else
|
||||
return __R_CON[offset];
|
||||
#endif //ARDUINO_ARCH_AVR
|
||||
}
|
||||
|
||||
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
|
||||
static void KeyExpansion(void)
|
||||
{
|
||||
unsigned char k;
|
||||
uint32_t i;
|
||||
// Used for the column/row operations
|
||||
unsigned char tempa[4];
|
||||
|
||||
// The first round key is the key itself.
|
||||
for (i = 0; i < Nk; ++i)
|
||||
{
|
||||
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
|
||||
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
|
||||
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
|
||||
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
|
||||
}
|
||||
|
||||
// All other round keys are found from the previous round keys.
|
||||
//i == Nk
|
||||
for (; i < Nb * (Nr + 1); ++i)
|
||||
{
|
||||
{
|
||||
tempa[0] = RoundKey[(i - 1) * 4 + 0];
|
||||
tempa[1] = RoundKey[(i - 1) * 4 + 1];
|
||||
tempa[2] = RoundKey[(i - 1) * 4 + 2];
|
||||
tempa[3] = RoundKey[(i - 1) * 4 + 3];
|
||||
}
|
||||
|
||||
if (i % Nk == 0)
|
||||
{
|
||||
// This function shifts the 4 bytes in a word to the left once.
|
||||
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
|
||||
|
||||
// Function RotWord()
|
||||
{
|
||||
k = tempa[0];
|
||||
tempa[0] = tempa[1];
|
||||
tempa[1] = tempa[2];
|
||||
tempa[2] = tempa[3];
|
||||
tempa[3] = k;
|
||||
}
|
||||
|
||||
// SubWord() is a function that takes a four-byte input word and
|
||||
// applies the S-box to each of the four bytes to produce an output word.
|
||||
|
||||
// Function Subword()
|
||||
{
|
||||
tempa[0] = getSBoxValue(tempa[0]);
|
||||
tempa[1] = getSBoxValue(tempa[1]);
|
||||
tempa[2] = getSBoxValue(tempa[2]);
|
||||
tempa[3] = getSBoxValue(tempa[3]);
|
||||
}
|
||||
|
||||
tempa[0] = (unsigned char)(tempa[0] ^ getRCon((unsigned char)(i / Nk)));
|
||||
}
|
||||
#if defined(AES256) && (AES256 == 1)
|
||||
if (i % Nk == 4)
|
||||
{
|
||||
// Function Subword()
|
||||
{
|
||||
tempa[0] = getSBoxValue(tempa[0]);
|
||||
tempa[1] = getSBoxValue(tempa[1]);
|
||||
tempa[2] = getSBoxValue(tempa[2]);
|
||||
tempa[3] = getSBoxValue(tempa[3]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
RoundKey[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ tempa[0];
|
||||
RoundKey[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ tempa[1];
|
||||
RoundKey[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ tempa[2];
|
||||
RoundKey[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ tempa[3];
|
||||
}
|
||||
}
|
||||
|
||||
// This function adds the round key to state.
|
||||
// The round key is added to the state by an XOR function.
|
||||
static void AddRoundKey(unsigned char round)
|
||||
{
|
||||
unsigned char i, j;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
(*state)[i][j] ^= RoundKey[round * Nb * 4 + i * Nb + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The SubBytes Function Substitutes the values in the
|
||||
// state matrix with values in an S-box.
|
||||
static void SubBytes(void)
|
||||
{
|
||||
unsigned char i, j;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
(*state)[j][i] = getSBoxValue((*state)[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The ShiftRows() function shifts the rows in the state to the left.
|
||||
// Each row is shifted with different offset.
|
||||
// Offset = Row number. So the first row is not shifted.
|
||||
static void ShiftRows(void)
|
||||
{
|
||||
unsigned char temp;
|
||||
|
||||
// Rotate first row 1 columns to left
|
||||
temp = (*state)[0][1];
|
||||
(*state)[0][1] = (*state)[1][1];
|
||||
(*state)[1][1] = (*state)[2][1];
|
||||
(*state)[2][1] = (*state)[3][1];
|
||||
(*state)[3][1] = temp;
|
||||
|
||||
// Rotate second row 2 columns to left
|
||||
temp = (*state)[0][2];
|
||||
(*state)[0][2] = (*state)[2][2];
|
||||
(*state)[2][2] = temp;
|
||||
|
||||
temp = (*state)[1][2];
|
||||
(*state)[1][2] = (*state)[3][2];
|
||||
(*state)[3][2] = temp;
|
||||
|
||||
// Rotate third row 3 columns to left
|
||||
temp = (*state)[0][3];
|
||||
(*state)[0][3] = (*state)[3][3];
|
||||
(*state)[3][3] = (*state)[2][3];
|
||||
(*state)[2][3] = (*state)[1][3];
|
||||
(*state)[1][3] = temp;
|
||||
}
|
||||
|
||||
static unsigned char xtime(unsigned char x)
|
||||
{
|
||||
return (unsigned char)((x << 1) ^ (((x >> 7) & 1) * 0x1b));
|
||||
}
|
||||
|
||||
// MixColumns function mixes the columns of the state matrix
|
||||
static void MixColumns(void)
|
||||
{
|
||||
unsigned char i;
|
||||
unsigned char Tmp, Tm, t;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
t = (*state)[i][0];
|
||||
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3];
|
||||
Tm = (*state)[i][0] ^ (*state)[i][1]; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp;
|
||||
Tm = (*state)[i][1] ^ (*state)[i][2]; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp;
|
||||
Tm = (*state)[i][2] ^ (*state)[i][3]; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp;
|
||||
Tm = (*state)[i][3] ^ t; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply is used to multiply numbers in the field GF(2^8)
|
||||
#if MULTIPLY_AS_A_FUNCTION
|
||||
static unsigned char Multiply(unsigned char x, unsigned char y)
|
||||
{
|
||||
return (((y & 1) * x) ^
|
||||
((y >> 1 & 1) * xtime(x)) ^
|
||||
((y >> 2 & 1) * xtime(xtime(x))) ^
|
||||
((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^
|
||||
((y >> 4 & 1) * xtime(xtime(xtime(xtime(x))))));
|
||||
}
|
||||
#else
|
||||
#define Multiply(x, y) \
|
||||
( ((y & 1) * x) ^ \
|
||||
((y>>1 & 1) * xtime(x)) ^ \
|
||||
((y>>2 & 1) * xtime(xtime(x))) ^ \
|
||||
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
|
||||
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
|
||||
|
||||
#endif
|
||||
|
||||
// MixColumns function mixes the columns of the state matrix.
|
||||
// The method used to multiply may be difficult to understand for the inexperienced.
|
||||
// Please use the references to gain more information.
|
||||
static void InvMixColumns(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char a, b, c, d;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
a = (*state)[i][0];
|
||||
b = (*state)[i][1];
|
||||
c = (*state)[i][2];
|
||||
d = (*state)[i][3];
|
||||
|
||||
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
|
||||
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
|
||||
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
|
||||
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The SubBytes Function Substitutes the values in the
|
||||
// state matrix with values in an S-box.
|
||||
static void InvSubBytes(void)
|
||||
{
|
||||
unsigned char i, j;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
for (j = 0; j < 4; ++j)
|
||||
{
|
||||
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void InvShiftRows(void)
|
||||
{
|
||||
unsigned char temp;
|
||||
|
||||
// Rotate first row 1 columns to right
|
||||
temp = (*state)[3][1];
|
||||
(*state)[3][1] = (*state)[2][1];
|
||||
(*state)[2][1] = (*state)[1][1];
|
||||
(*state)[1][1] = (*state)[0][1];
|
||||
(*state)[0][1] = temp;
|
||||
|
||||
// Rotate second row 2 columns to right
|
||||
temp = (*state)[0][2];
|
||||
(*state)[0][2] = (*state)[2][2];
|
||||
(*state)[2][2] = temp;
|
||||
|
||||
temp = (*state)[1][2];
|
||||
(*state)[1][2] = (*state)[3][2];
|
||||
(*state)[3][2] = temp;
|
||||
|
||||
// Rotate third row 3 columns to right
|
||||
temp = (*state)[0][3];
|
||||
(*state)[0][3] = (*state)[1][3];
|
||||
(*state)[1][3] = (*state)[2][3];
|
||||
(*state)[2][3] = (*state)[3][3];
|
||||
(*state)[3][3] = temp;
|
||||
}
|
||||
|
||||
|
||||
// Cipher is the main function that encrypts the PlainText.
|
||||
static void Cipher(void)
|
||||
{
|
||||
unsigned char round = 0;
|
||||
|
||||
// Add the First round key to the state before starting the rounds.
|
||||
AddRoundKey(0);
|
||||
|
||||
// There will be Nr rounds.
|
||||
// The first Nr-1 rounds are identical.
|
||||
// These Nr-1 rounds are executed in the loop below.
|
||||
for (round = 1; round < Nr; ++round)
|
||||
{
|
||||
SubBytes();
|
||||
ShiftRows();
|
||||
MixColumns();
|
||||
AddRoundKey(round);
|
||||
}
|
||||
|
||||
// The last round is given below.
|
||||
// The MixColumns function is not here in the last round.
|
||||
SubBytes();
|
||||
ShiftRows();
|
||||
AddRoundKey(Nr);
|
||||
}
|
||||
|
||||
static void InvCipher(void)
|
||||
{
|
||||
unsigned char round = 0;
|
||||
|
||||
// Add the First round key to the state before starting the rounds.
|
||||
AddRoundKey(Nr);
|
||||
|
||||
// There will be Nr rounds.
|
||||
// The first Nr-1 rounds are identical.
|
||||
// These Nr-1 rounds are executed in the loop below.
|
||||
for (round = (Nr - 1); round > 0; --round)
|
||||
{
|
||||
InvShiftRows();
|
||||
InvSubBytes();
|
||||
AddRoundKey(round);
|
||||
InvMixColumns();
|
||||
}
|
||||
|
||||
// The last round is given below.
|
||||
// The MixColumns function is not here in the last round.
|
||||
InvShiftRows();
|
||||
InvSubBytes();
|
||||
AddRoundKey(0);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Public functions: */
|
||||
/*****************************************************************************/
|
||||
#if defined(ECB) && (ECB == 1)
|
||||
|
||||
void gxaes_ecb_encrypt(const unsigned char* input, const unsigned char* key, unsigned char* output, const size_t length)
|
||||
{
|
||||
// Copy input to output, and work in-memory on output
|
||||
memcpy(output, input, length);
|
||||
state = (state_t*)output;
|
||||
|
||||
Key = key;
|
||||
KeyExpansion();
|
||||
|
||||
// The next function call encrypts the PlainText with the Key using AES algorithm.
|
||||
Cipher();
|
||||
}
|
||||
|
||||
void gxaes_ecb_decrypt(const unsigned char* input, const unsigned char* key, unsigned char *output, const size_t length)
|
||||
{
|
||||
// Copy input to output, and work in-memory on output
|
||||
memcpy(output, input, length);
|
||||
state = (state_t*)output;
|
||||
|
||||
// The KeyExpansion routine must be called before encryption.
|
||||
Key = key;
|
||||
KeyExpansion();
|
||||
|
||||
InvCipher();
|
||||
}
|
||||
|
||||
|
||||
#endif // #if defined(ECB) && (ECB == 1)
|
||||
|
||||
#if defined(CBC) && (CBC == 1)
|
||||
|
||||
static void XorWithIv(unsigned char* buf)
|
||||
{
|
||||
unsigned char i;
|
||||
for (i = 0; i < BLOCKLEN; ++i) //WAS for(i = 0; i < KEYLEN; ++i) but the block in AES is always 128bit so 16 bytes!
|
||||
{
|
||||
buf[i] ^= Iv[i];
|
||||
}
|
||||
}
|
||||
|
||||
void gxaes_cbc_encrypt(unsigned char* output, unsigned char* input, uint32_t length, const unsigned char* key, const unsigned char* iv)
|
||||
{
|
||||
uintptr_t i;
|
||||
unsigned char extra = length % BLOCKLEN; /* Remaining bytes in the last non-full block */
|
||||
|
||||
// Skip the key expansion if key is passed as 0
|
||||
if (0 != key)
|
||||
{
|
||||
Key = key;
|
||||
KeyExpansion();
|
||||
}
|
||||
|
||||
if (iv != 0)
|
||||
{
|
||||
Iv = (unsigned char*)iv;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i += BLOCKLEN)
|
||||
{
|
||||
XorWithIv(input);
|
||||
memcpy(output, input, BLOCKLEN);
|
||||
state = (state_t*)output;
|
||||
Cipher();
|
||||
Iv = output;
|
||||
input += BLOCKLEN;
|
||||
output += BLOCKLEN;
|
||||
//printf("Step %d - %d", i/16, i);
|
||||
}
|
||||
|
||||
if (extra)
|
||||
{
|
||||
memcpy(output, input, extra);
|
||||
state = (state_t*)output;
|
||||
Cipher();
|
||||
}
|
||||
}
|
||||
|
||||
void gxaes_cbc_decrypt(unsigned char* output, unsigned char* input, uint32_t length, const unsigned char* key, const unsigned char* iv)
|
||||
{
|
||||
uintptr_t i;
|
||||
unsigned char extra = length % BLOCKLEN; /* Remaining bytes in the last non-full block */
|
||||
|
||||
// Skip the key expansion if key is passed as 0
|
||||
if (0 != key)
|
||||
{
|
||||
Key = key;
|
||||
KeyExpansion();
|
||||
}
|
||||
|
||||
// If iv is passed as 0, we continue to encrypt without re-setting the Iv
|
||||
if (iv != 0)
|
||||
{
|
||||
Iv = (unsigned char*)iv;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i += BLOCKLEN)
|
||||
{
|
||||
memcpy(output, input, BLOCKLEN);
|
||||
state = (state_t*)output;
|
||||
InvCipher();
|
||||
XorWithIv(output);
|
||||
Iv = input;
|
||||
input += BLOCKLEN;
|
||||
output += BLOCKLEN;
|
||||
}
|
||||
|
||||
if (extra)
|
||||
{
|
||||
memcpy(output, input, extra);
|
||||
state = (state_t*)output;
|
||||
InvCipher();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if defined(CBC) && (CBC == 1)
|
||||
|
||||
#endif //DLMS_IGNORE_AES
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXAES1
|
||||
#define GXAES1
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_AES
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CBC
|
||||
#define CBC 1
|
||||
#endif
|
||||
|
||||
#ifndef ECB
|
||||
#define ECB 1
|
||||
#endif
|
||||
|
||||
#define AES128 1
|
||||
//#define AES192 1
|
||||
//#define AES256 1
|
||||
|
||||
#if defined(ECB) && (ECB == 1)
|
||||
|
||||
void gxaes_ecb_encrypt(const unsigned char* input, const unsigned char* key, unsigned char *output, const size_t length);
|
||||
void gxaes_ecb_decrypt(const unsigned char* input, const unsigned char* key, unsigned char *output, const size_t length);
|
||||
|
||||
#endif // #if defined(ECB) && (ECB == !)
|
||||
|
||||
#if defined(CBC) && (CBC == 1)
|
||||
void gxaes_cbc_encrypt(unsigned char* output, unsigned char* input, uint32_t length, const unsigned char* key, const unsigned char* iv);
|
||||
void gxaes_cbc_decrypt(unsigned char* output, unsigned char* input, uint32_t length, const unsigned char* key, const unsigned char* iv);
|
||||
|
||||
#endif // #if defined(CBC) && (CBC == 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DLMS_IGNORE_AES
|
||||
#endif //GXAES1
|
||||
|
|
@ -0,0 +1,460 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxmem.h"
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "errorcodes.h"
|
||||
#include "gxarray.h"
|
||||
#include "bytebuffer.h"
|
||||
#include "gxkey.h"
|
||||
|
||||
//Initialize gxArray.
|
||||
void arr_init(gxArray* arr)
|
||||
{
|
||||
arr->capacity = 0;
|
||||
arr->data = NULL;
|
||||
arr->size = 0;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
arr->position = 0;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
char arr_isAttached(gxArray* arr)
|
||||
{
|
||||
return (arr->capacity & 0x8000) == 0x8000;
|
||||
}
|
||||
|
||||
uint16_t arr_getCapacity(gxArray* arr)
|
||||
{
|
||||
return arr->capacity & 0x7FFF;
|
||||
}
|
||||
|
||||
void arr_attach(
|
||||
gxArray* arr,
|
||||
void* value,
|
||||
uint16_t count,
|
||||
uint16_t capacity)
|
||||
{
|
||||
arr->data = value;
|
||||
arr->capacity = (uint16_t)(0x8000 | capacity);
|
||||
arr->size = count;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
arr->position = 0;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
|
||||
//Allocate new size for the array in bytes.
|
||||
int arr_capacity(gxArray* arr, int capacity)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (!arr_isAttached(arr))
|
||||
{
|
||||
if (capacity == 0)
|
||||
{
|
||||
if (arr->data != NULL)
|
||||
{
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = (void**)gxmalloc(capacity * sizeof(void*));
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef gxrealloc
|
||||
void* tmp = (void**)gxrealloc(arr->data, capacity * sizeof(void*));
|
||||
//If not enought memory available.
|
||||
if (tmp == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
arr->data = tmp;
|
||||
#else
|
||||
//If compiler doesn't support realloc.
|
||||
void* old = arr->data;
|
||||
arr->data = (void**)gxmalloc(capacity * sizeof(void*));
|
||||
//If not enought memory available.
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = old;
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(arr->data, old, sizeof(void*) * arr->size);
|
||||
gxfree(old);
|
||||
#endif // gxrealloc
|
||||
}
|
||||
}
|
||||
arr->capacity = (uint16_t)capacity;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
if (arr_getCapacity(arr) < capacity)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int arr_push(gxArray* arr, void* item)
|
||||
{
|
||||
if (arr->size >= arr->capacity)
|
||||
{
|
||||
int ret = arr_capacity(arr, arr->capacity + GXARRAY_CAPACITY);
|
||||
if (ret != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
arr->data[arr->size] = item;
|
||||
++arr->size;
|
||||
return 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
void arr_clear(
|
||||
gxArray* arr)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int pos;
|
||||
if (arr->size != 0)
|
||||
{
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
gxfree(arr->data[pos]);
|
||||
}
|
||||
}
|
||||
if (!arr_isAttached(arr) && arr->capacity != 0)
|
||||
{
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
arr->capacity = 0;
|
||||
}
|
||||
if (!arr_isAttached(arr))
|
||||
{
|
||||
arr->size = 0;
|
||||
}
|
||||
#else
|
||||
arr->size = 0;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
arr->position = 0;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
void arr_empty(
|
||||
gxArray* arr)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (arr->size != 0)
|
||||
{
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
}
|
||||
arr->capacity = 0;
|
||||
if (!arr_isAttached(arr))
|
||||
{
|
||||
arr->size = 0;
|
||||
}
|
||||
#else
|
||||
arr->size = 0;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
arr->position = 0;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int arr_get(gxArray* arr, void** value)
|
||||
{
|
||||
if (arr->position >= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
*value = arr->data[arr->position];
|
||||
++arr->position;
|
||||
return 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int arr_getByIndex(gxArray* arr, uint16_t index, void** value)
|
||||
{
|
||||
if (arr == NULL || value == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
if (index >= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
*value = arr->data[index];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arr_getByIndex3(gxArray* arr, uint16_t index, void** value, unsigned char checkSize)
|
||||
{
|
||||
if (arr == NULL || value == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
if (index >= arr->size)
|
||||
{
|
||||
if (checkSize || index >= arr->capacity)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
*value = arr->data[index];
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int arr_getByIndex(gxArray* arr, uint16_t index, void** value, uint16_t itemSize)
|
||||
{
|
||||
if (arr == NULL || value == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
if (index >= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
*value = (void*)((unsigned char*)arr->data + (index * itemSize));
|
||||
return 0;
|
||||
}
|
||||
int arr_getByIndex3(gxArray* arr, uint16_t index, void** value, uint16_t itemSize, unsigned char checkSize)
|
||||
{
|
||||
if (arr == NULL || value == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
if (index >= arr->size)
|
||||
{
|
||||
if (checkSize || index >= arr->capacity)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
*value = (void*)((unsigned char*)arr->data + (index * itemSize));
|
||||
return 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
|
||||
int arr_getByIndex2(gxArray* arr, uint16_t index, void** value, uint16_t itemSize)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
return arr_getByIndex(arr, index, value);
|
||||
#else
|
||||
return arr_getByIndex(arr, index, value, itemSize);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
int arr_getByIndex4(gxArray* arr, uint16_t index, void** value, uint16_t itemSize, unsigned char checkSize)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
return arr_getByIndex3(arr, index, value, checkSize);
|
||||
#else
|
||||
return arr_getByIndex3(arr, index, value, itemSize, checkSize);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
int arr_getByIndexRef(gxArray* arr, uint16_t index, void** value)
|
||||
{
|
||||
if (arr == NULL || value == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
if (index >= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
*value = (void*)((gxArray**)arr->data)[index];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arr_setByIndexRef(gxArray* arr, void* value)
|
||||
{
|
||||
if (!(arr->size < arr_getCapacity(arr)))
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
((gxArray**)arr->data)[arr->size] = value;
|
||||
++arr->size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void arr_clearKeyValuePair(gxArray* arr)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxKey* k;
|
||||
int pos;
|
||||
if (arr->capacity != 0)
|
||||
{
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
k = (gxKey*)arr->data[pos];
|
||||
gxfree(k->key);
|
||||
gxfree(k->value);
|
||||
gxfree(k);
|
||||
}
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
arr->capacity = 0;
|
||||
arr->size = 0;
|
||||
arr->position = 0;
|
||||
}
|
||||
#else
|
||||
arr_clear(arr);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
void arr_clearStrings(gxArray* arr)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer* it;
|
||||
int pos;
|
||||
if (arr->capacity != 0)
|
||||
{
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
it = (gxByteBuffer*)arr->data[pos];
|
||||
gxfree(it->data);
|
||||
gxfree(it);
|
||||
}
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
arr->capacity = 0;
|
||||
arr->size = 0;
|
||||
arr->position = 0;
|
||||
}
|
||||
#else
|
||||
arr_clear(arr);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int arr_removeByIndex(gxArray* arr, uint16_t index, void** value)
|
||||
{
|
||||
int pos;
|
||||
if (index >= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
if (value != NULL)
|
||||
{
|
||||
*value = arr->data[index];
|
||||
}
|
||||
for (pos = index; pos != arr->size; ++pos)
|
||||
{
|
||||
arr->data[pos] = arr->data[pos + 1];
|
||||
}
|
||||
--arr->size;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int arr_removeByIndex(
|
||||
gxArray* arr,
|
||||
uint16_t index,
|
||||
uint16_t itemSize)
|
||||
{
|
||||
int ret;
|
||||
uint16_t pos;
|
||||
void* prev = NULL;
|
||||
void* item = NULL;
|
||||
if ((ret = arr_getByIndex(arr, index, &prev, itemSize)) == 0)
|
||||
{
|
||||
for (pos = index + 1; pos < arr->size; ++pos)
|
||||
{
|
||||
if ((ret = arr_getByIndex(arr, pos, &item, itemSize)) == 0)
|
||||
{
|
||||
memcpy(prev, item, itemSize);
|
||||
prev = item;
|
||||
}
|
||||
}
|
||||
--arr->size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int arr_swap(gxArray* arr, uint16_t index1, uint16_t index2)
|
||||
{
|
||||
void* tmp;
|
||||
if (!(index1 < arr->size || index2 < arr->size))
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
tmp = arr->data[index1];
|
||||
arr->data[index1] = arr->data[index2];
|
||||
arr->data[index2] = tmp;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int arr_swap(
|
||||
gxArray* arr,
|
||||
uint16_t index1,
|
||||
uint16_t index2,
|
||||
uint16_t itemSize,
|
||||
void* tmp)
|
||||
{
|
||||
int ret;
|
||||
void* prev = NULL;
|
||||
void* item = NULL;
|
||||
if ((ret = arr_getByIndex(arr, index1, &prev, itemSize)) == 0 &&
|
||||
(ret = arr_getByIndex(arr, index2, &item, itemSize)) == 0)
|
||||
{
|
||||
memcpy(tmp, prev, itemSize);
|
||||
memcpy(prev, item, itemSize);
|
||||
memcpy(item, tmp, itemSize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXARRAY_H
|
||||
#define GXARRAY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <string.h> /* memset */
|
||||
#include "gxint.h"
|
||||
|
||||
#define GXARRAY_CAPACITY 10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
void** data;
|
||||
#else
|
||||
void* data;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
uint16_t capacity;
|
||||
uint16_t size;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int position;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
} gxArray;
|
||||
|
||||
//Initialize gxArray.
|
||||
void arr_init(gxArray* arr);
|
||||
|
||||
void arr_attach(
|
||||
gxArray* arr,
|
||||
void* value,
|
||||
uint16_t count,
|
||||
uint16_t capacity);
|
||||
/*
|
||||
* Is static buffer used.
|
||||
*/
|
||||
char arr_isAttached(
|
||||
gxArray* arr);
|
||||
|
||||
/*Get maximum buffer size.*/
|
||||
uint16_t arr_getCapacity(
|
||||
gxArray* arr);
|
||||
|
||||
//Allocate new size for the array in bytes.
|
||||
int arr_capacity(gxArray* arr, int capacity);
|
||||
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Push new data to the gxArray.
|
||||
int arr_push(gxArray* arr, void* item);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Clear array. All items are automatically free.
|
||||
void arr_clear(gxArray* arr);
|
||||
|
||||
//Empty array but is not free items.
|
||||
void arr_empty(
|
||||
gxArray* arr);
|
||||
|
||||
//Clear key value pair array. All items are automatically free.
|
||||
void arr_clearKeyValuePair(gxArray* arr);
|
||||
|
||||
//Clear string array.
|
||||
void arr_clearStrings(gxArray* arr);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int arr_get(gxArray* arr, void** value);
|
||||
|
||||
int arr_getByIndex(
|
||||
gxArray* arr,
|
||||
uint16_t index,
|
||||
void** value);
|
||||
|
||||
int arr_getByIndex3(
|
||||
gxArray* arr,
|
||||
uint16_t index,
|
||||
void** value,
|
||||
unsigned char checkSize);
|
||||
|
||||
int arr_removeByIndex(
|
||||
gxArray* arr,
|
||||
uint16_t index,
|
||||
void** value);
|
||||
|
||||
//Swap two array items.
|
||||
int arr_swap(gxArray* arr, uint16_t index1, uint16_t index2);
|
||||
#else
|
||||
int arr_getByIndex(
|
||||
gxArray* arr,
|
||||
uint16_t index,
|
||||
void** value,
|
||||
uint16_t itemSize);
|
||||
|
||||
int arr_getByIndex3(
|
||||
gxArray* arr,
|
||||
uint16_t index,
|
||||
void** value,
|
||||
uint16_t itemSize,
|
||||
unsigned char checkSize);
|
||||
|
||||
int arr_removeByIndex(
|
||||
gxArray* arr,
|
||||
uint16_t index,
|
||||
uint16_t itemSize);
|
||||
|
||||
//Swap two array items.
|
||||
int arr_swap(
|
||||
gxArray* arr,
|
||||
uint16_t index1,
|
||||
uint16_t index2,
|
||||
uint16_t itemSize,
|
||||
void* tmp);
|
||||
|
||||
//This method is used to access array where items are saved with pointer.
|
||||
//Example: registerAssignment.
|
||||
int arr_getByIndexRef(gxArray* arr, uint16_t index, void** value);
|
||||
|
||||
int arr_setByIndexRef(gxArray* arr, void* value);
|
||||
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
int arr_getByIndex2(gxArray* arr, uint16_t index, void** value, uint16_t itemSize);
|
||||
int arr_getByIndex4(gxArray* arr, uint16_t index, void** value, uint16_t itemSize, unsigned char checkSize);
|
||||
|
||||
#define ARR_ATTACH(X, V, S) arr_attach(&X, V, S, sizeof(V)/sizeof(V[0]))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXARRAY_H
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef GXDEFINE_H
|
||||
#define GXDEFINE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Define max user name length.
|
||||
#define MAX_USER_NAME_LENGTH 20
|
||||
|
||||
//Define max destination length.
|
||||
#define MAX_DESTINATION_LENGTH 20
|
||||
|
||||
//Define max SAP logical device name length.
|
||||
#define MAX_SAP_LOGICAL_DEVICE_NAME_LENGTH 20
|
||||
|
||||
//Define max season profile name length.
|
||||
#define MAX_SEASON_PROFILE_NAME_LENGTH 20
|
||||
|
||||
//Define max season profile name length.
|
||||
#define MAX_SEASON_PROFILE_NAME_LENGTH 20
|
||||
|
||||
//Define max season profile week name length.
|
||||
#define MAX_SEASON_PROFILE_WEEK_NAME_LENGTH 20
|
||||
|
||||
//Define max week profile name length.
|
||||
#define MAX_SEASON_WEEK_PROFILE_NAME_LENGTH 20
|
||||
|
||||
//Define max IP4 setup IP option data length.
|
||||
#define MAX_IP4_SETUP_IP_OPTION_DATA_LENGTH 20
|
||||
|
||||
//Define max SAP item name length.
|
||||
#define MAX_SAP_ITEM_NAME_LENGTH 20
|
||||
|
||||
//Define max modem initialization string length.
|
||||
#define MAX_MODEM_INITIALIZATION_STRING_LENGTH 20
|
||||
|
||||
//Define max modem profile string length.
|
||||
#define MAX_MODEM_PROFILE_STRING_LENGTH 20
|
||||
|
||||
//Define max certificate serial number length.
|
||||
#define MAX_CERTIFICATE_SERIAL_NUMBER_LENGTH 20
|
||||
|
||||
//Define max certificate issuer length.
|
||||
#define MAX_CERTIFICATE_ISSUER_LENGTH 40
|
||||
|
||||
//Define max certificate subject length.
|
||||
#define MAX_CERTIFICATE_SUBJECT_LENGTH 20
|
||||
|
||||
//Define max function name length.
|
||||
#define MAX_FUNCTION_NAME_LENGTH 10
|
||||
|
||||
//Define max function target length.
|
||||
#define MAX_FUNCTION_TARGET_LENGTH 10
|
||||
|
||||
//Define max certificate subject alt length.
|
||||
#define MAX_CERTIFICATE_SUBJECT_ALT_LENGTH 40
|
||||
|
||||
//Define max certificate subject alt length.
|
||||
#define MAX_CAPTURE_DEFINITION_ELEMENT_LENGTH 100
|
||||
|
||||
//Define max certificate subject alt length.
|
||||
#define MAX_CHARGE_TABLE_INDEX_LENGTH 100
|
||||
|
||||
//Define max certificate subject alt length.
|
||||
#define MAX_TOKEN_GATEWAY_DESCRIPTION_LENGTH 20
|
||||
|
||||
//Define max image identification length.
|
||||
#define MAX_IMAGE_IDENTIFICATION_LENGTH 20
|
||||
|
||||
//Define image signature length.
|
||||
#define MAX_IMAGE_SIGNATURE_LENGTH 20
|
||||
|
||||
//Define max push setup target length.
|
||||
#define MAX_PUSH_SETUP_TARGET_LENGTH 20
|
||||
|
||||
//Define max currency name length.
|
||||
#define MAX_CURRENCY_NAME_LENGTH 20
|
||||
|
||||
//Define max client PDU size.
|
||||
#define MAX_CLIENT_PDU_SIZE 200
|
||||
|
||||
//Define max capture object buffer size.
|
||||
#define MAX_CAPTURE_OBJECT_BUFFER_SIZE 100
|
||||
|
||||
//Define max challenge size.
|
||||
#define MAX_CHALLENGE_SIZE 64
|
||||
|
||||
//Define max register activation mask name length.
|
||||
#define MAX_REGISTER_ACTIVATION_MASK_NAME_LENGTH 10
|
||||
|
||||
//Define max reporting system item name length.
|
||||
#define MAX_REPORTING_SYSTEM_ITEM_LENGTH 20
|
||||
|
||||
//Define max SAP item count. This is used when data is serialized.
|
||||
#define MAX_SAP_ITEM_SERIALIZE_COUNT 5
|
||||
|
||||
//Define key size for G3 MAC key table.
|
||||
#define MAX_G3_MAC_KEY_TABLE_KEY_SIZE 16
|
||||
|
||||
//Define neighbour table gain item size for G3 MAC Setup object.
|
||||
#define MAX_G3_MAC_NEIGHBOUR_TABLE_GAIN_ITEM_SIZE 6
|
||||
|
||||
//Define neighbour table gain size for G3 MAC Setup object.
|
||||
#define MAX_G3_MAC_NEIGHBOUR_TABLE_GAIN_SIZE 5
|
||||
|
||||
//Define neighbour table tone map item size in bytes for G3 MAC Setup object.
|
||||
#define MAX_G3_MAC_NEIGHBOUR_TABLE_TONE_MAP_ITEM_SIZE 3
|
||||
|
||||
//Define neighbour table tone map size for G3 MAC Setup object.
|
||||
#define MAX_G3_MAC_NEIGHBOUR_TABLE_TONE_MAP_SIZE 5
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXDEFINE_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,296 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef COSEM_GET_H
|
||||
#define COSEM_GET_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxobjects.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
int cosem_getData(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getRegister(
|
||||
gxValueEventArg* e);
|
||||
|
||||
#ifndef DLMS_IGNORE_CLOCK
|
||||
int cosem_getClock(
|
||||
gxValueEventArg* e);
|
||||
|
||||
//Update Daylight Saving time flag if DST is used.
|
||||
void clock_updateDST(
|
||||
gxClock* object,
|
||||
gxtime* value);
|
||||
|
||||
//Convert UTC date time to meter date time.
|
||||
int clock_utcToMeterTime(
|
||||
gxClock* object,
|
||||
gxtime* value);
|
||||
|
||||
#endif // DLMS_IGNORE_CLOCK
|
||||
|
||||
int cosem_getActionSchedule(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getActivityCalendar(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getAssociationLogicalName(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventArg* e);
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
int cosem_getAssociationShortName(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
int cosem_getAutoAnswer(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getAutoConnect(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getDemandRegister(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getMacAddressSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getExtendedRegister(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getGprsSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getSecuritySetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getIecHdlcSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getIecLocalPortSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getIP4Setup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getProfileGeneric(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getMbusSlavePortSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getDisconnectControl(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getLimiter(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getmMbusClient(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getModemConfiguration(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getPppSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getRegisterActivation(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getRegisterMonitor(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getSapAssignment(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getSchedule(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getScriptTable(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getSpecialDaysTable(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getTcpUdpSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getMbusMasterPortSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getMessageHandler(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getPushSetup(
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getValue(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventArg* e);
|
||||
|
||||
|
||||
#ifndef DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
int cosem_getG3PlcMacSetupNeighbourTables(
|
||||
gxArray* tables,
|
||||
uint16_t address,
|
||||
uint16_t count,
|
||||
gxValueEventArg* e);
|
||||
|
||||
int cosem_getG3PlcMacSetupPosTables(
|
||||
gxArray* tables,
|
||||
uint16_t address,
|
||||
uint16_t count,
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int cosem_getRow(
|
||||
gxArray* table,
|
||||
int index,
|
||||
gxArray* captureObjects,
|
||||
gxArray* columns,
|
||||
gxByteBuffer* data);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
int cosem_getTariffPlan(
|
||||
gxValueEventArg* e);
|
||||
|
||||
#ifndef DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
int cosem_getGsmDiagnostic(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
|
||||
#ifndef DLMS_IGNORE_PARAMETER_MONITOR
|
||||
int cosem_getParameterMonitor(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_PARAMETER_MONITOR
|
||||
|
||||
#ifndef DLMS_IGNORE_COMPACT_DATA
|
||||
//Convert compact data buffer to array of values.
|
||||
int compactData_getValues(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* templateDescription,
|
||||
gxByteBuffer* buffer,
|
||||
variantArray* values);
|
||||
#endif //DLMS_IGNORE_COMPACT_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
int cosem_getLlcSscsSetup(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
int cosem_getPrimeNbOfdmPlcPhysicalLayerCounters(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
int cosem_getPrimeNbOfdmPlcMacSetup(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
int cosem_getPrimeNbOfdmPlcMacFunctionalParameters(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
int cosem_getPrimeNbOfdmPlcMacCounters(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
int cosem_getPrimeNbOfdmPlcMacNetworkAdministrationData(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
int cosem_getPrimeNbOfdmPlcApplicationsIdentification(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
#ifndef DLMS_IGNORE_ARBITRATOR
|
||||
int cosem_getArbitrator(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_ARBITRATOR
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
||||
int cosem_getIec8802LlcType1Setup(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
||||
int cosem_getIec8802LlcType2Setup(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
||||
int cosem_getIec8802LlcType3Setup(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
||||
#ifndef DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
||||
int cosem_getSFSKActiveInitiator(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
||||
#ifndef DLMS_IGNORE_SFSK_MAC_COUNTERS
|
||||
int cosem_getFSKMacCounters(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_SFSK_MAC_COUNTERS
|
||||
#ifndef DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
||||
int cosem_getSFSKMacSynchronizationTimeouts(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
||||
#ifndef DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
||||
int cosem_getSFSKPhyMacSetUp(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
||||
#ifndef DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
||||
int cosem_getSFSKReportingSystemList(
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
||||
|
||||
#ifdef DLMS_ITALIAN_STANDARD
|
||||
//Convert compact data buffer to array of values.
|
||||
//Some Italy meters require that there is a array count in data.
|
||||
//This is against compact data structure defined in DLMS standard.
|
||||
int compactData_getValues2(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* templateDescription,
|
||||
gxByteBuffer* buffer,
|
||||
variantArray* values,
|
||||
unsigned char appendAA);
|
||||
#endif //DLMS_ITALIAN_STANDARD
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //COSEM_GET_H
|
||||
|
|
@ -0,0 +1,252 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef GXIGNORE_H
|
||||
#define GXIGNORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Uncomment defines to ignore non-needed parts to make image size smaller. */
|
||||
|
||||
// #define DLMS_IGNORE_HDLC
|
||||
// #define DLMS_IGNORE_WRAPPER
|
||||
// #define DLMS_IGNORE_PLC
|
||||
// #define DLMS_IGNORE_IEC
|
||||
// #define DLMS_IGNORE_NOTIFY
|
||||
// #define DLMS_IGNORE_SERVER
|
||||
// #define DLMS_IGNORE_CLIENT
|
||||
// #define GX_DLMS_MICROCONTROLLER
|
||||
// #define DLMS_IGNORE_HIGH_SHA256
|
||||
// #define DLMS_IGNORE_HIGH_SHA1
|
||||
// #define DLMS_IGNORE_HIGH_MD5
|
||||
// #define DLMS_IGNORE_AES
|
||||
// #define DLMS_IGNORE_HIGH_GMAC
|
||||
// #define DLMS_IGNORE_DATA
|
||||
// #define DLMS_IGNORE_REGISTER
|
||||
// #define DLMS_IGNORE_EXTENDED_REGISTER
|
||||
// #define DLMS_IGNORE_DEMAND_REGISTER
|
||||
// #define DLMS_IGNORE_REGISTER_ACTIVATION
|
||||
// #define DLMS_IGNORE_PROFILE_GENERIC
|
||||
// #define DLMS_IGNORE_CLOCK
|
||||
// #define DLMS_IGNORE_SCRIPT_TABLE
|
||||
// #define DLMS_IGNORE_SCHEDULE
|
||||
// #define DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
||||
// #define DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
// #define DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
||||
// #define DLMS_IGNORE_SAP_ASSIGNMENT
|
||||
// #define DLMS_IGNORE_IMAGE_TRANSFER
|
||||
// #define DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
// #define DLMS_IGNORE_ACTIVITY_CALENDAR
|
||||
// #define DLMS_IGNORE_REGISTER_MONITOR
|
||||
// #define DLMS_IGNORE_ACTION_SCHEDULE
|
||||
// #define DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
// #define DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
||||
// #define DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
||||
// #define DLMS_IGNORE_UTILITY_TABLES
|
||||
// #define DLMS_IGNORE_MODEM_CONFIGURATION
|
||||
// #define DLMS_IGNORE_AUTO_ANSWER
|
||||
// #define DLMS_IGNORE_AUTO_CONNECT
|
||||
// #define DLMS_IGNORE_TCP_UDP_SETUP
|
||||
// #define DLMS_IGNORE_IP4_SETUP
|
||||
// #define DLMS_IGNORE_IP6_SETUP
|
||||
// #define DLMS_IGNORE_MAC_ADDRESS_SETUP
|
||||
// #define DLMS_IGNORE_PPP_SETUP
|
||||
// #define DLMS_IGNORE_GPRS_SETUP
|
||||
// #define DLMS_IGNORE_SMTP_SETUP
|
||||
// #define DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
// #define DLMS_IGNORE_REGISTER_TABLE
|
||||
// #define DLMS_IGNORE_STATUS_MAPPING
|
||||
// #define DLMS_IGNORE_SECURITY_SETUP
|
||||
// #define DLMS_IGNORE_DISCONNECT_CONTROL
|
||||
// #define DLMS_IGNORE_LIMITER
|
||||
// #define DLMS_IGNORE_MBUS_CLIENT
|
||||
// #define DLMS_IGNORE_PUSH_SETUP
|
||||
// #define DLMS_IGNORE_PARAMETER_MONITOR
|
||||
// #define DLMS_IGNORE_WIRELESS_MODE_Q_CHANNEL
|
||||
// #define DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
||||
// #define DLMS_IGNORE_ZIG_BEE_SAS_STARTUP
|
||||
// #define DLMS_IGNORE_ZIG_BEE_SAS_JOIN
|
||||
// #define DLMS_IGNORE_ZIG_BEE_SAS_APS_FRAGMENTATION
|
||||
// #define DLMS_IGNORE_ZIG_BEE_NETWORK_CONTROL
|
||||
// #define DLMS_IGNORE_DATA_PROTECTION
|
||||
// #define DLMS_IGNORE_ACCOUNT
|
||||
// #define DLMS_IGNORE_CREDIT
|
||||
// #define DLMS_IGNORE_CHARGE
|
||||
// #define DLMS_IGNORE_TOKEN_GATEWAY
|
||||
// #define DLMS_IGNORE_COMPACT_DATA
|
||||
// #define DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
// #define DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
// #define DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
// #define DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
// #define DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
// #define DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
// #define DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
// #define DLMS_IGNORE_ARBITRATOR
|
||||
// #define DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
||||
// #define DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
// #define DLMS_IGNORE_G3_PLC_6LO_WPAN
|
||||
// #define DLMS_IGNORE_FUNCTION_CONTROL
|
||||
// #define DLMS_IGNORE_ARRAY_MANAGER
|
||||
|
||||
// #define DLMS_IGNORE_MALLOC
|
||||
// #define DLMS_USE_CUSTOM_MALLOC
|
||||
|
||||
// #define DLMS_IGNORE_OBJECT_POINTERS
|
||||
|
||||
// #define DLMS_IGNORE_FLOAT32
|
||||
// #define DLMS_IGNORE_FLOAT64
|
||||
|
||||
//Use EPOCH time. This can be used to improve memory usage.
|
||||
// #define DLMS_USE_EPOCH_TIME
|
||||
|
||||
//Use UTC time zone. Read more: https://www.gurux.fi/Gurux.DLMS.Objects.GXDLMSClock
|
||||
// #define DLMS_USE_UTC_TIME_ZONE
|
||||
|
||||
// #define DLMS_IGNORE_SET
|
||||
// #define DLMS_IGNORE_ACTION
|
||||
|
||||
// String converters are not used.
|
||||
// #define DLMS_IGNORE_STRING_CONVERTER
|
||||
|
||||
//Framework send debug information that can be used in debugging.
|
||||
// #define DLMS_DEBUG
|
||||
|
||||
//Defined if AVR is used.
|
||||
// #define USE_AVR
|
||||
|
||||
//Defined if program memory (flash) is used instead of SRAM.
|
||||
// #define USE_PROGMEM
|
||||
|
||||
// COSEM objects are using DLMS standard data types.
|
||||
// Using exact data types will save memory, but reading failes if meter returns wrong data type,
|
||||
// ex. Int8 when data type should be UInt8.
|
||||
// #define DLMS_COSEM_EXACT_DATA_TYPES
|
||||
|
||||
// If innovation counter size is UInt64 and not default UInt32.
|
||||
// #define DLMS_COSEM_INVOCATION_COUNTER_SIZE64
|
||||
|
||||
// Use 32 bit max size bytebuffer instead of 16 bit.
|
||||
// This might be used in client side if a lot of data is read from the meter.
|
||||
// #define GX_DLMS_BYTE_BUFFER_SIZE_32
|
||||
|
||||
//Serializer is not used.
|
||||
//DLMS_IGNORE_SERIALIZER
|
||||
//Serializer is used instead of file system.
|
||||
//#define GX_DLMS_SERIALIZER
|
||||
|
||||
//GENERAL_CIPHERING is not used.
|
||||
//#define DLMS_IGNORE_GENERAL_CIPHERING
|
||||
|
||||
/**
|
||||
* Ignore HDLC Control field check.
|
||||
Some meters are sending invalid control field.
|
||||
Note! It's not recommended to use this.
|
||||
*/
|
||||
//#define DLMS_IGNORE_HDLC_CHECK
|
||||
|
||||
// #define DLMS_ITALIAN_STANDARD
|
||||
// #define DLMS_INDONESIA_STANDARD
|
||||
|
||||
#ifdef ARDUINO
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//If Arduino is used.
|
||||
#include "ArduinoIgnore.h"
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif //ARDUINO
|
||||
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//If Arduino is used.
|
||||
#include "ArduinoIgnore.h"
|
||||
#define DLMS_IGNORE_IP6_SETUP
|
||||
#define DLMS_USE_EPOCH_TIME
|
||||
#define DLMS_IGNORE_NOTIFY
|
||||
#define GX_DLMS_MICROCONTROLLER
|
||||
#define DLMS_IGNORE_HIGH_SHA256
|
||||
#define DLMS_IGNORE_HIGH_SHA1
|
||||
#define DLMS_IGNORE_HIGH_MD5
|
||||
#define USE_PROGMEM
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif //ARDUINO_ARCH_AVR
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//If Arduino ESP32 is used.
|
||||
#include "ArduinoIgnore.h"
|
||||
#define DLMS_IGNORE_IP6_SETUP
|
||||
#define DLMS_USE_EPOCH_TIME
|
||||
#define DLMS_IGNORE_NOTIFY
|
||||
#define GX_DLMS_MICROCONTROLLER
|
||||
#define DLMS_IGNORE_HIGH_SHA256
|
||||
#define DLMS_IGNORE_HIGH_SHA1
|
||||
#define DLMS_IGNORE_HIGH_MD5
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif //ARDUINO_ARCH_ESP32
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//If Arduino ESP is used.
|
||||
#include "ArduinoIgnore.h"
|
||||
#ifndef ESP_PLATFORM
|
||||
#define ESP_PLATFORM
|
||||
#endif
|
||||
#define DLMS_IGNORE_IP6_SETUP
|
||||
#define DLMS_USE_EPOCH_TIME
|
||||
#define DLMS_IGNORE_NOTIFY
|
||||
#define GX_DLMS_MICROCONTROLLER
|
||||
#define DLMS_IGNORE_HIGH_SHA256
|
||||
#define DLMS_IGNORE_HIGH_SHA1
|
||||
#define DLMS_IGNORE_HIGH_MD5
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif //ARDUINO_ARCH_ESP8266
|
||||
|
||||
#ifdef USE_ESP32_FRAMEWORK_ESP_IDF
|
||||
#include "ArduinoIgnore.h"
|
||||
#ifndef ESP_PLATFORM
|
||||
#define ESP_PLATFORM
|
||||
#endif
|
||||
#define DLMS_IGNORE_IP6_SETUP
|
||||
#define DLMS_USE_EPOCH_TIME
|
||||
#define DLMS_IGNORE_NOTIFY
|
||||
#define DLMS_IGNORE_FUNCTION_CONTROL
|
||||
#define GX_DLMS_MICROCONTROLLER
|
||||
#define DLMS_IGNORE_HIGH_SHA256
|
||||
#define DLMS_IGNORE_HIGH_SHA1
|
||||
#define DLMS_IGNORE_HIGH_MD5
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXIGNORE_H
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXINT_H
|
||||
#define GXINT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if !(defined uint16_t) && !(defined _UINT16_T_DECLARED)
|
||||
#define uint16_t unsigned short
|
||||
#endif //!(defined uint16_t) && !(defined _UINT16_T_DECLARED)
|
||||
#if !(defined uint32_t) && !(defined _UINT32_T_DECLARED)
|
||||
#define uint32_t unsigned long
|
||||
#endif //!(defined uint32_t) && !(defined _UINT32_T_DECLARED)
|
||||
#if !(defined uint64_t) && !(defined _UINT64_T_DECLARED)
|
||||
#define uint64_t unsigned long long
|
||||
#endif //#!(defined uint64_t) && !(defined _UINT64_T_DECLARED)
|
||||
|
||||
#if !(defined int16_t) && !(defined _INT16_T_DECLARED)
|
||||
#define int16_t short
|
||||
#endif //!(defined int16_t) && !(defined _INT16_T_DECLARED)
|
||||
#if !(defined int32_t) && !(defined _INT32_T_DECLARED)
|
||||
#define int32_t long
|
||||
#endif //!(defined int32_t) && !(defined _INT32_T_DECLARED)
|
||||
#if !(defined int64_t) && !(defined _INT64_T_DECLARED)
|
||||
#define int64_t long long
|
||||
#endif //!(defined int64_t) && !(defined _INT64_T_DECLARED)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXINT_H
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxmem.h"
|
||||
#include "gxkey.h"
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxKey* key_init(void* key, void* value)
|
||||
{
|
||||
gxKey* obj = (gxKey*) gxmalloc(sizeof(gxKey));
|
||||
if (obj != NULL)
|
||||
{
|
||||
obj->key = key;
|
||||
obj->value = value;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
gxKey2* key_init2(unsigned char key, void* value)
|
||||
{
|
||||
gxKey2* obj = (gxKey2*)gxmalloc(sizeof(gxKey2));
|
||||
if (obj != NULL)
|
||||
{
|
||||
obj->key = key;
|
||||
obj->value = value;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXKEY_H
|
||||
#define GXKEY_H
|
||||
#include "gxignore.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
|
||||
typedef struct {
|
||||
void *key;
|
||||
void *value;
|
||||
} gxKey;
|
||||
|
||||
typedef struct {
|
||||
unsigned char key;
|
||||
void *value;
|
||||
} gxKey2;
|
||||
|
||||
//Make key.
|
||||
gxKey* key_init(void* key, void* value);
|
||||
|
||||
gxKey2* key_init2(unsigned char key, void* value);
|
||||
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //GXKEY_H
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GX_MEM
|
||||
#define GX_MEM
|
||||
#include "gxignore.h"
|
||||
#if !defined(DLMS_USE_CUSTOM_MALLOC) && !defined(DLMS_IGNORE_MALLOC)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> // malloc and free needs this or error is generated.
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
#ifndef gxfree
|
||||
#define gxfree(p) free(p)
|
||||
#endif
|
||||
|
||||
#ifndef gxmalloc
|
||||
#define gxmalloc(s) malloc(s)
|
||||
#endif
|
||||
|
||||
#ifndef gxcalloc
|
||||
#define gxcalloc(p, s) calloc(p, s)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef gxrealloc
|
||||
#define gxrealloc(p, s) realloc(p, s)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //!defined(DLMS_USE_CUSTOM_MALLOC) && !defined(DLMS_IGNORE_MALLOC)
|
||||
#endif //GX_MEM
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,472 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxignore.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "gxmem.h"
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#include "gxset.h"
|
||||
#include "cosem.h"
|
||||
|
||||
int cosem_setValue(dlmsSettings* settings, gxValueEventArg* e)
|
||||
{
|
||||
int ret = DLMS_ERROR_CODE_OK;
|
||||
if (e->index == 1)
|
||||
{
|
||||
#if defined(DLMS_IGNORE_MALLOC) || defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
ret = cosem_getOctetString2(e->value.byteArr, e->target->logicalName, 6, NULL);
|
||||
#else
|
||||
if (e->value.byteArr == NULL || e->value.byteArr->size - e->value.byteArr->position != 6)
|
||||
{
|
||||
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = bb_get(e->value.byteArr, e->target->logicalName, 6);
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
return ret;
|
||||
}
|
||||
switch (e->target->objectType)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_DATA
|
||||
case DLMS_OBJECT_TYPE_DATA:
|
||||
ret = cosem_setData(e);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_DATA
|
||||
#ifndef DLMS_IGNORE_REGISTER
|
||||
case DLMS_OBJECT_TYPE_REGISTER:
|
||||
ret = cosem_setRegister((gxRegister*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_REGISTER
|
||||
#ifndef DLMS_IGNORE_CLOCK
|
||||
case DLMS_OBJECT_TYPE_CLOCK:
|
||||
ret = cosem_setClock(settings, (gxClock*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_CLOCK
|
||||
#ifndef DLMS_IGNORE_ACTION_SCHEDULE
|
||||
case DLMS_OBJECT_TYPE_ACTION_SCHEDULE:
|
||||
ret = cosem_setActionSchedule(settings, (gxActionSchedule*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ACTION_SCHEDULE
|
||||
#ifndef DLMS_IGNORE_ACTIVITY_CALENDAR
|
||||
case DLMS_OBJECT_TYPE_ACTIVITY_CALENDAR:
|
||||
ret = cosem_setActivityCalendar(settings, (gxActivityCalendar*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ACTIVITY_CALENDAR
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
||||
case DLMS_OBJECT_TYPE_ASSOCIATION_LOGICAL_NAME:
|
||||
ret = cosem_setAssociationLogicalName(settings, (gxAssociationLogicalName*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
case DLMS_OBJECT_TYPE_ASSOCIATION_SHORT_NAME:
|
||||
ret = cosem_setAssociationShortName(settings, (gxAssociationShortName*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
#ifndef DLMS_IGNORE_AUTO_ANSWER
|
||||
case DLMS_OBJECT_TYPE_AUTO_ANSWER:
|
||||
ret = cosem_setAutoAnswer((gxAutoAnswer*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_AUTO_ANSWER
|
||||
#ifndef DLMS_IGNORE_AUTO_CONNECT
|
||||
case DLMS_OBJECT_TYPE_AUTO_CONNECT:
|
||||
ret = cosem_setAutoConnect((gxAutoConnect*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_AUTO_CONNECT
|
||||
#ifndef DLMS_IGNORE_DEMAND_REGISTER
|
||||
case DLMS_OBJECT_TYPE_DEMAND_REGISTER:
|
||||
ret = cosem_setDemandRegister((gxDemandRegister*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_DEMAND_REGISTER
|
||||
#ifndef DLMS_IGNORE_MAC_ADDRESS_SETUP
|
||||
case DLMS_OBJECT_TYPE_MAC_ADDRESS_SETUP:
|
||||
ret = cosem_setMacAddressSetup((gxMacAddressSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_MAC_ADDRESS_SETUP
|
||||
#ifndef DLMS_IGNORE_EXTENDED_REGISTER
|
||||
case DLMS_OBJECT_TYPE_EXTENDED_REGISTER:
|
||||
ret = cosem_setExtendedRegister((gxExtendedRegister*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_EXTENDED_REGISTER
|
||||
#ifndef DLMS_IGNORE_GPRS_SETUP
|
||||
case DLMS_OBJECT_TYPE_GPRS_SETUP:
|
||||
ret = cosem_setGprsSetup((gxGPRSSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_GPRS_SETUP
|
||||
#ifndef DLMS_IGNORE_SECURITY_SETUP
|
||||
case DLMS_OBJECT_TYPE_SECURITY_SETUP:
|
||||
ret = cosem_setSecuritySetup(settings, (gxSecuritySetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SECURITY_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
case DLMS_OBJECT_TYPE_IEC_HDLC_SETUP:
|
||||
ret = cosem_setIecHdlcSetup((gxIecHdlcSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
case DLMS_OBJECT_TYPE_IEC_LOCAL_PORT_SETUP:
|
||||
ret = cosem_setIecLocalPortSetup((gxLocalPortSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
||||
case DLMS_OBJECT_TYPE_IEC_TWISTED_PAIR_SETUP:
|
||||
ret = cosem_setIecTwistedPairSetup((gxIecTwistedPairSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
||||
#ifndef DLMS_IGNORE_IP4_SETUP
|
||||
case DLMS_OBJECT_TYPE_IP4_SETUP:
|
||||
ret = cosem_setIP4Setup(settings, (gxIp4Setup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IP4_SETUP
|
||||
#ifndef DLMS_IGNORE_IP6_SETUP
|
||||
case DLMS_OBJECT_TYPE_IP6_SETUP:
|
||||
ret = cosem_setIP6Setup(settings, (gxIp6Setup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IP6_SETUP
|
||||
#ifndef DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
||||
case DLMS_OBJECT_TYPE_MBUS_SLAVE_PORT_SETUP:
|
||||
ret = cosem_setMbusSlavePortSetup((gxMbusSlavePortSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
||||
#ifndef DLMS_IGNORE_IMAGE_TRANSFER
|
||||
case DLMS_OBJECT_TYPE_IMAGE_TRANSFER:
|
||||
ret = cosem_setImageTransfer((gxImageTransfer*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IMAGE_TRANSFER
|
||||
#ifndef DLMS_IGNORE_DISCONNECT_CONTROL
|
||||
case DLMS_OBJECT_TYPE_DISCONNECT_CONTROL:
|
||||
ret = cosem_setDisconnectControl((gxDisconnectControl*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_DISCONNECT_CONTROL
|
||||
#ifndef DLMS_IGNORE_LIMITER
|
||||
case DLMS_OBJECT_TYPE_LIMITER:
|
||||
ret = cosem_setLimiter(settings, (gxLimiter*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_LIMITER
|
||||
#ifndef DLMS_IGNORE_MBUS_CLIENT
|
||||
case DLMS_OBJECT_TYPE_MBUS_CLIENT:
|
||||
ret = cosem_setmMbusClient(settings, (gxMBusClient*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_MBUS_CLIENT
|
||||
#ifndef DLMS_IGNORE_MODEM_CONFIGURATION
|
||||
case DLMS_OBJECT_TYPE_MODEM_CONFIGURATION:
|
||||
ret = cosem_setModemConfiguration((gxModemConfiguration*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_MODEM_CONFIGURATION
|
||||
#ifndef DLMS_IGNORE_PPP_SETUP
|
||||
case DLMS_OBJECT_TYPE_PPP_SETUP:
|
||||
ret = cosem_setPppSetup(settings, (gxPppSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PPP_SETUP
|
||||
#ifndef DLMS_IGNORE_PROFILE_GENERIC
|
||||
case DLMS_OBJECT_TYPE_PROFILE_GENERIC:
|
||||
ret = cosem_setProfileGeneric(settings, (gxProfileGeneric*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PROFILE_GENERIC
|
||||
#ifndef DLMS_IGNORE_REGISTER_ACTIVATION
|
||||
case DLMS_OBJECT_TYPE_REGISTER_ACTIVATION:
|
||||
ret = cosem_setRegisterActivation(settings, e);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_REGISTER_ACTIVATION
|
||||
#ifndef DLMS_IGNORE_REGISTER_MONITOR
|
||||
case DLMS_OBJECT_TYPE_REGISTER_MONITOR:
|
||||
ret = cosem_setRegisterMonitor(settings, (gxRegisterMonitor*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_REGISTER_MONITOR
|
||||
#ifndef DLMS_IGNORE_REGISTER_TABLE
|
||||
case DLMS_OBJECT_TYPE_REGISTER_TABLE:
|
||||
ret = cosem_setRegistertable((gxRegisterTable*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_REGISTER_TABLE
|
||||
#ifndef DLMS_IGNORE_ZIG_BEE_SAS_STARTUP
|
||||
case DLMS_OBJECT_TYPE_ZIG_BEE_SAS_STARTUP:
|
||||
//TODO:
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
assert(0);
|
||||
#endif
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ZIG_BEE_SAS_STARTUP
|
||||
#ifndef DLMS_IGNORE_ZIG_BEE_SAS_JOIN
|
||||
case DLMS_OBJECT_TYPE_ZIG_BEE_SAS_JOIN:
|
||||
//TODO:
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
assert(0);
|
||||
#endif
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ZIG_BEE_SAS_JOIN
|
||||
#ifndef DLMS_IGNORE_ZIG_BEE_SAS_APS_FRAGMENTATION
|
||||
case DLMS_OBJECT_TYPE_ZIG_BEE_SAS_APS_FRAGMENTATION:
|
||||
//TODO:
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
assert(0);
|
||||
#endif
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ZIG_BEE_SAS_APS_FRAGMENTATION
|
||||
#ifndef DLMS_IGNORE_ZIG_BEE_NETWORK_CONTROL
|
||||
case DLMS_OBJECT_TYPE_ZIG_BEE_NETWORK_CONTROL:
|
||||
//TODO:
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
assert(0);
|
||||
#endif
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ZIG_BEE_NETWORK_CONTROL
|
||||
#ifndef DLMS_IGNORE_SAP_ASSIGNMENT
|
||||
case DLMS_OBJECT_TYPE_SAP_ASSIGNMENT:
|
||||
ret = cosem_setSapAssignment((gxSapAssignment*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SAP_ASSIGNMENT
|
||||
#ifndef DLMS_IGNORE_SCHEDULE
|
||||
case DLMS_OBJECT_TYPE_SCHEDULE:
|
||||
ret = cosem_setSchedule(settings, (gxSchedule*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SCHEDULE
|
||||
#ifndef DLMS_IGNORE_SCRIPT_TABLE
|
||||
case DLMS_OBJECT_TYPE_SCRIPT_TABLE:
|
||||
ret = cosem_setScriptTable(settings, (gxScriptTable*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SCRIPT_TABLE
|
||||
#ifndef DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
||||
case DLMS_OBJECT_TYPE_SPECIAL_DAYS_TABLE:
|
||||
ret = cosem_setSpecialDaysTable((gxSpecialDaysTable*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
||||
#ifndef DLMS_IGNORE_STATUS_MAPPING
|
||||
case DLMS_OBJECT_TYPE_STATUS_MAPPING:
|
||||
//TODO:
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
assert(0);
|
||||
#endif
|
||||
break;
|
||||
#endif //DLMS_IGNORE_STATUS_MAPPING
|
||||
#ifndef DLMS_IGNORE_TCP_UDP_SETUP
|
||||
case DLMS_OBJECT_TYPE_TCP_UDP_SETUP:
|
||||
ret = cosem_setTcpUdpSetup(settings, (gxTcpUdpSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_TCP_UDP_SETUP
|
||||
#ifndef DLMS_IGNORE_MBUS_DIAGNOSTIC
|
||||
case DLMS_OBJECT_TYPE_MBUS_DIAGNOSTIC:
|
||||
ret = cosem_setMbusDiagnostic((gxMbusDiagnostic*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_MBUS_DIAGNOSTIC
|
||||
#ifndef DLMS_IGNORE_MBUS_PORT_SETUP
|
||||
case DLMS_OBJECT_TYPE_MBUS_PORT_SETUP:
|
||||
ret = cosem_setMbusPortSetup((gxMBusPortSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_MBUS_PORT_SETUP
|
||||
#ifndef DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
||||
case DLMS_OBJECT_TYPE_G3_PLC_MAC_LAYER_COUNTERS:
|
||||
ret = cosem_setG3PlcMacLayerCounters((gxG3PlcMacLayerCounters*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
||||
#ifndef DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
case DLMS_OBJECT_TYPE_G3_PLC_MAC_SETUP:
|
||||
ret = cosem_setG3PlcMacSetup((gxG3PlcMacSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
#ifndef DLMS_IGNORE_G3_PLC_6LO_WPAN
|
||||
case DLMS_OBJECT_TYPE_G3_PLC_6LO_WPAN:
|
||||
ret = cosem_setG3Plc6LoWPAN((gxG3Plc6LoWPAN*)e->target,
|
||||
e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_G3_PLC_6LO_WPAN
|
||||
#ifndef DLMS_IGNORE_FUNCTION_CONTROL
|
||||
case DLMS_OBJECT_TYPE_FUNCTION_CONTROL:
|
||||
ret = cosem_setFunctionControl(settings,
|
||||
(gxFunctionControl*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_FUNCTION_CONTROL
|
||||
#ifndef DLMS_IGNORE_ARRAY_MANAGER
|
||||
case DLMS_OBJECT_TYPE_ARRAY_MANAGER:
|
||||
ret = cosem_setArrayManager(settings,
|
||||
(gxArrayManager*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ARRAY_MANAGER
|
||||
#ifndef DLMS_IGNORE_UTILITY_TABLES
|
||||
case DLMS_OBJECT_TYPE_UTILITY_TABLES:
|
||||
ret = cosem_setUtilityTables((gxUtilityTables*)e->target,
|
||||
e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_UTILITY_TABLES
|
||||
#ifndef DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
||||
case DLMS_OBJECT_TYPE_MBUS_MASTER_PORT_SETUP:
|
||||
ret = cosem_setMbusMasterPortSetup((gxMBusMasterPortSetup*)e->target,
|
||||
e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
||||
#ifndef DLMS_IGNORE_PUSH_SETUP
|
||||
case DLMS_OBJECT_TYPE_PUSH_SETUP:
|
||||
ret = cosem_setPushSetup(settings, (gxPushSetup*)e->target,
|
||||
e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PUSH_SETUP
|
||||
#ifndef DLMS_IGNORE_DATA_PROTECTION
|
||||
case DLMS_OBJECT_TYPE_DATA_PROTECTION:
|
||||
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
assert(0);
|
||||
#endif
|
||||
break;
|
||||
#endif //DLMS_IGNORE_DATA_PROTECTION
|
||||
#ifndef DLMS_IGNORE_ACCOUNT
|
||||
case DLMS_OBJECT_TYPE_ACCOUNT:
|
||||
ret = cosem_setAccount((gxAccount*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ACCOUNT
|
||||
#ifndef DLMS_IGNORE_CREDIT
|
||||
case DLMS_OBJECT_TYPE_CREDIT:
|
||||
ret = cosem_setCredit((gxCredit*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_CREDIT
|
||||
#ifndef DLMS_IGNORE_CHARGE
|
||||
case DLMS_OBJECT_TYPE_CHARGE:
|
||||
ret = cosem_setCharge(settings, (gxCharge*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_CHARGE
|
||||
#ifndef DLMS_IGNORE_TOKEN_GATEWAY
|
||||
case DLMS_OBJECT_TYPE_TOKEN_GATEWAY:
|
||||
ret = cosem_setTokenGateway((gxTokenGateway*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_TOKEN_GATEWAY
|
||||
#ifndef DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
case DLMS_OBJECT_TYPE_GSM_DIAGNOSTIC:
|
||||
ret = cosem_setGsmDiagnostic((gxGsmDiagnostic*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
|
||||
#ifndef DLMS_IGNORE_COMPACT_DATA
|
||||
case DLMS_OBJECT_TYPE_COMPACT_DATA:
|
||||
ret = cosem_setCompactData(settings, (gxCompactData*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_COMPACT_DATA
|
||||
#ifndef DLMS_IGNORE_PARAMETER_MONITOR
|
||||
case DLMS_OBJECT_TYPE_PARAMETER_MONITOR:
|
||||
ret = cosem_setParameterMonitor(settings, (gxParameterMonitor*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PARAMETER_MONITOR
|
||||
#ifndef DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
case DLMS_OBJECT_TYPE_LLC_SSCS_SETUP:
|
||||
ret = cosem_setLlcSscsSetup(settings, (gxLlcSscsSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
case DLMS_OBJECT_TYPE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS:
|
||||
ret = cosem_setPrimeNbOfdmPlcPhysicalLayerCounters(settings, (gxPrimeNbOfdmPlcPhysicalLayerCounters*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
case DLMS_OBJECT_TYPE_PRIME_NB_OFDM_PLC_MAC_SETUP:
|
||||
ret = cosem_setPrimeNbOfdmPlcMacSetup(settings, (gxPrimeNbOfdmPlcMacSetup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
case DLMS_OBJECT_TYPE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS:
|
||||
ret = cosem_setPrimeNbOfdmPlcMacFunctionalParameters(settings, (gxPrimeNbOfdmPlcMacFunctionalParameters*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
case DLMS_OBJECT_TYPE_PRIME_NB_OFDM_PLC_MAC_COUNTERS:
|
||||
ret = cosem_setPrimeNbOfdmPlcMacCounters(settings, (gxPrimeNbOfdmPlcMacCounters*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
case DLMS_OBJECT_TYPE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA:
|
||||
ret = cosem_setPrimeNbOfdmPlcMacNetworkAdministrationData(settings, (gxPrimeNbOfdmPlcMacNetworkAdministrationData*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
case DLMS_OBJECT_TYPE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION:
|
||||
ret = cosem_setPrimeNbOfdmPlcApplicationsIdentification(settings, (gxPrimeNbOfdmPlcApplicationsIdentification*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
#ifndef DLMS_IGNORE_ARBITRATOR
|
||||
case DLMS_OBJECT_TYPE_ARBITRATOR:
|
||||
ret = cosem_setArbitrator(settings, (gxArbitrator*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_ARBITRATOR
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
||||
case DLMS_OBJECT_TYPE_IEC_8802_LLC_TYPE1_SETUP:
|
||||
ret = cosem_setIec8802LlcType1Setup(settings, (gxIec8802LlcType1Setup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
||||
case DLMS_OBJECT_TYPE_IEC_8802_LLC_TYPE2_SETUP:
|
||||
ret = cosem_setIec8802LlcType2Setup(settings, (gxIec8802LlcType2Setup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
||||
case DLMS_OBJECT_TYPE_IEC_8802_LLC_TYPE3_SETUP:
|
||||
ret = cosem_setIec8802LlcType3Setup(settings, (gxIec8802LlcType3Setup*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
||||
#ifndef DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
||||
case DLMS_OBJECT_TYPE_SFSK_ACTIVE_INITIATOR:
|
||||
ret = cosem_setSFSKActiveInitiator(settings, (gxSFSKActiveInitiator*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
||||
#ifndef DLMS_IGNORE_SFSK_MAC_COUNTERS
|
||||
case DLMS_OBJECT_TYPE_SFSK_MAC_COUNTERS:
|
||||
ret = cosem_setFSKMacCounters(settings, (gxFSKMacCounters*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SFSK_MAC_COUNTERS
|
||||
#ifndef DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
||||
case DLMS_OBJECT_TYPE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS:
|
||||
ret = cosem_setSFSKMacSynchronizationTimeouts(settings, (gxSFSKMacSynchronizationTimeouts*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
||||
#ifndef DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
||||
case DLMS_OBJECT_TYPE_SFSK_PHY_MAC_SETUP:
|
||||
ret = cosem_setSFSKPhyMacSetUp(settings, (gxSFSKPhyMacSetUp*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
||||
#ifndef DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
||||
case DLMS_OBJECT_TYPE_SFSK_REPORTING_SYSTEM_LIST:
|
||||
ret = cosem_setSFSKReportingSystemList(settings, (gxSFSKReportingSystemList*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
||||
#ifdef DLMS_ITALIAN_STANDARD
|
||||
case DLMS_OBJECT_TYPE_TARIFF_PLAN:
|
||||
ret = cosem_setTariffPlan((gxTariffPlan*)e->target, e->index, &e->value);
|
||||
break;
|
||||
#endif //DLMS_ITALIAN_STANDARD
|
||||
default:
|
||||
//Unknown type.
|
||||
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef COSEM_SET_H
|
||||
#define COSEM_SET_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(DLMS_IGNORE_MALLOC) || defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
#include "gxsetignoremalloc.h"
|
||||
#else
|
||||
#include "gxsetmalloc.h"
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#include "gxobjects.h"
|
||||
#include "dlmssettings.h"
|
||||
int cosem_setValue(dlmsSettings* settings, gxValueEventArg *e);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// The season profile is sorted according to start date
|
||||
// (in increasing order).
|
||||
int cosem_orderSeasonProfile(gxArray* profile);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//COSEM_SET_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,396 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef COSEM_SET_MALLOC_H
|
||||
#define COSEM_SET_MALLOC_H
|
||||
|
||||
#include "gxignore.h"
|
||||
#if !defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxobjects.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
#ifndef DLMS_IGNORE_DATA
|
||||
int cosem_setData(gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_REGISTER
|
||||
int cosem_setRegister(gxRegister* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_REGISTER
|
||||
|
||||
#ifndef DLMS_IGNORE_CLOCK
|
||||
int cosem_setClock(dlmsSettings* settings, gxClock* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_CLOCK
|
||||
|
||||
#ifndef DLMS_IGNORE_ACTION_SCHEDULE
|
||||
int cosem_setActionSchedule(dlmsSettings* settings, gxActionSchedule* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ACTION_SCHEDULE
|
||||
|
||||
#ifndef DLMS_IGNORE_ACTIVITY_CALENDAR
|
||||
int cosem_setActivityCalendar(dlmsSettings* settings, gxActivityCalendar* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ACTIVITY_CALENDAR
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
||||
int cosem_parseLNObjects(dlmsSettings* settings, gxByteBuffer* data, objectArray* objects);
|
||||
int cosem_setAssociationLogicalName(dlmsSettings* settings, gxAssociationLogicalName* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
int cosem_parseSNObjects(dlmsSettings* settings, gxByteBuffer* data, objectArray* objects);
|
||||
int cosem_setAssociationShortName(dlmsSettings* settings, gxAssociationShortName* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
#ifndef DLMS_IGNORE_AUTO_ANSWER
|
||||
int cosem_setAutoAnswer(gxAutoAnswer* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_AUTO_ANSWER
|
||||
|
||||
#ifndef DLMS_IGNORE_AUTO_CONNECT
|
||||
int cosem_setAutoConnect(gxAutoConnect* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_AUTO_CONNECT
|
||||
|
||||
#ifndef DLMS_IGNORE_DEMAND_REGISTER
|
||||
int cosem_setDemandRegister(gxDemandRegister* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_DEMAND_REGISTER
|
||||
|
||||
#ifndef DLMS_IGNORE_MAC_ADDRESS_SETUP
|
||||
int cosem_setMacAddressSetup(gxMacAddressSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MAC_ADDRESS_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_EXTENDED_REGISTER
|
||||
int cosem_setExtendedRegister(gxExtendedRegister* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_EXTENDED_REGISTER
|
||||
|
||||
#ifndef DLMS_IGNORE_GPRS_SETUP
|
||||
int cosem_setGprsSetup(gxGPRSSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_GPRS_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_SECURITY_SETUP
|
||||
int cosem_setSecuritySetup(dlmsSettings* settings, gxSecuritySetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SECURITY_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
int cosem_setIecHdlcSetup(gxIecHdlcSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
int cosem_setIecLocalPortSetup(gxLocalPortSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IP4_SETUP
|
||||
int cosem_setIP4Setup(dlmsSettings* settings, gxIp4Setup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IP4_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_PROFILE_GENERIC
|
||||
int cosem_setProfileGeneric(dlmsSettings* settings, gxProfileGeneric* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PROFILE_GENERIC
|
||||
|
||||
#ifndef DLMS_IGNORE_UTILITY_TABLES
|
||||
int cosem_setUtilityTables(gxUtilityTables* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_UTILITY_TABLES
|
||||
|
||||
#ifndef DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
||||
int cosem_setMbusSlavePortSetup(gxMbusSlavePortSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_DISCONNECT_CONTROL
|
||||
int cosem_setDisconnectControl(gxDisconnectControl* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_DISCONNECT_CONTROL
|
||||
|
||||
#ifndef DLMS_IGNORE_LIMITER
|
||||
int cosem_setLimiter(dlmsSettings* settings, gxLimiter* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_LIMITER
|
||||
|
||||
#ifndef DLMS_IGNORE_MBUS_CLIENT
|
||||
int cosem_setmMbusClient(dlmsSettings* settings, gxMBusClient* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MBUS_CLIENT
|
||||
|
||||
#ifndef DLMS_IGNORE_MODEM_CONFIGURATION
|
||||
int cosem_setModemConfiguration(gxModemConfiguration* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MODEM_CONFIGURATION
|
||||
|
||||
#ifndef DLMS_IGNORE_PPP_SETUP
|
||||
int cosem_setPppSetup(dlmsSettings* settings, gxPppSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PPP_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_REGISTER_ACTIVATION
|
||||
int cosem_setRegisterActivation(dlmsSettings* settings, gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_REGISTER_ACTIVATION
|
||||
|
||||
#ifndef DLMS_IGNORE_REGISTER_MONITOR
|
||||
int cosem_setRegisterMonitor(dlmsSettings* settings, gxRegisterMonitor* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_REGISTER_MONITOR
|
||||
|
||||
#ifndef DLMS_IGNORE_SAP_ASSIGNMENT
|
||||
int cosem_setSapAssignment(gxSapAssignment* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SAP_ASSIGNMENT
|
||||
|
||||
#ifndef DLMS_IGNORE_SCHEDULE
|
||||
int cosem_setSchedule(dlmsSettings* settings, gxSchedule* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SCHEDULE
|
||||
|
||||
#ifndef DLMS_IGNORE_SCRIPT_TABLE
|
||||
int cosem_setScriptTable(dlmsSettings* settings, gxScriptTable* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SCRIPT_TABLE
|
||||
|
||||
#ifndef DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
||||
int cosem_setSpecialDaysTable(gxSpecialDaysTable* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
||||
|
||||
#ifndef DLMS_IGNORE_TCP_UDP_SETUP
|
||||
int cosem_setTcpUdpSetup(dlmsSettings* settings, gxTcpUdpSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_TCP_UDP_SETUP
|
||||
#ifndef DLMS_IGNORE_MBUS_DIAGNOSTIC
|
||||
int cosem_setMbusDiagnostic(gxMbusDiagnostic* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MBUS_DIAGNOSTIC
|
||||
#ifndef DLMS_IGNORE_MBUS_PORT_SETUP
|
||||
int cosem_setMbusPortSetup(gxMBusPortSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MBUS_PORT_SETUP
|
||||
#ifndef DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
||||
int cosem_setMbusMasterPortSetup(gxMBusMasterPortSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
||||
int cosem_setG3PlcMacLayerCounters(gxG3PlcMacLayerCounters* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
||||
#ifndef DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
int cosem_setG3PlcMacSetup(gxG3PlcMacSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
#ifndef DLMS_IGNORE_G3_PLC_6LO_WPAN
|
||||
int cosem_setG3Plc6LoWPAN(gxG3Plc6LoWPAN* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_G3_PLC_6LO_WPAN
|
||||
#ifndef DLMS_IGNORE_FUNCTION_CONTROL
|
||||
int cosem_setFunctionControl(
|
||||
dlmsSettings* settings,
|
||||
gxFunctionControl* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_FUNCTION_CONTROL
|
||||
#ifndef DLMS_IGNORE_ARRAY_MANAGER
|
||||
int cosem_setArrayManager(dlmsSettings* settings, gxArrayManager* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ARRAY_MANAGER
|
||||
|
||||
#ifndef DLMS_IGNORE_PUSH_SETUP
|
||||
int cosem_setPushSetup(dlmsSettings* settings, gxPushSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PUSH_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
int cosem_setGsmDiagnostic(gxGsmDiagnostic* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
|
||||
#ifndef DLMS_IGNORE_COMPACT_DATA
|
||||
int compactData_updateTemplateDescription(
|
||||
dlmsSettings* settings,
|
||||
gxCompactData* object);
|
||||
#endif //DLMS_IGNORE_COMPACT_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
||||
int cosem_setIecTwistedPairSetup(gxIecTwistedPairSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IP6_SETUP
|
||||
int cosem_setIP6Setup(dlmsSettings* settings, gxIp6Setup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IP6_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IMAGE_TRANSFER
|
||||
int cosem_setImageTransfer(gxImageTransfer* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IMAGE_TRANSFER
|
||||
|
||||
#ifndef DLMS_IGNORE_REGISTER_TABLE
|
||||
int cosem_setRegistertable(gxRegisterTable* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_REGISTER_TABLE
|
||||
|
||||
#ifndef DLMS_IGNORE_ACCOUNT
|
||||
int cosem_setAccount(gxAccount* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ACCOUNT
|
||||
|
||||
#ifndef DLMS_IGNORE_CREDIT
|
||||
int cosem_setCredit(gxCredit* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_CREDIT
|
||||
#ifndef DLMS_IGNORE_CHARGE
|
||||
int cosem_setCharge(dlmsSettings* settings, gxCharge* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_CHARGE
|
||||
#ifndef DLMS_IGNORE_TOKEN_GATEWAY
|
||||
int cosem_setTokenGateway(gxTokenGateway* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_TOKEN_GATEWAY
|
||||
|
||||
#ifndef DLMS_IGNORE_COMPACT_DATA
|
||||
int cosem_setCompactData(
|
||||
dlmsSettings* settings,
|
||||
gxCompactData* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_COMPACT_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_PARAMETER_MONITOR
|
||||
int cosem_setParameterMonitor(
|
||||
dlmsSettings* settings,
|
||||
gxParameterMonitor* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PARAMETER_MONITOR
|
||||
|
||||
#ifndef DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
int cosem_setLlcSscsSetup(
|
||||
dlmsSettings* settings,
|
||||
gxLlcSscsSetup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
int cosem_setPrimeNbOfdmPlcPhysicalLayerCounters(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcPhysicalLayerCounters* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
int cosem_setPrimeNbOfdmPlcMacSetup(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcMacSetup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
int cosem_setPrimeNbOfdmPlcMacFunctionalParameters(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcMacFunctionalParameters* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
int cosem_setPrimeNbOfdmPlcMacCounters(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcMacCounters* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
int cosem_setPrimeNbOfdmPlcMacNetworkAdministrationData(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcMacNetworkAdministrationData* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
int cosem_setPrimeNbOfdmPlcApplicationsIdentification(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcApplicationsIdentification* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
|
||||
#ifndef DLMS_IGNORE_ARBITRATOR
|
||||
int cosem_setArbitrator(
|
||||
dlmsSettings* settings,
|
||||
gxArbitrator* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ARBITRATOR
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
||||
int cosem_setIec8802LlcType1Setup(
|
||||
dlmsSettings* settings,
|
||||
gxIec8802LlcType1Setup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
||||
int cosem_setIec8802LlcType2Setup(
|
||||
dlmsSettings* settings,
|
||||
gxIec8802LlcType2Setup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
||||
int cosem_setIec8802LlcType3Setup(
|
||||
dlmsSettings* settings,
|
||||
gxIec8802LlcType3Setup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
||||
int cosem_setSFSKActiveInitiator(
|
||||
dlmsSettings* settings,
|
||||
gxSFSKActiveInitiator* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_MAC_COUNTERS
|
||||
int cosem_setFSKMacCounters(
|
||||
dlmsSettings* settings,
|
||||
gxFSKMacCounters* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_MAC_COUNTERS
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
||||
int cosem_setSFSKMacSynchronizationTimeouts(
|
||||
dlmsSettings* settings,
|
||||
gxSFSKMacSynchronizationTimeouts* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
||||
int cosem_setSFSKPhyMacSetUp(
|
||||
dlmsSettings* settings,
|
||||
gxSFSKPhyMacSetUp* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
||||
int cosem_setSFSKReportingSystemList(
|
||||
dlmsSettings* settings,
|
||||
gxSFSKReportingSystemList* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //!defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
#endif//COSEM_SET_MALLOC_H
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef VALUE_EVENT_ARG_H
|
||||
#define VALUE_EVENT_ARG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxignore.h"
|
||||
#include "gxobjects.h"
|
||||
#include "errorcodes.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* CGXDLMSVariant value.
|
||||
*/
|
||||
dlmsVARIANT value;
|
||||
#if !defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
/**
|
||||
* Data type of the value.
|
||||
*/
|
||||
DLMS_DATA_TYPE dataType;
|
||||
#endif //!defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
/**
|
||||
* Is request handled.
|
||||
*/
|
||||
unsigned char handled;
|
||||
/**
|
||||
* Target DLMS object
|
||||
*/
|
||||
gxObject* target;
|
||||
|
||||
/**
|
||||
* Attribute index.
|
||||
*/
|
||||
unsigned char index;
|
||||
/**
|
||||
* Optional selector.
|
||||
*/
|
||||
unsigned char selector;
|
||||
/**
|
||||
* Optional parameters.
|
||||
*/
|
||||
dlmsVARIANT parameters;
|
||||
/**
|
||||
* Occurred error.
|
||||
*/
|
||||
DLMS_ERROR_CODE error;
|
||||
/**
|
||||
* Is action. This is reserved for internal use.
|
||||
*/
|
||||
unsigned char action;
|
||||
|
||||
/**
|
||||
* Is value added as byte array.
|
||||
*/
|
||||
unsigned char byteArray;
|
||||
|
||||
/**
|
||||
* Is value max PDU size skipped.
|
||||
*/
|
||||
unsigned char skipMaxPduSize;
|
||||
|
||||
/**
|
||||
* Transaction begin index.
|
||||
*/
|
||||
uint32_t transactionStartIndex;
|
||||
/**
|
||||
* Transaction end index.
|
||||
*/
|
||||
uint32_t transactionEndIndex;
|
||||
//It this transaction.
|
||||
uint16_t transaction;
|
||||
} gxValueEventArg;
|
||||
|
||||
/**
|
||||
* Initialize value event arg.
|
||||
*/
|
||||
void ve_init(
|
||||
gxValueEventArg* ve);
|
||||
|
||||
/**
|
||||
* Clear value event arg.
|
||||
*/
|
||||
void ve_clear(
|
||||
gxValueEventArg* ve);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
gxValueEventArg* data;
|
||||
#else
|
||||
gxValueEventArg** data;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
unsigned char capacity;
|
||||
unsigned char size;
|
||||
unsigned char position;
|
||||
} gxValueEventCollection;
|
||||
|
||||
|
||||
//Initialize value event collection.
|
||||
void vec_init(
|
||||
gxValueEventCollection* arr);
|
||||
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
//Attach value event collection.
|
||||
void vec_attach(
|
||||
gxValueEventCollection* arr,
|
||||
gxValueEventArg* value,
|
||||
unsigned char count,
|
||||
unsigned char capacity);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
/*
|
||||
* Is static buffer used.
|
||||
*/
|
||||
char vec_isAttached(
|
||||
gxValueEventCollection* arr);
|
||||
|
||||
//Bit array capacity.
|
||||
unsigned char vec_getCapacity(
|
||||
gxValueEventCollection* arr);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Push new data to the value event collection.
|
||||
int vec_push(
|
||||
gxValueEventCollection* arr,
|
||||
gxValueEventArg* item);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//empty array, but items are not free.
|
||||
void vec_empty(
|
||||
gxValueEventCollection* arr);
|
||||
|
||||
//Clear array. All items are automatically free.
|
||||
void vec_clear(
|
||||
gxValueEventCollection* arr);
|
||||
|
||||
int vec_getByIndex(
|
||||
gxValueEventCollection* arr,
|
||||
int index,
|
||||
gxValueEventArg** value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //VALUE_EVENT_ARG_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,274 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXHELPERS_H
|
||||
#define GXHELPERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "gxignore.h"
|
||||
#ifdef USE_AVR
|
||||
//If AVR is used.
|
||||
#include <avr/pgmspace.h>
|
||||
#endif //USE_AVR
|
||||
|
||||
#include "bytebuffer.h"
|
||||
#include "variant.h"
|
||||
|
||||
static const unsigned char EMPTY_SYSTEM_TITLE[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static const unsigned char EMPTY_LN[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
static const unsigned char DEFAULT_ASSOCIATION[6] = { 0, 0, 40, 0, 0, 255 };
|
||||
static const unsigned char EMPTY_KEY[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
//Get error message directly from EEPROM to save RAM.
|
||||
#if defined(ARDUINO) || defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
|
||||
//If AVR is used.
|
||||
#ifdef IDF_VER//espressif is using the different folder.
|
||||
#include <pgmspace.h>
|
||||
#else
|
||||
#include <avr/pgmspace.h>
|
||||
#endif//ESP_PLATFORM
|
||||
#define GET_STR_FROM_EEPROM(x) PSTR(x)
|
||||
#else
|
||||
#define GET_STR_FROM_EEPROM(x) (const char*)x
|
||||
#endif//defined(ARDUINO) || defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
|
||||
|
||||
|
||||
//Get UInt32.
|
||||
#define GETU32(pt) (((uint32_t)(pt)[0] << 24) | \
|
||||
((uint32_t)(pt)[1] << 16) | \
|
||||
((uint32_t)(pt)[2] << 8) | \
|
||||
((uint32_t)(pt)[3]))
|
||||
|
||||
//Set Int32 as Big Endian value.
|
||||
#define PUT32(ct, st) { \
|
||||
(ct)[0] = (unsigned char)((st) >> 24); \
|
||||
(ct)[1] = (unsigned char)((st) >> 16); \
|
||||
(ct)[2] = (unsigned char)((st) >> 8); \
|
||||
(ct)[3] = (unsigned char)(st); }
|
||||
|
||||
//Check byte order.
|
||||
unsigned char hlp_isBigEndian(void);
|
||||
|
||||
//Convert ASCII value to numeric unsigned char value.
|
||||
unsigned char hlp_getValue(char c);
|
||||
|
||||
const char* hlp_getErrorMessage(int error);
|
||||
|
||||
//Returns items count. Use hlp_getObjectCount22.
|
||||
int hlp_getObjectCount(gxByteBuffer* buff);
|
||||
|
||||
//Returns items count.
|
||||
int hlp_getObjectCount2(
|
||||
gxByteBuffer* buff,
|
||||
uint16_t* count);
|
||||
|
||||
//Get count size in bytes.
|
||||
unsigned char hlp_getObjectCountSizeInBytes(uint32_t count);
|
||||
|
||||
// Set count of items.
|
||||
int hlp_setObjectCount(
|
||||
uint32_t count,
|
||||
gxByteBuffer* buff);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
/**
|
||||
* Convert byte array to hex string. This method use malloc to allocate enough memory.
|
||||
*/
|
||||
char* hlp_bytesToHex(const unsigned char* pBytes, int count);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
/**
|
||||
* Convert byte array to hex string.
|
||||
*/
|
||||
int hlp_bytesToHex2(const unsigned char* bytes, uint16_t count, char* buff, uint16_t size);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
/**
|
||||
* Convert hex string to byte array. This method use malloc to allocate enough memory.
|
||||
*/
|
||||
int hlp_hexToBytes(
|
||||
const char* str,
|
||||
unsigned char** arr,
|
||||
uint16_t* count);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
/**
|
||||
* Convert hex string to byte array.
|
||||
*/
|
||||
int hlp_hexToBytes2(
|
||||
const char* str,
|
||||
unsigned char* arr,
|
||||
uint16_t* count);
|
||||
|
||||
#if !defined(DLMS_IGNORE_MALLOC)
|
||||
//Set logical name from string.
|
||||
int hlp_setLogicalName(unsigned char ln[6], const char* name);
|
||||
#endif //!defined(DLMS_IGNORE_MALLOC)
|
||||
|
||||
#if !defined(DLMS_IGNORE_STRING_CONVERTER) && !defined(DLMS_IGNORE_MALLOC)
|
||||
void hlp_trace(unsigned char* data, int index, int count, unsigned char send);
|
||||
//Get Logical Name from string.
|
||||
int hlp_parseLogicalName(gxByteBuffer* value, unsigned char ln[6]);
|
||||
|
||||
//Set logical name from string.
|
||||
int hlp_setLogicalName2(dlmsVARIANT* ln, const char* name);
|
||||
|
||||
int hlp_appendLogicalName(gxByteBuffer* bb, const unsigned char value[6]);
|
||||
|
||||
//Print logical name to cout.
|
||||
int hlp_printLogicalName(
|
||||
//Format.
|
||||
const char* format,
|
||||
//Logical name.
|
||||
const unsigned char value[6]);
|
||||
#endif //!defined(DLMS_IGNORE_STRING_CONVERTER) && !defined(DLMS_IGNORE_MALLOC)
|
||||
|
||||
int hlp_getLogicalNameToString(const unsigned char value[6], char* ln);
|
||||
|
||||
void hlp_replace(gxByteBuffer* str, char oldCh, char newCh);
|
||||
|
||||
double hlp_getScaler(int scaler);
|
||||
|
||||
/**
|
||||
* Get data type in bytes.
|
||||
*
|
||||
* @param type
|
||||
* Data type.
|
||||
* @return Size of data type in bytes.
|
||||
*/
|
||||
int hlp_getDataTypeSize(DLMS_DATA_TYPE type);
|
||||
|
||||
/**
|
||||
* Convert integer to string.
|
||||
*
|
||||
* @param str
|
||||
* Parsed string.
|
||||
* @param strsize
|
||||
* String size.
|
||||
* @param value
|
||||
* Integer value.
|
||||
* @param isSigned
|
||||
* Is value signed number.
|
||||
* @param digits
|
||||
* number of digits in string.
|
||||
* @return Length of the string or -1 if error has occurred.
|
||||
*/
|
||||
int hlp_intToString(
|
||||
char* str,
|
||||
int bufsize,
|
||||
int32_t value,
|
||||
unsigned char isSigned,
|
||||
unsigned char digits);
|
||||
|
||||
/**
|
||||
* Convert integer to string.
|
||||
*
|
||||
* @param str
|
||||
* Parsed string.
|
||||
* @param strsize
|
||||
* String size.
|
||||
* @param value
|
||||
* Integer value.
|
||||
* @param digits
|
||||
* number of digits in string.
|
||||
* @return Length of the string or -1 if error has occurred.
|
||||
*/
|
||||
int hlp_uint64ToString(
|
||||
char* str,
|
||||
int bufsize,
|
||||
uint64_t value,
|
||||
unsigned char digits);
|
||||
|
||||
/**
|
||||
* Convert string to integer.
|
||||
*
|
||||
* @param str
|
||||
* Parsed string.
|
||||
* @return Value of string as integer.
|
||||
*/
|
||||
int32_t hlp_stringToInt(
|
||||
const char* str);
|
||||
/**
|
||||
* Convert integer to string.
|
||||
*
|
||||
* @param str
|
||||
* Parsed string.
|
||||
* @param strsize
|
||||
* String size.
|
||||
* @param value
|
||||
* Integer value.
|
||||
* @param isSigned
|
||||
* Is value signed number.
|
||||
* @return Length of the string or -1 if error has occurred.
|
||||
*/
|
||||
int hlp_int64ToString(
|
||||
char* str,
|
||||
int bufsize,
|
||||
int64_t value,
|
||||
unsigned char isSigned);
|
||||
|
||||
/**
|
||||
* Convert string to integer64.
|
||||
*
|
||||
* @param str
|
||||
* Parsed string.
|
||||
* @return Value of string as integer.
|
||||
*/
|
||||
int64_t hlp_stringToInt64(
|
||||
const char* str);
|
||||
|
||||
/**
|
||||
* Random generator using Linear-feedback shift register.
|
||||
* https://en.wikipedia.org/wiki/Linear-feedback_shift_register
|
||||
*
|
||||
* @return Random number.
|
||||
*/
|
||||
unsigned char hlp_rand(void);
|
||||
|
||||
//Add bits from byte array to bit array.
|
||||
int hlp_add(
|
||||
bitArray* arr,
|
||||
gxByteBuffer* bytes,
|
||||
uint16_t count);
|
||||
|
||||
|
||||
//Swap bits. Reserved for internal use.
|
||||
unsigned char hlp_swapBits(unsigned char value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXHELPERS_H
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef LN_PARAMETERS_H
|
||||
#define LN_PARAMETERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "dlmssettings.h"
|
||||
#include "bytebuffer.h"
|
||||
#include "enums.h"
|
||||
|
||||
/**
|
||||
* LN Parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* DLMS settings.
|
||||
*/
|
||||
dlmsSettings *settings;
|
||||
/**
|
||||
* DLMS command.
|
||||
*/
|
||||
DLMS_COMMAND command;
|
||||
/**
|
||||
* Request type.
|
||||
*/
|
||||
int requestType;
|
||||
/**
|
||||
* Attribute descriptor.
|
||||
*/
|
||||
gxByteBuffer attributeDescriptor;
|
||||
/**
|
||||
* Data.
|
||||
*/
|
||||
gxByteBuffer m_Data;
|
||||
|
||||
/**
|
||||
* Send date and time. This is used in Data notification messages.
|
||||
*/
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time;
|
||||
#else
|
||||
struct tm time;
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
/**
|
||||
* Reply status.
|
||||
*/
|
||||
int status;
|
||||
/**
|
||||
* Are there more data to send or more data to receive.
|
||||
*/
|
||||
unsigned char multipleBlocks;
|
||||
/**
|
||||
* Is this last block in send.
|
||||
*/
|
||||
unsigned char lastBlock;
|
||||
/**
|
||||
* Block index.
|
||||
*/
|
||||
int blockIndex;
|
||||
} lnParameters;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //LN_PARAMETERS_H
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
#include "gxmem.h"
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "message.h"
|
||||
#include "errorcodes.h"
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Initialize gxByteBuffer.
|
||||
void mes_init(message* mes)
|
||||
{
|
||||
mes->capacity = MESSAGE_CAPACITY;
|
||||
mes->data = (gxByteBuffer**)gxmalloc(mes->capacity * sizeof(gxByteBuffer*));
|
||||
mes->size = 0;
|
||||
mes->attached = 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
void mes_attach(message* mes, gxByteBuffer** data, unsigned char capacity)
|
||||
{
|
||||
mes->capacity = capacity;
|
||||
mes->data = data;
|
||||
mes->size = 0;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
mes->attached = 1;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Push new message.
|
||||
int mes_push(message* mes, gxByteBuffer* item)
|
||||
{
|
||||
if (mes->size == mes->capacity)
|
||||
{
|
||||
if (mes->attached)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
mes->capacity += MESSAGE_CAPACITY;
|
||||
if (mes->data == NULL)
|
||||
{
|
||||
mes->data = (gxByteBuffer**)gxmalloc(mes->capacity * sizeof(gxByteBuffer*));
|
||||
if (mes->data == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef gxrealloc
|
||||
//If compiler supports realloc.
|
||||
mes->data = (gxByteBuffer**)gxrealloc(mes->data, mes->capacity * sizeof(gxByteBuffer*));
|
||||
if (mes->data == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
#else
|
||||
//If compiler doesn't support realloc.
|
||||
gxByteBuffer** old = mes->data;
|
||||
mes->data = (gxByteBuffer**)gxmalloc(mes->capacity * sizeof(gxByteBuffer*));
|
||||
//If not enought memory available.
|
||||
if (mes->data == NULL)
|
||||
{
|
||||
mes->data = old;
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(mes->data, old, sizeof(gxByteBuffer*) * mes->size);
|
||||
gxfree(old);
|
||||
#endif // gxrealloc
|
||||
}
|
||||
}
|
||||
mes->data[mes->size] = item;
|
||||
++mes->size;
|
||||
return 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
void mes_clear(message* mes)
|
||||
{
|
||||
int pos;
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
for (pos = 0; pos != mes->capacity; ++pos)
|
||||
{
|
||||
mes->data[pos]->size = mes->data[pos]->position = 0;
|
||||
}
|
||||
#else
|
||||
if (!mes->attached)
|
||||
{
|
||||
if (mes->size != 0)
|
||||
{
|
||||
for (pos = 0; pos != mes->size; ++pos)
|
||||
{
|
||||
gxfree(mes->data[pos]->data);
|
||||
gxfree(mes->data[pos]);
|
||||
}
|
||||
}
|
||||
if (mes->data != NULL)
|
||||
{
|
||||
gxfree(mes->data);
|
||||
mes->data = NULL;
|
||||
}
|
||||
mes->capacity = 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
mes->size = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef MESSAGE_H
|
||||
#define MESSAGE_H
|
||||
|
||||
#include "gxignore.h"
|
||||
#include "bytebuffer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MESSAGE_CAPACITY 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gxByteBuffer** data;
|
||||
unsigned char capacity;
|
||||
unsigned char size;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
unsigned char attached;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
} message;
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Initialize gxByteBuffer.
|
||||
void mes_init(message* mes);
|
||||
//Push new message.
|
||||
int mes_push(
|
||||
message* mes,
|
||||
gxByteBuffer* item);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
void mes_attach(message* mes, gxByteBuffer** data, unsigned char capacity);
|
||||
|
||||
//Clear message list.
|
||||
void mes_clear(
|
||||
message* mes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //MESSAGE_H
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#include "object_locker.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace xt211 {
|
||||
|
||||
std::vector<void *> AnyObjectLocker::locked_objects_(5);
|
||||
Mutex AnyObjectLocker::lock_;
|
||||
|
||||
// unlock() function removed
|
||||
|
||||
}; // namespace xt211
|
||||
}; // namespace esphome
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace xt211 {
|
||||
|
||||
class AnyObjectLocker {
|
||||
public:
|
||||
static bool try_lock(void *obj) {
|
||||
if (!lock_.try_lock()) {
|
||||
return false;
|
||||
}
|
||||
bool result = false;
|
||||
if (std::find(locked_objects_.begin(), locked_objects_.end(), obj) == locked_objects_.end()) {
|
||||
locked_objects_.push_back(obj);
|
||||
result = true;
|
||||
}
|
||||
lock_.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
// unlock() function removed to enforce read-only/no-session-release
|
||||
|
||||
private:
|
||||
static std::vector<void *> locked_objects_;
|
||||
static Mutex lock_;
|
||||
};
|
||||
}; // namespace xt211
|
||||
}; // namespace esphome
|
||||
|
|
@ -0,0 +1,446 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxmem.h"
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#if defined(_WIN64) || defined(_WIN32) || defined(__linux__)
|
||||
#include <stdio.h>
|
||||
#endif //defined(_WIN64) || defined(_WIN32) || defined(__linux__)
|
||||
#include <string.h>
|
||||
#include "objectarray.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32) || defined(__linux__)
|
||||
#include <stdio.h>
|
||||
#include "helpers.h"
|
||||
#endif //defined(_WIN64) || defined(_WIN32) || defined(__linux__)
|
||||
|
||||
//Initialize objectArray.
|
||||
void oa_init(objectArray* arr)
|
||||
{
|
||||
arr->capacity = 0;
|
||||
arr->data = NULL;
|
||||
#if !(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
arr->position = 0;
|
||||
#endif //!(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
arr->size = 0;
|
||||
}
|
||||
|
||||
char oa_isAttached(objectArray* arr)
|
||||
{
|
||||
return (arr->capacity & 0x8000) == 0x8000;
|
||||
}
|
||||
|
||||
uint16_t oa_getCapacity(objectArray* arr)
|
||||
{
|
||||
return arr->capacity & 0x7FFF;
|
||||
}
|
||||
|
||||
//Allocate new size for the array in bytes.
|
||||
int oa_capacity(objectArray* arr, const uint16_t capacity)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (!oa_isAttached(arr))
|
||||
{
|
||||
arr->capacity = capacity;
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = (gxObject**)gxmalloc(arr->capacity * sizeof(gxObject*));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef gxrealloc
|
||||
//If compiler supports realloc.
|
||||
arr->data = (gxObject**)gxrealloc(arr->data, arr->capacity * sizeof(gxObject*));
|
||||
#else
|
||||
//If compiler doesn't support realloc.
|
||||
gxObject** old = arr->data;
|
||||
arr->data = (gxObject**)gxmalloc(arr->capacity * sizeof(gxObject*));
|
||||
//If not enought memory available.
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = old;
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(arr->data, old, sizeof(gxObject*) * arr->size);
|
||||
gxfree(old);
|
||||
#endif // gxrealloc
|
||||
}
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
if (oa_getCapacity(arr) < capacity)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Attach object to objectArray.
|
||||
void oa_attach(objectArray* arr, gxObject** item, uint16_t count)
|
||||
{
|
||||
arr->capacity = 0x8000 + count;
|
||||
arr->size = count;
|
||||
#if !(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
arr->position = 0;
|
||||
#endif //!(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
arr->data = item;
|
||||
}
|
||||
|
||||
int oa_verify(objectArray* arr)
|
||||
{
|
||||
uint16_t pos;
|
||||
int ret;
|
||||
gxObject* it;
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
if ((ret = oa_getByIndex(arr, pos, &it)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (it->objectType == 0)
|
||||
{
|
||||
#if defined(_WIN64) || defined(_WIN32) || defined(__linux__)
|
||||
if (pos > 0)
|
||||
{
|
||||
char ln[25];
|
||||
if ((ret = oa_getByIndex(arr, pos - 1, &it)) != 0 ||
|
||||
(ret = hlp_getLogicalNameToString(it->logicalName, ln)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
printf("Last initialized object:%s\n", ln);
|
||||
}
|
||||
#endif
|
||||
//If init2 is not called.
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
return DLMS_ERROR_CODE_OK;
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Push new data to the objectArray.
|
||||
int oa_push(objectArray* arr, gxObject* item)
|
||||
{
|
||||
if (!oa_isAttached(arr) && arr->size >= arr->capacity)
|
||||
{
|
||||
arr->capacity += OBJECT_ARRAY_CAPACITY;
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = (gxObject**)gxmalloc(arr->capacity * sizeof(gxObject*));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef gxrealloc
|
||||
//If compiler supports realloc.
|
||||
arr->data = (gxObject**)gxrealloc(arr->data, arr->capacity * sizeof(gxObject*));
|
||||
#else
|
||||
//If compiler doesn't support realloc.
|
||||
gxObject** old = arr->data;
|
||||
arr->data = (gxObject**)gxmalloc(arr->capacity * sizeof(gxObject*));
|
||||
//If not enought memory available.
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = old;
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(arr->data, old, sizeof(gxObject*) * arr->size);
|
||||
gxfree(old);
|
||||
#endif // gxrealloc
|
||||
}
|
||||
}
|
||||
if (oa_getCapacity(arr) <= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
arr->data[arr->size] = item;
|
||||
++arr->size;
|
||||
return DLMS_ERROR_CODE_OK;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
void oa_copy(objectArray* target, objectArray* source)
|
||||
{
|
||||
int pos;
|
||||
oa_empty(target);
|
||||
oa_capacity(target, source->size);
|
||||
for (pos = 0; pos != source->size; ++pos)
|
||||
{
|
||||
target->data[pos] = source->data[pos];
|
||||
}
|
||||
target->size = source->size;
|
||||
}
|
||||
|
||||
void oa_move(objectArray* target, objectArray* source)
|
||||
{
|
||||
int pos;
|
||||
oa_empty(target);
|
||||
oa_capacity(target, source->size);
|
||||
for (pos = 0; pos != source->size; ++pos)
|
||||
{
|
||||
target->data[pos] = source->data[pos];
|
||||
}
|
||||
target->size = source->size;
|
||||
source->size = 0;
|
||||
#if !(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
source->position = 0;
|
||||
#endif //!(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
}
|
||||
|
||||
void oa_clear2(
|
||||
objectArray* arr,
|
||||
uint16_t index,
|
||||
uint16_t count)
|
||||
{
|
||||
uint16_t pos;
|
||||
if (arr->data != NULL)
|
||||
{
|
||||
//Clear objects first.
|
||||
for (pos = 0; pos != count; ++pos)
|
||||
{
|
||||
obj_clear(arr->data[index + pos]);
|
||||
}
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
for (pos = 0; pos != count; ++pos)
|
||||
{
|
||||
gxfree(arr->data[index + pos]);
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
arr->size = index;
|
||||
#if !(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
arr->position = 0;
|
||||
#endif //!(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
}
|
||||
|
||||
void oa_clear(objectArray* arr, unsigned char releaseObjects)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
uint16_t pos;
|
||||
if (arr->data != NULL)
|
||||
{
|
||||
//Clear objects first.
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
obj_clear(arr->data[pos]);
|
||||
}
|
||||
if (releaseObjects)
|
||||
{
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
gxfree(arr->data[pos]);
|
||||
}
|
||||
}
|
||||
if (!oa_isAttached(arr))
|
||||
{
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
arr->capacity = 0;
|
||||
}
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
arr->size = 0;
|
||||
#if !(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
arr->position = 0;
|
||||
#endif //!(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
}
|
||||
|
||||
void oa_empty(objectArray* arr)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (!oa_isAttached(arr))
|
||||
{
|
||||
if (arr->data != NULL)
|
||||
{
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
}
|
||||
arr->capacity = 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
arr->size = 0;
|
||||
#if !(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
arr->position = 0;
|
||||
#endif //!(defined(GX_DLMS_MICROCONTROLLER) || defined(DLMS_IGNORE_MALLOC))
|
||||
}
|
||||
|
||||
//Get item from object array by index.
|
||||
int oa_getByIndex(
|
||||
const objectArray* arr,
|
||||
uint16_t index,
|
||||
gxObject** item)
|
||||
{
|
||||
if (index >= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
*item = (gxObject*)arr->data[index];
|
||||
return DLMS_ERROR_CODE_OK;
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
int oa_findBySN(
|
||||
objectArray* objects,
|
||||
uint16_t sn,
|
||||
gxObject** object)
|
||||
{
|
||||
uint16_t pos;
|
||||
int ret = DLMS_ERROR_CODE_OK;
|
||||
gxObject* obj = NULL;
|
||||
*object = NULL;
|
||||
for (pos = 0; pos != objects->size; ++pos)
|
||||
{
|
||||
ret = oa_getByIndex(objects, pos, &obj);
|
||||
if (ret != DLMS_ERROR_CODE_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (obj->shortName == sn)
|
||||
{
|
||||
*object = obj;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
int oa_findByLN(
|
||||
objectArray* objects,
|
||||
DLMS_OBJECT_TYPE type,
|
||||
const unsigned char* ln,
|
||||
gxObject** object)
|
||||
{
|
||||
uint16_t pos;
|
||||
int ret = DLMS_ERROR_CODE_OK;
|
||||
gxObject* obj = NULL;
|
||||
*object = NULL;
|
||||
if (ln == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
for (pos = 0; pos != objects->size; ++pos)
|
||||
{
|
||||
if ((ret = oa_getByIndex(objects, pos, &obj)) != DLMS_ERROR_CODE_OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if ((obj->objectType == type || DLMS_OBJECT_TYPE_NONE == type) && memcmp(obj->logicalName, ln, 6) == 0)
|
||||
{
|
||||
*object = obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int oa_getObjects(objectArray* src, DLMS_OBJECT_TYPE type, objectArray* objects)
|
||||
{
|
||||
uint16_t pos;
|
||||
int ret = DLMS_ERROR_CODE_OK;
|
||||
gxObject* obj = NULL;
|
||||
if (src == NULL || objects == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
for (pos = 0; pos != src->size; ++pos)
|
||||
{
|
||||
ret = oa_getByIndex(src, pos, &obj);
|
||||
if (ret != DLMS_ERROR_CODE_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (obj->objectType == type || type == DLMS_OBJECT_TYPE_NONE)
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
if (objects->data == NULL || !(objects->size < oa_getCapacity(objects)))
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
objects->data[objects->size] = obj;
|
||||
++objects->size;
|
||||
#else
|
||||
oa_push(objects, obj);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
}
|
||||
//Trim array.
|
||||
oa_capacity(objects, objects->size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int oa_getObjects2(
|
||||
objectArray* src,
|
||||
DLMS_OBJECT_TYPE* types,
|
||||
unsigned char typeCount,
|
||||
objectArray* objects)
|
||||
{
|
||||
uint16_t pos, pos2;
|
||||
int ret = DLMS_ERROR_CODE_OK;
|
||||
gxObject* obj = NULL;
|
||||
oa_empty(objects);
|
||||
if (src == NULL || objects == NULL || types == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
for (pos = 0; pos != src->size; ++pos)
|
||||
{
|
||||
ret = oa_getByIndex(src, pos, &obj);
|
||||
if (ret != DLMS_ERROR_CODE_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
for (pos2 = 0; pos2 != typeCount; ++pos2)
|
||||
{
|
||||
if (types[pos2] == obj->objectType)
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
if (!(objects->size < oa_getCapacity(objects)))
|
||||
{
|
||||
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
memcpy(&objects->data[objects->size], obj, sizeof(gxObject));
|
||||
++objects->size;
|
||||
#else
|
||||
oa_push(objects, obj);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Trim array.
|
||||
oa_capacity(objects, objects->size);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef OBJECTARRAY_H
|
||||
#define OBJECTARRAY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxignore.h"
|
||||
#include "gxobjects.h"
|
||||
|
||||
#define OBJECT_ARRAY_CAPACITY 10
|
||||
|
||||
//Initialize variantArray.
|
||||
void oa_init(
|
||||
objectArray* arr);
|
||||
|
||||
//Attach objects to objectArray.
|
||||
void oa_attach(
|
||||
objectArray * arr,
|
||||
gxObject** item,
|
||||
uint16_t count);
|
||||
|
||||
//Verify that all objects are called init2. This is used for developing purposes.
|
||||
int oa_verify(
|
||||
objectArray * arr);
|
||||
|
||||
|
||||
|
||||
char oa_isAttached(objectArray* arr);
|
||||
|
||||
uint16_t oa_getCapacity(objectArray* arr);
|
||||
|
||||
//Allocate new size for the array in bytes.
|
||||
int oa_capacity(
|
||||
objectArray* arr,
|
||||
const uint16_t capacity);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Push new data to the variantArray.
|
||||
int oa_push(
|
||||
objectArray * arr,
|
||||
gxObject* item);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Copy content of object array.
|
||||
void oa_copy(
|
||||
objectArray *target,
|
||||
objectArray* source);
|
||||
|
||||
//Move content of object array.
|
||||
void oa_move(
|
||||
objectArray* target,
|
||||
objectArray* source);
|
||||
|
||||
//Clear object array. Clear will free objects as well.
|
||||
void oa_clear2(
|
||||
objectArray* arr,
|
||||
uint16_t index,
|
||||
uint16_t count);
|
||||
|
||||
//Clear object array. Clear will free objects as well.
|
||||
void oa_clear(
|
||||
objectArray* arr,
|
||||
unsigned char releaseObjects);
|
||||
|
||||
//Empty object array. Empty do not free objects.
|
||||
void oa_empty(
|
||||
objectArray* arr);
|
||||
|
||||
//Get item from object array by index.
|
||||
int oa_getByIndex(
|
||||
const objectArray* arr,
|
||||
uint16_t index,
|
||||
gxObject** item);
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
//Find object using Short Name.
|
||||
int oa_findBySN(
|
||||
objectArray* objects,
|
||||
uint16_t sn,
|
||||
gxObject** object);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
//Find object using Logical Name.
|
||||
int oa_findByLN(
|
||||
objectArray* objects,
|
||||
DLMS_OBJECT_TYPE type,
|
||||
const unsigned char* ln,
|
||||
gxObject** object);
|
||||
|
||||
//Get object by object type.
|
||||
int oa_getObjects(
|
||||
objectArray* src,
|
||||
DLMS_OBJECT_TYPE type,
|
||||
objectArray* objects);
|
||||
|
||||
//Get object by array of object type.
|
||||
int oa_getObjects2(
|
||||
objectArray* src,
|
||||
DLMS_OBJECT_TYPE* types,
|
||||
unsigned char typeCount,
|
||||
objectArray* objects);
|
||||
|
||||
#define OA_ATTACH(X, V) oa_attach(&X, (gxObject**) V, sizeof(V)/sizeof(V[0]))
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //OBJECTARRAY_H
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "parameters.h"
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
void params_initSN(
|
||||
gxSNParameters *target,
|
||||
dlmsSettings *settings,
|
||||
DLMS_COMMAND command,
|
||||
int count,
|
||||
unsigned char commandType,
|
||||
gxByteBuffer* attributeDescriptor,
|
||||
gxByteBuffer* data,
|
||||
DLMS_COMMAND encryptedCommand)
|
||||
{
|
||||
target->settings = settings;
|
||||
target->blockIndex = (uint16_t)settings->blockIndex;
|
||||
target->command = command;
|
||||
target->encryptedCommand = encryptedCommand;
|
||||
target->count = count;
|
||||
target->requestType = commandType;
|
||||
target->attributeDescriptor = attributeDescriptor;
|
||||
target->data = data;
|
||||
target->multipleBlocks = 0;
|
||||
target->time = 0;
|
||||
target->lastBlock = 1;
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
target->serializedPdu = settings->serializedPdu;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
#endif // DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
void params_initLN(
|
||||
gxLNParameters *target,
|
||||
dlmsSettings* settings,
|
||||
unsigned char invokeId,
|
||||
DLMS_COMMAND command,
|
||||
unsigned char commandType,
|
||||
gxByteBuffer* attributeDescriptor,
|
||||
gxByteBuffer* data,
|
||||
unsigned char status,
|
||||
DLMS_COMMAND encryptedCommand,
|
||||
unsigned char multipleBlocks,
|
||||
unsigned char lastBlock)
|
||||
{
|
||||
target->invokeId = invokeId;
|
||||
target->settings = settings;
|
||||
target->blockIndex = settings->blockIndex;
|
||||
target->command = command;
|
||||
target->encryptedCommand = encryptedCommand;
|
||||
target->requestType = commandType;
|
||||
target->attributeDescriptor = attributeDescriptor;
|
||||
target->data = data;
|
||||
target->time = 0;
|
||||
target->status = status;
|
||||
target->multipleBlocks = multipleBlocks;
|
||||
target->lastBlock = lastBlock;
|
||||
//Serialize data to this PDU.
|
||||
target->serializedPdu = settings->serializedPdu;
|
||||
}
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef PARAMETERS_H
|
||||
#define PARAMETERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "gxignore.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
/**
|
||||
* SN Parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* DLMS settings.
|
||||
*/
|
||||
dlmsSettings *settings;
|
||||
/**
|
||||
* DLMS command.
|
||||
*/
|
||||
DLMS_COMMAND command;
|
||||
/**
|
||||
* Encrypted DLMS command.
|
||||
*/
|
||||
DLMS_COMMAND encryptedCommand;
|
||||
/**
|
||||
* Request type.
|
||||
*/
|
||||
unsigned char requestType;
|
||||
/**
|
||||
* Attribute descriptor.
|
||||
*/
|
||||
gxByteBuffer* attributeDescriptor;
|
||||
/**
|
||||
* Data.
|
||||
*/
|
||||
gxByteBuffer* data;
|
||||
/**
|
||||
* Send date and time. This is used in Data notification messages.
|
||||
*/
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time;
|
||||
#else
|
||||
struct tm* time;
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
/**
|
||||
* Item Count.
|
||||
*/
|
||||
int count;
|
||||
|
||||
/**
|
||||
* Are there more data to send or more data to receive.
|
||||
*/
|
||||
unsigned char multipleBlocks;
|
||||
|
||||
/**
|
||||
* Is this last block.
|
||||
*/
|
||||
unsigned char lastBlock;
|
||||
/**
|
||||
* Block index.
|
||||
*/
|
||||
uint16_t blockIndex;
|
||||
//Serialize data to this PDU.
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
gxByteBuffer* serializedPdu;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
} gxSNParameters;
|
||||
|
||||
void params_initSN(
|
||||
gxSNParameters *target,
|
||||
dlmsSettings *settings,
|
||||
DLMS_COMMAND command,
|
||||
int count,
|
||||
unsigned char commandType,
|
||||
gxByteBuffer* attributeDescriptor,
|
||||
gxByteBuffer* data,
|
||||
DLMS_COMMAND encryptedCommand);
|
||||
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
/**
|
||||
* LN Parameters
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* DLMS settings.
|
||||
*/
|
||||
dlmsSettings *settings;
|
||||
/**
|
||||
* DLMS command.
|
||||
*/
|
||||
DLMS_COMMAND command;
|
||||
/**
|
||||
* Encrypted DLMS command.
|
||||
*/
|
||||
DLMS_COMMAND encryptedCommand;
|
||||
/**
|
||||
* Request type.
|
||||
*/
|
||||
unsigned char requestType;
|
||||
/**
|
||||
* Attribute descriptor.
|
||||
*/
|
||||
gxByteBuffer* attributeDescriptor;
|
||||
/**
|
||||
* Data.
|
||||
*/
|
||||
gxByteBuffer* data;
|
||||
/**
|
||||
* Send date and time. This is used in Data notification messages.
|
||||
*/
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time;
|
||||
#else
|
||||
struct tm* time;
|
||||
#endif // DLMS_USE_EPOCH_TIME
|
||||
/**
|
||||
* Reply status.
|
||||
*/
|
||||
unsigned char status;
|
||||
/**
|
||||
* Are there more data to send or more data to receive.
|
||||
*/
|
||||
unsigned char multipleBlocks;
|
||||
/**
|
||||
* Is this last block in send.
|
||||
*/
|
||||
unsigned char lastBlock;
|
||||
/**
|
||||
* Block index.
|
||||
*/
|
||||
uint32_t blockIndex;
|
||||
/**
|
||||
* Received invoke ID.
|
||||
*/
|
||||
unsigned char invokeId;
|
||||
//Serialize data to this PDU.
|
||||
gxByteBuffer* serializedPdu;
|
||||
} gxLNParameters;
|
||||
|
||||
void params_initLN(
|
||||
gxLNParameters *target,
|
||||
dlmsSettings* settings,
|
||||
unsigned char invokeId,
|
||||
DLMS_COMMAND command,
|
||||
unsigned char commandType,
|
||||
gxByteBuffer* attributeDescriptor,
|
||||
gxByteBuffer* data,
|
||||
unsigned char status,
|
||||
DLMS_COMMAND encryptedCommand,
|
||||
unsigned char multipleBlocks,
|
||||
unsigned char lastBlock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //PARAMETERS_H
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <string.h> /* memset */
|
||||
#include "gxmem.h"
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#include "replydata.h"
|
||||
|
||||
/**
|
||||
* @return Is more data available.
|
||||
*/
|
||||
unsigned char reply_isMoreData(gxReplyData* reply)
|
||||
{
|
||||
return reply->moreData != DLMS_DATA_REQUEST_TYPES_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize reply structure.
|
||||
*/
|
||||
void reply_init(gxReplyData* reply)
|
||||
{
|
||||
reply->invokeId = 0;
|
||||
reply->commandType = 0;
|
||||
reply->moreData = DLMS_DATA_REQUEST_TYPES_NONE;
|
||||
reply->encryptedCommand = reply->command = DLMS_COMMAND_NONE;
|
||||
BYTE_BUFFER_INIT(&reply->data);
|
||||
reply->complete = 0;
|
||||
var_init(&reply->dataValue);
|
||||
reply->totalCount = 0;
|
||||
reply->readPosition = 0;
|
||||
reply->packetLength = 0;
|
||||
reply->peek = 0;
|
||||
reply->ignoreValue = 0;
|
||||
reply->dataType = DLMS_DATA_TYPE_NONE;
|
||||
reply->cipherIndex = 0;
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
reply->time = 0;
|
||||
#else
|
||||
memset(&reply->time, 0, sizeof(struct tm));
|
||||
#endif // DLMS_USE_EPOCH_TIME
|
||||
reply->preEstablished = 0;
|
||||
reply->blockNumber = 0;
|
||||
reply->blockNumberAck = 0;
|
||||
reply->streaming = 0;
|
||||
reply->windowSize = 0;
|
||||
reply->serverAddress = 0;
|
||||
reply->clientAddress = 0;
|
||||
}
|
||||
|
||||
void reply_clear2(gxReplyData* reply, unsigned char clearData)
|
||||
{
|
||||
reply->invokeId = 0;
|
||||
reply->moreData = DLMS_DATA_REQUEST_TYPES_NONE;
|
||||
reply->encryptedCommand = reply->command = DLMS_COMMAND_NONE;
|
||||
if (clearData)
|
||||
{
|
||||
bb_clear(&reply->data);
|
||||
reply->preEstablished = 0;
|
||||
}
|
||||
reply->complete = 0;
|
||||
var_clear(&reply->dataValue);
|
||||
reply->totalCount = 0;
|
||||
reply->readPosition = 0;
|
||||
reply->packetLength = 0;
|
||||
reply->peek = 0;
|
||||
reply->ignoreValue = 0;
|
||||
reply->dataType = DLMS_DATA_TYPE_NONE;
|
||||
reply->cipherIndex = 0;
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
reply->time = 0;
|
||||
#else
|
||||
memset(&reply->time, 0, sizeof(struct tm));
|
||||
#endif // DLMS_USE_EPOCH_TIME
|
||||
reply->blockNumber = 0;
|
||||
reply->blockNumberAck = 0;
|
||||
reply->streaming = 0;
|
||||
reply->windowSize = 0;
|
||||
reply->serverAddress = 0;
|
||||
reply->clientAddress = 0;
|
||||
}
|
||||
|
||||
void reply_clear(gxReplyData* reply)
|
||||
{
|
||||
reply_clear2(reply, 1);
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXREPLYDATA_H
|
||||
#define GXREPLYDATA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "variant.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Is more data available.
|
||||
*/
|
||||
DLMS_DATA_REQUEST_TYPES moreData;
|
||||
/**
|
||||
* Received command.
|
||||
*/
|
||||
DLMS_COMMAND command;
|
||||
/**
|
||||
* Encrypted command.
|
||||
*/
|
||||
DLMS_COMMAND encryptedCommand;
|
||||
|
||||
unsigned char commandType;
|
||||
|
||||
/**
|
||||
* Received data.
|
||||
*/
|
||||
gxByteBuffer data;
|
||||
|
||||
/**
|
||||
* Is frame complete.
|
||||
*/
|
||||
unsigned char complete;
|
||||
|
||||
/**
|
||||
* Read value.
|
||||
*/
|
||||
dlmsVARIANT dataValue;
|
||||
|
||||
/**
|
||||
* Expected count of element in the array.
|
||||
*/
|
||||
uint16_t totalCount;
|
||||
|
||||
#if defined(GX_DLMS_BYTE_BUFFER_SIZE_32) || (!defined(GX_DLMS_MICROCONTROLLER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
/**
|
||||
* Last read position. This is used in peek to solve how far data is read.
|
||||
*/
|
||||
uint32_t readPosition;
|
||||
/**
|
||||
* Packet length.
|
||||
*/
|
||||
uint32_t packetLength;
|
||||
#else
|
||||
/**
|
||||
* Last read position. This is used in peek to solve how far data is read.
|
||||
*/
|
||||
uint16_t readPosition;
|
||||
/**
|
||||
* Packet length.
|
||||
*/
|
||||
uint16_t packetLength;
|
||||
#endif
|
||||
/**
|
||||
* Try Get value.
|
||||
*/
|
||||
unsigned char peek;
|
||||
|
||||
/**
|
||||
* Value is not try to parse. This is used in data collector.
|
||||
*/
|
||||
unsigned char ignoreValue;
|
||||
|
||||
DLMS_DATA_TYPE dataType;
|
||||
|
||||
/**
|
||||
* Cipher index is position where data is decrypted.
|
||||
*/
|
||||
uint16_t cipherIndex;
|
||||
|
||||
/**
|
||||
* Data notification date time.
|
||||
*/
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time;
|
||||
#else
|
||||
struct tm time;
|
||||
#endif // DLMS_USE_EPOCH_TIME
|
||||
/**
|
||||
* Pre-established connection.
|
||||
*/
|
||||
unsigned char preEstablished;
|
||||
unsigned char invokeId;
|
||||
|
||||
//GBT block number.
|
||||
uint16_t blockNumber;
|
||||
//GBT block number ACK.
|
||||
uint16_t blockNumberAck;
|
||||
//GBT is streaming used.
|
||||
unsigned streaming;
|
||||
//GBT window size
|
||||
unsigned windowSize;
|
||||
//Server address.
|
||||
uint16_t serverAddress;
|
||||
//Client address.
|
||||
uint16_t clientAddress;
|
||||
} gxReplyData;
|
||||
|
||||
unsigned char reply_isMoreData(gxReplyData* reply);
|
||||
|
||||
/**
|
||||
* Initialize reply structure.
|
||||
*/
|
||||
void reply_init(gxReplyData* reply);
|
||||
|
||||
void reply_clear(gxReplyData* reply);
|
||||
|
||||
void reply_clear2(gxReplyData* reply, unsigned char clearData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXREPLYDATA_H
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from . import (
|
||||
XT211,
|
||||
xt211_ns,
|
||||
obis_code,
|
||||
CONF_XT211_ID,
|
||||
CONF_OBIS_CODE,
|
||||
CONF_DONT_PUBLISH,
|
||||
CONF_CLASS,
|
||||
)
|
||||
|
||||
XT211Sensor = xt211_ns.class_("XT211Sensor", sensor.Sensor)
|
||||
|
||||
CONF_MULTIPLIER = "multiplier"
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
sensor.sensor_schema(
|
||||
XT211Sensor,
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(CONF_XT211_ID): cv.use_id(XT211),
|
||||
cv.Required(CONF_OBIS_CODE): obis_code,
|
||||
cv.Optional(CONF_DONT_PUBLISH, default=False): cv.boolean,
|
||||
cv.Optional(CONF_MULTIPLIER, default=1.0): cv.float_,
|
||||
cv.Optional(CONF_CLASS, default=3): cv.int_,
|
||||
}
|
||||
),
|
||||
cv.has_exactly_one_key(CONF_OBIS_CODE),
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
component = await cg.get_variable(config[CONF_XT211_ID])
|
||||
var = await sensor.new_sensor(config)
|
||||
cg.add(var.set_obis_code(config[CONF_OBIS_CODE]))
|
||||
cg.add(var.set_dont_publish(config.get(CONF_DONT_PUBLISH)))
|
||||
cg.add(var.set_multiplier(config[CONF_MULTIPLIER]))
|
||||
cg.add(var.set_obis_class(config[CONF_CLASS]))
|
||||
cg.add(component.register_sensor(var))
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,157 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_SERVER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "serverevents.h"
|
||||
#include "dlms.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*Received data from the client.*/
|
||||
unsigned char* data;
|
||||
/*Data size.*/
|
||||
uint16_t dataSize;
|
||||
/*Server reply for the client.*/
|
||||
gxByteBuffer* reply;
|
||||
/*Is GBT streaming in progress.*/
|
||||
DLMS_DATA_REQUEST_TYPES moreData;
|
||||
/*GBT Message count to send.*/
|
||||
unsigned char gbtCount;
|
||||
/*HDLC window count to send.*/
|
||||
unsigned char hdlcWindowCount;
|
||||
/*Received command.*/
|
||||
DLMS_COMMAND command;
|
||||
#ifndef DLMS_IGNORE_IEC
|
||||
/*Baudrate is changed when optical probe is used.*/
|
||||
uint16_t newBaudRate;
|
||||
#endif //DLMS_IGNORE_IEC
|
||||
}gxServerReply;
|
||||
|
||||
int sr_initialize(
|
||||
gxServerReply* sr,
|
||||
unsigned char* data,
|
||||
uint16_t dataSize,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
int svr_initialize(
|
||||
dlmsServerSettings* settings);
|
||||
|
||||
/*Server handles received bytes from the client.*/
|
||||
int svr_handleRequest(
|
||||
dlmsServerSettings* settings,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
/*Server handles received bytes from the client.*/
|
||||
int svr_handleRequest2(
|
||||
dlmsServerSettings* settings,
|
||||
unsigned char* buff,
|
||||
uint16_t size,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
/*Server handles received byte from the client.*/
|
||||
int svr_handleRequest3(
|
||||
dlmsServerSettings* settings,
|
||||
unsigned char data,
|
||||
gxByteBuffer* reply);
|
||||
|
||||
/*Server handles received bytes from the client.*/
|
||||
int svr_handleRequest4(
|
||||
dlmsServerSettings* settings,
|
||||
gxServerReply* sr);
|
||||
|
||||
void svr_reset(
|
||||
dlmsServerSettings* settings);
|
||||
|
||||
/*
|
||||
Run the background processes.
|
||||
*/
|
||||
int svr_run(
|
||||
dlmsServerSettings* settings,
|
||||
//Current EPOCH time.
|
||||
uint32_t time,
|
||||
//Next EPOCH execution time.
|
||||
uint32_t* next);
|
||||
|
||||
#ifndef DLMS_IGNORE_REGISTER_MONITOR
|
||||
/*
|
||||
The server verifies that value of monitored object don't cross the thresholds.
|
||||
Selected script is invoked if value is passed.
|
||||
*/
|
||||
int svr_monitor(dlmsServerSettings* settings, gxRegisterMonitor* object);
|
||||
/*
|
||||
The server verifies that values of monitored objects don't cross the thresholds.
|
||||
Selected script is invoked if value is passed.
|
||||
*/
|
||||
int svr_monitorAll(dlmsServerSettings* settings);
|
||||
#endif //DLMS_IGNORE_REGISTER_MONITOR
|
||||
|
||||
#ifndef DLMS_IGNORE_LIMITER
|
||||
/*
|
||||
The server verifies that value of monitored object don't cross the thresholds.
|
||||
Selected script is invoked if value is passed.
|
||||
*/
|
||||
int svr_limiter(dlmsServerSettings* settings, gxLimiter* object, uint32_t now);
|
||||
/*
|
||||
The server verifies that values of monitored objects don't cross the thresholds.
|
||||
Selected script is invoked if value is passed.
|
||||
*/
|
||||
int svr_limiterAll(dlmsServerSettings* settings, uint32_t now);
|
||||
#endif //DLMS_IGNORE_LIMITER
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
/**
|
||||
* Update short names.
|
||||
*/
|
||||
int svr_updateShortNames(
|
||||
dlmsServerSettings* settings,
|
||||
unsigned char force);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
//Check is client changing the settings with action.
|
||||
//This can be used to check is meter data changed.
|
||||
//Return value is saved atribute index or zero if nothing hasn't change.
|
||||
uint32_t svr_isChangedWithAction(DLMS_OBJECT_TYPE objectType, unsigned char methodIndex);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DLMS_IGNORE_SERVER
|
||||
#endif //SERVER_H
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
#include "serverevents.h"
|
||||
#ifdef DLMS_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif //DLMS_DEBUG
|
||||
|
||||
void svr_notifyTrace(const char* str, int err)
|
||||
{
|
||||
#ifdef DLMS_DEBUG
|
||||
if (err != 0)
|
||||
{
|
||||
char tmp[20];
|
||||
sprintf(tmp, " Error: %d", err);
|
||||
svr_trace(str, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
svr_trace(str, " succeeded.");
|
||||
}
|
||||
#endif// DLMS_DEBUG
|
||||
}
|
||||
|
||||
void svr_notifyTrace2(const char* str, const short ot, const unsigned char* ln, int err)
|
||||
{
|
||||
#ifdef DLMS_DEBUG
|
||||
if (err != 0)
|
||||
{
|
||||
char tmp[20];
|
||||
sprintf(tmp, " %d:%d.%d.%d.%d.%d.%d Error: %d", ot, ln[0], ln[1], ln[2], ln[3], ln[4], ln[5], err);
|
||||
svr_trace(str, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
svr_trace(str, " succeeded.");
|
||||
}
|
||||
#endif// DLMS_DEBUG
|
||||
}
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef SERVER_EVENTS_H
|
||||
#define SERVER_EVENTS_H
|
||||
|
||||
#include "gxignore.h"
|
||||
#if !defined(DLMS_IGNORE_SERVER) || defined(DLMS_DEBUG)
|
||||
#include "dlmssettings.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifndef DLMS_IGNORE_SERVER
|
||||
/**
|
||||
* Check is data sent to this server.
|
||||
*
|
||||
* @param serverAddress
|
||||
* Server address.
|
||||
* @param clientAddress
|
||||
* Client address.
|
||||
* @return True, if data is sent to this server.
|
||||
*/
|
||||
extern unsigned char svr_isTarget(
|
||||
dlmsSettings* settings,
|
||||
uint32_t serverAddress,
|
||||
uint32_t clientAddress);
|
||||
|
||||
/**
|
||||
* Get attribute access level.
|
||||
*/
|
||||
extern DLMS_ACCESS_MODE svr_getAttributeAccess(
|
||||
dlmsSettings* settings,
|
||||
gxObject* obj,
|
||||
unsigned char index);
|
||||
|
||||
/**
|
||||
* Get method access level.
|
||||
*/
|
||||
extern DLMS_METHOD_ACCESS_MODE svr_getMethodAccess(
|
||||
dlmsSettings* settings,
|
||||
gxObject* obj,
|
||||
unsigned char index);
|
||||
|
||||
/**
|
||||
* called when client makes connection to the server.
|
||||
*/
|
||||
extern int svr_connected(
|
||||
dlmsServerSettings* settings);
|
||||
|
||||
/**
|
||||
* Client has try to made invalid connection. Password is incorrect.
|
||||
*
|
||||
* @param connectionInfo
|
||||
* Connection information.
|
||||
*/
|
||||
extern int svr_invalidConnection(
|
||||
dlmsServerSettings* settings);
|
||||
|
||||
/**
|
||||
* called when client clses connection to the server.
|
||||
*/
|
||||
extern int svr_disconnected(
|
||||
dlmsServerSettings* settings);
|
||||
|
||||
extern void svr_preGet(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
|
||||
extern void svr_postGet(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
|
||||
/**
|
||||
* Read selected item(s).
|
||||
*
|
||||
* @param args
|
||||
* Handled read requests.
|
||||
*/
|
||||
extern void svr_preRead(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
|
||||
/**
|
||||
* Write selected item(s).
|
||||
*
|
||||
* @param args
|
||||
* Handled write requests.
|
||||
*/
|
||||
extern void svr_preWrite(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
|
||||
/**
|
||||
* Action is occurred.
|
||||
*
|
||||
* @param args
|
||||
* Handled action requests.
|
||||
*/
|
||||
extern void svr_preAction(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
|
||||
/**
|
||||
* Read selected item(s).
|
||||
*
|
||||
* @param args
|
||||
* Handled read requests.
|
||||
*/
|
||||
extern void svr_postRead(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
|
||||
/**
|
||||
* Write selected item(s).
|
||||
*
|
||||
* @param args
|
||||
* Handled write requests.
|
||||
*/
|
||||
extern void svr_postWrite(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
|
||||
/**
|
||||
* Action is occurred.
|
||||
*
|
||||
* @param args
|
||||
* Handled action requests.
|
||||
*/
|
||||
extern void svr_postAction(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
|
||||
/**
|
||||
* Check whether the authentication and password are correct.
|
||||
*
|
||||
* @param authentication
|
||||
* Authentication level.
|
||||
* @param password
|
||||
* Password.
|
||||
* @return Source diagnostic.
|
||||
*/
|
||||
extern DLMS_SOURCE_DIAGNOSTIC svr_validateAuthentication(
|
||||
dlmsServerSettings* settings,
|
||||
DLMS_AUTHENTICATION authentication,
|
||||
gxByteBuffer* password);
|
||||
|
||||
/**
|
||||
* Find object.
|
||||
*
|
||||
* @param objectType
|
||||
* Object type.
|
||||
* @param sn
|
||||
* Short Name. In Logical name referencing this is not used.
|
||||
* @param ln
|
||||
* Logical Name. In Short Name referencing this is not used.
|
||||
* @return Found object or NULL if object is not found.
|
||||
*/
|
||||
extern int svr_findObject(
|
||||
dlmsSettings* settings,
|
||||
DLMS_OBJECT_TYPE objectType,
|
||||
int sn,
|
||||
unsigned char* ln,
|
||||
gxValueEventArg* e);
|
||||
|
||||
/**
|
||||
* This is reserved for future use.
|
||||
*
|
||||
* @param args
|
||||
* Handled data type requests.
|
||||
*/
|
||||
extern void svr_getDataType(
|
||||
dlmsSettings* settings,
|
||||
gxValueEventCollection* args);
|
||||
#endif //DLMS_IGNORE_SERVER
|
||||
#ifdef DLMS_DEBUG
|
||||
/**
|
||||
* Trace that can be used in debugging.
|
||||
*
|
||||
* str: Method info.
|
||||
* Data: optional data.
|
||||
*/
|
||||
extern void svr_trace(
|
||||
const char* str,
|
||||
const char* data);
|
||||
#endif //DLMS_DEBUG
|
||||
|
||||
//Server uses notify trace if DLMS_DEBUG is defined.
|
||||
void svr_notifyTrace(const char* str, int err);
|
||||
|
||||
//Server uses notify trace if DLMS_DEBUG is defined.
|
||||
void svr_notifyTrace2(const char* str, const short ot, const unsigned char* ln, int err);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DLMS_IGNORE_SERVER
|
||||
#endif //SERVER_EVENTS_H
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef SN_PARAMETERS_H
|
||||
#define SN_PARAMETERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
#include "dlmssettings.h"
|
||||
#include "bytebuffer.h"
|
||||
#include "enums.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* DLMS settings.
|
||||
*/
|
||||
dlmsSettings *settings;
|
||||
/**
|
||||
* DLMS command.
|
||||
*/
|
||||
DLMS_COMMAND command;
|
||||
/**
|
||||
* Request type.
|
||||
*/
|
||||
int requestType;
|
||||
/**
|
||||
* Attribute descriptor.
|
||||
*/
|
||||
gxByteBuffer attributeDescriptor;
|
||||
/**
|
||||
* Data.
|
||||
*/
|
||||
gxByteBuffer data;
|
||||
/**
|
||||
* Send date and time. This is used in Data notification messages.
|
||||
*/
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time;
|
||||
#else
|
||||
struct tm time;
|
||||
#endif // DLMS_USE_EPOCH_TIME
|
||||
|
||||
/**
|
||||
* Item Count.
|
||||
*/
|
||||
int count;
|
||||
|
||||
/**
|
||||
* Are there more data to send or more data to receive.
|
||||
*/
|
||||
unsigned char multipleBlocks;
|
||||
|
||||
/**
|
||||
* Block index.
|
||||
*/
|
||||
int blockIndex;
|
||||
} snParameters;
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //SN_PARAMETERS_H
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import text_sensor
|
||||
from . import (
|
||||
XT211,
|
||||
xt211_ns,
|
||||
obis_code,
|
||||
CONF_XT211_ID,
|
||||
CONF_OBIS_CODE,
|
||||
CONF_DONT_PUBLISH,
|
||||
CONF_CLASS,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ["xt211"]
|
||||
|
||||
XT211TextSensor = xt211_ns.class_(
|
||||
"XT211TextSensor", text_sensor.TextSensor
|
||||
)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
text_sensor.text_sensor_schema(
|
||||
XT211TextSensor,
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(CONF_XT211_ID): cv.use_id(XT211),
|
||||
cv.Required(CONF_OBIS_CODE): obis_code,
|
||||
cv.Optional(CONF_DONT_PUBLISH, default=False): cv.boolean,
|
||||
cv.Optional(CONF_CLASS, default=1): cv.int_,
|
||||
}
|
||||
),
|
||||
cv.has_exactly_one_key(CONF_OBIS_CODE),
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
component = await cg.get_variable(config[CONF_XT211_ID])
|
||||
var = await text_sensor.new_text_sensor(config)
|
||||
cg.add(var.set_obis_code(config[CONF_OBIS_CODE]))
|
||||
cg.add(var.set_dont_publish(config.get(CONF_DONT_PUBLISH)))
|
||||
cg.add(var.set_obis_class(config[CONF_CLASS]))
|
||||
|
||||
cg.add(component.register_sensor(var))
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef CHIPPERINGENUMS_H
|
||||
#define CHIPPERINGENUMS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef DLMS_IGNORE_HIGH_GMAC
|
||||
|
||||
#endif //DLMS_IGNORE_HIGH_GMAC
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //CHIPPERINGENUMS_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef COSEM_INVOKE_H
|
||||
#define COSEM_INVOKE_H
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//extern "C" {
|
||||
//#endif
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_SERVER
|
||||
|
||||
#include "gxobjects.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
int cosem_invoke(
|
||||
dlmsServerSettings* settings,
|
||||
gxValueEventArg* e);
|
||||
|
||||
#ifndef DLMS_IGNORE_COMPACT_DATA
|
||||
/*
|
||||
* Copies the values of the objects to capture into the buffer by reading
|
||||
* capture objects.
|
||||
*/
|
||||
int cosem_captureCompactData(
|
||||
dlmsSettings* settings,
|
||||
gxCompactData* object);
|
||||
#endif //DLMS_IGNORE_COMPACT_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_SCRIPT_TABLE
|
||||
int invoke_ScriptTable(
|
||||
dlmsServerSettings* settings,
|
||||
gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_SCRIPT_TABLE
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
#endif //DLMS_IGNORE_SERVER
|
||||
|
||||
#endif //COSEM_INVOKE_H
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_HIGH_MD5
|
||||
#include <string.h>
|
||||
#include "gxmd5.h"
|
||||
|
||||
unsigned int gxmd5_F(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
unsigned int gxmd5_G(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
|
||||
unsigned int gxmd5_H(unsigned int x, unsigned int y, unsigned int z)
|
||||
{
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
unsigned int gxmd5_I(uint32_t x, uint32_t y, uint32_t z)
|
||||
{
|
||||
return y ^ (x | ~z);
|
||||
}
|
||||
|
||||
unsigned int gxmd5_rotate_left(unsigned int x, int n)
|
||||
{
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
void gxmd5_FF(uint32_t* a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac)
|
||||
{
|
||||
*a = gxmd5_rotate_left(*a + gxmd5_F(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
void gxmd5_GG(uint32_t* a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
|
||||
*a = gxmd5_rotate_left(*a + gxmd5_G(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
void gxmd5_HH(uint32_t* a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
|
||||
*a = gxmd5_rotate_left(*a + gxmd5_H(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
void gxmd5_II(uint32_t* a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) {
|
||||
*a = gxmd5_rotate_left(*a + gxmd5_I(b, c, d) + x + ac, s) + b;
|
||||
}
|
||||
|
||||
void gxmd5_decode(uint32_t* output, unsigned char* input, unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
{
|
||||
output[i] = (input[j]) | (((uint32_t)input[j + 1]) << 8) |
|
||||
(((uint32_t)input[j + 2]) << 16) | (((uint32_t)input[j + 3]) << 24);
|
||||
}
|
||||
}
|
||||
|
||||
void gxmd5_encode(unsigned char* output, uint32_t* input, unsigned int len)
|
||||
{
|
||||
unsigned int i, pos = 0;
|
||||
for (i = 0; i != len; ++i)
|
||||
{
|
||||
output[pos] = input[i] & 0xff;
|
||||
++pos;
|
||||
output[pos] = (input[i] >> 8) & 0xff;
|
||||
++pos;
|
||||
output[pos] = (input[i] >> 16) & 0xff;
|
||||
++pos;
|
||||
output[pos] = (input[i] >> 24) & 0xff;
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
void gxmd5_transform(unsigned char* block, uint32_t* state)
|
||||
{
|
||||
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
gxmd5_decode(x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
gxmd5_FF(&a, b, c, d, x[0], S11, 0xd76aa478);
|
||||
gxmd5_FF(&d, a, b, c, x[1], S12, 0xe8c7b756);
|
||||
gxmd5_FF(&c, d, a, b, x[2], S13, 0x242070db);
|
||||
gxmd5_FF(&b, c, d, a, x[3], S14, 0xc1bdceee);
|
||||
gxmd5_FF(&a, b, c, d, x[4], S11, 0xf57c0faf);
|
||||
gxmd5_FF(&d, a, b, c, x[5], S12, 0x4787c62a);
|
||||
gxmd5_FF(&c, d, a, b, x[6], S13, 0xa8304613);
|
||||
gxmd5_FF(&b, c, d, a, x[7], S14, 0xfd469501);
|
||||
gxmd5_FF(&a, b, c, d, x[8], S11, 0x698098d8);
|
||||
gxmd5_FF(&d, a, b, c, x[9], S12, 0x8b44f7af);
|
||||
gxmd5_FF(&c, d, a, b, x[10], S13, 0xffff5bb1);
|
||||
gxmd5_FF(&b, c, d, a, x[11], S14, 0x895cd7be);
|
||||
gxmd5_FF(&a, b, c, d, x[12], S11, 0x6b901122);
|
||||
gxmd5_FF(&d, a, b, c, x[13], S12, 0xfd987193);
|
||||
gxmd5_FF(&c, d, a, b, x[14], S13, 0xa679438e);
|
||||
gxmd5_FF(&b, c, d, a, x[15], S14, 0x49b40821);
|
||||
|
||||
/* Round 2 */
|
||||
gxmd5_GG(&a, b, c, d, x[1], S21, 0xf61e2562);
|
||||
gxmd5_GG(&d, a, b, c, x[6], S22, 0xc040b340);
|
||||
gxmd5_GG(&c, d, a, b, x[11], S23, 0x265e5a51);
|
||||
gxmd5_GG(&b, c, d, a, x[0], S24, 0xe9b6c7aa);
|
||||
gxmd5_GG(&a, b, c, d, x[5], S21, 0xd62f105d);
|
||||
gxmd5_GG(&d, a, b, c, x[10], S22, 0x2441453);
|
||||
gxmd5_GG(&c, d, a, b, x[15], S23, 0xd8a1e681);
|
||||
gxmd5_GG(&b, c, d, a, x[4], S24, 0xe7d3fbc8);
|
||||
gxmd5_GG(&a, b, c, d, x[9], S21, 0x21e1cde6);
|
||||
gxmd5_GG(&d, a, b, c, x[14], S22, 0xc33707d6);
|
||||
gxmd5_GG(&c, d, a, b, x[3], S23, 0xf4d50d87);
|
||||
gxmd5_GG(&b, c, d, a, x[8], S24, 0x455a14ed);
|
||||
gxmd5_GG(&a, b, c, d, x[13], S21, 0xa9e3e905);
|
||||
gxmd5_GG(&d, a, b, c, x[2], S22, 0xfcefa3f8);
|
||||
gxmd5_GG(&c, d, a, b, x[7], S23, 0x676f02d9);
|
||||
gxmd5_GG(&b, c, d, a, x[12], S24, 0x8d2a4c8a);
|
||||
|
||||
/* Round 3 */
|
||||
gxmd5_HH(&a, b, c, d, x[5], S31, 0xfffa3942);
|
||||
gxmd5_HH(&d, a, b, c, x[8], S32, 0x8771f681);
|
||||
gxmd5_HH(&c, d, a, b, x[11], S33, 0x6d9d6122);
|
||||
gxmd5_HH(&b, c, d, a, x[14], S34, 0xfde5380c);
|
||||
gxmd5_HH(&a, b, c, d, x[1], S31, 0xa4beea44);
|
||||
gxmd5_HH(&d, a, b, c, x[4], S32, 0x4bdecfa9);
|
||||
gxmd5_HH(&c, d, a, b, x[7], S33, 0xf6bb4b60);
|
||||
gxmd5_HH(&b, c, d, a, x[10], S34, 0xbebfbc70);
|
||||
gxmd5_HH(&a, b, c, d, x[13], S31, 0x289b7ec6);
|
||||
gxmd5_HH(&d, a, b, c, x[0], S32, 0xeaa127fa);
|
||||
gxmd5_HH(&c, d, a, b, x[3], S33, 0xd4ef3085);
|
||||
gxmd5_HH(&b, c, d, a, x[6], S34, 0x4881d05);
|
||||
gxmd5_HH(&a, b, c, d, x[9], S31, 0xd9d4d039);
|
||||
gxmd5_HH(&d, a, b, c, x[12], S32, 0xe6db99e5);
|
||||
gxmd5_HH(&c, d, a, b, x[15], S33, 0x1fa27cf8);
|
||||
gxmd5_HH(&b, c, d, a, x[2], S34, 0xc4ac5665);
|
||||
|
||||
/* Round 4 */
|
||||
gxmd5_II(&a, b, c, d, x[0], S41, 0xf4292244);
|
||||
gxmd5_II(&d, a, b, c, x[7], S42, 0x432aff97);
|
||||
gxmd5_II(&c, d, a, b, x[14], S43, 0xab9423a7);
|
||||
gxmd5_II(&b, c, d, a, x[5], S44, 0xfc93a039);
|
||||
gxmd5_II(&a, b, c, d, x[12], S41, 0x655b59c3);
|
||||
gxmd5_II(&d, a, b, c, x[3], S42, 0x8f0ccc92);
|
||||
gxmd5_II(&c, d, a, b, x[10], S43, 0xffeff47d);
|
||||
gxmd5_II(&b, c, d, a, x[1], S44, 0x85845dd1);
|
||||
gxmd5_II(&a, b, c, d, x[8], S41, 0x6fa87e4f);
|
||||
gxmd5_II(&d, a, b, c, x[15], S42, 0xfe2ce6e0);
|
||||
gxmd5_II(&c, d, a, b, x[6], S43, 0xa3014314);
|
||||
gxmd5_II(&b, c, d, a, x[13], S44, 0x4e0811a1);
|
||||
gxmd5_II(&a, b, c, d, x[4], S41, 0xf7537e82);
|
||||
gxmd5_II(&d, a, b, c, x[11], S42, 0xbd3af235);
|
||||
gxmd5_II(&c, d, a, b, x[2], S43, 0x2ad7d2bb);
|
||||
gxmd5_II(&b, c, d, a, x[9], S44, 0xeb86d391);
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
}
|
||||
|
||||
int gxmd5_update(unsigned char* data, uint32_t len, unsigned char* buffer, uint32_t* count, uint32_t* state)
|
||||
{
|
||||
unsigned int i;
|
||||
// Number of bytes.
|
||||
unsigned int index = count[0] / 8 % 64;
|
||||
|
||||
// Update number of bits
|
||||
if ((count[0] += (len << 3)) < (len << 3))
|
||||
{
|
||||
count[1]++;
|
||||
}
|
||||
count[1] += (len >> 29);
|
||||
|
||||
// number of bytes we need to fill in buffer
|
||||
unsigned int firstpart = 64 - index;
|
||||
|
||||
|
||||
// transform as many times as possible.
|
||||
if (len >= firstpart)
|
||||
{
|
||||
memcpy(&buffer[index], data, firstpart);
|
||||
gxmd5_transform(buffer, state);
|
||||
|
||||
// Transform block
|
||||
for (i = firstpart; i + 64 <= len; i += 64)
|
||||
{
|
||||
gxmd5_transform(data + i, state);
|
||||
}
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
memcpy(&buffer[index], &data[i], len - i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gxmd5_encrypt(gxByteBuffer* data, gxByteBuffer* digest)
|
||||
{
|
||||
// Bytes that didn't fit in last 64 byte chunk
|
||||
unsigned char buffer[64];
|
||||
// Number of bits (lo, hi)
|
||||
uint32_t count[2] = { 0, 0 };
|
||||
// Digest
|
||||
uint32_t state[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
|
||||
bb_capacity(digest, 16);
|
||||
|
||||
gxmd5_update(data->data, data->size, buffer, count, state);
|
||||
|
||||
static unsigned char padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
// Save number of bits
|
||||
unsigned char bits[8];
|
||||
gxmd5_encode(bits, count, 2);
|
||||
|
||||
// Pad out to 56 mod 64.
|
||||
unsigned int index = count[0] / 8 % 64;
|
||||
unsigned int padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
gxmd5_update(padding, padLen, buffer, count, state);
|
||||
|
||||
// Append length (before padding)
|
||||
gxmd5_update(bits, 8, buffer, count, state);
|
||||
|
||||
// Store state in digest
|
||||
gxmd5_encode(digest->data, state, 4);
|
||||
digest->size = 16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif //DLMS_IGNORE_HIGH_MD5
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXMD5_H
|
||||
#define GXMD5_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//If MD5 is not used.
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_HIGH_MD5
|
||||
|
||||
#include "bytebuffer.h"
|
||||
|
||||
// Constants .
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
|
||||
int gxmd5_encrypt(gxByteBuffer* data, gxByteBuffer* crypted);
|
||||
|
||||
#endif //DLMS_IGNORE_HIGH_MD5
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXMD5_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,179 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXSERIALIZER_H
|
||||
#define GXSERIALIZER_H
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_SERIALIZER
|
||||
|
||||
#include "gxobjects.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !(!defined(GX_DLMS_SERIALIZER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__)))
|
||||
/*Return EEPROM or Flash size.*/
|
||||
extern uint32_t SERIALIZER_SIZE();
|
||||
//Read bytes from.
|
||||
extern int SERIALIZER_LOAD(uint32_t index, uint32_t count, void* value);
|
||||
//Write byte
|
||||
extern int SERIALIZER_SAVE(uint32_t index, uint32_t count, const void* value);
|
||||
#endif //#if !defined(GX_DLMS_SERIALIZER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__))
|
||||
|
||||
//This attribute is not serialized.
|
||||
#define IGNORE_ATTRIBUTE(OBJECT, INDEX) {OBJECT, INDEX, 0}
|
||||
|
||||
//This attribute is not serialized by object type.
|
||||
#define IGNORE_ATTRIBUTE_BY_TYPE(TYPE, INDEX) {0, INDEX, TYPE}
|
||||
|
||||
#define ___COSEM_ATTRIBUTES(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16,...) _16
|
||||
//Visual Studio reguires this.
|
||||
#define ___EXPAND(x) x
|
||||
#define ___COUNT_ATTRIBUTES(...) ___EXPAND(___COSEM_ATTRIBUTES(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
|
||||
|
||||
#define GET_ALL_ATTRIBUTES() -1
|
||||
#define GET_ATTRIBUTE1(A) 1 << (A - 1)
|
||||
#define GET_ATTRIBUTE2(A, B) GET_ATTRIBUTE1(A) | GET_ATTRIBUTE1(B)
|
||||
#define GET_ATTRIBUTE3(A, B, C) GET_ATTRIBUTE2(A, B) | GET_ATTRIBUTE1(C)
|
||||
#define GET_ATTRIBUTE4(A, B, C, D) GET_ATTRIBUTE3(A, B, C) | GET_ATTRIBUTE1(D)
|
||||
#define GET_ATTRIBUTE5(A, B, C, D, E) GET_ATTRIBUTE4(A, B, C, D) | GET_ATTRIBUTE1(E)
|
||||
#define GET_ATTRIBUTE6(A, B, C, D, E, F) GET_ATTRIBUTE5(A, B, C, D, E) | GET_ATTRIBUTE1(F)
|
||||
#define GET_ATTRIBUTE7(A, B, C, D, E, F, G) GET_ATTRIBUTE6(A, B, C, D, E, F) | GET_ATTRIBUTE1(G)
|
||||
#define GET_ATTRIBUTE8(A, B, C, D, E, F, G, H) GET_ATTRIBUTE7(A, B, C, D, E, F, G) | GET_ATTRIBUTE1(H)
|
||||
#define GET_ATTRIBUTE9(A, B, C, D, E, F, G, H, I) GET_ATTRIBUTE8(A, B, C, D, E, F, G, H) | GET_ATTRIBUTE1(I)
|
||||
#define GET_ATTRIBUTE10(A, B, C, D, E, F, G, H, I, J)GET_ATTRIBUTE9(A, B, C, D, E, F, G, H, I) | GET_ATTRIBUTE1(J)
|
||||
#define GET_ATTRIBUTE11(A, B, C, D, E, F, G, H, I, J, K) GET_ATTRIBUTE10(A, B, C, D, E, F, G, H, I, J) | GET_ATTRIBUTE1(K)
|
||||
#define GET_ATTRIBUTE12(A, B, C, D, E, F, G, H, I, J, K, L) GET_ATTRIBUTE11(A, B, C, D, E, F, G, H, I, J, K) | GET_ATTRIBUTE1(L)
|
||||
#define GET_ATTRIBUTE13(A, B, C, D, E, F, G, H, I, J, K, L, M) GET_ATTRIBUTE12(A, B, C, D, E, F, G, H, I, J, K, L) | GET_ATTRIBUTE1(M)
|
||||
#define GET_ATTRIBUTE14(A, B, C, D, E, F, G, H, I, J, K, L, M, N) GET_ATTRIBUTE13(A, B, C, D, E, F, G, H, I, J, K, L, M) | GET_ATTRIBUTE1(N)
|
||||
#define GET_ATTRIBUTE15(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) GET_ATTRIBUTE14(A, B, C, D, E, F, G, H, I, J, K, L, M, N) | GET_ATTRIBUTE1(O)
|
||||
#define GET_ATTRIBUTE16(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) GET_ATTRIBUTE15(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) | GET_ATTRIBUTE1(P)
|
||||
#define CONC(A, B) CONC_(A, B)
|
||||
#define CONC_(A, B) A##B
|
||||
#define GET_ATTRIBUTE(...) CONC(GET_ATTRIBUTE, ___COUNT_ATTRIBUTES(__VA_ARGS__))(__VA_ARGS__)
|
||||
#define GET_ATTRIBUTE_EXCEPT(...) (uint16_t)~(GET_ATTRIBUTE(__VA_ARGS__))
|
||||
#define GET_ATTRIBUTE_ALL() 0xFFFF
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*Target to ignore*/
|
||||
gxObject* target;
|
||||
/*Bit enumerated attribute list from attributes that are not serialized.*/
|
||||
uint16_t attributes;
|
||||
/*Object type to ignore*/
|
||||
uint16_t objectType;
|
||||
} gxSerializerIgnore;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//List of attributes that are not serialized.
|
||||
gxSerializerIgnore* ignoredAttributes;
|
||||
//Count of ignored objects.
|
||||
uint16_t count;
|
||||
|
||||
|
||||
#if !defined(GX_DLMS_SERIALIZER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__))
|
||||
FILE* stream;
|
||||
#else
|
||||
//Serialization position is used to save serialization index.
|
||||
uint32_t position;
|
||||
//Index of where changed data starts. This is used for debugging.
|
||||
uint32_t updateStart;
|
||||
//Index of where changed data ends. This is used for debugging.
|
||||
uint32_t updateEnd;
|
||||
#endif //!defined(GX_DLMS_SERIALIZER) && (defined(_WIN32) || defined(_WIN64) || defined(__linux__))
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
//Only this object is saved if it is set.
|
||||
gxObject* savedObject;
|
||||
//Only attributes saved when savedObject is used.
|
||||
uint32_t savedAttributes;
|
||||
//This is for internal use.
|
||||
//Whether to save the object. This is needed if only changed object is used.
|
||||
gxObject* currentObject;
|
||||
//This is for internal use.
|
||||
uint16_t currentIndex;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
} gxSerializerSettings;
|
||||
|
||||
void ser_init(gxSerializerSettings* settings);
|
||||
|
||||
//Serialize object to bytebuffer.
|
||||
int ser_saveObject(
|
||||
gxSerializerSettings* serializeSettings,
|
||||
gxObject* object);
|
||||
|
||||
//Serialize objects to flash.
|
||||
int ser_saveObjects(
|
||||
gxSerializerSettings* serializeSettings,
|
||||
gxObject** objects,
|
||||
uint16_t count);
|
||||
|
||||
//Serialize objects to flash.
|
||||
int ser_saveObjects2(
|
||||
gxSerializerSettings* serializeSettings,
|
||||
objectArray* objects);
|
||||
|
||||
//Serialize object from flash.
|
||||
int ser_loadObject(
|
||||
dlmsSettings* settings,
|
||||
gxSerializerSettings* serializeSettings,
|
||||
gxObject* object);
|
||||
|
||||
//Serialize objects from the flash.
|
||||
int ser_loadObjects(
|
||||
dlmsSettings* settings,
|
||||
gxSerializerSettings* serializeSettings,
|
||||
gxObject** object,
|
||||
uint16_t count);
|
||||
|
||||
//Serialize objects from the flash.
|
||||
int ser_loadObjects2(
|
||||
dlmsSettings* settings,
|
||||
gxSerializerSettings* serializeSettings,
|
||||
objectArray* object);
|
||||
|
||||
//Get data size in bytes.
|
||||
int ser_getDataSize(
|
||||
gxSerializerSettings* serializeSettings,
|
||||
void* size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DLMS_IGNORE_SERIALIZER
|
||||
#endif //GXSERIALIZER_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,388 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef COSEM_SET_IGNORE_MALLOC_H
|
||||
#define COSEM_SET_IGNORE_MALLOC_H
|
||||
|
||||
#include "gxignore.h"
|
||||
#if defined(DLMS_IGNORE_MALLOC) || defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "gxobjects.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
#ifndef DLMS_IGNORE_DATA
|
||||
int cosem_setData(gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_REGISTER
|
||||
int cosem_setRegister(gxRegister* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_REGISTER
|
||||
|
||||
#ifndef DLMS_IGNORE_CLOCK
|
||||
int cosem_setClock(dlmsSettings* settings, gxClock* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_CLOCK
|
||||
|
||||
#ifndef DLMS_IGNORE_ACTION_SCHEDULE
|
||||
int cosem_setActionSchedule(dlmsSettings* settings, gxActionSchedule* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_ACTION_SCHEDULE
|
||||
|
||||
#ifndef DLMS_IGNORE_ACTIVITY_CALENDAR
|
||||
int cosem_setActivityCalendar(dlmsSettings* settings, gxActivityCalendar* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_ACTIVITY_CALENDAR
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
||||
int cosem_parseLNObjects(dlmsSettings* settings, gxByteBuffer* data, objectArray* objects);
|
||||
int cosem_setAssociationLogicalName(dlmsSettings* settings, gxAssociationLogicalName* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
||||
|
||||
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
int cosem_parseSNObjects(dlmsSettings* settings, gxByteBuffer* data, objectArray* objects);
|
||||
int cosem_setAssociationShortName(dlmsSettings* settings, gxAssociationShortName* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
||||
|
||||
#ifndef DLMS_IGNORE_AUTO_ANSWER
|
||||
int cosem_setAutoAnswer(gxAutoAnswer* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_AUTO_ANSWER
|
||||
|
||||
#ifndef DLMS_IGNORE_AUTO_CONNECT
|
||||
int cosem_setAutoConnect(gxAutoConnect* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_AUTO_CONNECT
|
||||
|
||||
#ifndef DLMS_IGNORE_DEMAND_REGISTER
|
||||
int cosem_setDemandRegister(gxDemandRegister* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_DEMAND_REGISTER
|
||||
|
||||
#ifndef DLMS_IGNORE_MAC_ADDRESS_SETUP
|
||||
int cosem_setMacAddressSetup(gxMacAddressSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_MAC_ADDRESS_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_EXTENDED_REGISTER
|
||||
int cosem_setExtendedRegister(gxExtendedRegister* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_EXTENDED_REGISTER
|
||||
|
||||
#ifndef DLMS_IGNORE_GPRS_SETUP
|
||||
int cosem_setGprsSetup(gxGPRSSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_GPRS_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_SECURITY_SETUP
|
||||
int cosem_setSecuritySetup(dlmsSettings* settings, gxSecuritySetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_SECURITY_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
int cosem_setIecHdlcSetup(gxIecHdlcSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_IEC_HDLC_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
int cosem_setIecLocalPortSetup(gxLocalPortSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IP4_SETUP
|
||||
int cosem_setIP4Setup(dlmsSettings* settings, gxIp4Setup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_IP4_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_PROFILE_GENERIC
|
||||
int cosem_setProfileGeneric(dlmsSettings* settings, gxProfileGeneric* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_PROFILE_GENERIC
|
||||
|
||||
#ifndef DLMS_IGNORE_UTILITY_TABLES
|
||||
int cosem_setUtilityTables(gxUtilityTables* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_UTILITY_TABLES
|
||||
|
||||
#ifndef DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
||||
int cosem_setMbusSlavePortSetup(gxMbusSlavePortSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_DISCONNECT_CONTROL
|
||||
int cosem_setDisconnectControl(gxDisconnectControl* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_DISCONNECT_CONTROL
|
||||
|
||||
#ifndef DLMS_IGNORE_LIMITER
|
||||
int cosem_setLimiter(dlmsSettings* settings, gxLimiter* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_LIMITER
|
||||
|
||||
#ifndef DLMS_IGNORE_MBUS_CLIENT
|
||||
int cosem_setmMbusClient(dlmsSettings* settings, gxMBusClient* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_MBUS_CLIENT
|
||||
|
||||
#ifndef DLMS_IGNORE_MODEM_CONFIGURATION
|
||||
int cosem_setModemConfiguration(gxModemConfiguration* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_MODEM_CONFIGURATION
|
||||
|
||||
#ifndef DLMS_IGNORE_PPP_SETUP
|
||||
int cosem_setPppSetup(dlmsSettings* settings, gxPppSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_PPP_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_REGISTER_ACTIVATION
|
||||
int cosem_setRegisterActivation(dlmsSettings* settings, gxValueEventArg* e);
|
||||
#endif //DLMS_IGNORE_REGISTER_ACTIVATION
|
||||
|
||||
#ifndef DLMS_IGNORE_REGISTER_MONITOR
|
||||
int cosem_setRegisterMonitor(dlmsSettings* settings, gxRegisterMonitor* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_REGISTER_MONITOR
|
||||
|
||||
#ifndef DLMS_IGNORE_SAP_ASSIGNMENT
|
||||
int cosem_setSapAssignment(gxSapAssignment* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_SAP_ASSIGNMENT
|
||||
|
||||
#ifndef DLMS_IGNORE_SCHEDULE
|
||||
int cosem_setSchedule(dlmsSettings* settings, gxSchedule* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_SCHEDULE
|
||||
|
||||
#ifndef DLMS_IGNORE_SCRIPT_TABLE
|
||||
int cosem_setScriptTable(dlmsSettings* settings, gxScriptTable* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_SCRIPT_TABLE
|
||||
|
||||
#ifndef DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
||||
int cosem_setSpecialDaysTable(gxSpecialDaysTable* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
||||
|
||||
#ifndef DLMS_IGNORE_TCP_UDP_SETUP
|
||||
int cosem_setTcpUdpSetup(dlmsSettings* settings, gxTcpUdpSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_TCP_UDP_SETUP
|
||||
#ifndef DLMS_IGNORE_MBUS_DIAGNOSTIC
|
||||
int cosem_setMbusDiagnostic(gxMbusDiagnostic* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MBUS_DIAGNOSTIC
|
||||
#ifndef DLMS_IGNORE_MBUS_PORT_SETUP
|
||||
int cosem_setMbusPortSetup(gxMBusPortSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_MBUS_PORT_SETUP
|
||||
#ifndef DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
||||
int cosem_setMbusMasterPortSetup(gxMBusMasterPortSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
||||
int cosem_setG3PlcMacLayerCounters(gxG3PlcMacLayerCounters* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
||||
#ifndef DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
int cosem_setG3PlcMacSetup(gxG3PlcMacSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_G3_PLC_MAC_SETUP
|
||||
#ifndef DLMS_IGNORE_G3_PLC_6LO_WPAN
|
||||
int cosem_setG3Plc6LoWPAN(gxG3Plc6LoWPAN* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_G3_PLC_6LO_WPAN
|
||||
#ifndef DLMS_IGNORE_FUNCTION_CONTROL
|
||||
int cosem_setFunctionControl(
|
||||
dlmsSettings* settings,
|
||||
gxFunctionControl* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_FUNCTION_CONTROL
|
||||
#ifndef DLMS_IGNORE_ARRAY_MANAGER
|
||||
int cosem_setArrayManager(dlmsSettings* settings, gxArrayManager* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ARRAY_MANAGER
|
||||
#ifndef DLMS_IGNORE_PUSH_SETUP
|
||||
int cosem_setPushSetup(dlmsSettings* settings, gxPushSetup* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_PUSH_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
int cosem_setGsmDiagnostic(gxGsmDiagnostic* object, unsigned char index, dlmsVARIANT *value);
|
||||
#endif //DLMS_IGNORE_GSM_DIAGNOSTIC
|
||||
|
||||
#ifndef DLMS_IGNORE_COMPACT_DATA
|
||||
int compactData_updateTemplateDescription(
|
||||
dlmsSettings* settings,
|
||||
gxCompactData* object);
|
||||
#endif //DLMS_IGNORE_COMPACT_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
||||
int cosem_setIecTwistedPairSetup(gxIecTwistedPairSetup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IP6_SETUP
|
||||
int cosem_setIP6Setup(dlmsSettings* settings, gxIp6Setup* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IP6_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IMAGE_TRANSFER
|
||||
int cosem_setImageTransfer(gxImageTransfer* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IMAGE_TRANSFER
|
||||
#ifndef DLMS_IGNORE_REGISTER_TABLE
|
||||
int cosem_setRegistertable(gxRegisterTable* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_REGISTER_TABLE
|
||||
#ifndef DLMS_IGNORE_ACCOUNT
|
||||
int cosem_setAccount(gxAccount* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ACCOUNT
|
||||
#ifndef DLMS_IGNORE_CREDIT
|
||||
int cosem_setCredit(gxCredit* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_CREDIT
|
||||
#ifndef DLMS_IGNORE_CHARGE
|
||||
int cosem_setCharge(dlmsSettings* settings, gxCharge* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_CHARGE
|
||||
#ifndef DLMS_IGNORE_TOKEN_GATEWAY
|
||||
int cosem_setTokenGateway(gxTokenGateway* object, unsigned char index, dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_TOKEN_GATEWAY
|
||||
|
||||
#ifndef DLMS_IGNORE_COMPACT_DATA
|
||||
int cosem_setCompactData(
|
||||
dlmsSettings* settings,
|
||||
gxCompactData* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_COMPACT_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_PARAMETER_MONITOR
|
||||
int cosem_setParameterMonitor(
|
||||
dlmsSettings* settings,
|
||||
gxParameterMonitor* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PARAMETER_MONITOR
|
||||
|
||||
#ifndef DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
int cosem_setLlcSscsSetup(
|
||||
dlmsSettings* settings,
|
||||
gxLlcSscsSetup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_LLC_SSCS_SETUP
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
int cosem_setPrimeNbOfdmPlcPhysicalLayerCounters(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcPhysicalLayerCounters* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
||||
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
int cosem_setPrimeNbOfdmPlcMacSetup(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcMacSetup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
int cosem_setPrimeNbOfdmPlcMacFunctionalParameters(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcMacFunctionalParameters* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
int cosem_setPrimeNbOfdmPlcMacCounters(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcMacCounters* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
int cosem_setPrimeNbOfdmPlcMacNetworkAdministrationData(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcMacNetworkAdministrationData* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
||||
|
||||
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
int cosem_setPrimeNbOfdmPlcApplicationsIdentification(
|
||||
dlmsSettings* settings,
|
||||
gxPrimeNbOfdmPlcApplicationsIdentification* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
||||
#ifndef DLMS_IGNORE_ARBITRATOR
|
||||
int cosem_setArbitrator(
|
||||
dlmsSettings* settings,
|
||||
gxArbitrator* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_ARBITRATOR
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
||||
int cosem_setIec8802LlcType1Setup(
|
||||
dlmsSettings* settings,
|
||||
gxIec8802LlcType1Setup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
||||
int cosem_setIec8802LlcType2Setup(
|
||||
dlmsSettings* settings,
|
||||
gxIec8802LlcType2Setup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
||||
int cosem_setIec8802LlcType3Setup(
|
||||
dlmsSettings* settings,
|
||||
gxIec8802LlcType3Setup* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
||||
int cosem_setSFSKActiveInitiator(
|
||||
dlmsSettings* settings,
|
||||
gxSFSKActiveInitiator* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_MAC_COUNTERS
|
||||
int cosem_setFSKMacCounters(
|
||||
dlmsSettings* settings,
|
||||
gxFSKMacCounters* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_MAC_COUNTERS
|
||||
#ifndef DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
||||
int cosem_setSFSKMacSynchronizationTimeouts(
|
||||
dlmsSettings* settings,
|
||||
gxSFSKMacSynchronizationTimeouts* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
||||
int cosem_setSFSKPhyMacSetUp(
|
||||
dlmsSettings* settings,
|
||||
gxSFSKPhyMacSetUp* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
||||
|
||||
#ifndef DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
||||
int cosem_setSFSKReportingSystemList(
|
||||
dlmsSettings* settings,
|
||||
gxSFSKReportingSystemList* object,
|
||||
unsigned char index,
|
||||
dlmsVARIANT* value);
|
||||
#endif //DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //defined(DLMS_IGNORE_MALLOC) || defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
#endif//COSEM_SET_IGNORE_MALLOC_H
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_HIGH_SHA1
|
||||
#include <string.h>
|
||||
#include "gxsha1.h"
|
||||
|
||||
#define SHA1_ROL(value, bits) (((value) << (bits)) | (((value) & 0xffffffff) >> (32 - (bits))))
|
||||
#define SHA1_BLK(i) (block[i&15] = SHA1_ROL(block[(i+13)&15] ^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i&15],1))
|
||||
|
||||
#define SHA1_R0(v,w,x,y,z,i) z += ((w & (x ^ y)) ^ y) + block[i] + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
|
||||
#define SHA1_R1(v,w,x,y,z,i) z += ((w & (x ^ y)) ^ y) + SHA1_BLK(i) + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
|
||||
#define SHA1_R2(v,w,x,y,z,i) z += (w ^ x ^ y) + SHA1_BLK(i) + 0x6ed9eba1 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
|
||||
#define SHA1_R3(v,w,x,y,z,i) z += (((w | x) & y) | ( w & x)) + SHA1_BLK(i) + 0x8f1bbcdc + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
|
||||
#define SHA1_R4(v,w,x,y,z,i) z += (w ^ x ^ y) + SHA1_BLK(i) + 0xca62c1d6 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
|
||||
|
||||
/*
|
||||
* Hash block is a single 512-bit block.
|
||||
*/
|
||||
void gxsha1_transform(uint32_t* block, uint32_t* digest, uint32_t* transforms)
|
||||
{
|
||||
uint32_t a = digest[0];
|
||||
uint32_t b = digest[1];
|
||||
uint32_t c = digest[2];
|
||||
uint32_t d = digest[3];
|
||||
uint32_t e = digest[4];
|
||||
|
||||
SHA1_R0(a, b, c, d, e, 0);
|
||||
SHA1_R0(e, a, b, c, d, 1);
|
||||
SHA1_R0(d, e, a, b, c, 2);
|
||||
SHA1_R0(c, d, e, a, b, 3);
|
||||
SHA1_R0(b, c, d, e, a, 4);
|
||||
SHA1_R0(a, b, c, d, e, 5);
|
||||
SHA1_R0(e, a, b, c, d, 6);
|
||||
SHA1_R0(d, e, a, b, c, 7);
|
||||
SHA1_R0(c, d, e, a, b, 8);
|
||||
SHA1_R0(b, c, d, e, a, 9);
|
||||
SHA1_R0(a, b, c, d, e, 10);
|
||||
SHA1_R0(e, a, b, c, d, 11);
|
||||
SHA1_R0(d, e, a, b, c, 12);
|
||||
SHA1_R0(c, d, e, a, b, 13);
|
||||
SHA1_R0(b, c, d, e, a, 14);
|
||||
SHA1_R0(a, b, c, d, e, 15);
|
||||
SHA1_R1(e, a, b, c, d, 16);
|
||||
SHA1_R1(d, e, a, b, c, 17);
|
||||
SHA1_R1(c, d, e, a, b, 18);
|
||||
SHA1_R1(b, c, d, e, a, 19);
|
||||
SHA1_R2(a, b, c, d, e, 20);
|
||||
SHA1_R2(e, a, b, c, d, 21);
|
||||
SHA1_R2(d, e, a, b, c, 22);
|
||||
SHA1_R2(c, d, e, a, b, 23);
|
||||
SHA1_R2(b, c, d, e, a, 24);
|
||||
SHA1_R2(a, b, c, d, e, 25);
|
||||
SHA1_R2(e, a, b, c, d, 26);
|
||||
SHA1_R2(d, e, a, b, c, 27);
|
||||
SHA1_R2(c, d, e, a, b, 28);
|
||||
SHA1_R2(b, c, d, e, a, 29);
|
||||
SHA1_R2(a, b, c, d, e, 30);
|
||||
SHA1_R2(e, a, b, c, d, 31);
|
||||
SHA1_R2(d, e, a, b, c, 32);
|
||||
SHA1_R2(c, d, e, a, b, 33);
|
||||
SHA1_R2(b, c, d, e, a, 34);
|
||||
SHA1_R2(a, b, c, d, e, 35);
|
||||
SHA1_R2(e, a, b, c, d, 36);
|
||||
SHA1_R2(d, e, a, b, c, 37);
|
||||
SHA1_R2(c, d, e, a, b, 38);
|
||||
SHA1_R2(b, c, d, e, a, 39);
|
||||
SHA1_R3(a, b, c, d, e, 40);
|
||||
SHA1_R3(e, a, b, c, d, 41);
|
||||
SHA1_R3(d, e, a, b, c, 42);
|
||||
SHA1_R3(c, d, e, a, b, 43);
|
||||
SHA1_R3(b, c, d, e, a, 44);
|
||||
SHA1_R3(a, b, c, d, e, 45);
|
||||
SHA1_R3(e, a, b, c, d, 46);
|
||||
SHA1_R3(d, e, a, b, c, 47);
|
||||
SHA1_R3(c, d, e, a, b, 48);
|
||||
SHA1_R3(b, c, d, e, a, 49);
|
||||
SHA1_R3(a, b, c, d, e, 50);
|
||||
SHA1_R3(e, a, b, c, d, 51);
|
||||
SHA1_R3(d, e, a, b, c, 52);
|
||||
SHA1_R3(c, d, e, a, b, 53);
|
||||
SHA1_R3(b, c, d, e, a, 54);
|
||||
SHA1_R3(a, b, c, d, e, 55);
|
||||
SHA1_R3(e, a, b, c, d, 56);
|
||||
SHA1_R3(d, e, a, b, c, 57);
|
||||
SHA1_R3(c, d, e, a, b, 58);
|
||||
SHA1_R3(b, c, d, e, a, 59);
|
||||
SHA1_R4(a, b, c, d, e, 60);
|
||||
SHA1_R4(e, a, b, c, d, 61);
|
||||
SHA1_R4(d, e, a, b, c, 62);
|
||||
SHA1_R4(c, d, e, a, b, 63);
|
||||
SHA1_R4(b, c, d, e, a, 64);
|
||||
SHA1_R4(a, b, c, d, e, 65);
|
||||
SHA1_R4(e, a, b, c, d, 66);
|
||||
SHA1_R4(d, e, a, b, c, 67);
|
||||
SHA1_R4(c, d, e, a, b, 68);
|
||||
SHA1_R4(b, c, d, e, a, 69);
|
||||
SHA1_R4(a, b, c, d, e, 70);
|
||||
SHA1_R4(e, a, b, c, d, 71);
|
||||
SHA1_R4(d, e, a, b, c, 72);
|
||||
SHA1_R4(c, d, e, a, b, 73);
|
||||
SHA1_R4(b, c, d, e, a, 74);
|
||||
SHA1_R4(a, b, c, d, e, 75);
|
||||
SHA1_R4(e, a, b, c, d, 76);
|
||||
SHA1_R4(d, e, a, b, c, 77);
|
||||
SHA1_R4(c, d, e, a, b, 78);
|
||||
SHA1_R4(b, c, d, e, a, 79);
|
||||
|
||||
digest[0] += a;
|
||||
digest[1] += b;
|
||||
digest[2] += c;
|
||||
digest[3] += d;
|
||||
digest[4] += e;
|
||||
|
||||
++* transforms;
|
||||
}
|
||||
|
||||
void gxsha1_update(gxByteBuffer* data, uint32_t* digest, uint32_t* transforms)
|
||||
{
|
||||
unsigned int pos;
|
||||
uint32_t block[16];
|
||||
while (data->size - data->position > 64)
|
||||
{
|
||||
for (pos = 0; pos != 16; ++pos)
|
||||
{
|
||||
bb_getUInt32(data, &block[pos]);
|
||||
}
|
||||
gxsha1_transform(block, digest, transforms);
|
||||
}
|
||||
}
|
||||
|
||||
int gxsha1_final(gxByteBuffer* data, uint32_t* digest, uint32_t* transforms, gxByteBuffer* reply)
|
||||
{
|
||||
int pos;
|
||||
bb_capacity(reply, (uint16_t) *transforms * 64);
|
||||
bb_set(reply, data->data, data->size);
|
||||
/* Total number of hashed bits */
|
||||
uint64_t total_bits = (*transforms * 64 + data->size) * 8;
|
||||
|
||||
/* Padding */
|
||||
bb_setUInt8(reply, 0x80);
|
||||
uint32_t orig_size = reply->size;
|
||||
bb_zero(reply, reply->size, 64 - reply->size);
|
||||
uint32_t block[16];
|
||||
for (pos = 0; pos != 16; ++pos)
|
||||
{
|
||||
bb_getUInt32(reply, &block[pos]);
|
||||
}
|
||||
if (orig_size > 64 - 8)
|
||||
{
|
||||
gxsha1_transform(block, digest, transforms);
|
||||
for (pos = 0; pos < 16 - 2; ++pos)
|
||||
{
|
||||
block[pos] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append total_bits, split this uint64 into two uint32 */
|
||||
block[16 - 1] = (uint32_t)total_bits;
|
||||
block[16 - 2] = (uint32_t)(total_bits >> 32);
|
||||
gxsha1_transform(block, digest, transforms);
|
||||
bb_capacity(reply, 20);
|
||||
reply->position = reply->size = 0;
|
||||
for (pos = 0; pos < 5; ++pos)
|
||||
{
|
||||
bb_setUInt32(reply, digest[pos]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gxsha1_encrypt(gxByteBuffer* data, gxByteBuffer* result)
|
||||
{
|
||||
uint32_t digest[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
|
||||
uint32_t transforms = 0;
|
||||
gxsha1_update(data, digest, &transforms);
|
||||
return gxsha1_final(data, digest, &transforms, result);
|
||||
}
|
||||
|
||||
#endif //DLMS_IGNORE_HIGH_SHA1
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXSHA1
|
||||
#define GXSHA1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_HIGH_SHA1
|
||||
|
||||
#include "bytebuffer.h"
|
||||
|
||||
int gxsha1_encrypt(gxByteBuffer* data, gxByteBuffer* digest);
|
||||
|
||||
#endif //DLMS_IGNORE_HIGH_SHA1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //GXSHA_256
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_HIGH_SHA256
|
||||
#include <string.h>
|
||||
#include "gxsha256.h"
|
||||
|
||||
const uint32_t sha256_k[64] =
|
||||
{ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
|
||||
|
||||
#define SHA2_SHFR(x, n) (x >> n)
|
||||
#define SHA2_ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
|
||||
#define SHA2_ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
|
||||
#define SHA2_CH(x, y, z) ((x & y) ^ (~x & z))
|
||||
#define SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
|
||||
#define SHA256_F1(x) (SHA2_ROTR(x, 2) ^ SHA2_ROTR(x, 13) ^ SHA2_ROTR(x, 22))
|
||||
#define SHA256_F2(x) (SHA2_ROTR(x, 6) ^ SHA2_ROTR(x, 11) ^ SHA2_ROTR(x, 25))
|
||||
#define SHA256_F3(x) (SHA2_ROTR(x, 7) ^ SHA2_ROTR(x, 18) ^ SHA2_SHFR(x, 3))
|
||||
#define SHA256_F4(x) (SHA2_ROTR(x, 17) ^ SHA2_ROTR(x, 19) ^ SHA2_SHFR(x, 10))
|
||||
#define SHA2_UNPACK32(x, str) \
|
||||
{ \
|
||||
*((str) + 3) = (unsigned char) ((x) ); \
|
||||
*((str) + 2) = (unsigned char) ((x) >> 8); \
|
||||
*((str) + 1) = (unsigned char) ((x) >> 16); \
|
||||
*((str) + 0) = (unsigned char) ((x) >> 24); \
|
||||
}
|
||||
#define SHA2_PACK32(str, x) \
|
||||
{ \
|
||||
*(x) = ((uint32_t) *((str) + 3) ) \
|
||||
| ((uint32_t) *((str) + 2) << 8) \
|
||||
| ((uint32_t) *((str) + 1) << 16) \
|
||||
| ((uint32_t) *((str) + 0) << 24); \
|
||||
}
|
||||
|
||||
|
||||
void gxsha256_transform(uint32_t *h, const unsigned char *message, unsigned int block_nb)
|
||||
{
|
||||
uint32_t w[64];
|
||||
uint32_t wv[8];
|
||||
uint32_t t1, t2;
|
||||
const unsigned char *sub_block;
|
||||
unsigned int i;
|
||||
int j;
|
||||
for (i = 0; i < block_nb; i++)
|
||||
{
|
||||
sub_block = message + (i << 6);
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
SHA2_PACK32(&sub_block[j << 2], &w[j]);
|
||||
}
|
||||
for (j = 16; j < 64; j++)
|
||||
{
|
||||
w[j] = SHA256_F4(w[j - 2]) + w[j - 7] + SHA256_F3(w[j - 15]) + w[j - 16];
|
||||
}
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
wv[j] = h[j];
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
t1 = wv[7] + SHA256_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
|
||||
+ sha256_k[j] + w[j];
|
||||
t2 = SHA256_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
|
||||
wv[7] = wv[6];
|
||||
wv[6] = wv[5];
|
||||
wv[5] = wv[4];
|
||||
wv[4] = wv[3] + t1;
|
||||
wv[3] = wv[2];
|
||||
wv[2] = wv[1];
|
||||
wv[1] = wv[0];
|
||||
wv[0] = t1 + t2;
|
||||
}
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
h[j] += wv[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int gxsha256_update(uint32_t *h, unsigned char *block, gxByteBuffer* data, unsigned int *len, unsigned int *totalLen)
|
||||
{
|
||||
unsigned int block_nb;
|
||||
unsigned int new_len, rem_len, tmp_len;
|
||||
const unsigned char *shifted_message;
|
||||
tmp_len = 64 - (data->size - data->position);
|
||||
rem_len = data->size < tmp_len ? data->size : tmp_len;
|
||||
memcpy(&block[data->position], data->data, rem_len);
|
||||
if (data->size - data->position < 64)
|
||||
{
|
||||
data->position = data->size;
|
||||
return 0;
|
||||
}
|
||||
new_len = *len - rem_len;
|
||||
block_nb = new_len / 64;
|
||||
shifted_message = data->data + rem_len;
|
||||
gxsha256_transform(h, block, 1);
|
||||
gxsha256_transform(h, shifted_message, block_nb);
|
||||
rem_len = new_len % 64;
|
||||
memcpy(block, &shifted_message[block_nb << 6], rem_len);
|
||||
*len = rem_len;
|
||||
*totalLen += (block_nb + 1) << 6;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gxsha256_final(uint32_t *h, unsigned char *block, unsigned char *digest, unsigned int len, unsigned int totalLen)
|
||||
{
|
||||
unsigned int block_nb;
|
||||
unsigned int pm_len;
|
||||
uint32_t len_b;
|
||||
int i;
|
||||
block_nb = (1 + ((64 - 9) < (len % 64)));
|
||||
len_b = (totalLen + len) << 3;
|
||||
pm_len = block_nb << 6;
|
||||
memset(block + len, 0, pm_len - len);
|
||||
block[len] = 0x80;
|
||||
SHA2_UNPACK32(len_b, block + pm_len - 4);
|
||||
gxsha256_transform(h, block, block_nb);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
SHA2_UNPACK32(h[i], &digest[i << 2]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gxsha256_encrypt(gxByteBuffer* data, gxByteBuffer* digest)
|
||||
{
|
||||
unsigned int len = data->size, totalLen = 0;
|
||||
uint32_t h[8] = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
|
||||
unsigned char block[128];
|
||||
bb_capacity(digest, 32);
|
||||
digest->size = 32;
|
||||
gxsha256_update((uint32_t*)&h, block, data, &len, &totalLen);
|
||||
return gxsha256_final(h, block, digest->data, len, totalLen);
|
||||
}
|
||||
|
||||
#endif //DLMS_IGNORE_HIGH_SHA256
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GXSHA_256
|
||||
#define GXSHA_256
|
||||
|
||||
#include "gxignore.h"
|
||||
#ifndef DLMS_IGNORE_HIGH_SHA256
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include "bytebuffer.h"
|
||||
|
||||
int gxsha256_encrypt(gxByteBuffer* data, gxByteBuffer* digest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DLMS_IGNORE_HIGH_SHA256
|
||||
|
||||
#endif //GXSHA_256
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxmem.h"
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#include "gxvalueeventargs.h"
|
||||
#include "objectarray.h"
|
||||
|
||||
void vec_init(gxValueEventCollection* arr)
|
||||
{
|
||||
arr->capacity = 0;
|
||||
arr->data = NULL;
|
||||
arr->position = 0;
|
||||
arr->size = 0;
|
||||
}
|
||||
|
||||
char vec_isAttached(gxValueEventCollection* arr)
|
||||
{
|
||||
return (arr->capacity & 0x80) == 0x80;
|
||||
}
|
||||
|
||||
unsigned char vec_getCapacity(gxValueEventCollection* arr)
|
||||
{
|
||||
return arr->capacity & 0x7F;
|
||||
}
|
||||
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
void vec_attach(
|
||||
gxValueEventCollection* arr,
|
||||
gxValueEventArg* value,
|
||||
unsigned char count,
|
||||
unsigned char capacity)
|
||||
{
|
||||
arr->data = value;
|
||||
arr->capacity = (uint16_t)(0x80 | capacity);
|
||||
arr->size = count;
|
||||
arr->position = 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Allocate new size for the array in bytes.
|
||||
int vec_capacity(gxValueEventCollection* arr, unsigned char capacity)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (!vec_isAttached(arr))
|
||||
{
|
||||
arr->capacity = capacity;
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = (gxValueEventArg * *)gxmalloc(arr->capacity * sizeof(gxValueEventArg*));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef gxrealloc
|
||||
//If compiler supports realloc.
|
||||
arr->data = (gxValueEventArg * *)gxrealloc(arr->data, arr->capacity * sizeof(gxValueEventArg*));
|
||||
#else
|
||||
//If compiler doesn't supports realloc.
|
||||
gxValueEventArg ** old = arr->data;
|
||||
arr->data = (gxValueEventArg * *)gxmalloc(arr->capacity * sizeof(gxValueEventArg*));
|
||||
//If not enought memory available.
|
||||
if (arr->data == NULL)
|
||||
{
|
||||
arr->data = old;
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(arr->data, old, sizeof(gxValueEventArg*) * arr->size);
|
||||
gxfree(old);
|
||||
#endif //gxrealloc
|
||||
}
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
if (vec_getCapacity(arr) < capacity)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Push new data to the gxValueEventCollection.
|
||||
int vec_push(gxValueEventCollection * arr, gxValueEventArg* item)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!vec_isAttached(arr))
|
||||
{
|
||||
if (arr->size >= vec_getCapacity(arr))
|
||||
{
|
||||
if ((ret = vec_capacity(arr, arr->capacity + 2)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vec_getCapacity(arr) <= arr->size)
|
||||
{
|
||||
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
arr->data[arr->size] = item;
|
||||
++arr->size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
void vec_empty(
|
||||
gxValueEventCollection* arr)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (!vec_isAttached(arr))
|
||||
{
|
||||
if (arr->size != 0)
|
||||
{
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
}
|
||||
arr->capacity = 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
arr->size = 0;
|
||||
arr->position = 0;
|
||||
}
|
||||
|
||||
void vec_clear(
|
||||
gxValueEventCollection* arr)
|
||||
{
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
if (!vec_isAttached(arr))
|
||||
{
|
||||
int pos;
|
||||
if (arr->size != 0)
|
||||
{
|
||||
for (pos = 0; pos != arr->size; ++pos)
|
||||
{
|
||||
ve_clear(arr->data[pos]);
|
||||
gxfree(arr->data[pos]);
|
||||
}
|
||||
gxfree(arr->data);
|
||||
arr->data = NULL;
|
||||
}
|
||||
arr->capacity = 0;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
arr->size = 0;
|
||||
arr->position = 0;
|
||||
}
|
||||
|
||||
int vec_getByIndex(gxValueEventCollection* arr, int index, gxValueEventArg** value)
|
||||
{
|
||||
if (index >= arr->size)
|
||||
{
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
}
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
*value = &arr->data[index];
|
||||
#else
|
||||
* value = arr->data[index];
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ve_init(gxValueEventArg * ve)
|
||||
{
|
||||
var_init(&ve->value);
|
||||
ve->handled = 0;
|
||||
ve->target = NULL;
|
||||
ve->index = 0;
|
||||
#if !defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
ve->dataType = DLMS_DATA_TYPE_NONE;
|
||||
#endif //!defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
ve->selector = 0;
|
||||
var_init(&ve->parameters);
|
||||
ve->error = DLMS_ERROR_CODE_OK;
|
||||
ve->action = 0;
|
||||
ve->byteArray = 0;
|
||||
ve->skipMaxPduSize = 0;
|
||||
ve->transactionStartIndex = 0;
|
||||
ve->transactionEndIndex = 0;
|
||||
ve->transaction = 0;
|
||||
}
|
||||
|
||||
void ve_clear(gxValueEventArg * ve)
|
||||
{
|
||||
var_clear(&ve->value);
|
||||
ve->handled = 0;
|
||||
ve->target = NULL;
|
||||
ve->index = 0;
|
||||
#if !defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
ve->dataType = DLMS_DATA_TYPE_NONE;
|
||||
#endif //!defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
ve->selector = 0;
|
||||
var_clear(&ve->parameters);
|
||||
ve->error = DLMS_ERROR_CODE_OK;
|
||||
ve->action = 0;
|
||||
ve->byteArray = 0;
|
||||
ve->skipMaxPduSize = 0;
|
||||
ve->transactionStartIndex = 0;
|
||||
ve->transactionEndIndex = 0;
|
||||
ve->transaction = 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,514 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "gxignore.h"
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#include "gxmem.h"
|
||||
#if _MSC_VER > 1400
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
#include "notify.h"
|
||||
#include "cosem.h"
|
||||
#include "gxset.h"
|
||||
#include "serverevents.h"
|
||||
|
||||
int notify_getData(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* reply,
|
||||
gxReplyData* data)
|
||||
{
|
||||
return dlms_getData2(settings, reply, data, 0);
|
||||
}
|
||||
|
||||
int notify_addData(
|
||||
dlmsSettings* settings,
|
||||
gxObject* obj,
|
||||
unsigned char index,
|
||||
gxByteBuffer* buff)
|
||||
{
|
||||
int ret;
|
||||
gxValueEventArg e;
|
||||
ve_init(&e);
|
||||
e.target = obj;
|
||||
e.index = index;
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
e.value.byteArr = buff;
|
||||
e.value.vt = DLMS_DATA_TYPE_OCTET_STRING;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
if ((ret = cosem_getValue(settings, &e)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (e.byteArray)
|
||||
{
|
||||
if (!bb_isAttached(buff))
|
||||
{
|
||||
bb_set(buff, e.value.byteArr->data, e.value.byteArr->size);
|
||||
var_clear(&e.value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ret = dlms_setData(buff, e.value.vt, &e.value);
|
||||
var_clear(&e.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int notify_generateDataNotificationMessages2(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time,
|
||||
#else
|
||||
struct tm* time,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxByteBuffer* data,
|
||||
message* messages)
|
||||
{
|
||||
int ret;
|
||||
if (settings->useLogicalNameReferencing)
|
||||
{
|
||||
gxLNParameters p;
|
||||
params_initLN(&p, settings, 0, DLMS_COMMAND_DATA_NOTIFICATION, 0, data, NULL, 0xff, DLMS_COMMAND_NONE, 0, 0);
|
||||
p.time = time;
|
||||
ret = dlms_getLnMessages(&p, messages);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(DLMS_IGNORE_ASSOCIATION_SHORT_NAME) && !defined(DLMS_IGNORE_MALLOC)
|
||||
gxSNParameters p;
|
||||
params_initSN(&p, settings, DLMS_COMMAND_DATA_NOTIFICATION, 1, 0, data, NULL, DLMS_COMMAND_NONE);
|
||||
ret = dlms_getSnMessages(&p, messages);
|
||||
#else
|
||||
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
#endif //!defined(DLMS_IGNORE_ASSOCIATION_SHORT_NAME) && !defined(DLMS_IGNORE_MALLOC)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int notify_generateDataNotificationMessages(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t date,
|
||||
#else
|
||||
struct tm* date,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxArray* objects,
|
||||
message* messages)
|
||||
{
|
||||
int ret = 0;
|
||||
uint16_t pos;
|
||||
gxListItem* it;
|
||||
gxByteBuffer buff;
|
||||
BYTE_BUFFER_INIT(&buff);
|
||||
bb_setUInt8(&buff, DLMS_DATA_TYPE_STRUCTURE);
|
||||
hlp_setObjectCount(objects->size, &buff);
|
||||
for (pos = 0; pos != objects->size; ++pos)
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
if ((ret = arr_getByIndex(objects, pos, (void**)&it, sizeof(gxListItem))) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if ((ret = arr_getByIndex(objects, pos, (void**)&it)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
if ((ret = notify_addData(settings, it->key, it->value, &buff)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
return notify_generateDataNotificationMessages2(settings, date, &buff, messages);
|
||||
}
|
||||
bb_clear(&buff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Sends Event Notification Request.
|
||||
int notify_generateEventNotificationMessages(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time,
|
||||
#else
|
||||
struct tm* time,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxListItem* item,
|
||||
variantArray* data,
|
||||
gxByteBuffer* pdu,
|
||||
message* messages)
|
||||
{
|
||||
int ret;
|
||||
uint16_t pos;
|
||||
dlmsVARIANT* it;
|
||||
if ((ret = bb_setUInt16(pdu, item->key->objectType)) != 0 ||
|
||||
(ret = bb_set(pdu, item->key->logicalName, 6)) != 0 ||
|
||||
(ret = bb_setUInt8(pdu, item->value)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (data == NULL)
|
||||
{
|
||||
if ((ret = notify_addData(settings, item->key, item->value, pdu)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ret = bb_setUInt8(pdu, DLMS_DATA_TYPE_ARRAY)) == 0 &&
|
||||
(ret = hlp_setObjectCount(data->size, pdu)) == 0)
|
||||
{
|
||||
for (pos = 0; pos != data->size; ++pos)
|
||||
{
|
||||
if ((ret = va_getByIndex(data, pos, &it)) != 0 ||
|
||||
(ret = dlms_setData(pdu, it->vt, it)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
gxLNParameters p;
|
||||
params_initLN(&p, settings, 0, DLMS_COMMAND_EVENT_NOTIFICATION, 0, pdu, NULL, 0xff, DLMS_COMMAND_NONE, 0, 0);
|
||||
p.time = time;
|
||||
ret = dlms_getLnMessages(&p, messages);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//Sends Event Notification Request.
|
||||
int notify_generateEventNotificationMessages2(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time,
|
||||
#else
|
||||
struct tm* time,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxListItem* item,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* pdu,
|
||||
message* messages)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = bb_setUInt16(pdu, item->key->objectType)) != 0 ||
|
||||
(ret = bb_set(pdu, item->key->logicalName, 6)) != 0 ||
|
||||
(ret = bb_setUInt8(pdu, item->value)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
ret = bb_set2(pdu, data, data->position, bb_available(data));
|
||||
if (ret == 0)
|
||||
{
|
||||
gxLNParameters p;
|
||||
params_initLN(&p, settings, 0, DLMS_COMMAND_EVENT_NOTIFICATION, 0, pdu, NULL, 0xff, DLMS_COMMAND_NONE, 0, 0);
|
||||
p.time = time;
|
||||
ret = dlms_getLnMessages(&p, messages);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef DLMS_IGNORE_PUSH_SETUP
|
||||
|
||||
int notify_generatePushSetupMessages(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t date,
|
||||
#else
|
||||
struct tm* date,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxPushSetup* push,
|
||||
message* messages)
|
||||
{
|
||||
int ret = 0;
|
||||
uint16_t pos;
|
||||
gxByteBuffer pdu;
|
||||
gxValueEventCollection args;
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
gxTarget* it;
|
||||
pdu = *settings->serializedPdu;
|
||||
gxValueEventArg p[1];
|
||||
ve_init(&p[0]);
|
||||
p[0].action = 1;
|
||||
vec_attach(&args, p, 1, 1);
|
||||
#else
|
||||
gxValueEventArg e;
|
||||
gxKey* it;
|
||||
BYTE_BUFFER_INIT(&pdu);
|
||||
ve_init(&e);
|
||||
vec_init(&args);
|
||||
vec_push(&args, &e);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
if (push == NULL || messages == NULL)
|
||||
{
|
||||
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
||||
}
|
||||
mes_clear(messages);
|
||||
if ((ret = bb_setUInt8(&pdu, DLMS_DATA_TYPE_STRUCTURE)) == 0 &&
|
||||
(ret = hlp_setObjectCount(push->pushObjectList.size, &pdu)) == 0)
|
||||
{
|
||||
for (pos = 0; pos != push->pushObjectList.size; ++pos)
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
if ((ret = arr_getByIndex(&push->pushObjectList, pos, (void**)&it, sizeof(gxTarget))) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if ((ret = arr_getByIndex(&push->pushObjectList, pos, (void**)&it)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
p[0].target = it->target;
|
||||
p[0].index = it->attributeIndex;
|
||||
svr_preRead(settings, &args);
|
||||
if (p[0].error != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if ((ret = notify_addData(settings, it->target, it->attributeIndex, &pdu)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#else
|
||||
e.target = (gxObject*)it->key;
|
||||
e.index = ((gxTarget*)it->value)->attributeIndex;
|
||||
#ifndef DLMS_IGNORE_SERVER
|
||||
svr_preRead(settings, &args);
|
||||
#endif
|
||||
if (e.error != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (e.value.vt != DLMS_DATA_TYPE_NONE)
|
||||
{
|
||||
ret = dlms_setData(&pdu, e.value.vt, &e.value);
|
||||
var_clear(&e.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ret = notify_addData(settings, (gxObject*)it->key, ((gxTarget*)it->value)->attributeIndex, &pdu)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#ifndef DLMS_IGNORE_SERVER
|
||||
svr_postRead(settings, &args);
|
||||
#endif //DLMS_IGNORE_SERVER
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
ve_clear(&p[0]);
|
||||
if (p[0].error != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#else
|
||||
ve_clear(&e);
|
||||
if (e.error != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
}
|
||||
vec_empty(&args);
|
||||
if (ret == 0)
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
//Update size and position
|
||||
settings->serializedPdu->position = pdu.position;
|
||||
settings->serializedPdu->size = pdu.size;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
ret = notify_generateDataNotificationMessages2(settings, date, &pdu, messages);
|
||||
}
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
bb_clear(&pdu);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
return ret;
|
||||
}
|
||||
|
||||
int notify_parsePush(
|
||||
dlmsSettings* settings,
|
||||
variantArray* data,
|
||||
gxArray* items)
|
||||
{
|
||||
gxListItem* k;
|
||||
gxObject* obj;
|
||||
unsigned char index;
|
||||
int classID, ret;
|
||||
uint16_t pos;
|
||||
gxValueEventArg e;
|
||||
dlmsVARIANT* it, * list, * tmp;
|
||||
if ((ret = va_getByIndex(data, 0, &list)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (pos = 0; pos != list->Arr->size; ++pos)
|
||||
{
|
||||
if ((ret = va_getByIndex(list->Arr, pos, &it)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if ((ret = va_getByIndex(it->Arr, 0, &tmp)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
classID = var_toInteger(tmp) & 0xFFFF;
|
||||
if (classID > 0)
|
||||
{
|
||||
if ((ret = va_getByIndex(it->Arr, 1, &tmp)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if ((ret = oa_findByLN(&settings->objects, (DLMS_OBJECT_TYPE)classID, tmp->byteArr->data, &obj)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (obj == NULL)
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
#else
|
||||
if ((ret = cosem_createObject((DLMS_OBJECT_TYPE)classID, &obj)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
memcpy(obj->logicalName, tmp->byteArr, 6);
|
||||
oa_push(&settings->objects, obj);
|
||||
//Add object to released objects list.
|
||||
ret = oa_push(&settings->releasedObjects, obj);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
||||
#else
|
||||
if ((ret = va_getByIndex(it->Arr, 2, &tmp)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
index = (unsigned char)var_toInteger(tmp);
|
||||
#if defined(_WIN64) || defined(__LP64__) || defined(_LP64)
|
||||
arr_push(items, key_init(obj, (void*)(uint64_t)index));
|
||||
#else
|
||||
arr_push(items, key_init(obj, (void*)(uint32_t)index));
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
}
|
||||
}
|
||||
ve_init(&e);
|
||||
for (pos = 0; pos != items->size; ++pos)
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
if ((ret = arr_getByIndex(items, pos, (void**)&k, sizeof(gxListItem))) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if ((ret = arr_getByIndex(items, pos, (void**)&k)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
obj = (gxObject*)k->key;
|
||||
if ((ret = va_getByIndex(data, pos, &it)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
index = k->value;
|
||||
e.target = obj;
|
||||
e.index = index;
|
||||
e.value = *it;
|
||||
if ((ret = cosem_setValue(settings, &e)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
int notify_getPushValues(
|
||||
dlmsSettings* settings,
|
||||
gxPushSetup* pushSetup,
|
||||
variantArray* data,
|
||||
gxArray* items)
|
||||
{
|
||||
gxObject* tmp;
|
||||
gxKey* k;
|
||||
int ret = 0;
|
||||
uint16_t pos;
|
||||
gxValueEventArg e;
|
||||
dlmsVARIANT* it;
|
||||
for (pos = 0; pos != pushSetup->pushObjectList.size; ++pos)
|
||||
{
|
||||
if ((ret = arr_getByIndex(&pushSetup->pushObjectList, pos, (void**)&k)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if ((ret = cosem_createObject(((gxObject*)k->key)->objectType, &tmp)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
memcpy(tmp->logicalName, ((gxObject*)k->key)->logicalName, 6);
|
||||
|
||||
if ((ret = va_getByIndex(data, pos, &it)) != 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
e.target = (gxObject*)tmp;
|
||||
e.index = ((gxTarget*)k->value)->attributeIndex;
|
||||
e.value = *it;
|
||||
if ((ret = cosem_setValue(settings, &e)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
arr_push(items, key_init(e.target, co_init(e.index, 0)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif //!defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
|
||||
#endif //DLMS_IGNORE_PUSH_SETUP
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef NOTIFY_H
|
||||
#define NOTIFY_H
|
||||
#include "gxignore.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "dlms.h"
|
||||
#include "gxget.h"
|
||||
#include "gxkey.h"
|
||||
|
||||
/**
|
||||
* Removes the HDLC frame from the packet, and returns COSEM data only.
|
||||
*
|
||||
* @param reply
|
||||
* The received data from the device.
|
||||
* @param data
|
||||
* Information from the received data.
|
||||
* @return Is frame complete.
|
||||
*/
|
||||
int notify_getData(
|
||||
dlmsSettings* settings,
|
||||
gxByteBuffer* reply,
|
||||
gxReplyData *data);
|
||||
|
||||
/**
|
||||
* Add value of COSEM object to byte buffer. AddData method can be used with
|
||||
* GetDataNotificationMessage -method. DLMS specification do not specify the
|
||||
* structure of Data-Notification body. So each manufacture can sent
|
||||
* different data.
|
||||
*
|
||||
* @param obj
|
||||
* COSEM object.
|
||||
* @param index
|
||||
* Attribute index.
|
||||
* @param buff
|
||||
* Byte buffer.
|
||||
*/
|
||||
int notify_addData(
|
||||
dlmsSettings* settings,
|
||||
gxObject* obj,
|
||||
unsigned char index,
|
||||
gxByteBuffer* buff);
|
||||
|
||||
/**
|
||||
* Generates data notification message.
|
||||
*
|
||||
* @param date
|
||||
* Date time. Set to null or Date(0) if not used
|
||||
* @param data
|
||||
* Notification body.
|
||||
* @return Generated data notification message(s).
|
||||
*/
|
||||
int notify_generateDataNotificationMessages2(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time,
|
||||
#else
|
||||
struct tm* time,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxByteBuffer* data,
|
||||
message* messages);
|
||||
|
||||
/**
|
||||
* Generates data notification message.
|
||||
*
|
||||
* @param date
|
||||
* Date time. Set To Min or Max if not added.
|
||||
* @param objects
|
||||
* List of objects and attribute indexes to notify.
|
||||
* @return Generated data notification message(s).
|
||||
*/
|
||||
int notify_generateDataNotificationMessages(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t date,
|
||||
#else
|
||||
struct tm* date,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxArray* objects,
|
||||
message* messages);
|
||||
|
||||
#ifndef DLMS_IGNORE_PUSH_SETUP
|
||||
/**
|
||||
* Generates push setup message.
|
||||
*
|
||||
* @param date
|
||||
* Date time. Set to null or Date(0) if not used.
|
||||
* @param push
|
||||
* Target Push object.
|
||||
* @return Generated data notification message(s).
|
||||
*/
|
||||
int notify_generatePushSetupMessages(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t date,
|
||||
#else
|
||||
struct tm* date,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxPushSetup* push,
|
||||
message* messages);
|
||||
|
||||
/**
|
||||
* Returns collection of push objects. If this method is used Push object
|
||||
* must be set for first object on push object list.
|
||||
*
|
||||
* @param data
|
||||
* Received value.
|
||||
* @return Array of objects and called indexes.
|
||||
*/
|
||||
int notify_parsePush(
|
||||
dlmsSettings* settings,
|
||||
variantArray* data,
|
||||
gxArray* items);
|
||||
|
||||
#if !defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
int notify_getPushValues(
|
||||
dlmsSettings* settings,
|
||||
gxPushSetup* pushSetup,
|
||||
variantArray* data,
|
||||
gxArray* items);
|
||||
#endif //!defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
||||
|
||||
//Sends Event Notification Request.
|
||||
int notify_generateEventNotificationMessages2(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time,
|
||||
#else
|
||||
struct tm* time,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxListItem* item,
|
||||
gxByteBuffer* data,
|
||||
gxByteBuffer* pdu,
|
||||
message* messages);
|
||||
|
||||
//Sends Event Notification Request.
|
||||
int notify_generateEventNotificationMessages(
|
||||
dlmsSettings* settings,
|
||||
#ifdef DLMS_USE_EPOCH_TIME
|
||||
uint32_t time,
|
||||
#else
|
||||
struct tm* time,
|
||||
#endif //DLMS_USE_EPOCH_TIME
|
||||
gxListItem* item,
|
||||
variantArray* data,
|
||||
gxByteBuffer* pdu,
|
||||
message* messages);
|
||||
|
||||
#endif //DLMS_IGNORE_PUSH_SETUP
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //NOTIFY_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,534 @@
|
|||
//
|
||||
// --------------------------------------------------------------------------
|
||||
// Gurux Ltd
|
||||
//
|
||||
//
|
||||
//
|
||||
// Filename: $HeadURL$
|
||||
//
|
||||
// Version: $Revision$,
|
||||
// $Date$
|
||||
// $Author$
|
||||
//
|
||||
// Copyright (c) Gurux Ltd
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DESCRIPTION
|
||||
//
|
||||
// This file is a part of Gurux Device Framework.
|
||||
//
|
||||
// Gurux Device Framework is Open Source software; you can redistribute it
|
||||
// and/or modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; version 2 of the License.
|
||||
// Gurux Device Framework is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// This code is licensed under the GNU General Public License v2.
|
||||
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef VARIANT_H
|
||||
#define VARIANT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "gxignore.h"
|
||||
#include "date.h"
|
||||
#include "enums.h"
|
||||
#include "errorcodes.h"
|
||||
#include "bytebuffer.h"
|
||||
#include "bitarray.h"
|
||||
#if _MSC_VER > 1400
|
||||
#pragma warning(disable : 4201)
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#define GX_SWAP_UINT16(a)(((a & 0xFF) << 8) | ((a & 0xFF00) >> 8))
|
||||
#define GX_SWAP_UINT32(a)(GX_SWAP_UINT16(a & 0xFFFF) << 16) | (GX_SWAP_UINT16(a >> 16) )
|
||||
|
||||
#define VARIANT_ARRAY_CAPACITY 10
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
||||
#define VERIFY(X, TYPE) (assert(X.vt == TYPE))
|
||||
#else
|
||||
#define VERIFY(X, TYPE)
|
||||
#endif
|
||||
|
||||
#define V_VT(X) ((X)->vt)
|
||||
#define GX_UNION(X, Y, Z) V_VT(X)=Z;(X)->Y
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
#define GX_UNION2(X, Y, Z, S, C) (X)->size=S;(X)->capacity=C;V_VT(X)=Z;(X)->Y
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#define GX_UINT8(X) GX_UNION(&X, bVal, DLMS_DATA_TYPE_UINT8)
|
||||
#define GX_UINT16(X) GX_UNION(&X, uiVal, DLMS_DATA_TYPE_UINT16)
|
||||
#define GX_UINT32(X) GX_UNION(&X, ulVal, DLMS_DATA_TYPE_UINT32)
|
||||
#define GX_UINT64(X) GX_UNION(&X, ullVal, DLMS_DATA_TYPE_UINT64)
|
||||
#define GX_INT8(X) GX_UNION(&X, cVal, DLMS_DATA_TYPE_INT8)
|
||||
#define GX_INT16(X) GX_UNION(&X, iVal, DLMS_DATA_TYPE_INT16)
|
||||
#define GX_INT32(X) GX_UNION(&X, lVal, DLMS_DATA_TYPE_INT32)
|
||||
#define GX_INT64(X) GX_UNION(&X, llVal, DLMS_DATA_TYPE_INT64)
|
||||
#define GX_FLOAT(X) GX_UNION(&X, fltVal, DLMS_DATA_TYPE_FLOAT32)
|
||||
#define GX_DOUBLE(X) GX_UNION(&X, dblVal, DLMS_DATA_TYPE_FLOAT64)
|
||||
#define GX_BOOL(X) GX_UNION(&X, bVal, DLMS_DATA_TYPE_BOOLEAN)
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
#define GX_DATETIME(X) X.size = 12; GX_UNION(&X, pVal, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_DATETIME))
|
||||
#else
|
||||
#define GX_DATETIME(X) GX_UNION(&X, pVal, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_DATETIME))
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
#define GX_DATE(X) GX_UNION(&X, pVal, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_DATE))
|
||||
#define GX_TIME(X) GX_UNION(&X, pVal, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_TIME))
|
||||
#define GX_UINT8_BYREF(X, VALUE_) GX_UNION(&X, pbVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_UINT8))
|
||||
#define GX_UINT16_BYREF(X, VALUE_) GX_UNION(&X, puiVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_UINT16))
|
||||
#define GX_UINT32_BYREF(X, VALUE_) GX_UNION(&X, pulVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_UINT32))
|
||||
#define GX_UINT64_BYREF(X, VALUE_) GX_UNION(&X, pullVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_UINT64))
|
||||
#define GX_INT8_BYREF(X, VALUE_) GX_UNION(&X, pcVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_INT8))
|
||||
#define GX_INT16_BYREF(X, VALUE_) GX_UNION(&X, piVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_INT16))
|
||||
#define GX_INT32_BYREF(X, VALUE_) GX_UNION(&X, plVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_INT32))
|
||||
#define GX_INT64_BYREF(X, VALUE_) GX_UNION(&X, pllVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_INT64))
|
||||
#define GX_FLOAT_BYREF(X, VALUE_) GX_UNION(&X, pfltVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_FLOAT32))
|
||||
#define GX_DOUBLE_BYREF(X, VALUE_) GX_UNION(&X, pdblVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_FLOAT64))
|
||||
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
#define GX_OCTET_STRING(X, VALUE_, SIZE_) GX_UNION2(&X, pVal = VALUE_, (DLMS_DATA_TYPE) (DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_OCTET_STRING), SIZE_, sizeof(VALUE_))
|
||||
#define GX_BIT_STRING(X, VALUE_, SIZE_) GX_UNION2(&X, pVal = VALUE_, (DLMS_DATA_TYPE) (DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_BIT_STRING), SIZE_, 8 * sizeof(VALUE_)/sizeof(VALUE_[0]))
|
||||
#define GX_STRING(X, VALUE_, SIZE_) GX_UNION2(&X, pVal = VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_STRING), SIZE_, sizeof(VALUE_))
|
||||
#define GX_ARRAY(X, VALUE_) GX_UNION2(&X, pVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_ARRAY), 0, 0)
|
||||
#define GX_STRUCT(X, VALUE_) GX_UNION2(&X, pVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_STRUCTURE), 0, 0)
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#define GX_BOOL_BYREF(X, VALUE_) GX_UNION(&X, pcVal = &VALUE_, (DLMS_DATA_TYPE)(DLMS_DATA_TYPE_BYREF | DLMS_DATA_TYPE_BOOLEAN))
|
||||
|
||||
/*Get UInt8 value from variant.*/
|
||||
#define GX_GET_UINT8(X) (X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.bVal : *X.pbVal
|
||||
|
||||
/*Get UInt16 value from variant.*/
|
||||
#define GX_GET_UINT16(X) (X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.uiVal : *X.puiVal
|
||||
|
||||
/*Get UInt32 value from variant.*/
|
||||
#define GX_GET_UINT32(X) (X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.culVal : *X.pulVal
|
||||
|
||||
/*Get UInt64 value from variant.*/
|
||||
#define GX_GET_UINT64(X) (X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.cullVal : *X.pullVal
|
||||
|
||||
/*Get Int8 value from variant.*/
|
||||
#define GX_GET_INT8(X) (X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.cVal : *X.pcVal
|
||||
/*Get Int16 value from variant.*/
|
||||
#define GX_GET_INT16(X)(X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.iVal : *X.piVal
|
||||
/*Get Int32 value from variant.*/
|
||||
#define GX_GET_INT32(X)(X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.lVal : *X.plVal
|
||||
/*Get Int64 value from variant.*/
|
||||
#define GX_GET_INT64(X)(X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.llVal : *X.pllVal
|
||||
/*Get float value from variant.*/
|
||||
#define GX_GET_FLOAT(X) (X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.fltVal : *X.pfltVal
|
||||
/*Get double value from variant.*/
|
||||
#define GX_GET_DOUBLE(X) (X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? X.dblVal : *X.pdblVal
|
||||
/*Get boolean value from variant.*/
|
||||
#define GX_GET_BOOL(X) (X.vt & DLMS_DATA_TYPE_BYREF) == 0 ? (X.bVal != 0) : (*X.pbVal != 0)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
void* data;
|
||||
#else
|
||||
void** data;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
uint16_t capacity;
|
||||
uint16_t size;
|
||||
} variantArray;
|
||||
|
||||
typedef struct tagdlmsVARIANT
|
||||
{
|
||||
DLMS_DATA_TYPE vt;
|
||||
union
|
||||
{
|
||||
unsigned char bVal;
|
||||
signed char cVal;
|
||||
int16_t iVal;
|
||||
int32_t lVal;
|
||||
int64_t llVal;
|
||||
#ifndef DLMS_IGNORE_FLOAT32
|
||||
float fltVal;
|
||||
#endif //DLMS_IGNORE_FLOAT32
|
||||
#ifndef DLMS_IGNORE_FLOAT64
|
||||
double dblVal;
|
||||
#endif //DLMS_IGNORE_FLOAT64
|
||||
unsigned char boolVal;
|
||||
uint16_t uiVal;
|
||||
uint32_t ulVal;
|
||||
uint64_t ullVal;
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
gxtime* dateTime;
|
||||
gxByteBuffer* strVal;
|
||||
gxByteBuffer* strUtfVal;
|
||||
bitArray* bitArr;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
variantArray* Arr;
|
||||
gxByteBuffer* byteArr;
|
||||
unsigned char* pbVal;
|
||||
signed char* pcVal;
|
||||
short* piVal;
|
||||
int32_t* plVal;
|
||||
int64_t* pllVal;
|
||||
#ifndef DLMS_IGNORE_FLOAT32
|
||||
float* pfltVal;
|
||||
#endif //DLMS_IGNORE_FLOAT32
|
||||
#ifndef DLMS_IGNORE_FLOAT64
|
||||
double* pdblVal;
|
||||
#endif //DLMS_IGNORE_FLOAT64
|
||||
unsigned char* pboolVal;
|
||||
uint16_t* puiVal;
|
||||
uint32_t* pulVal;
|
||||
uint64_t* pullVal;
|
||||
void* pVal;
|
||||
};
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
uint16_t size;
|
||||
uint16_t capacity;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
} dlmsVARIANT;
|
||||
|
||||
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
typedef dlmsVARIANT* dlmsVARIANT_PTR;
|
||||
#else
|
||||
typedef dlmsVARIANT* dlmsVARIANT_PTR;
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//Initialize variantArray.
|
||||
void va_init(
|
||||
variantArray* arr);
|
||||
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
void va_attach(
|
||||
variantArray* trg,
|
||||
dlmsVARIANT* src,
|
||||
uint16_t size,
|
||||
uint16_t capacity);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
void va_attach2(
|
||||
variantArray* trg,
|
||||
variantArray* src);
|
||||
|
||||
//Is variant array attached.
|
||||
char va_isAttached(variantArray* arr);
|
||||
|
||||
//Get variant array capacity.
|
||||
uint16_t va_size(
|
||||
variantArray* arr);
|
||||
|
||||
//Get variant array capacity.
|
||||
uint16_t va_getCapacity(
|
||||
variantArray* arr);
|
||||
|
||||
|
||||
//Allocate new size for the array in bytes.
|
||||
int va_capacity(
|
||||
variantArray* arr,
|
||||
uint16_t capacity);
|
||||
|
||||
//Push new data to the variantArray.
|
||||
int va_push(
|
||||
variantArray* arr,
|
||||
dlmsVARIANT* item);
|
||||
|
||||
void va_clear(
|
||||
variantArray* arr);
|
||||
|
||||
//Set byte value to variant.
|
||||
int var_setUInt8(
|
||||
dlmsVARIANT* data,
|
||||
unsigned char value);
|
||||
|
||||
//Set UInt16 value to variant.
|
||||
int var_setUInt16(
|
||||
dlmsVARIANT* data,
|
||||
uint16_t value);
|
||||
|
||||
//Set UInt32 value to variant.
|
||||
int var_setUInt32(dlmsVARIANT
|
||||
* data,
|
||||
uint32_t value);
|
||||
|
||||
//Set UInt64 value to variant.
|
||||
int var_setUInt64(
|
||||
dlmsVARIANT* data,
|
||||
uint64_t value);
|
||||
|
||||
//Set signed byte value to variant.
|
||||
int var_setInt8(
|
||||
dlmsVARIANT* data,
|
||||
char value);
|
||||
|
||||
//Set Int16 value to variant.
|
||||
int var_setInt16(
|
||||
dlmsVARIANT* data,
|
||||
short value);
|
||||
|
||||
//Set Int32 value to variant.
|
||||
int var_setInt32(
|
||||
dlmsVARIANT* data,
|
||||
int32_t value);
|
||||
|
||||
//Set Int64 value to variant.
|
||||
int var_setInt64(
|
||||
dlmsVARIANT* data,
|
||||
int64_t value);
|
||||
|
||||
#ifndef DLMS_IGNORE_FLOAT64
|
||||
int var_setDouble(
|
||||
dlmsVARIANT* data,
|
||||
double value);
|
||||
#endif //DLMS_IGNORE_FLOAT64
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int var_setDateTime(
|
||||
dlmsVARIANT* target,
|
||||
gxtime* value);
|
||||
|
||||
int var_setDate(
|
||||
dlmsVARIANT* target,
|
||||
gxtime* value);
|
||||
|
||||
int var_setTime(
|
||||
dlmsVARIANT* target,
|
||||
gxtime* value);
|
||||
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
int var_setBoolean(
|
||||
dlmsVARIANT* target,
|
||||
char value);
|
||||
|
||||
int var_getDateTime(
|
||||
dlmsVARIANT* target,
|
||||
gxtime* value);
|
||||
|
||||
int var_getDateTime2(
|
||||
gxtime* dateTime,
|
||||
gxByteBuffer* ba);
|
||||
|
||||
int var_getDate(
|
||||
gxtime* date,
|
||||
gxByteBuffer* ba);
|
||||
|
||||
int var_getTime(
|
||||
gxtime* date,
|
||||
gxByteBuffer* ba);
|
||||
|
||||
int var_setDateTimeAsOctetString(
|
||||
dlmsVARIANT* target,
|
||||
gxtime* value);
|
||||
|
||||
int var_setDateAsOctetString(
|
||||
dlmsVARIANT* target,
|
||||
gxtime* value);
|
||||
|
||||
int var_setTimeAsOctetString(
|
||||
dlmsVARIANT* target,
|
||||
gxtime* value);
|
||||
|
||||
//Get byte value from variant.
|
||||
int var_getUInt8(
|
||||
dlmsVARIANT* data,
|
||||
unsigned char* value);
|
||||
|
||||
//Get UInt16 value from variant.
|
||||
int var_getUInt16(
|
||||
dlmsVARIANT* data,
|
||||
uint16_t* value);
|
||||
|
||||
//Get UInt32 value from variant.
|
||||
int var_getUInt32(
|
||||
dlmsVARIANT* data,
|
||||
uint32_t* value);
|
||||
|
||||
//Get UInt64 value from variant.
|
||||
int var_getUInt64(
|
||||
dlmsVARIANT* data,
|
||||
uint64_t* value);
|
||||
|
||||
//Get signed byte value from variant.
|
||||
int var_getInt8(
|
||||
dlmsVARIANT* data,
|
||||
char* value);
|
||||
|
||||
//Get Int16 value from variant.
|
||||
int var_getInt16(
|
||||
dlmsVARIANT* data,
|
||||
short* value);
|
||||
|
||||
//Get Int32 value from variant.
|
||||
int var_getInt32(
|
||||
dlmsVARIANT* data,
|
||||
int32_t* value);
|
||||
|
||||
//Get Int64 value from variant.
|
||||
int var_getInt64(
|
||||
dlmsVARIANT* data,
|
||||
int64_t* value);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int var_addBytes(
|
||||
dlmsVARIANT* data,
|
||||
const unsigned char* value,
|
||||
uint16_t count);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int var_setString(
|
||||
dlmsVARIANT* data,
|
||||
const char* value,
|
||||
uint16_t count);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
void var_attach(
|
||||
dlmsVARIANT* target,
|
||||
gxByteBuffer* source);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
int var_addOctetString(
|
||||
dlmsVARIANT* data,
|
||||
gxByteBuffer* ba);
|
||||
|
||||
int var_setEnum(dlmsVARIANT* data,
|
||||
unsigned char value);
|
||||
|
||||
int var_addByteArray(
|
||||
dlmsVARIANT* data,
|
||||
gxByteBuffer* ba,
|
||||
uint16_t index,
|
||||
uint16_t count);
|
||||
|
||||
//Initialize variant.
|
||||
int var_init(
|
||||
dlmsVARIANT* data);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//attach static array.
|
||||
void var_attachArray(
|
||||
dlmsVARIANT* data,
|
||||
const variantArray* arr,
|
||||
const uint16_t count);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//attach static structure.
|
||||
void var_attachStructure(
|
||||
dlmsVARIANT* data,
|
||||
const dlmsVARIANT** arr,
|
||||
const uint16_t count);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
//copy variant.
|
||||
int var_copy(
|
||||
dlmsVARIANT* value,
|
||||
dlmsVARIANT* copy);
|
||||
|
||||
//Clear variant.
|
||||
int var_clear(
|
||||
dlmsVARIANT* data);
|
||||
|
||||
//Get bytes from variant value.
|
||||
int var_getBytes(
|
||||
dlmsVARIANT* data,
|
||||
gxByteBuffer* ba);
|
||||
|
||||
//Get bytes from variant value.
|
||||
int var_getBytes2(
|
||||
dlmsVARIANT* data,
|
||||
DLMS_DATA_TYPE type,
|
||||
gxByteBuffer* ba);
|
||||
|
||||
//Get bytes from variant value without data type.
|
||||
int var_getBytes3(
|
||||
dlmsVARIANT* data,
|
||||
DLMS_DATA_TYPE type,
|
||||
gxByteBuffer* ba,
|
||||
unsigned char addType);
|
||||
|
||||
//Get size in bytes.
|
||||
int var_getSize(
|
||||
DLMS_DATA_TYPE vt);
|
||||
|
||||
//Convert variant value to integer.
|
||||
int var_toInteger(
|
||||
dlmsVARIANT* data);
|
||||
|
||||
//Get item from variant array by index.
|
||||
int va_getByIndex(
|
||||
variantArray* arr,
|
||||
int index,
|
||||
dlmsVARIANT_PTR* item);
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//copy variant array.
|
||||
int va_copyArray(
|
||||
variantArray* target,
|
||||
variantArray* source);
|
||||
|
||||
//Add given value to the array N times.
|
||||
int va_addValue(
|
||||
variantArray* target,
|
||||
dlmsVARIANT* value,
|
||||
uint16_t count);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
int var_changeType(
|
||||
dlmsVARIANT* value,
|
||||
DLMS_DATA_TYPE newType);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#ifndef DLMS_IGNORE_MALLOC
|
||||
//Convert variant to string.
|
||||
//Note! toString do not clear existing byte array.
|
||||
int var_toString(
|
||||
dlmsVARIANT* item,
|
||||
gxByteBuffer* value);
|
||||
|
||||
//Convert variant array to string.
|
||||
//Note! toString do not clear existing byte array.
|
||||
int va_toString(
|
||||
variantArray* items,
|
||||
gxByteBuffer* ba);
|
||||
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
//Convert variant to double.
|
||||
double var_toDouble(
|
||||
dlmsVARIANT* target);
|
||||
|
||||
#ifdef DLMS_IGNORE_MALLOC
|
||||
//Attach value by ref.
|
||||
int var_byRef(
|
||||
dlmsVARIANT* target,
|
||||
DLMS_DATA_TYPE type,
|
||||
void* value);
|
||||
#endif //DLMS_IGNORE_MALLOC
|
||||
|
||||
#ifndef GX_DLMS_MICROCONTROLLER
|
||||
//Print content of the variant to cout.
|
||||
int var_print(
|
||||
//Format.
|
||||
const char* format,
|
||||
dlmsVARIANT* target);
|
||||
|
||||
//Print content of the variant array to cout.
|
||||
int va_print(
|
||||
variantArray* target);
|
||||
|
||||
#endif //GX_DLMS_MICROCONTROLLER
|
||||
|
||||
#define VA_ATTACH(X, V, S) va_attach(&X, V, S, sizeof(V)/sizeof(V[0]))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //VARIANT_H
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
#include "xt211.h"
|
||||
#include "xt211_axdr_parser.h"
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace esphome {
|
||||
namespace xt211 {
|
||||
|
||||
static const char *TAG0 = "xt211_";
|
||||
|
||||
#define TAG (this->tag_.c_str())
|
||||
|
||||
static constexpr uint8_t
|
||||
BOOT_WAIT_S = 10;
|
||||
|
||||
void XT211Component::setup() {
|
||||
ESP_LOGD(TAG, "setup (PUSH mode only)");
|
||||
|
||||
this->buffers_.init(DEFAULT_IN_BUF_SIZE_PUSH);
|
||||
|
||||
#ifdef USE_ESP32
|
||||
iuart_ = make_unique<XT211Uart>(*static_cast<uart::IDFUARTComponent *>(this->parent_));
|
||||
#endif
|
||||
|
||||
#if USE_ESP8266
|
||||
iuart_ = make_unique<XT211Uart>(*static_cast<uart::ESP8266UartComponent *>(this->parent_));
|
||||
#endif
|
||||
|
||||
this->set_baud_rate_(this->baud_rate_);
|
||||
|
||||
CosemObjectFoundCallback fn = [this](auto... args) { (void) this->set_sensor_value(args...); };
|
||||
|
||||
this->axdr_parser_ = new AxdrStreamParser(&this->buffers_.in, fn, this->push_show_log_);
|
||||
|
||||
// default patterns
|
||||
this->axdr_parser_->register_pattern_dsl("T1", "TC,TO,TS,TV");
|
||||
this->axdr_parser_->register_pattern_dsl("T2", "TO,TV,TSU");
|
||||
this->axdr_parser_->register_pattern_dsl("T3", "TV,TC,TSU,TO");
|
||||
this->axdr_parser_->register_pattern_dsl("U.ZPA", "F,C,O,A,TV");
|
||||
|
||||
// user-provided pattern
|
||||
if (this->push_custom_pattern_dsl_.length() > 0) {
|
||||
this->axdr_parser_->register_pattern_dsl("CUSTOM", this->push_custom_pattern_dsl_, 0);
|
||||
}
|
||||
|
||||
bool locked = false;
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (this->try_lock_uart_session_()) {
|
||||
locked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!locked) {
|
||||
ESP_LOGE(TAG, "Failed to lock UART session. Aborting setup.");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
this->set_timeout(BOOT_WAIT_S * 1000, [this]() {
|
||||
ESP_LOGD(TAG, "Boot timeout, component is ready to use");
|
||||
this->clear_rx_buffers_();
|
||||
this->set_next_state_(State::IDLE);
|
||||
});
|
||||
}
|
||||
|
||||
void XT211Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "XT211 (PUSH Mode Read-Only):");
|
||||
ESP_LOGCONFIG(TAG, " Receive Timeout: %ums", this->receive_timeout_ms_);
|
||||
ESP_LOGCONFIG(TAG, " Mode: PUSH Data Reception");
|
||||
ESP_LOGCONFIG(TAG, " Sensors:");
|
||||
for (const auto &sensors: sensors_) {
|
||||
auto &s = sensors.second;
|
||||
ESP_LOGCONFIG(TAG, " OBIS code: %s, Name: %s", s->get_obis_code().c_str(), s->get_sensor_name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void XT211Component::register_sensor(XT211SensorBase *sensor) {
|
||||
this->sensors_.insert({sensor->get_obis_code(), sensor});
|
||||
}
|
||||
|
||||
void XT211Component::abort_mission_() {
|
||||
ESP_LOGV(TAG, "Push mode error, returning to listening");
|
||||
this->clear_rx_buffers_();
|
||||
this->set_next_state_(State::IDLE);
|
||||
}
|
||||
|
||||
void XT211Component::report_failure(bool failure) {
|
||||
if (!failure) {
|
||||
this->stats_.failures_ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
this->stats_.failures_++;
|
||||
ESP_LOGE(TAG, "Failure reported. Count: %u", this->stats_.failures_);
|
||||
}
|
||||
|
||||
void XT211Component::loop() {
|
||||
if (!this->is_ready() || this->state_ == State::NOT_INITIALIZED)
|
||||
return;
|
||||
|
||||
switch (this->state_) {
|
||||
case State::IDLE: {
|
||||
this->update_last_rx_time_();
|
||||
this->indicate_transmission(false);
|
||||
this->indicate_session(false);
|
||||
|
||||
// Push mode listening logic
|
||||
if (this->available() > 0) {
|
||||
// Set up for receiving push data
|
||||
memset(this->buffers_.in.data, 0, buffers_.in.capacity);
|
||||
this->buffers_.in.size = 0;
|
||||
// read what we can then move forward to avoid buffer overflow
|
||||
this->receive_frame_raw_();
|
||||
|
||||
ESP_LOGV(TAG, "Push mode: incoming data detected");
|
||||
this->stats_.connections_tried_++;
|
||||
this->loop_state_.session_started_ms = millis();
|
||||
|
||||
this->indicate_transmission(true);
|
||||
this->set_next_state_(State::COMMS_RX);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case State::WAIT:
|
||||
if (this->check_wait_timeout_()) {
|
||||
this->set_next_state_(this->wait_.next_state);
|
||||
this->update_last_rx_time_();
|
||||
}
|
||||
break;
|
||||
|
||||
case State::COMMS_RX: {
|
||||
this->handle_comms_rx_();
|
||||
}
|
||||
break;
|
||||
|
||||
case State::MISSION_FAILED: {
|
||||
this->set_next_state_(State::IDLE);
|
||||
this->report_failure(true);
|
||||
this->stats_dump();
|
||||
}
|
||||
break;
|
||||
|
||||
case State::PUSH_DATA_PROCESS: {
|
||||
this->handle_push_data_process_();
|
||||
}
|
||||
break;
|
||||
|
||||
case State::PUBLISH: {
|
||||
this->handle_publish_();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Should not happen
|
||||
ESP_LOGW(TAG, "Unhandled state: %s", state_to_string(this->state_));
|
||||
this->set_next_state_(State::IDLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void XT211Component::handle_comms_rx_() {
|
||||
this->log_state_();
|
||||
|
||||
if (this->check_rx_timeout_()) {
|
||||
ESP_LOGI(TAG, "Push data reception completed (timeout reached)");
|
||||
|
||||
this->indicate_connection(false);
|
||||
this->indicate_transmission(false);
|
||||
|
||||
// check if we received any data at all
|
||||
this->indicate_connection(true);
|
||||
if (this->buffers_.in.size > 0) {
|
||||
ESP_LOGV(TAG, "Push mode RX data avail, len=%d", this->buffers_.in.size);
|
||||
this->set_next_state_(State::PUSH_DATA_PROCESS);
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Push mode RX timeout, no data, idling");
|
||||
this->set_next_state_(State::IDLE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
received_frame_size_ = this->receive_frame_raw_();
|
||||
// keep reading until timeout
|
||||
}
|
||||
|
||||
void XT211Component::handle_push_data_process_() {
|
||||
this->log_state_();
|
||||
ESP_LOGD(TAG, "Processing received push data");
|
||||
this->loop_state_.sensor_iter = this->sensors_.begin();
|
||||
this->set_next_state_(State::PUBLISH);
|
||||
this->process_push_data();
|
||||
this->clear_rx_buffers_();
|
||||
}
|
||||
|
||||
void XT211Component::handle_publish_() {
|
||||
this->log_state_();
|
||||
ESP_LOGD(TAG, "Publishing data");
|
||||
this->update_last_rx_time_();
|
||||
|
||||
if (this->loop_state_.sensor_iter != this->sensors_.end()) {
|
||||
if (this->loop_state_.sensor_iter->second->shall_we_publish()) {
|
||||
this->loop_state_.sensor_iter->second->publish();
|
||||
}
|
||||
this->loop_state_.sensor_iter++;
|
||||
} else {
|
||||
this->stats_dump();
|
||||
if (this->crc_errors_per_session_sensor_ != nullptr) {
|
||||
this->crc_errors_per_session_sensor_->publish_state(this->stats_.crc_errors_per_session());
|
||||
}
|
||||
this->report_failure(false);
|
||||
this->set_next_state_(State::IDLE);
|
||||
ESP_LOGD(TAG, "Total time: %u ms", millis() - this->loop_state_.session_started_ms);
|
||||
}
|
||||
}
|
||||
|
||||
// This is the entry point for PollingComponent, which is now unused.
|
||||
void XT211Component::update() {}
|
||||
|
||||
void XT211Component::set_next_state_delayed_(uint32_t ms, State next_state) {
|
||||
if (ms == 0) {
|
||||
set_next_state_(next_state);
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Short delay for %u ms", ms);
|
||||
set_next_state_(State::WAIT);
|
||||
wait_.start_time = millis();
|
||||
wait_.delay_ms = ms;
|
||||
wait_.next_state = next_state;
|
||||
}
|
||||
}
|
||||
|
||||
void XT211Component::PushBuffers::init(size_t default_in_buf_size) {
|
||||
BYTE_BUFFER_INIT(&in);
|
||||
bb_capacity(&in, default_in_buf_size);
|
||||
this->reset();
|
||||
}
|
||||
|
||||
void XT211Component::PushBuffers::reset() {
|
||||
in.size = 0;
|
||||
in.position = 0;
|
||||
}
|
||||
|
||||
void XT211Component::PushBuffers::check_and_grow_input(uint16_t
|
||||
more_data) {
|
||||
const uint16_t GROW_EPSILON = 20;
|
||||
if (in.size + more_data > in.capacity) {
|
||||
ESP_LOGVV(TAG0,
|
||||
"Growing input buffer from %d to %d", in.capacity, in.size + more_data + GROW_EPSILON);
|
||||
bb_capacity(&in, in
|
||||
.size + more_data + GROW_EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
void XT211Component::process_push_data() {
|
||||
ESP_LOGD(TAG, "Processing PUSH data frame with AXDR parser");
|
||||
|
||||
// Ensure we parse from the beginning of the collected frame
|
||||
this->buffers_.in.position = 0;
|
||||
const auto total_size = this->buffers_.in.size;
|
||||
ESP_LOGD(TAG, "PUSH frame size: %u bytes", static_cast<unsigned>(total_size));
|
||||
|
||||
size_t total_objects = 0;
|
||||
size_t iterations = 0;
|
||||
|
||||
while (this->buffers_.in.position < this->buffers_.in.size) {
|
||||
auto before = this->buffers_.in.position;
|
||||
auto parsed_now = this->axdr_parser_->parse();
|
||||
auto after = this->buffers_.in.position;
|
||||
iterations++;
|
||||
|
||||
if (parsed_now == 0 && after == before) {
|
||||
// No progress, avoid potential infinite loop on malformed frames
|
||||
ESP_LOGW(TAG, "AXDR parser made no progress at pos=%u/%u, aborting", static_cast<unsigned>(after),
|
||||
static_cast<unsigned>(this->buffers_.in.size));
|
||||
break;
|
||||
}
|
||||
total_objects += parsed_now;
|
||||
ESP_LOGV(TAG, "AXDR iteration %u: parsed=%u, pos=%u/%u, objects_total=%u", static_cast<unsigned>(iterations),
|
||||
static_cast<unsigned>(parsed_now), static_cast<unsigned>(after),
|
||||
static_cast<unsigned>(this->buffers_.in.size), static_cast<unsigned>(total_objects));
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "PUSH data parsing complete: %u objects, bytes consumed %u/%u", static_cast<unsigned>(total_objects),
|
||||
static_cast<unsigned>(this->buffers_.in.position), static_cast<unsigned>(total_size));
|
||||
}
|
||||
|
||||
int XT211Component::set_sensor_value(uint16_t class_id, const uint8_t *obis_code, DLMS_DATA_TYPE value_type,
|
||||
const uint8_t *value_buffer_ptr, uint8_t value_length, const int8_t *scaler,
|
||||
const uint8_t *unit) {
|
||||
static char obis_buf[32];
|
||||
auto er = hlp_getLogicalNameToString(obis_code, obis_buf);
|
||||
|
||||
std::string obis_str(obis_buf);
|
||||
|
||||
auto range = this->sensors_.equal_range(obis_str);
|
||||
int found_count = 0;
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
XT211SensorBase *sensor = it->second;
|
||||
if (!sensor->shall_we_publish()) {
|
||||
continue;
|
||||
}
|
||||
ESP_LOGD(TAG, "Found sensor for OBIS code %s: '%s' ", obis_buf, sensor->get_sensor_name().c_str());
|
||||
found_count++;
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
if (sensor->get_type() == SensorType::SENSOR) {
|
||||
float val = dlms_data_as_float(value_type, value_buffer_ptr, value_length);
|
||||
if (scaler != nullptr) {
|
||||
float scale = pow(10, *scaler);
|
||||
val *= scale;
|
||||
}
|
||||
static_cast<XT211Sensor *>(sensor)->set_value(val);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
if (sensor->get_type() == SensorType::TEXT_SENSOR) {
|
||||
auto val = dlms_data_as_string(value_type, value_buffer_ptr, value_length);
|
||||
static_cast<XT211TextSensor *>(sensor)->set_value(val.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
if (sensor->get_type() == SensorType::BINARY_SENSOR) {
|
||||
bool val = dlms_data_as_float(value_type, value_buffer_ptr, value_length) != 0.0f;
|
||||
static_cast<XT211BinarySensor *>(sensor)->set_value(val);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (found_count == 0) {
|
||||
ESP_LOGVV(TAG, "No sensor found for OBIS code: '%s'", (char *) obis_buf);
|
||||
} else {
|
||||
ESP_LOGVV(TAG, "Updated %d sensors for OBIS code: '%s'", found_count, (char *) obis_buf);
|
||||
}
|
||||
|
||||
return DLMS_ERROR_CODE_OK;
|
||||
}
|
||||
|
||||
void XT211Component::indicate_transmission(bool transmission_on) {
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
if (this->transmission_binary_sensor_) {
|
||||
this->transmission_binary_sensor_->publish_state(transmission_on);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void XT211Component::indicate_session(bool session_on) {
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
if (this->session_binary_sensor_) {
|
||||
this->session_binary_sensor_->publish_state(session_on);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void XT211Component::indicate_connection(bool connection_on) {
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
if (this->connection_binary_sensor_) {
|
||||
this->connection_binary_sensor_->publish_state(connection_on);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t XT211Component::receive_frame_(FrameStopFunction stop_fn) {
|
||||
const uint32_t read_time_limit_ms = 45;
|
||||
size_t ret_val;
|
||||
|
||||
auto count_available = this->available();
|
||||
if (count_available <= 0)
|
||||
return 0;
|
||||
|
||||
uint32_t read_start = millis();
|
||||
uint8_t * p;
|
||||
|
||||
// ESP_LOGVV(TAG, "avail RX: %d", count_available);
|
||||
buffers_.check_and_grow_input(count_available);
|
||||
|
||||
while (count_available-- > 0) {
|
||||
if (millis() - read_start > read_time_limit_ms) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = &this->buffers_.in.data[this->buffers_.in.size];
|
||||
if (!iuart_->read_one_byte(p)) {
|
||||
return 0;
|
||||
}
|
||||
this->buffers_.in.size++;
|
||||
|
||||
if (stop_fn(this->buffers_.in.data, this->buffers_.in.size)) {
|
||||
ESP_LOGVV(TAG, "RX: %s", format_hex_pretty(this->buffers_.in.data, this->buffers_.in.size).c_str());
|
||||
ret_val = this->buffers_.in.size;
|
||||
|
||||
this->update_last_rx_time_();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
yield();
|
||||
App.feed_wdt();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t XT211Component::receive_frame_raw_() {
|
||||
auto frame_end_check_timeout = [](uint8_t *b, size_t s) {
|
||||
return false; // never stop by content, only by timeout
|
||||
};
|
||||
return receive_frame_(frame_end_check_timeout);
|
||||
}
|
||||
|
||||
void XT211Component::clear_rx_buffers_() {
|
||||
int available = this->available();
|
||||
if (available > 0) {
|
||||
ESP_LOGVV(TAG, "Cleaning garbage from UART input buffer: %d bytes", available);
|
||||
}
|
||||
|
||||
int len;
|
||||
while (available > 0) {
|
||||
len = std::min(available, (int) buffers_.in.capacity);
|
||||
this->read_array(this->buffers_.in.data, len);
|
||||
available -= len;
|
||||
}
|
||||
memset(this->buffers_.in.data, 0, buffers_.in.capacity);
|
||||
this->buffers_.in.size = 0;
|
||||
this->buffers_.in.position = 0;
|
||||
}
|
||||
|
||||
const char *XT211Component::state_to_string(State state) {
|
||||
switch (state) {
|
||||
case State::NOT_INITIALIZED:
|
||||
return "NOT_INITIALIZED";
|
||||
case State::IDLE:
|
||||
return "IDLE";
|
||||
case State::WAIT:
|
||||
return "WAIT";
|
||||
case State::COMMS_RX:
|
||||
return "COMMS_RX";
|
||||
case State::MISSION_FAILED:
|
||||
return "MISSION_FAILED";
|
||||
case State::PUBLISH:
|
||||
return "PUBLISH";
|
||||
case State::PUSH_DATA_PROCESS:
|
||||
return "PUSH_DATA_PROCESS";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void XT211Component::log_state_(State *next_state) {
|
||||
if (this->state_ != this->last_reported_state_) {
|
||||
if (next_state == nullptr) {
|
||||
ESP_LOGV(TAG, "State::%s", state_to_string(this->state_));
|
||||
} else {
|
||||
ESP_LOGV(TAG, "State::%s -> %s", state_to_string(this->state_), state_to_string(*next_state));
|
||||
}
|
||||
this->last_reported_state_ = this->state_;
|
||||
}
|
||||
}
|
||||
|
||||
void XT211Component::stats_dump() {
|
||||
ESP_LOGV(TAG, "============================================");
|
||||
ESP_LOGV(TAG, "Data collection and publishing finished.");
|
||||
ESP_LOGV(TAG, "Total number of sessions ............. %u", this->stats_.connections_tried_);
|
||||
ESP_LOGV(TAG, "Total number of invalid frames ....... %u", this->stats_.invalid_frames_);
|
||||
ESP_LOGV(TAG, "Total number of CRC errors ........... %u", this->stats_.crc_errors_);
|
||||
ESP_LOGV(TAG, "Total number of CRC errors recovered . %u", this->stats_.crc_errors_recovered_);
|
||||
ESP_LOGV(TAG, "CRC errors per session ............... %f", this->stats_.crc_errors_per_session());
|
||||
ESP_LOGV(TAG, "Number of failures ................... %u", this->stats_.failures_);
|
||||
ESP_LOGV(TAG, "============================================");
|
||||
}
|
||||
|
||||
bool XT211Component::try_lock_uart_session_() {
|
||||
if (AnyObjectLocker::try_lock(this->parent_)) {
|
||||
ESP_LOGV(TAG, "UART bus %p locked by %s", this->parent_, this->tag_.c_str());
|
||||
return true;
|
||||
}
|
||||
ESP_LOGV(TAG, "UART bus %p busy", this->parent_);
|
||||
return false;
|
||||
}
|
||||
|
||||
void XT211Component::set_baud_rate_(uint32_t baud_rate) {
|
||||
if (this->iuart_ != nullptr) {
|
||||
this->iuart_->update_baudrate(baud_rate);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t XT211Component::next_obj_id_ = 0;
|
||||
|
||||
std::string XT211Component::generateTag() { return str_sprintf("%s%03d", TAG0, ++next_obj_id_); }
|
||||
|
||||
} // namespace xt211
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "xt211_sensor.h"
|
||||
#include "xt211_uart.h"
|
||||
#include "object_locker.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "converters.h"
|
||||
#include "cosem.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace xt211 {
|
||||
static const size_t DEFAULT_IN_BUF_SIZE_PUSH = 2048;
|
||||
|
||||
using SensorMap = std::multimap<std::string, XT211SensorBase *>;
|
||||
|
||||
using FrameStopFunction = std::function<
|
||||
bool(uint8_t
|
||||
*buf,
|
||||
size_t size
|
||||
)>;
|
||||
|
||||
class AxdrStreamParser;
|
||||
|
||||
class XT211Component : public PollingComponent, public uart::UARTDevice {
|
||||
public:
|
||||
XT211Component() : tag_(generateTag()) {};
|
||||
|
||||
void setup() override;
|
||||
|
||||
void dump_config() override;
|
||||
|
||||
void loop() override;
|
||||
|
||||
void update() override; // Kept for PollingComponent, but will be empty
|
||||
float get_setup_priority() const override { return setup_priority::DATA; };
|
||||
|
||||
void set_baud_rate(uint32_t baud_rate) { this->baud_rate_ = baud_rate; };
|
||||
|
||||
void set_receive_timeout_ms(uint32_t timeout) { this->receive_timeout_ms_ = timeout; };
|
||||
|
||||
void register_sensor(XT211SensorBase *sensor);
|
||||
|
||||
void set_reboot_after_failure(uint16_t number_of_failures) { this->failures_before_reboot_ = number_of_failures; }
|
||||
|
||||
// PUSH mode is now default, these are for configuring it
|
||||
void set_push_show_log(bool show_log) { this->push_show_log_ = show_log; }
|
||||
|
||||
void set_push_custom_pattern_dsl(const std::string &dsl) { this->push_custom_pattern_dsl_ = dsl; }
|
||||
|
||||
bool has_error{true};
|
||||
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
SUB_BINARY_SENSOR(transmission)
|
||||
SUB_BINARY_SENSOR(session)
|
||||
SUB_BINARY_SENSOR(connection)
|
||||
#endif
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
SUB_TEXT_SENSOR(last_scan)
|
||||
#endif
|
||||
|
||||
protected:
|
||||
bool push_show_log_{false};
|
||||
std::string push_custom_pattern_dsl_{""};
|
||||
|
||||
uint32_t receive_timeout_ms_{2000};
|
||||
|
||||
std::unique_ptr <XT211Uart> iuart_;
|
||||
|
||||
SensorMap sensors_;
|
||||
|
||||
sensor::Sensor *crc_errors_per_session_sensor_{};
|
||||
|
||||
enum class State : uint8_t {
|
||||
NOT_INITIALIZED,
|
||||
IDLE,
|
||||
WAIT,
|
||||
COMMS_RX,
|
||||
MISSION_FAILED,
|
||||
PUSH_DATA_PROCESS, // Process received push data
|
||||
PUBLISH,
|
||||
} state_{State::NOT_INITIALIZED};
|
||||
State last_reported_state_{State::NOT_INITIALIZED};
|
||||
|
||||
struct {
|
||||
uint32_t start_time{0};
|
||||
uint32_t delay_ms{0};
|
||||
State next_state{State::IDLE};
|
||||
} wait_;
|
||||
|
||||
bool is_idling() const { return this->state_ == State::WAIT || this->state_ == State::IDLE; };
|
||||
|
||||
void set_next_state_(State next_state) { state_ = next_state; };
|
||||
|
||||
void set_next_state_delayed_(uint32_t ms, State next_state);
|
||||
|
||||
void process_push_data();
|
||||
|
||||
// State handler methods extracted from loop()
|
||||
void handle_comms_rx_();
|
||||
|
||||
void handle_push_data_process_();
|
||||
|
||||
void handle_publish_();
|
||||
|
||||
int set_sensor_value(uint16_t class_id, const uint8_t *obis_code, DLMS_DATA_TYPE value_type,
|
||||
const uint8_t *value_buffer_ptr, uint8_t value_length, const int8_t *scaler,
|
||||
const uint8_t *unit);
|
||||
|
||||
void indicate_transmission(bool transmission_on);
|
||||
|
||||
void indicate_session(bool session_on);
|
||||
|
||||
void indicate_connection(bool connection_on);
|
||||
|
||||
AxdrStreamParser *axdr_parser_{nullptr};
|
||||
|
||||
size_t received_frame_size_{0};
|
||||
|
||||
uint32_t baud_rate_{9600};
|
||||
|
||||
uint32_t last_rx_time_{0};
|
||||
|
||||
struct LoopState {
|
||||
uint32_t session_started_ms{0}; // start of session
|
||||
SensorMap::iterator sensor_iter{nullptr}; // publishing sensor values
|
||||
|
||||
} loop_state_;
|
||||
|
||||
struct PushBuffers {
|
||||
gxByteBuffer in;
|
||||
|
||||
void init(size_t default_in_buf_size);
|
||||
|
||||
void reset();
|
||||
|
||||
void check_and_grow_input(uint16_t more_data);
|
||||
|
||||
} buffers_;
|
||||
|
||||
protected:
|
||||
void clear_rx_buffers_();
|
||||
|
||||
void set_baud_rate_(uint32_t baud_rate);
|
||||
|
||||
size_t receive_frame_(FrameStopFunction stop_fn);
|
||||
|
||||
size_t receive_frame_raw_();
|
||||
|
||||
inline void update_last_rx_time_() { this->last_rx_time_ = millis(); }
|
||||
|
||||
bool check_wait_timeout_() { return millis() - wait_.start_time >= wait_.delay_ms; }
|
||||
|
||||
bool check_rx_timeout_() { return millis() - this->last_rx_time_ >= receive_timeout_ms_; }
|
||||
|
||||
void report_failure(bool failure);
|
||||
|
||||
void abort_mission_();
|
||||
|
||||
const char *state_to_string(State state);
|
||||
|
||||
void log_state_(State *next_state = nullptr);
|
||||
|
||||
struct Stats {
|
||||
uint32_t connections_tried_{0};
|
||||
uint32_t crc_errors_{0};
|
||||
uint32_t crc_errors_recovered_{0};
|
||||
uint32_t invalid_frames_{0};
|
||||
uint8_t failures_{0};
|
||||
|
||||
float crc_errors_per_session() const { return (float) crc_errors_ / connections_tried_; }
|
||||
} stats_;
|
||||
|
||||
void stats_dump();
|
||||
|
||||
uint8_t failures_before_reboot_{0};
|
||||
|
||||
bool try_lock_uart_session_();
|
||||
// unlock_uart_session_() has been removed
|
||||
|
||||
public:
|
||||
private:
|
||||
static uint8_t next_obj_id_;
|
||||
std::string tag_;
|
||||
|
||||
static std::string generateTag();
|
||||
};
|
||||
|
||||
} // namespace xt211
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,877 @@
|
|||
#include "xt211_axdr_parser.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace esphome {
|
||||
namespace xt211 {
|
||||
|
||||
constexpr const char *TAG = "xt211.axdr";
|
||||
|
||||
const char *dlms_error_to_string(int error) {
|
||||
switch (error) {
|
||||
case DLMS_ERROR_CODE_OK:
|
||||
return "DLMS_ERROR_CODE_OK";
|
||||
case DLMS_ERROR_CODE_HARDWARE_FAULT:
|
||||
return "DLMS_ERROR_CODE_HARDWARE_FAULT";
|
||||
case DLMS_ERROR_CODE_TEMPORARY_FAILURE:
|
||||
return "DLMS_ERROR_CODE_TEMPORARY_FAILURE";
|
||||
case DLMS_ERROR_CODE_READ_WRITE_DENIED:
|
||||
return "DLMS_ERROR_CODE_READ_WRITE_DENIED";
|
||||
case DLMS_ERROR_CODE_UNDEFINED_OBJECT:
|
||||
return "DLMS_ERROR_CODE_UNDEFINED_OBJECT";
|
||||
case DLMS_ERROR_CODE_ACCESS_VIOLATED:
|
||||
return "DLMS_ERROR_CODE_ACCESS_VIOLATED";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
const char *dlms_data_type_to_string(DLMS_DATA_TYPE vt) {
|
||||
switch (vt) {
|
||||
case DLMS_DATA_TYPE_NONE:
|
||||
return "DLMS_DATA_TYPE_NONE";
|
||||
case DLMS_DATA_TYPE_BOOLEAN:
|
||||
return "DLMS_DATA_TYPE_BOOLEAN";
|
||||
case DLMS_DATA_TYPE_BIT_STRING:
|
||||
return "DLMS_DATA_TYPE_BIT_STRING";
|
||||
case DLMS_DATA_TYPE_INT32:
|
||||
return "DLMS_DATA_TYPE_INT32";
|
||||
case DLMS_DATA_TYPE_UINT32:
|
||||
return "DLMS_DATA_TYPE_UINT32";
|
||||
case DLMS_DATA_TYPE_OCTET_STRING:
|
||||
return "DLMS_DATA_TYPE_OCTET_STRING";
|
||||
case DLMS_DATA_TYPE_STRING:
|
||||
return "DLMS_DATA_TYPE_STRING";
|
||||
case DLMS_DATA_TYPE_BINARY_CODED_DESIMAL:
|
||||
return "DLMS_DATA_TYPE_BINARY_CODED_DESIMAL";
|
||||
case DLMS_DATA_TYPE_STRING_UTF8:
|
||||
return "DLMS_DATA_TYPE_STRING_UTF8";
|
||||
case DLMS_DATA_TYPE_INT8:
|
||||
return "DLMS_DATA_TYPE_INT8";
|
||||
case DLMS_DATA_TYPE_INT16:
|
||||
return "DLMS_DATA_TYPE_INT16";
|
||||
case DLMS_DATA_TYPE_UINT8:
|
||||
return "DLMS_DATA_TYPE_UINT8";
|
||||
case DLMS_DATA_TYPE_UINT16:
|
||||
return "DLMS_DATA_TYPE_UINT16";
|
||||
case DLMS_DATA_TYPE_INT64:
|
||||
return "DLMS_DATA_TYPE_INT64";
|
||||
case DLMS_DATA_TYPE_UINT64:
|
||||
return "DLMS_DATA_TYPE_UINT64";
|
||||
case DLMS_DATA_TYPE_ENUM:
|
||||
return "DLMS_DATA_TYPE_ENUM";
|
||||
case DLMS_DATA_TYPE_FLOAT32:
|
||||
return "DLMS_DATA_TYPE_FLOAT32";
|
||||
case DLMS_DATA_TYPE_FLOAT64:
|
||||
return "DLMS_DATA_TYPE_FLOAT64";
|
||||
case DLMS_DATA_TYPE_DATETIME:
|
||||
return "DLMS_DATA_TYPE_DATETIME";
|
||||
case DLMS_DATA_TYPE_DATE:
|
||||
return "DLMS_DATA_TYPE_DATE";
|
||||
case DLMS_DATA_TYPE_TIME:
|
||||
return "DLMS_DATA_TYPE_TIME";
|
||||
case DLMS_DATA_TYPE_ARRAY:
|
||||
return "DLMS_DATA_TYPE_ARRAY";
|
||||
case DLMS_DATA_TYPE_STRUCTURE:
|
||||
return "DLMS_DATA_TYPE_STRUCTURE";
|
||||
case DLMS_DATA_TYPE_COMPACT_ARRAY:
|
||||
return "DLMS_DATA_TYPE_COMPACT_ARRAY";
|
||||
case DLMS_DATA_TYPE_BYREF:
|
||||
return "DLMS_DATA_TYPE_BYREF";
|
||||
default:
|
||||
return "DMS_DATA_TYPE UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
bool hlp_isValueDataType(DLMS_DATA_TYPE type) {
|
||||
switch (type) {
|
||||
// Complex/Container types - NOT value types
|
||||
case DLMS_DATA_TYPE_ARRAY:
|
||||
case DLMS_DATA_TYPE_STRUCTURE:
|
||||
case DLMS_DATA_TYPE_COMPACT_ARRAY:
|
||||
return false;
|
||||
|
||||
// All other types are value types
|
||||
case DLMS_DATA_TYPE_NONE:
|
||||
case DLMS_DATA_TYPE_BOOLEAN:
|
||||
case DLMS_DATA_TYPE_BIT_STRING:
|
||||
case DLMS_DATA_TYPE_INT32:
|
||||
case DLMS_DATA_TYPE_UINT32:
|
||||
case DLMS_DATA_TYPE_OCTET_STRING:
|
||||
case DLMS_DATA_TYPE_STRING:
|
||||
case DLMS_DATA_TYPE_BINARY_CODED_DESIMAL:
|
||||
case DLMS_DATA_TYPE_STRING_UTF8:
|
||||
case DLMS_DATA_TYPE_INT8:
|
||||
case DLMS_DATA_TYPE_INT16:
|
||||
case DLMS_DATA_TYPE_UINT8:
|
||||
case DLMS_DATA_TYPE_UINT16:
|
||||
case DLMS_DATA_TYPE_INT64:
|
||||
case DLMS_DATA_TYPE_UINT64:
|
||||
case DLMS_DATA_TYPE_ENUM:
|
||||
case DLMS_DATA_TYPE_FLOAT32:
|
||||
case DLMS_DATA_TYPE_FLOAT64:
|
||||
case DLMS_DATA_TYPE_DATETIME:
|
||||
case DLMS_DATA_TYPE_DATE:
|
||||
case DLMS_DATA_TYPE_TIME:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
float dlms_data_as_float(DLMS_DATA_TYPE value_type, const uint8_t *value_buffer_ptr, uint8_t value_length) {
|
||||
if (value_buffer_ptr == nullptr || value_length == 0)
|
||||
return 0.0f;
|
||||
|
||||
auto be16 = [](const uint8_t *p) -> uint16_t { return (uint16_t) ((p[0] << 8) | p[1]); };
|
||||
auto be32 = [](const uint8_t *p) -> uint32_t {
|
||||
return ((uint32_t) p[0] << 24) | ((uint32_t) p[1] << 16) | ((uint32_t) p[2] << 8) | (uint32_t) p[3];
|
||||
};
|
||||
auto be64 = [](const uint8_t *p) -> uint64_t {
|
||||
uint64_t v = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
v = (v << 8) | p[i];
|
||||
return v;
|
||||
};
|
||||
|
||||
switch (value_type) {
|
||||
case DLMS_DATA_TYPE_BOOLEAN:
|
||||
case DLMS_DATA_TYPE_ENUM:
|
||||
case DLMS_DATA_TYPE_UINT8:
|
||||
return static_cast<float>(value_buffer_ptr[0]);
|
||||
case DLMS_DATA_TYPE_INT8:
|
||||
return static_cast<float>(static_cast<int8_t>(value_buffer_ptr[0]));
|
||||
case DLMS_DATA_TYPE_UINT16:
|
||||
if (value_length >= 2)
|
||||
return static_cast<float>(be16(value_buffer_ptr));
|
||||
return 0.0f;
|
||||
case DLMS_DATA_TYPE_INT16:
|
||||
if (value_length >= 2) {
|
||||
int16_t v = static_cast<int16_t>(be16(value_buffer_ptr));
|
||||
return static_cast<float>(v);
|
||||
}
|
||||
return 0.0f;
|
||||
case DLMS_DATA_TYPE_UINT32:
|
||||
if (value_length >= 4)
|
||||
return static_cast<float>(be32(value_buffer_ptr));
|
||||
return 0.0f;
|
||||
case DLMS_DATA_TYPE_INT32:
|
||||
if (value_length >= 4) {
|
||||
int32_t v = static_cast<int32_t>(be32(value_buffer_ptr));
|
||||
return static_cast<float>(v);
|
||||
}
|
||||
return 0.0f;
|
||||
case DLMS_DATA_TYPE_UINT64:
|
||||
if (value_length >= 8)
|
||||
return static_cast<float>(be64(value_buffer_ptr));
|
||||
return 0.0f;
|
||||
case DLMS_DATA_TYPE_INT64:
|
||||
if (value_length >= 8) {
|
||||
uint64_t u = be64(value_buffer_ptr);
|
||||
int64_t v = static_cast<int64_t>(u);
|
||||
return static_cast<float>(v);
|
||||
}
|
||||
return 0.0f;
|
||||
case DLMS_DATA_TYPE_FLOAT32:
|
||||
if (value_length >= 4) {
|
||||
uint32_t u = be32(value_buffer_ptr);
|
||||
float f{};
|
||||
std::memcpy(&f, &u, sizeof(f));
|
||||
return f;
|
||||
}
|
||||
return 0.0f;
|
||||
case DLMS_DATA_TYPE_FLOAT64:
|
||||
if (value_length >= 8) {
|
||||
uint8_t b[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
b[i] = value_buffer_ptr[i];
|
||||
|
||||
double d{};
|
||||
std::memcpy(&d, b, sizeof(d));
|
||||
return static_cast<float>(d);
|
||||
}
|
||||
return 0.0f;
|
||||
default:
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
std::string dlms_data_as_string(DLMS_DATA_TYPE value_type, const uint8_t *value_buffer_ptr, uint8_t value_length) {
|
||||
if (value_buffer_ptr == nullptr && value_length == 0)
|
||||
return std::string();
|
||||
|
||||
auto hex_of = [](const uint8_t *p, uint8_t len) -> std::string {
|
||||
std::ostringstream ss;
|
||||
ss << std::hex << std::setfill('0');
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
ss << std::setw(2) << static_cast<int>(p[i]);
|
||||
if (i + 1 < len)
|
||||
ss << ""; // compact
|
||||
}
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
switch (value_type) {
|
||||
case DLMS_DATA_TYPE_OCTET_STRING:
|
||||
case DLMS_DATA_TYPE_STRING:
|
||||
case DLMS_DATA_TYPE_STRING_UTF8: {
|
||||
return std::string(reinterpret_cast<const char *>(value_buffer_ptr),
|
||||
reinterpret_cast<const char *>(value_buffer_ptr) + value_length);
|
||||
}
|
||||
case DLMS_DATA_TYPE_BIT_STRING:
|
||||
case DLMS_DATA_TYPE_BINARY_CODED_DESIMAL:
|
||||
return hex_of(value_buffer_ptr, value_length);
|
||||
|
||||
case DLMS_DATA_TYPE_BOOLEAN:
|
||||
case DLMS_DATA_TYPE_ENUM:
|
||||
case DLMS_DATA_TYPE_UINT8: {
|
||||
return std::to_string(static_cast<unsigned>(value_buffer_ptr ? value_buffer_ptr[0] : 0));
|
||||
}
|
||||
case DLMS_DATA_TYPE_INT8: {
|
||||
return std::to_string(static_cast<int>(static_cast<int8_t>(value_buffer_ptr ? value_buffer_ptr[0] : 0)));
|
||||
}
|
||||
case DLMS_DATA_TYPE_UINT16: {
|
||||
if (value_length >= 2) {
|
||||
uint16_t v = (uint16_t) ((value_buffer_ptr[0] << 8) | value_buffer_ptr[1]);
|
||||
return std::to_string(v);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
case DLMS_DATA_TYPE_INT16: {
|
||||
if (value_length >= 2) {
|
||||
int16_t v = (int16_t) ((value_buffer_ptr[0] << 8) | value_buffer_ptr[1]);
|
||||
return std::to_string(v);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
case DLMS_DATA_TYPE_UINT32: {
|
||||
if (value_length >= 4) {
|
||||
uint32_t v = ((uint32_t) value_buffer_ptr[0] << 24) | ((uint32_t) value_buffer_ptr[1] << 16) |
|
||||
((uint32_t) value_buffer_ptr[2] << 8) | (uint32_t) value_buffer_ptr[3];
|
||||
return std::to_string(v);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
case DLMS_DATA_TYPE_INT32: {
|
||||
if (value_length >= 4) {
|
||||
int32_t v = ((int32_t) value_buffer_ptr[0] << 24) | ((int32_t) value_buffer_ptr[1] << 16) |
|
||||
((int32_t) value_buffer_ptr[2] << 8) | (int32_t) value_buffer_ptr[3];
|
||||
return std::to_string(v);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
case DLMS_DATA_TYPE_UINT64: {
|
||||
if (value_length >= 8) {
|
||||
uint64_t v = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
v = (v << 8) | value_buffer_ptr[i];
|
||||
return std::to_string(v);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
case DLMS_DATA_TYPE_INT64: {
|
||||
if (value_length >= 8) {
|
||||
uint64_t u = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
u = (u << 8) | value_buffer_ptr[i];
|
||||
int64_t v = static_cast<int64_t>(u);
|
||||
return std::to_string(v);
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
case DLMS_DATA_TYPE_FLOAT32:
|
||||
case DLMS_DATA_TYPE_FLOAT64: {
|
||||
float f = dlms_data_as_float(value_type, value_buffer_ptr, value_length);
|
||||
// Use minimal formatting
|
||||
std::ostringstream ss;
|
||||
ss << f;
|
||||
return ss.str();
|
||||
}
|
||||
case DLMS_DATA_TYPE_DATETIME:
|
||||
case DLMS_DATA_TYPE_DATE:
|
||||
case DLMS_DATA_TYPE_TIME:
|
||||
// For now, return hex. Higher-level layers may decode properly.
|
||||
return hex_of(value_buffer_ptr, value_length);
|
||||
|
||||
case DLMS_DATA_TYPE_NONE:
|
||||
default:
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
void AxdrPatternRegistry::add_pattern(const AxdrDescriptorPattern &p) {
|
||||
auto it = std::upper_bound(
|
||||
patterns_.begin(), patterns_.end(), p,
|
||||
[](const AxdrDescriptorPattern &a, const AxdrDescriptorPattern &b) { return a.priority < b.priority; });
|
||||
patterns_.insert(it, p);
|
||||
}
|
||||
|
||||
uint8_t AxdrStreamParser::peek_byte_() {
|
||||
if (this->buffer_->position + 1 > this->buffer_->size) {
|
||||
return 0xFF;
|
||||
}
|
||||
return this->buffer_->data[this->buffer_->position];
|
||||
}
|
||||
|
||||
uint8_t AxdrStreamParser::read_byte_() {
|
||||
if (this->buffer_->position + 1 > this->buffer_->size) {
|
||||
return 0xFF;
|
||||
}
|
||||
return this->buffer_->data[this->buffer_->position++];
|
||||
}
|
||||
|
||||
uint16_t AxdrStreamParser::read_u16_() {
|
||||
if (this->buffer_->position + 2 > this->buffer_->size) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
uint16_t value =
|
||||
(this->buffer_->data[this->buffer_->position] << 8) | this->buffer_->data[this->buffer_->position + 1];
|
||||
this->buffer_->position += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t AxdrStreamParser::read_u32_() {
|
||||
if (this->buffer_->position + 4 > this->buffer_->size) {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
uint32_t value =
|
||||
(this->buffer_->data[this->buffer_->position] << 24) | (this->buffer_->data[this->buffer_->position + 1] << 16) |
|
||||
(this->buffer_->data[this->buffer_->position + 2] << 8) | this->buffer_->data[this->buffer_->position + 3];
|
||||
this->buffer_->position += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
bool AxdrStreamParser::test_if_date_time_12b_() {
|
||||
if (this->buffer_->position + 12 > this->buffer_->size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t *buf = this->buffer_->data + this->buffer_->position;
|
||||
if (!buf)
|
||||
return false;
|
||||
|
||||
// Year
|
||||
uint16_t year = (buf[0] << 8) | buf[1];
|
||||
if (!(year == 0x0000 || (year >= 1970 && year <= 2100)))
|
||||
return false;
|
||||
|
||||
// Month
|
||||
uint8_t month = buf[2];
|
||||
if (!(month == 0xFF || (month >= 1 && month <= 12)))
|
||||
return false;
|
||||
|
||||
// Day of month
|
||||
uint8_t day = buf[3];
|
||||
if (!(day == 0xFF || (day >= 1 && day <= 31)))
|
||||
return false;
|
||||
|
||||
// Day of week
|
||||
uint8_t dow = buf[4];
|
||||
if (!(dow == 0xFF || (dow >= 1 && dow <= 7)))
|
||||
return false;
|
||||
|
||||
// Hour
|
||||
uint8_t hour = buf[5];
|
||||
if (!(hour == 0xFF || hour <= 23))
|
||||
return false;
|
||||
|
||||
// Minute
|
||||
uint8_t minute = buf[6];
|
||||
if (!(minute == 0xFF || minute <= 59))
|
||||
return false;
|
||||
|
||||
// Second
|
||||
uint8_t second = buf[7];
|
||||
if (!(second == 0xFF || second <= 59))
|
||||
return false;
|
||||
|
||||
// Hundredths of second
|
||||
uint8_t ms = buf[8];
|
||||
if (!(ms == 0xFF || ms <= 99))
|
||||
return false;
|
||||
|
||||
// some makers mix up the order
|
||||
// Deviation (timezone offset, signed, 2 bytes)
|
||||
uint16_t u_dev = (buf[9] << 8) | buf[10];
|
||||
int16_t s_dev = (int16_t) (u_dev);
|
||||
if (!((s_dev == (int16_t) 0x8000 || (s_dev >= -720 && s_dev <= 720))))
|
||||
return false;
|
||||
|
||||
uint8_t clock_status = buf[11];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr uint16_t MAX_CLASS_ID = 0x00FF;
|
||||
constexpr uint8_t MAX_ATTRIBUTE_ID = 0x20;
|
||||
constexpr size_t MIN_UNTAGGED_ATTRIBUTE_DESCRIPTOR_SIZE = 9;
|
||||
constexpr size_t MIN_TAGGED_ATTRIBUTE_DESCRIPTOR_SIZE = 14;
|
||||
|
||||
bool AxdrStreamParser::skip_data_(uint8_t type) {
|
||||
int data_size = hlp_getDataTypeSize((DLMS_DATA_TYPE) type);
|
||||
|
||||
if (data_size == 0) // Zero-length data (NONE type) - nothing to skip
|
||||
return true;
|
||||
|
||||
if (data_size > 0) { // Fixed size data
|
||||
if (this->buffer_->position + data_size > this->buffer_->size) {
|
||||
return false;
|
||||
}
|
||||
this->buffer_->position += data_size;
|
||||
} else { // Variable size data
|
||||
uint8_t length = read_byte_();
|
||||
if (length == 0xFF) {
|
||||
return false;
|
||||
}
|
||||
if (this->buffer_->position + length > this->buffer_->size) {
|
||||
return false;
|
||||
}
|
||||
this->buffer_->position += length;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AxdrStreamParser::skip_sequence_(uint8_t type) {
|
||||
uint8_t elements_count = read_byte_();
|
||||
if (elements_count == 0xFF) {
|
||||
ESP_LOGV(TAG, "Invalid sequence length when skipping at position %d", this->buffer_->position - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Skipping %s with %d elements at position %d",
|
||||
(type == DLMS_DATA_TYPE_STRUCTURE) ? "STRUCTURE" : "ARRAY", elements_count, this->buffer_->position - 1);
|
||||
|
||||
for (uint8_t i = 0; i < elements_count; i++) {
|
||||
uint8_t elem_type = read_byte_();
|
||||
if (!parse_element_(elem_type)) {
|
||||
ESP_LOGV(TAG, "Failed to skip element %d of %s at position %d", i + 1,
|
||||
(type == DLMS_DATA_TYPE_STRUCTURE) ? "STRUCTURE" : "ARRAY", this->buffer_->position - 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AxdrStreamParser::parse_data_(uint8_t type, uint8_t depth) { return skip_data_(type); }
|
||||
|
||||
bool AxdrStreamParser::parse_sequence_(uint8_t type, uint8_t depth) {
|
||||
uint8_t elements_count = read_byte_();
|
||||
if (elements_count == 0xFF) {
|
||||
ESP_LOGVV(TAG, "Invalid sequence length at position %d", this->buffer_->position - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t elements_consumed = 0;
|
||||
|
||||
while (elements_consumed < elements_count) {
|
||||
uint32_t original_position = this->buffer_->position;
|
||||
|
||||
if (try_match_patterns_(elements_consumed)) {
|
||||
uint8_t used = this->last_pattern_elements_consumed_ ? this->last_pattern_elements_consumed_ : 1;
|
||||
elements_consumed += used;
|
||||
this->last_pattern_elements_consumed_ = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this->buffer_->position >= this->buffer_->size) {
|
||||
ESP_LOGV(TAG, "Unexpected end while reading element %d of %s", elements_consumed + 1,
|
||||
(type == DLMS_DATA_TYPE_STRUCTURE) ? "STRUCTURE" : "ARRAY");
|
||||
return false;
|
||||
}
|
||||
uint8_t elem_type = read_byte_();
|
||||
if (!parse_element_(elem_type, depth + 1)) {
|
||||
return false;
|
||||
}
|
||||
elements_consumed++;
|
||||
|
||||
if (this->buffer_->position == original_position) {
|
||||
ESP_LOGV(TAG, "No progress parsing element %d at position %d, aborting to avoid infinite loop", elements_consumed,
|
||||
original_position);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AxdrStreamParser::parse_element_(uint8_t type, uint8_t depth) {
|
||||
if (type == DLMS_DATA_TYPE_STRUCTURE || type == DLMS_DATA_TYPE_ARRAY) {
|
||||
return parse_sequence_(type, depth);
|
||||
} else {
|
||||
return parse_data_(type, depth);
|
||||
}
|
||||
}
|
||||
|
||||
size_t AxdrStreamParser::parse() {
|
||||
if (this->buffer_ == nullptr || this->buffer_->size == 0) {
|
||||
ESP_LOGV(TAG, "Buffer is null or empty");
|
||||
return 0;
|
||||
}
|
||||
// Skip to notification flag 0x0F
|
||||
while (this->buffer_->position < this->buffer_->size) {
|
||||
uint8_t flag = read_byte_();
|
||||
if (flag == 0x0F) {
|
||||
ESP_LOGD(TAG, "Found notification flag at position %d", this->buffer_->position - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip 5 bytes (invoke id and priority)
|
||||
for (int i = 0; i < 5; i++) {
|
||||
uint8_t priority = read_byte_();
|
||||
}
|
||||
|
||||
// Check for datetime object before the data
|
||||
bool is_date_time = test_if_date_time_12b_();
|
||||
if (is_date_time) {
|
||||
ESP_LOGV(TAG, "Skipping datetime at position %d", this->buffer_->position);
|
||||
this->buffer_->position += 12;
|
||||
}
|
||||
|
||||
// First byte after flag should be the data type
|
||||
uint8_t start_type = read_byte_();
|
||||
if (start_type != (uint8_t) DLMS_DATA_TYPE_STRUCTURE && start_type != (uint8_t) DLMS_DATA_TYPE_ARRAY) {
|
||||
ESP_LOGV(TAG, "Expected structure or array after notification flag, found type %02X at position %d", start_type,
|
||||
this->buffer_->position);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse the data, looking for attribute descriptors
|
||||
bool success = parse_element_(start_type, 0);
|
||||
if (!success) {
|
||||
ESP_LOGV(TAG, "Some errors occurred parsing AXDR data");
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Fast parsing completed, processed %d bytes", this->buffer_->position);
|
||||
return this->objects_found_;
|
||||
}
|
||||
|
||||
bool AxdrStreamParser::capture_generic_value_(AxdrCaptures &c) {
|
||||
uint8_t vt = read_byte_();
|
||||
if (!hlp_isValueDataType((DLMS_DATA_TYPE) vt)) {
|
||||
return false;
|
||||
}
|
||||
int ds = hlp_getDataTypeSize((DLMS_DATA_TYPE) vt);
|
||||
const uint8_t *ptr = nullptr;
|
||||
uint8_t len = 0;
|
||||
if (ds > 0) {
|
||||
if (this->buffer_->position + ds > this->buffer_->size)
|
||||
return false;
|
||||
ptr = &this->buffer_->data[this->buffer_->position];
|
||||
len = (uint8_t) ds;
|
||||
this->buffer_->position += ds;
|
||||
} else if (ds == 0) {
|
||||
ptr = nullptr;
|
||||
len = 0;
|
||||
} else {
|
||||
uint8_t L = read_byte_();
|
||||
if (L == 0xFF || this->buffer_->position + L > this->buffer_->size)
|
||||
return false;
|
||||
ptr = &this->buffer_->data[this->buffer_->position];
|
||||
len = L;
|
||||
this->buffer_->position += L;
|
||||
}
|
||||
c.value_type = (DLMS_DATA_TYPE) vt;
|
||||
c.value_ptr = ptr;
|
||||
c.value_len = len;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AxdrStreamParser::emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptures &c) {
|
||||
if (!c.obis)
|
||||
return;
|
||||
uint16_t cid = c.class_id ? c.class_id : pat.default_class_id;
|
||||
|
||||
if (this->show_log_) {
|
||||
ESP_LOGD(TAG, "Pattern match '%s' at idx %d ===============", pat.name, c.elem_idx);
|
||||
|
||||
auto val_f = dlms_data_as_float((DLMS_DATA_TYPE) c.value_type, c.value_ptr, c.value_len);
|
||||
auto val_s = dlms_data_as_string((DLMS_DATA_TYPE) c.value_type, c.value_ptr, c.value_len);
|
||||
ESP_LOGI(TAG, "Found attribute descriptor: class_id=%d, obis=%d.%d.%d.%d.%d.%d", cid, c.obis[0], c.obis[1],
|
||||
c.obis[2], c.obis[3], c.obis[4], c.obis[5], c.value_type);
|
||||
if (c.has_scaler_unit) {
|
||||
ESP_LOGI(TAG, "Value type: %s, len %d, scaler %d, unit %d (%s)",
|
||||
dlms_data_type_to_string((DLMS_DATA_TYPE) c.value_type), c.value_len, c.scaler, c.unit_enum,
|
||||
obj_getUnitAsString(c.unit_enum));
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Value type: %s, len %d", dlms_data_type_to_string((DLMS_DATA_TYPE) c.value_type), c.value_len);
|
||||
}
|
||||
ESP_LOGI(TAG, " as hex dump : %s", esphome::format_hex_pretty(c.value_ptr, c.value_len).c_str());
|
||||
ESP_LOGI(TAG, " as string :'%s'", val_s.c_str());
|
||||
ESP_LOGI(TAG, " as number : %f", val_f);
|
||||
if (c.has_scaler_unit) {
|
||||
ESP_LOGI(TAG, " as number * scaler : %f", val_f * std::pow(10, c.scaler));
|
||||
}
|
||||
}
|
||||
|
||||
if (callback_) {
|
||||
if (c.has_scaler_unit) {
|
||||
callback_(cid, c.obis, c.value_type, c.value_ptr, c.value_len, &c.scaler, &c.unit_enum);
|
||||
} else {
|
||||
callback_(cid, c.obis, c.value_type, c.value_ptr, c.value_len, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
this->objects_found_++;
|
||||
}
|
||||
|
||||
bool AxdrStreamParser::match_pattern_(uint8_t elem_idx, const AxdrDescriptorPattern &pat,
|
||||
uint8_t &elements_consumed_at_level0) {
|
||||
AxdrCaptures cap{};
|
||||
elements_consumed_at_level0 = 0;
|
||||
uint8_t level = 0;
|
||||
auto consume_one = [&]() {
|
||||
if (level == 0)
|
||||
elements_consumed_at_level0++;
|
||||
};
|
||||
auto initial_position = this->buffer_->position;
|
||||
|
||||
for (const auto &step : pat.steps) {
|
||||
switch (step.type) {
|
||||
case AxdrTokenType::EXPECT_TO_BE_FIRST: {
|
||||
if (elem_idx != 0)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_TYPE_EXACT: {
|
||||
uint8_t t = read_byte_();
|
||||
if (t != step.param_u8_a)
|
||||
return false;
|
||||
consume_one();
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_TYPE_U_I_8: {
|
||||
uint8_t t = read_byte_();
|
||||
if (!(t == DLMS_DATA_TYPE_INT8 || t == DLMS_DATA_TYPE_UINT8))
|
||||
return false;
|
||||
consume_one();
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_CLASS_ID_UNTAGGED: {
|
||||
uint16_t v = read_u16_();
|
||||
if (
|
||||
// v == 0 ||
|
||||
v > MAX_CLASS_ID)
|
||||
return false;
|
||||
cap.class_id = v;
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_OBIS6_TAGGED: {
|
||||
uint8_t t = read_byte_();
|
||||
if (t != DLMS_DATA_TYPE_OCTET_STRING)
|
||||
return false;
|
||||
uint8_t len = read_byte_();
|
||||
if (len != 6)
|
||||
return false;
|
||||
if (this->buffer_->position + 6 > this->buffer_->size)
|
||||
return false;
|
||||
cap.obis = &this->buffer_->data[this->buffer_->position];
|
||||
this->buffer_->position += 6;
|
||||
consume_one();
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_OBIS6_UNTAGGED: {
|
||||
if (this->buffer_->position + 6 > this->buffer_->size)
|
||||
return false;
|
||||
cap.obis = &this->buffer_->data[this->buffer_->position];
|
||||
this->buffer_->position += 6;
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_ATTR8_UNTAGGED: {
|
||||
uint8_t a = read_byte_();
|
||||
if (a == 0)
|
||||
return false;
|
||||
// cap.attr_id = a;
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_VALUE_GENERIC: {
|
||||
if (!capture_generic_value_(cap))
|
||||
return false;
|
||||
consume_one();
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_STRUCTURE_N: {
|
||||
uint8_t t = read_byte_();
|
||||
if (t != DLMS_DATA_TYPE_STRUCTURE)
|
||||
return false;
|
||||
uint8_t cnt = read_byte_();
|
||||
if (cnt != step.param_u8_a)
|
||||
return false;
|
||||
consume_one();
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_SCALER_TAGGED: {
|
||||
uint8_t t = read_byte_();
|
||||
if (t != DLMS_DATA_TYPE_INT8)
|
||||
return false;
|
||||
uint8_t b = read_byte_();
|
||||
cap.scaler = (int8_t) b;
|
||||
cap.has_scaler_unit = true;
|
||||
consume_one();
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::EXPECT_UNIT_ENUM_TAGGED: {
|
||||
uint8_t t = read_byte_();
|
||||
if (t != DLMS_DATA_TYPE_ENUM)
|
||||
return false;
|
||||
uint8_t b = read_byte_();
|
||||
cap.unit_enum = b;
|
||||
cap.has_scaler_unit = true;
|
||||
consume_one();
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::GOING_DOWN: {
|
||||
level++;
|
||||
break;
|
||||
}
|
||||
case AxdrTokenType::GOING_UP: {
|
||||
level--;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (elements_consumed_at_level0 == 0) {
|
||||
elements_consumed_at_level0 = 1; // Fallback: one element to move forward
|
||||
}
|
||||
cap.elem_idx = initial_position;
|
||||
emit_object_(pat, cap);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AxdrStreamParser::try_match_patterns_(uint8_t elem_idx) {
|
||||
const auto &pats = registry_.patterns();
|
||||
for (const auto &p : pats) {
|
||||
uint8_t consumed = 0;
|
||||
uint32_t saved_position = buffer_->position;
|
||||
if (match_pattern_(elem_idx, p, consumed)) {
|
||||
this->last_pattern_elements_consumed_ = consumed;
|
||||
return true;
|
||||
} else {
|
||||
buffer_->position = saved_position;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AxdrStreamParser::register_pattern_dsl(const char *name, const std::string &dsl, int priority) {
|
||||
AxdrDescriptorPattern pat{name, priority, {}, 0};
|
||||
// DSL tokens separated by commas, optional spaces. Supported atoms:
|
||||
// F : must be first element in sequence
|
||||
// C : raw class_id (uint16 payload, no type tag)
|
||||
// TC : tagged class_id (type tag UINT16 + uint16 payload)
|
||||
// O : raw OBIS (6 bytes payload, no type tag)
|
||||
// TO : tagged OBIS (type tag OCTET_STRING + length=6 + 6 bytes)
|
||||
// A : raw attribute id (uint8 payload, no type tag)
|
||||
// TA : tagged attribute (type tag INT8/UINT8 + 1 byte)
|
||||
// TV : tagged value (type tag + payload for any value type)
|
||||
// TSU : tagged scaler+unit structure (STRUCTURE tag + count 2 + TS + TU)
|
||||
// Additionally supported:
|
||||
// TS : tagged scaler (type tag INT8 + int8 payload)
|
||||
// TU : tagged unit (type tag ENUM + uint8 payload)
|
||||
// S(...) : structure with N elements, expands inner tokens
|
||||
// Examples: "TC,TO,TA,TV", "TO,TV,TSU", "F,C,O,A,TV"
|
||||
|
||||
// For simplicity we parse left-to-right and translate to steps.
|
||||
|
||||
auto trim = [](const std::string &s) {
|
||||
size_t b = s.find_first_not_of(" \t\r\n");
|
||||
size_t e = s.find_last_not_of(" \t\r\n");
|
||||
if (b == std::string::npos)
|
||||
return std::string();
|
||||
return s.substr(b, e - b + 1);
|
||||
};
|
||||
|
||||
std::list<std::string> tokens;
|
||||
std::string current;
|
||||
int paren = 0;
|
||||
for (char c : dsl) {
|
||||
if (c == '(') {
|
||||
paren++;
|
||||
current.push_back(c);
|
||||
} else if (c == ')') {
|
||||
paren--;
|
||||
current.push_back(c);
|
||||
} else if (c == ',' && paren == 0) {
|
||||
tokens.push_back(trim(current));
|
||||
current.clear();
|
||||
} else
|
||||
current.push_back(c);
|
||||
}
|
||||
if (!current.empty())
|
||||
tokens.push_back(trim(current));
|
||||
|
||||
for (auto it = tokens.begin(); it != tokens.end(); ++it) {
|
||||
auto &tok = *it;
|
||||
if (tok.empty())
|
||||
continue;
|
||||
if (tok == "F") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_TO_BE_FIRST});
|
||||
} else if (tok == "C") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_CLASS_ID_UNTAGGED});
|
||||
} else if (tok == "TC") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_TYPE_EXACT, (uint8_t) DLMS_DATA_TYPE_UINT16});
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_CLASS_ID_UNTAGGED});
|
||||
} else if (tok == "O") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_OBIS6_UNTAGGED});
|
||||
} else if (tok == "TO") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_OBIS6_TAGGED});
|
||||
} else if (tok == "A") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_ATTR8_UNTAGGED});
|
||||
} else if (tok == "TA") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_TYPE_U_I_8});
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_ATTR8_UNTAGGED});
|
||||
} else if (tok == "TS") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_SCALER_TAGGED});
|
||||
} else if (tok == "TU") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_UNIT_ENUM_TAGGED});
|
||||
} else if (tok == "TSU") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_STRUCTURE_N, 2});
|
||||
pat.steps.push_back({AxdrTokenType::GOING_DOWN});
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_SCALER_TAGGED});
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_UNIT_ENUM_TAGGED});
|
||||
pat.steps.push_back({AxdrTokenType::GOING_UP});
|
||||
} else if (tok == "V" || tok == "TV") {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_VALUE_GENERIC});
|
||||
} else if (tok.rfind("S", 0) == 0) {
|
||||
size_t l = tok.find('(');
|
||||
size_t r = tok.rfind(')');
|
||||
std::list<std::string> inner_tokens;
|
||||
if (l != std::string::npos && r != std::string::npos && r > l + 1) {
|
||||
std::string inner = tok.substr(l + 1, r - l - 1);
|
||||
std::vector<std::string> innerT;
|
||||
std::string cur;
|
||||
for (char c2 : inner) {
|
||||
if (c2 == ',') {
|
||||
inner_tokens.push_back(trim(cur));
|
||||
cur.clear();
|
||||
} else
|
||||
cur.push_back(c2);
|
||||
}
|
||||
if (!cur.empty())
|
||||
inner_tokens.push_back(trim(cur));
|
||||
}
|
||||
if (!inner_tokens.empty()) {
|
||||
pat.steps.push_back({AxdrTokenType::EXPECT_STRUCTURE_N, static_cast<uint8_t>(inner_tokens.size())});
|
||||
inner_tokens.push_front("DN");
|
||||
inner_tokens.push_back("UP");
|
||||
tokens.insert(std::next(it), inner_tokens.begin(), inner_tokens.end());
|
||||
}
|
||||
|
||||
} else if (tok == "DN") {
|
||||
pat.steps.push_back({AxdrTokenType::GOING_DOWN});
|
||||
} else if (tok == "UP") {
|
||||
pat.steps.push_back({AxdrTokenType::GOING_UP});
|
||||
}
|
||||
}
|
||||
|
||||
registry_.add_pattern(pat);
|
||||
}
|
||||
|
||||
} // namespace xt211
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "client.h"
|
||||
#include "converters.h"
|
||||
#include "cosem.h"
|
||||
#include "dlmssettings.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace xt211 {
|
||||
|
||||
const char *dlms_data_type_to_string(DLMS_DATA_TYPE vt);
|
||||
const char *dlms_error_to_string(int error);
|
||||
float dlms_data_as_float(DLMS_DATA_TYPE value_type, const uint8_t *value_buffer_ptr, uint8_t value_length);
|
||||
std::string dlms_data_as_string(DLMS_DATA_TYPE value_type, const uint8_t *value_buffer_ptr, uint8_t value_length);
|
||||
|
||||
bool hlp_isValueDataType(DLMS_DATA_TYPE type);
|
||||
|
||||
using CosemObjectFoundCallback =
|
||||
std::function<void(uint16_t class_id, const uint8_t *obis, DLMS_DATA_TYPE value_type, const uint8_t *value_ptr,
|
||||
uint8_t value_len, const int8_t *scaler, const uint8_t *unit)>;
|
||||
|
||||
enum class AxdrTokenType : uint8_t {
|
||||
EXPECT_TO_BE_FIRST,
|
||||
EXPECT_TYPE_EXACT, // param_u8_a = required DLMS type tag
|
||||
EXPECT_TYPE_U_I_8, // param_u8_a = required DLMS type tag; accept UINT8 or INT8
|
||||
EXPECT_CLASS_ID_UNTAGGED, // capture class_id (big endian)
|
||||
EXPECT_OBIS6_TAGGED, // capture 6-byte tagged OBIS
|
||||
EXPECT_OBIS6_UNTAGGED, // capture 6-byte OBIS
|
||||
EXPECT_ATTR8_UNTAGGED, // capture attribute id (accept INT8/UINT8 depending on flags)
|
||||
EXPECT_VALUE_GENERIC, // capture value: first byte is type tag; supports fixed/variable lengths
|
||||
EXPECT_STRUCTURE_N, // expect a structure with element count = param_u8_a
|
||||
EXPECT_SCALER_TAGGED, // capture scaler (INT8 or UINT8)
|
||||
EXPECT_UNIT_ENUM_TAGGED, // capture unit enum (ENUM base + 1 byte value)
|
||||
GOING_DOWN, // capture going down
|
||||
GOING_UP, // capture going up
|
||||
};
|
||||
|
||||
struct AxdrPatternStep {
|
||||
AxdrTokenType type;
|
||||
uint8_t param_u8_a{0};
|
||||
};
|
||||
|
||||
struct AxdrDescriptorPattern {
|
||||
const char *name;
|
||||
int priority{0};
|
||||
std::vector<AxdrPatternStep> steps;
|
||||
|
||||
uint16_t default_class_id{0};
|
||||
uint8_t value_attr_id{2};
|
||||
uint8_t scaler_unit_attr_id{3};
|
||||
};
|
||||
|
||||
struct AxdrCaptures {
|
||||
uint32_t elem_idx{0};
|
||||
uint16_t class_id{0};
|
||||
const uint8_t *obis{nullptr};
|
||||
DLMS_DATA_TYPE value_type{DLMS_DATA_TYPE_NONE};
|
||||
const uint8_t *value_ptr{nullptr};
|
||||
uint8_t value_len{0};
|
||||
|
||||
bool has_scaler_unit{false};
|
||||
int8_t scaler{0};
|
||||
uint8_t unit_enum{DLMS_UNIT_NO_UNIT};
|
||||
};
|
||||
|
||||
class AxdrPatternRegistry {
|
||||
public:
|
||||
void add_pattern(const AxdrDescriptorPattern &p);
|
||||
const std::vector<AxdrDescriptorPattern> &patterns() const { return patterns_; }
|
||||
void clear() { patterns_.clear(); }
|
||||
|
||||
private:
|
||||
std::vector<AxdrDescriptorPattern> patterns_{};
|
||||
};
|
||||
|
||||
class AxdrStreamParser {
|
||||
gxByteBuffer *buffer_;
|
||||
CosemObjectFoundCallback callback_;
|
||||
size_t objects_found_ = 0;
|
||||
bool show_log_ = false;
|
||||
|
||||
AxdrPatternRegistry registry_{};
|
||||
uint8_t last_pattern_elements_consumed_{0};
|
||||
|
||||
uint8_t peek_byte_();
|
||||
uint8_t read_byte_();
|
||||
uint16_t read_u16_();
|
||||
uint32_t read_u32_();
|
||||
|
||||
bool test_if_date_time_12b_();
|
||||
|
||||
bool parse_element_(uint8_t type, uint8_t depth = 0);
|
||||
bool parse_sequence_(uint8_t type, uint8_t depth = 0);
|
||||
bool parse_data_(uint8_t type, uint8_t depth = 0);
|
||||
bool skip_data_(uint8_t type);
|
||||
bool skip_sequence_(uint8_t type);
|
||||
|
||||
bool try_match_patterns_(uint8_t elem_idx);
|
||||
bool match_pattern_(uint8_t elem_idx, const AxdrDescriptorPattern &pat, uint8_t &elements_consumed_at_level);
|
||||
bool capture_generic_value_(AxdrCaptures &c);
|
||||
void emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptures &c);
|
||||
|
||||
public:
|
||||
AxdrStreamParser(gxByteBuffer *buf, CosemObjectFoundCallback callback, bool show_log)
|
||||
: buffer_(buf), callback_(callback), show_log_(show_log) {}
|
||||
size_t parse();
|
||||
void register_pattern_dsl(const char *name, const std::string &dsl, int priority = 10);
|
||||
void clear_patterns() { registry_.clear(); }
|
||||
};
|
||||
|
||||
} // namespace xt211
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
#endif
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#endif
|
||||
#include <cmath> // for std::pow
|
||||
|
||||
namespace esphome {
|
||||
namespace xt211 {
|
||||
|
||||
enum SensorType { SENSOR, TEXT_SENSOR, BINARY_SENSOR };
|
||||
|
||||
// const char * UNIT_STR_UNKNOWN = "Unknown unit";
|
||||
#define UNIT_STR_UNKNOWN_NOT_YET "Unknown unit / not yet known"
|
||||
#define UNIT_STR_UNKNOWN "Unknown unit"
|
||||
|
||||
class XT211SensorBase {
|
||||
public:
|
||||
static const uint8_t MAX_REQUEST_SIZE = 15;
|
||||
|
||||
virtual SensorType get_type() const = 0;
|
||||
virtual const StringRef &get_sensor_name() = 0;
|
||||
virtual EntityBase *get_base() = 0;
|
||||
virtual void publish() = 0;
|
||||
|
||||
void set_obis_code(const char *obis_code) { this->obis_code_ = obis_code; }
|
||||
const std::string &get_obis_code() const { return this->obis_code_; }
|
||||
|
||||
void set_dont_publish(bool dont_publish) { this->we_shall_publish_ = !dont_publish; }
|
||||
bool shall_we_publish() const { return this->we_shall_publish_; }
|
||||
|
||||
void set_obis_class(int obis_class) { this->obis_class_ = obis_class; }
|
||||
int get_obis_class() { return this->obis_class_; }
|
||||
|
||||
virtual bool has_got_scale_and_unit() { return false; } // PULL mode logic removed
|
||||
|
||||
protected:
|
||||
std::string obis_code_;
|
||||
int obis_class_{3 /*DLMS_OBJECT_TYPE_REGISTER*/};
|
||||
bool we_shall_publish_{true};
|
||||
// Removed has_value_, tries_
|
||||
};
|
||||
|
||||
class XT211Sensor : public XT211SensorBase, public sensor::Sensor {
|
||||
public:
|
||||
SensorType get_type() const override { return SENSOR; }
|
||||
const StringRef &get_sensor_name() { return this->get_name(); }
|
||||
EntityBase *get_base() { return this; }
|
||||
void publish() override { publish_state(this->value_); }
|
||||
|
||||
bool has_got_scale_and_unit() override { return true; } // PULL mode logic removed
|
||||
|
||||
void set_multiplier(float multiplier) { this->multiplier_ = multiplier; }
|
||||
|
||||
void set_value(float value) {
|
||||
// Scale is applied in XT211Component::set_sensor_value before calling this
|
||||
this->value_ = value * multiplier_;
|
||||
}
|
||||
|
||||
protected:
|
||||
float value_{NAN};
|
||||
float multiplier_{1.0f};
|
||||
// Removed scaler_, scale_f_, unit_, unit_s_, scale_and_unit_detected_
|
||||
};
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
class XT211TextSensor : public XT211SensorBase, public text_sensor::TextSensor {
|
||||
public:
|
||||
SensorType get_type() const override { return TEXT_SENSOR; }
|
||||
const StringRef &get_sensor_name() { return this->get_name(); }
|
||||
EntityBase *get_base() { return this; }
|
||||
void publish() override { publish_state(value_); }
|
||||
|
||||
bool has_got_scale_and_unit() override { return true; }
|
||||
|
||||
void set_value(const char *value) {
|
||||
value_ = std::string(value);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string value_;
|
||||
|
||||
};
|
||||
#endif
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
class XT211BinarySensor : public XT211SensorBase, public binary_sensor::BinarySensor {
|
||||
public:
|
||||
SensorType get_type() const override { return BINARY_SENSOR; }
|
||||
const StringRef &get_sensor_name() { return this->get_name(); }
|
||||
EntityBase *get_base() { return this; }
|
||||
void publish() override { publish_state(value_); }
|
||||
|
||||
bool has_got_scale_and_unit() override { return true; }
|
||||
|
||||
void set_value(bool value) {
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool value_;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace xt211
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#include "esphome/components/uart/uart_component_esp_idf.h"
|
||||
#include "esphome/core/log.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
#include "esphome/components/uart/uart_component_esp8266.h"
|
||||
#endif
|
||||
|
||||
namespace esphome {
|
||||
namespace xt211 {
|
||||
|
||||
static const uint32_t TIMEOUT = 20; // default value in uart implementation is 100ms
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
|
||||
class XSoftSerial : public uart::ESP8266SoftwareSerial {
|
||||
public:
|
||||
void set_bit_time(uint32_t bt) { bit_time_ = bt; }
|
||||
};
|
||||
|
||||
class XT211Uart final : public uart::ESP8266UartComponent {
|
||||
public:
|
||||
XT211Uart(uart::ESP8266UartComponent const &uart)
|
||||
: uart_(uart), hw_(uart.*(&XT211Uart::hw_serial_)), sw_(uart.*(&XT211Uart::sw_serial_)) {}
|
||||
|
||||
void update_baudrate(uint32_t baudrate) {
|
||||
if (this->hw_ != nullptr) {
|
||||
this->hw_->updateBaudRate(baudrate);
|
||||
} else if (baudrate > 0) {
|
||||
((XSoftSerial *) sw_)->set_bit_time(F_CPU / baudrate);
|
||||
}
|
||||
}
|
||||
|
||||
bool read_one_byte(uint8_t *data) {
|
||||
if (this->hw_ != nullptr) {
|
||||
if (!this->check_read_timeout_quick_(1))
|
||||
return false;
|
||||
this->hw_->readBytes(data, 1);
|
||||
} else {
|
||||
if (sw_->available() < 1)
|
||||
return false;
|
||||
assert(this->sw_ != nullptr);
|
||||
optional<uint8_t> b = this->sw_->read_byte();
|
||||
if (b) {
|
||||
*data = *b;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool check_read_timeout_quick_(size_t len) {
|
||||
if (this->hw_->available() >= int(len))
|
||||
return true;
|
||||
|
||||
uint32_t start_time = millis();
|
||||
while (this->hw_->available() < int(len)) {
|
||||
if (millis() - start_time > TIMEOUT) {
|
||||
return false;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uart::ESP8266UartComponent const &uart_;
|
||||
HardwareSerial *const hw_; // hardware Serial
|
||||
uart::ESP8266SoftwareSerial *const sw_; // software serial
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
// backward compatibility with old IDF versions
|
||||
#ifndef portTICK_PERIOD_MS
|
||||
#define portTICK_PERIOD_MS portTICK_RATE_MS
|
||||
#endif
|
||||
|
||||
class XT211Uart final : public uart::IDFUARTComponent {
|
||||
public:
|
||||
XT211Uart(uart::IDFUARTComponent &uart)
|
||||
: uart_(uart), iuart_num_(uart.*(&XT211Uart::uart_num_)), ilock_(uart.*(&XT211Uart::lock_)) {}
|
||||
|
||||
// Reconfigure baudrate
|
||||
void update_baudrate(uint32_t baudrate) {
|
||||
xSemaphoreTake(ilock_, portMAX_DELAY);
|
||||
uart_set_baudrate(iuart_num_, baudrate);
|
||||
xSemaphoreGive(ilock_);
|
||||
}
|
||||
|
||||
bool read_one_byte(uint8_t *data) { return read_array_quick_(data, 1); }
|
||||
|
||||
protected:
|
||||
bool check_read_timeout_quick_(size_t len) {
|
||||
if (uart_.available() >= int(len))
|
||||
return true;
|
||||
|
||||
uint32_t start_time = millis();
|
||||
while (uart_.available() < int(len)) {
|
||||
if (millis() - start_time > TIMEOUT) {
|
||||
return false;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_array_quick_(uint8_t *data, size_t len) {
|
||||
size_t length_to_read = len;
|
||||
if (!this->check_read_timeout_quick_(len))
|
||||
return false;
|
||||
xSemaphoreTake(this->ilock_, portMAX_DELAY);
|
||||
if (this->has_peek_) {
|
||||
length_to_read--;
|
||||
*data = this->peek_byte_;
|
||||
data++;
|
||||
this->has_peek_ = false;
|
||||
}
|
||||
if (length_to_read > 0)
|
||||
uart_read_bytes(this->iuart_num_, data, length_to_read, 20 / portTICK_PERIOD_MS);
|
||||
xSemaphoreGive(this->ilock_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uart::IDFUARTComponent &uart_;
|
||||
uart_port_t iuart_num_;
|
||||
SemaphoreHandle_t &ilock_;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace xt211
|
||||
} // namespace esphome
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
esphome:
|
||||
name: esphome-smartmeter
|
||||
friendly_name: SmartMeter
|
||||
|
||||
esp32:
|
||||
variant: esp32c3
|
||||
framework:
|
||||
type: esp-idf
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
# Allow Over-The-Air updates
|
||||
ota:
|
||||
- platform: esphome
|
||||
|
||||
wifi:
|
||||
ssid: "wifi_ssid"
|
||||
password: "wifi_password"
|
||||
|
||||
external_components:
|
||||
- source:
|
||||
type: local
|
||||
path: components
|
||||
|
||||
uart:
|
||||
id: bus_1
|
||||
rx_pin: GPIO21
|
||||
tx_pin: GPIO20
|
||||
baud_rate: 9600
|
||||
data_bits: 8
|
||||
parity: NONE
|
||||
stop_bits: 1
|
||||
|
||||
xt211:
|
||||
push_show_log: true
|
||||
|
||||
text_sensor:
|
||||
- platform: xt211
|
||||
name: Serial number
|
||||
obis_code: 0.0.96.1.1.255
|
||||
entity_category: diagnostic
|
||||
- platform: xt211
|
||||
name: Disconnector state
|
||||
obis_code: 0.0.96.3.10.255
|
||||
entity_category: diagnostic
|
||||
- platform: xt211
|
||||
name: Limmiter
|
||||
obis_code: 0.0.17.0.0.255
|
||||
entity_category: diagnostic
|
||||
|
||||
- platform: xt211
|
||||
name: Current tariff
|
||||
obis_code: 0.0.96.14.0.255
|
||||
entity_category: diagnostic
|
||||
|
||||
- platform: xt211
|
||||
name: Relay 1
|
||||
obis_code: 0.1.96.3.10.255
|
||||
- platform: xt211
|
||||
name: Relay 2
|
||||
obis_code: 0.2.96.3.10.255
|
||||
- platform: xt211
|
||||
name: Relay 3
|
||||
obis_code: 0.3.96.3.10.255
|
||||
- platform: xt211
|
||||
name: Relay 4
|
||||
obis_code: 0.4.96.3.10.255
|
||||
|
||||
sensor:
|
||||
- platform: xt211
|
||||
id: active_energy_consumed
|
||||
name: Energy
|
||||
obis_code: 1.0.1.8.0.255
|
||||
unit_of_measurement: kWh
|
||||
accuracy_decimals: 0
|
||||
device_class: energy
|
||||
state_class: total_increasing
|
||||
|
||||
- platform: xt211
|
||||
id: active_energy_consumed_t1
|
||||
name: Energy T1
|
||||
obis_code: 1.0.1.8.1.255
|
||||
unit_of_measurement: kWh
|
||||
accuracy_decimals: 0
|
||||
device_class: energy
|
||||
state_class: total_increasing
|
||||
- platform: xt211
|
||||
id: active_energy_consumed_t2
|
||||
name: Energy T2
|
||||
obis_code: 1.0.1.8.2.255
|
||||
unit_of_measurement: kWh
|
||||
accuracy_decimals: 0
|
||||
device_class: energy
|
||||
state_class: total_increasing
|
||||
- platform: xt211
|
||||
id: active_energy_consumed_t3
|
||||
name: Energy T3
|
||||
obis_code: 1.0.1.8.3.255
|
||||
unit_of_measurement: kWh
|
||||
accuracy_decimals: 0
|
||||
device_class: energy
|
||||
state_class: total_increasing
|
||||
- platform: xt211
|
||||
id: active_energy_consumed_t4
|
||||
name: Energy T4
|
||||
obis_code: 1.0.1.8.4.255
|
||||
unit_of_measurement: kWh
|
||||
accuracy_decimals: 0
|
||||
device_class: energy
|
||||
state_class: total_increasing
|
||||
|
||||
- platform: xt211
|
||||
id: active_power
|
||||
name: Active power consumption
|
||||
obis_code: 1.0.1.7.0.255
|
||||
unit_of_measurement: W
|
||||
accuracy_decimals: 0
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
|
||||
- platform: xt211
|
||||
id: active_power_l1
|
||||
name: Active power consumption L1
|
||||
obis_code: 1.0.21.7.0.255
|
||||
unit_of_measurement: W
|
||||
accuracy_decimals: 0
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
- platform: xt211
|
||||
id: active_power_l2
|
||||
name: Active power consumption L2
|
||||
obis_code: 1.0.41.7.0.255
|
||||
unit_of_measurement: W
|
||||
accuracy_decimals: 0
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
- platform: xt211
|
||||
id: active_power_l3
|
||||
name: Active power consumption L3
|
||||
obis_code: 1.0.61.7.0.255
|
||||
unit_of_measurement: W
|
||||
accuracy_decimals: 0
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
|
||||
- platform: xt211
|
||||
id: active_power_delivery
|
||||
name: Active power delivery
|
||||
obis_code: 1.0.2.7.0.255
|
||||
unit_of_measurement: W
|
||||
accuracy_decimals: 0
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
|
||||
- platform: xt211
|
||||
id: active_power_l1_delivery
|
||||
name: Active power L1 delivery
|
||||
obis_code: 1.0.22.7.0.255
|
||||
unit_of_measurement: W
|
||||
accuracy_decimals: 0
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
- platform: xt211
|
||||
id: active_power_l2_delivery
|
||||
name: Active power L2 delivery
|
||||
obis_code: 1.0.42.7.0.255
|
||||
unit_of_measurement: W
|
||||
accuracy_decimals: 0
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
- platform: xt211
|
||||
id: active_power_l3_delivery
|
||||
name: Active power L3 delivery
|
||||
obis_code: 1.0.62.7.0.255
|
||||
unit_of_measurement: W
|
||||
accuracy_decimals: 0
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
Loading…
Reference in New Issue