Compare commits

..

No commits in common. 'v1.5' and 'v1.5.3' have entirely different histories.
v1.5 ... v1.5.3

@ -43,7 +43,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -54,7 +54,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@ -68,4 +68,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v1

@ -243,24 +243,10 @@
/* enable to configure MmsServer at runtime */
#define CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME 1
/* Define the default number of the maximum outstanding calls allowed by the caller (client) */
#define CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING 5
/* Define the default number of the maximum outstanding calls allowed by the calling endpoint (server) */
#define CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED 5
/************************************************************************************
* Check configuration for consistency - DO NOT MODIFY THIS PART!
************************************************************************************/
#if (CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING < 1)
#error "Invalid configuration: CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING must be greater than 0!"
#endif
#if (CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED < 1)
#error "Invalid configuration: CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED must be greater than 0!"
#endif
#if (MMS_JOURNAL_SERVICE != 1)
#if (CONFIG_IEC61850_LOG_SERVICE == 1)

@ -232,24 +232,10 @@
/* enable to configure MmsServer at runtime */
#define CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME 1
/* Define the default number of the maximum outstanding calls allowed by the caller (client) */
#define CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING 5
/* Define the default number of the maximum outstanding calls allowed by the calling endpoint (server) */
#define CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED 5
/************************************************************************************
* Check configuration for consistency - DO NOT MODIFY THIS PART!
************************************************************************************/
#if (CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING < 1)
#error "Invalid configuration: CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING must be greater than 0!"
#endif
#if (CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED < 1)
#error "Invalid configuration: CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED must be greater than 0!"
#endif
#if (MMS_JOURNAL_SERVICE != 1)
#if (CONFIG_IEC61850_LOG_SERVICE == 1)

@ -431,9 +431,6 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 IedConnection_getRequestTimeout(IntPtr self);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_setMaxOutstandingCalls(IntPtr self, int calling, int called);
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern void IedConnection_setTimeQuality(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool leapSecondKnown, [MarshalAs(UnmanagedType.I1)] bool clockFailure, [MarshalAs(UnmanagedType.I1)] bool clockNotSynchronized, int subsecondPrecision);
@ -818,16 +815,6 @@ namespace IEC61850
}
}
/// <summary>
/// Set the maximum number outstanding calls allowed for this connection
/// </summary>
/// <param name="calling">the maximum outstanding calls allowed by the caller (client)</param>
/// <param name="called">the maximum outstanding calls allowed by the called endpoint (server)</param>
public void SetMaxOutstandingCalls(int calling, int called)
{
IedConnection_setMaxOutstandingCalls(connection, calling, called);
}
/// <summary>
/// Gets or sets the maximum size if a PDU (has to be set before calling connect!).
/// </summary>
@ -1188,9 +1175,6 @@ namespace IEC61850
private static List<MmsJournalEntry> WrapNativeLogQueryResult(IntPtr linkedList)
{
if (linkedList == IntPtr.Zero)
return null;
List<MmsJournalEntry> journalEntries = new List<MmsJournalEntry>();
IntPtr element = LinkedList_getNext(linkedList);
@ -2254,15 +2238,11 @@ namespace IEC61850
GetDataSetDirectoryHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2;
handle.Free();
List<string> newList = null;
IntPtr element = LinkedList_getNext(dataSetDirectory);
if (dataSetDirectory != IntPtr.Zero)
{
newList = new List<string>();
handle.Free();
IntPtr element = LinkedList_getNext(dataSetDirectory);
List<string> newList = new List<string>();
while (element != IntPtr.Zero)
{
@ -2274,7 +2254,6 @@ namespace IEC61850
}
LinkedList_destroy(dataSetDirectory);
}
handler.Invoke(invokeId, handlerParameter, (IedClientError)err, newList, isDeletable);
}
@ -2449,9 +2428,11 @@ namespace IEC61850
dataSet = new DataSet(nativeDataSet);
}
handler(invokeId, handlerParameter, clientError, dataSet);
}
public delegate void ReadDataSetHandler(UInt32 invokeId,object parameter,IedClientError err,DataSet dataSet);
/// <summary>
@ -2585,6 +2566,7 @@ namespace IEC61850
{
handler(invokeId, handlerParameter, clientError, null, moreFollows);
}
}
/// <summary>
@ -2650,6 +2632,7 @@ namespace IEC61850
return GetLogicalDeviceDataSetsAsync(null, ldName, continueAfter, handler, parameter);
}
public UInt32 GetLogicalDeviceDataSetsAsync(List<string> result, string ldName, string continueAfter, GetNameListHandler handler, object parameter)
{
int error;

@ -130,9 +130,10 @@ if(CONFIG_USE_EXTERNAL_MBEDTLS_DYNLIB)
link_directories(${CONFIG_EXTERNAL_MBEDTLS_DYNLIB_PATH})
else()
file(GLOB tls_SRCS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.28/library/*.c)
add_definitions(-DMBEDTLS_CONFIG_FILE="mbedtls_config.h")
endif(CONFIG_USE_EXTERNAL_MBEDTLS_DYNLIB)
add_definitions(-DMBEDTLS_CONFIG_FILE="mbedtls_config.h")
set (libhal_SRCS ${libhal_SRCS}
${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls/tls_mbedtls.c
)

@ -17,7 +17,6 @@
#include <unistd.h>
#include <sys/time.h>
#include <sys/select.h>
#include <poll.h>
#include "hal_serial.h"
#include "hal_time.h"
@ -30,10 +29,11 @@ struct sSerialPort {
char parity;
uint8_t stopBits;
uint64_t lastSentTime;
int timeout;
struct timeval timeout;
SerialPortError lastError;
};
SerialPort
SerialPort_create(const char* interfaceName, int baudRate, uint8_t dataBits, char parity, uint8_t stopBits)
{
@ -46,7 +46,8 @@ SerialPort_create(const char* interfaceName, int baudRate, uint8_t dataBits, cha
self->stopBits = stopBits;
self->parity = parity;
self->lastSentTime = 0;
self->timeout = 100; /* 100 ms */
self->timeout.tv_sec = 0;
self->timeout.tv_usec = 100000; /* 100 ms */
strncpy(self->interfaceName, interfaceName, 99);
self->lastError = SERIAL_PORT_ERROR_NONE;
}
@ -211,7 +212,8 @@ SerialPort_discardInBuffer(SerialPort self)
void
SerialPort_setTimeout(SerialPort self, int timeout)
{
self->timeout = timeout;
self->timeout.tv_sec = timeout / 1000;
self->timeout.tv_usec = (timeout % 1000) * 1000;
}
SerialPortError
@ -224,14 +226,14 @@ int
SerialPort_readByte(SerialPort self)
{
uint8_t buf[1];
struct pollfd fds[1];
fd_set set;
self->lastError = SERIAL_PORT_ERROR_NONE;
fds[0].fd = self->fd;
fds[0].events = POLLIN;
FD_ZERO(&set);
FD_SET(self->fd, &set);
int ret = poll(fds, 1, self->timeout);
int ret = select(self->fd + 1, &set, NULL, NULL, &(self->timeout));
if (ret == -1) {
self->lastError = SERIAL_PORT_ERROR_UNKNOWN;

@ -478,6 +478,10 @@ Socket_connectAsync(Socket self, const char* address, int port)
if (!prepareAddress(address, port, &serverAddress))
return false;
fd_set fdSet;
FD_ZERO(&fdSet);
FD_SET(self->fd, &fdSet);
activateTcpNoDelay(self);
fcntl(self->fd, F_SETFL, O_NONBLOCK);
@ -501,14 +505,17 @@ Socket_connectAsync(Socket self, const char* address, int port)
SocketState
Socket_checkAsyncConnectState(Socket self)
{
struct pollfd fds[1];
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
fds[0].fd = self->fd;
fds[0].events = POLLOUT;
fd_set fdSet;
FD_ZERO(&fdSet);
FD_SET(self->fd, &fdSet);
int result = poll(fds, 1, 0);
int selectVal = select(self->fd + 1, NULL, &fdSet , NULL, &timeout);
if (result == 1) {
if (selectVal == 1) {
/* Check if connection is established */
@ -523,7 +530,7 @@ Socket_checkAsyncConnectState(Socket self)
return SOCKET_STATE_FAILED;
}
else if (result == 0) {
else if (selectVal == 0) {
return SOCKET_STATE_CONNECTING;
}
else {
@ -537,14 +544,15 @@ Socket_connect(Socket self, const char* address, int port)
if (Socket_connectAsync(self, address, port) == false)
return false;
struct pollfd fds[1];
fds[0].fd = self->fd;
fds[0].events = POLLOUT;
struct timeval timeout;
timeout.tv_sec = self->connectTimeout / 1000;
timeout.tv_usec = (self->connectTimeout % 1000) * 1000;
int result = poll(fds, 1, self->connectTimeout);
fd_set fdSet;
FD_ZERO(&fdSet);
FD_SET(self->fd, &fdSet);
if (result == 1) {
if (select(self->fd + 1, NULL, &fdSet , NULL, &timeout) == 1) {
/* Check if connection is established */

@ -662,12 +662,10 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
uint32_t numberOfDatSetEntries = 0;
if (buffer[bufPos++] == 0x61)
{
if (buffer[bufPos++] == 0x61) {
int gooseLength;
bufPos = BerDecoder_decodeLength(buffer, &gooseLength, bufPos, apduLength);
if (bufPos < 0)
{
if (bufPos < 0) {
if (DEBUG_GOOSE_SUBSCRIBER)
printf("GOOSE_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
return 0;
@ -675,14 +673,12 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
int gooseEnd = bufPos + gooseLength;
while (bufPos < gooseEnd)
{
while (bufPos < gooseEnd) {
int elementLength;
uint8_t tag = buffer[bufPos++];
bufPos = BerDecoder_decodeLength(buffer, &elementLength, bufPos, apduLength);
if (bufPos < 0)
{
if (bufPos < 0) {
if (DEBUG_GOOSE_SUBSCRIBER)
printf("GOOSE_SUBSCRIBER: Malformed message: failed to decode BER length tag!\n");
return 0;
@ -700,8 +696,7 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
{
LinkedList element = LinkedList_getNext(self->subscriberList);
while (element)
{
while (element != NULL) {
GooseSubscriber subscriber = (GooseSubscriber) LinkedList_getData(element);
if (subscriber->isObserver)
@ -718,10 +713,8 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
matchingSubscriber = subscriber;
break;
}
else if (subscriber->goCBRefLen == elementLength)
{
if (memcmp(subscriber->goCBRef, buffer + bufPos, elementLength) == 0)
{
else if (subscriber->goCBRefLen == elementLength) {
if (memcmp(subscriber->goCBRef, buffer + bufPos, elementLength) == 0) {
if (DEBUG_GOOSE_SUBSCRIBER)
printf("GOOSE_SUBSCRIBER: gocbRef is matching!\n");
matchingSubscriber = subscriber;
@ -839,17 +832,15 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
bufPos += elementLength;
}
if (matchingSubscriber != NULL)
{
if (matchingSubscriber != NULL) {
matchingSubscriber->timeAllowedToLive = timeAllowedToLive;
matchingSubscriber->ndsCom = ndsCom;
matchingSubscriber->simulation = simulation;
if (matchingSubscriber->dataSetValuesSelfAllocated)
{
if (matchingSubscriber->dataSetValuesSelfAllocated) {
/* when confRev changed replaced old data set */
if ((matchingSubscriber->dataSetValues != NULL) && (matchingSubscriber->confRev != confRev))
{
if ((matchingSubscriber->dataSetValues != NULL) && (matchingSubscriber->confRev != confRev)) {
MmsValue_delete(matchingSubscriber->dataSetValues);
matchingSubscriber->dataSetValues = NULL;
}
@ -875,8 +866,7 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
if (matchingSubscriber->dataSetValues == NULL)
matchingSubscriber->dataSetValues = parseAllDataUnknownValue(matchingSubscriber, dataSetBufferAddress, dataSetBufferLength, false);
else
{
else {
GooseParseError parseError = parseAllData(dataSetBufferAddress, dataSetBufferLength, matchingSubscriber->dataSetValues);
if (parseError != GOOSE_PARSE_ERROR_NO_ERROR) {
@ -886,8 +876,7 @@ parseGoosePayload(GooseReceiver self, uint8_t* buffer, int apduLength)
matchingSubscriber->parseError = parseError;
}
if (matchingSubscriber->stNum == stNum)
{
if (matchingSubscriber->stNum == stNum) {
if (matchingSubscriber->sqNum >= sqNum) {
isValid = false;
}
@ -931,18 +920,13 @@ parseGooseMessage(GooseReceiver self, uint8_t* buffer, int numbytes)
uint8_t priority = 0;
uint16_t vlanId = 0;
bool vlanSet = false;
/* check for VLAN tag */
if ((buffer[bufPos] == 0x81) && (buffer[bufPos + 1] == 0x00))
{
if ((buffer[bufPos] == 0x81) && (buffer[bufPos + 1] == 0x00)) {
priority = buffer[bufPos + 2] & 0xF8 >> 5;
vlanId = ((buffer[bufPos + 2] & 0x07) << 8) + buffer[bufPos + 3];
vlanSet = true;
bufPos += 4; /* skip VLAN tag */
headerLength += 4;
if (numbytes < (22 + 4))
return;
}
/* check for GOOSE Ethertype */
@ -972,22 +956,13 @@ parseGooseMessage(GooseReceiver self, uint8_t* buffer, int numbytes)
int apduLength = length - 8;
if (apduLength < 0)
{
if (DEBUG_GOOSE_SUBSCRIBER)
printf("GOOSE_SUBSCRIBER: Invalid length field\n");
return;
}
if (numbytes < length + headerLength)
{
if (numbytes < length + headerLength) {
if (DEBUG_GOOSE_SUBSCRIBER)
printf("GOOSE_SUBSCRIBER: Invalid PDU size\n");
return;
}
if (DEBUG_GOOSE_SUBSCRIBER)
{
if (DEBUG_GOOSE_SUBSCRIBER) {
printf("GOOSE_SUBSCRIBER: GOOSE message:\nGOOSE_SUBSCRIBER: ----------------\n");
printf("GOOSE_SUBSCRIBER: DST-MAC: %02x:%02x:%02x:%02x:%02X:%02X\n",
dstMac[0], dstMac[1], dstMac[2], dstMac[3], dstMac[4], dstMac[5]);
@ -999,8 +974,7 @@ parseGooseMessage(GooseReceiver self, uint8_t* buffer, int numbytes)
/* check if there is an interested subscriber */
LinkedList element = LinkedList_getNext(self->subscriberList);
while (element)
{
while (element != NULL) {
GooseSubscriber subscriber = (GooseSubscriber) LinkedList_getData(element);
if (subscriber->isObserver)
@ -1016,8 +990,7 @@ parseGooseMessage(GooseReceiver self, uint8_t* buffer, int numbytes)
}
if (((subscriber->appId == -1) || (subscriber->appId == appId)) &&
(!subscriber->dstMacSet || (memcmp(subscriber->dstMac, dstMac,6) == 0)))
{
(!subscriber->dstMacSet || (memcmp(subscriber->dstMac, dstMac,6) == 0))) {
subscriberFound = true;
break;
}
@ -1041,12 +1014,9 @@ gooseReceiverLoop(void *threadParameter)
EthernetHandleSet handleSet = EthernetHandleSet_new();
EthernetHandleSet_addSocket(handleSet, self->ethSocket);
bool running = true;
if (self->running) {
if (running)
{
while (running)
{
while (self->running) {
switch (EthernetHandleSet_waitReady(handleSet, 100))
{
case -1:
@ -1060,8 +1030,6 @@ gooseReceiverLoop(void *threadParameter)
}
if (self->stop)
break;
running = self->running;
}
GooseReceiver_stopThreadless(self);
@ -1078,8 +1046,7 @@ void
GooseReceiver_start(GooseReceiver self)
{
#if (CONFIG_MMS_THREADLESS_STACK == 0)
if (GooseReceiver_startThreadless(self))
{
if (GooseReceiver_startThreadless(self)) {
self->thread = Thread_create((ThreadExecutionFunction) gooseReceiverLoop, (void*) self, false);
if (self->thread != NULL) {

@ -3,7 +3,7 @@
*
* Client implementation for IEC 61850 reporting.
*
* Copyright 2013-2024 Michael Zillgith
* Copyright 2013-2022 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -283,27 +283,14 @@ lookupReportHandler(IedConnection self, const char* rcbReference)
return NULL;
}
static void
uninstallReportHandler(IedConnection self, const char* rcbReference)
{
ClientReport report = lookupReportHandler(self, rcbReference);
if (report != NULL) {
LinkedList_remove(self->enabledReports, report);
ClientReport_destroy(report);
}
}
void
IedConnection_installReportHandler(IedConnection self, const char* rcbReference, const char* rptId, ReportCallbackFunction handler,
void* handlerParameter)
{
Semaphore_wait(self->reportHandlerMutex);
ClientReport report = lookupReportHandler(self, rcbReference);
if (report != NULL) {
uninstallReportHandler(self, rcbReference);
IedConnection_uninstallReportHandler(self, rcbReference);
if (DEBUG_IED_CLIENT)
printf("DEBUG_IED_CLIENT: Removed existing report callback handler for %s\n", rcbReference);
@ -319,8 +306,8 @@ IedConnection_installReportHandler(IedConnection self, const char* rcbReference,
else
report->rptId = NULL;
Semaphore_wait(self->reportHandlerMutex);
LinkedList_add(self->enabledReports, report);
Semaphore_post(self->reportHandlerMutex);
if (DEBUG_IED_CLIENT)
@ -332,7 +319,12 @@ IedConnection_uninstallReportHandler(IedConnection self, const char* rcbReferenc
{
Semaphore_wait(self->reportHandlerMutex);
uninstallReportHandler(self, rcbReference);
ClientReport report = lookupReportHandler(self, rcbReference);
if (report != NULL) {
LinkedList_remove(self->enabledReports, report);
ClientReport_destroy(report);
}
Semaphore_post(self->reportHandlerMutex);
}
@ -375,8 +367,6 @@ IedConnection_triggerGIReport(IedConnection self, IedClientError* error, const c
void
iedConnection_handleReport(IedConnection self, MmsValue* value)
{
Semaphore_wait(self->reportHandlerMutex);
MmsValue* rptIdValue = MmsValue_getElement(value, 0);
if ((rptIdValue == NULL) || (MmsValue_getType(rptIdValue) != MMS_VISIBLE_STRING)) {
@ -780,13 +770,14 @@ iedConnection_handleReport(IedConnection self, MmsValue* value)
}
}
Semaphore_wait(self->reportHandlerMutex);
if (matchingReport->callback != NULL)
matchingReport->callback(matchingReport->callbackParameter, matchingReport);
exit_function:
Semaphore_post(self->reportHandlerMutex);
exit_function:
return;
}

@ -33,6 +33,7 @@
#define DEFAULT_CONNECTION_TIMEOUT 10000
#define DATA_SET_MAX_NAME_LENGTH 64 /* is 32 according to standard! */
#define OUTSTANDING_CALLS 12
typedef struct sICLogicalDevice
{
@ -173,10 +174,8 @@ iedConnection_allocateOutstandingCall(IedConnection self)
int i = 0;
for (i = 0; i < self->maxOutstandingCalled; i++)
{
if (self->outstandingCalls[i].used == false)
{
for (i = 0; i < OUTSTANDING_CALLS; i++) {
if (self->outstandingCalls[i].used == false) {
self->outstandingCalls[i].used = true;
call = &(self->outstandingCalls[i]);
break;
@ -207,10 +206,8 @@ iedConnection_lookupOutstandingCall(IedConnection self, uint32_t invokeId)
int i = 0;
for (i = 0; i < self->maxOutstandingCalled; i++)
{
if ((self->outstandingCalls[i].used) && (self->outstandingCalls[i].invokeId == invokeId))
{
for (i = 0; i < OUTSTANDING_CALLS; i++) {
if ((self->outstandingCalls[i].used) && (self->outstandingCalls[i].invokeId == invokeId)) {
call = &(self->outstandingCalls[i]);
break;
}
@ -618,8 +615,7 @@ createNewConnectionObject(TLSConfiguration tlsConfig, bool useThreads)
self->reportHandlerMutex = Semaphore_create(1);
self->outstandingCallsLock = Semaphore_create(1);
self->maxOutstandingCalled = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
self->outstandingCalls = (IedConnectionOutstandingCall) GLOBAL_CALLOC(CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED, sizeof(struct sIedConnectionOutstandingCall));
self->outstandingCalls = (IedConnectionOutstandingCall) GLOBAL_CALLOC(OUTSTANDING_CALLS, sizeof(struct sIedConnectionOutstandingCall));
self->connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
@ -664,29 +660,6 @@ IedConnection_setLocalAddress(IedConnection self, const char* localIpAddress, in
IsoConnectionParameters_setLocalTcpParameters(isoP, localIpAddress, localPort);
}
void
IedConnection_setMaxOutstandingCalls(IedConnection self, int calling, int called)
{
if (calling < 1)
calling = 1;
if (called < 1)
called = 1;
if (self->outstandingCalls)
{
GLOBAL_FREEMEM(self->outstandingCalls);
}
self->maxOutstandingCalled = called;
self->outstandingCalls = (IedConnectionOutstandingCall)GLOBAL_CALLOC(called, sizeof(struct sIedConnectionOutstandingCall));
if (self->connection)
{
MmsConnnection_setMaxOutstandingCalls(self->connection, calling, called);
}
}
void
IedConnection_setConnectTimeout(IedConnection self, uint32_t timeoutInMs)
{
@ -696,8 +669,7 @@ IedConnection_setConnectTimeout(IedConnection self, uint32_t timeoutInMs)
void
IedConnection_setRequestTimeout(IedConnection self, uint32_t timeoutInMs)
{
if (self->connection)
{
if (self->connection) {
MmsConnection_setRequestTimeout(self->connection, timeoutInMs);
}
}
@ -3731,29 +3703,26 @@ getDataSetHandlerInternal(uint32_t invokeId, void* parameter, MmsError err, MmsV
IedConnectionOutstandingCall call = iedConnection_lookupOutstandingCall(self, invokeId);
if (call)
{
if (call) {
IedConnection_ReadDataSetHandler handler = (IedConnection_ReadDataSetHandler) call->callback;
ClientDataSet dataSet = (ClientDataSet) call->specificParameter;
char* dataSetReference = (char*) call->specificParameter2.pointer;
if (value)
{
if (value != NULL) {
if (dataSet == NULL) {
dataSet = ClientDataSet_create(dataSetReference);
ClientDataSet_setDataSetValues(dataSet, MmsValue_clone(value));
ClientDataSet_setDataSetValues(dataSet, value);
GLOBAL_FREEMEM(dataSetReference);
}
else {
MmsValue* dataSetValues = ClientDataSet_getValues(dataSet);
MmsValue_update(dataSetValues, value);
}
MmsValue_delete(value);
}
if (dataSetReference)
GLOBAL_FREEMEM(dataSetReference);
}
handler(invokeId, call->callbackParameter, iedConnection_mapMmsErrorToIedError(err), dataSet);

@ -1,7 +1,7 @@
/*
* iec61850_client.h
*
* Copyright 2013-2023 Michael Zillgith
* Copyright 2013-2021 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -255,16 +255,6 @@ IedConnection_setLocalAddress(IedConnection self, const char* localIpAddress, in
LIB61850_API void
IedConnection_setConnectTimeout(IedConnection self, uint32_t timeoutInMs);
/**
* \brief Set the maximum number outstanding calls allowed for this connection
*
* \param self the connection object
* \param calling the maximum outstanding calls allowed by the caller (client)
* \param called the maximum outstanding calls allowed by the called endpoint (server)
*/
LIB61850_API void
IedConnection_setMaxOutstandingCalls(IedConnection self, int calling, int called);
/**
* \brief set the request timeout in ms
*
@ -1266,11 +1256,9 @@ typedef void (*ReportCallbackFunction) (void* parameter, ClientReport report);
* Otherwise the internal data structures storing the received data set values will not be updated
* correctly.
*
* \note Replacing a report handler you only have to call this function. There is no separate call to
* When replacing a report handler you only have to call this function. There is no separate call to
* IedConnection_uninstallReportHandler() required.
*
* \note Do not call this function inside of the ReportCallbackFunction. Doing so will cause a deadlock.
*
* \param self the connection object
* \param rcbReference object reference of the report control block
* \param rptId a string that identifies the report. If the rptId is not available then the
@ -1285,8 +1273,6 @@ IedConnection_installReportHandler(IedConnection self, const char* rcbReference,
/**
* \brief uninstall a report handler function for the specified report control block (RCB)
*
* \note Do not call this function inside of the ReportCallbackFunction. Doing so will cause a deadlock.
*
* \param self the connection object
* \param rcbReference object reference of the report control block
*/

@ -69,7 +69,6 @@ struct sIedConnection
Semaphore outstandingCallsLock;
IedConnectionOutstandingCall outstandingCalls;
int maxOutstandingCalled;
IedConnectionClosedHandler connectionCloseHandler;
void* connectionClosedParameter;

@ -1,7 +1,7 @@
/*
* mms_mapping.c
*
* Copyright 2013-2024 Michael Zillgith
* Copyright 2013-2022 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -1309,8 +1309,8 @@ checkForServiceTrackingVariables(MmsMapping* self, LogicalNode* logicalNode)
{
ModelNode* modelNode = logicalNode->firstChild;
while (modelNode)
{
while (modelNode) {
if (!strcmp(modelNode->name, "SpcTrk") || !strcmp(modelNode->name, "DpcTrk") ||
!strcmp(modelNode->name, "IncTrk") || !strcmp(modelNode->name, "EncTrk1") ||
!strcmp(modelNode->name, "ApcFTrk") || !strcmp(modelNode->name, "ApcIntTrk") ||
@ -2644,10 +2644,6 @@ mmsWriteHandler(void* parameter, MmsDomain* domain,
if (nextSep != NULL) {
nextSep = strchr(nextSep + 1, '$');
if (nextSep == NULL) {
return DATA_ACCESS_ERROR_OBJECT_ACCESS_UNSUPPORTED;
}
char* nameId = nextSep + 1;
if (strcmp(nameId, "ActSG") == 0) {

@ -160,16 +160,6 @@ MmsConnection_setFilestoreBasepath(MmsConnection self, const char* basepath);
LIB61850_API void
MmsConnection_setRequestTimeout(MmsConnection self, uint32_t timeoutInMs);
/**
* \brief Set the maximum number outstanding calls allowed for this connection
*
* \param self MmsConnection instance to operate on
* \param calling the maximum outstanding calls allowed by the caller (client)
* \param called the maximum outstanding calls allowed by the called endpoint (server)
*/
LIB61850_API void
MmsConnnection_setMaxOutstandingCalls(MmsConnection self, int calling, int called);
/**
* \brief Get the request timeout in ms for this connection
*

@ -95,8 +95,6 @@ struct sMmsConnection {
Semaphore outstandingCallsLock;
MmsOutstandingCall outstandingCalls;
int maxOutstandingCalled;
int maxOutstandingCalling;
uint32_t requestTimeout;
uint32_t connectTimeout;

@ -1,7 +1,7 @@
/*
* mms_common_internal.h
*
* Copyright 2013-2024 Michael Zillgith
* Copyright 2013-2019 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -30,10 +30,10 @@
#include "byte_buffer.h"
#include "mms_server.h"
#define DEFAULT_MAX_SERV_OUTSTANDING_CALLING 5
#define DEFAULT_MAX_SERV_OUTSTANDING_CALLED 5
#define DEFAULT_DATA_STRUCTURE_NESTING_LEVEL 10
typedef struct sMmsOutstandingCall* MmsOutstandingCall;
#if (MMS_FILE_SERVICE == 1)
#ifndef CONFIG_MMS_MAX_NUMBER_OF_OPEN_FILES_PER_CONNECTION
@ -42,6 +42,8 @@ typedef struct sMmsOutstandingCall* MmsOutstandingCall;
#include "hal_filesystem.h"
typedef struct sMmsOutstandingCall* MmsOutstandingCall;
typedef struct {
int32_t frsmId;
uint32_t readPosition;

@ -126,10 +126,7 @@ parseUserInformation(AcseConnection* self, uint8_t* buffer, int bufPos, int maxB
bufPos = BerDecoder_decodeLength(buffer, &len, bufPos, maxBufPos);
if (len == 0)
continue;
if ((bufPos < 0) || (bufPos + len > maxBufPos)) {
if (bufPos < 0) {
*userInfoValid = false;
return -1;
}
@ -189,23 +186,8 @@ parseAarePdu(AcseConnection* self, uint8_t* buffer, int bufPos, int maxBufPos)
int len;
bufPos = BerDecoder_decodeLength(buffer, &len, bufPos, maxBufPos);
if (bufPos < 0)
{
if (DEBUG_ACSE)
printf("ACSE: Invalid PDU!\n");
return ACSE_ERROR;
}
if (len == 0)
continue;
if (bufPos + len > maxBufPos)
{
if (DEBUG_ACSE)
printf("ACSE: Invalid PDU!\n");
return ACSE_ERROR;
}
switch (tag)
{
@ -287,18 +269,7 @@ parseAarqPdu(AcseConnection* self, uint8_t* buffer, int bufPos, int maxBufPos)
bufPos = BerDecoder_decodeLength(buffer, &len, bufPos, maxBufPos);
if (bufPos < 0)
{
if (DEBUG_ACSE)
printf("ACSE: Invalid PDU!\n");
return ACSE_ASSOCIATE_FAILED;
}
if (len == 0)
continue;
if (bufPos + len > maxBufPos)
{
if (bufPos < 0) {
if (DEBUG_ACSE)
printf("ACSE: Invalid PDU!\n");
return ACSE_ASSOCIATE_FAILED;
@ -449,14 +420,6 @@ AcseConnection_parseMessage(AcseConnection* self, ByteBuffer* message)
{
AcseIndication indication = ACSE_ERROR;
if (message == NULL || message->size < 1)
{
if (DEBUG_ACSE)
printf("ACSE: invalid message - no payload\n");
return ACSE_ERROR;
}
uint8_t* buffer = message->buffer;
int messageSize = message->size;

@ -63,6 +63,7 @@ AcseAuthenticationParameter_setAuthMechanism(AcseAuthenticationParameter self, A
self->mechanism = mechanism;
}
IsoConnectionParameters
IsoConnectionParameters_create()
{
@ -74,13 +75,7 @@ IsoConnectionParameters_create()
void
IsoConnectionParameters_destroy(IsoConnectionParameters self)
{
if (self)
{
if (self->localIpAddress)
GLOBAL_FREEMEM((void*)(self->localIpAddress));
GLOBAL_FREEMEM(self);
}
}
void
@ -94,6 +89,7 @@ IsoConnectionParameters_setTlsConfiguration(IsoConnectionParameters self, TLSCon
#endif
}
void
IsoConnectionParameters_setAcseAuthenticationParameter(IsoConnectionParameters self,
AcseAuthenticationParameter acseAuthParameter)

@ -37,6 +37,7 @@
#define CONFIG_MMS_CONNECTION_DEFAULT_TIMEOUT 5000
#define CONFIG_MMS_CONNECTION_DEFAULT_CONNECT_TIMEOUT 10000
#define OUTSTANDING_CALLS 10
static void
setConnectionState(MmsConnection self, MmsConnectionState newState)
@ -254,12 +255,9 @@ checkForOutstandingCall(MmsConnection self, uint32_t invokeId)
Semaphore_wait(self->outstandingCallsLock);
for (i = 0; i < self->maxOutstandingCalled; i++)
{
if (self->outstandingCalls[i].isUsed)
{
if (self->outstandingCalls[i].invokeId == invokeId)
{
for (i = 0; i < OUTSTANDING_CALLS; i++) {
if (self->outstandingCalls[i].isUsed) {
if (self->outstandingCalls[i].invokeId == invokeId) {
Semaphore_post(self->outstandingCallsLock);
return &(self->outstandingCalls[i]);
}
@ -278,10 +276,8 @@ addToOutstandingCalls(MmsConnection self, uint32_t invokeId, eMmsOutstandingCall
Semaphore_wait(self->outstandingCallsLock);
for (i = 0; i < self->maxOutstandingCalled; i++)
{
if (self->outstandingCalls[i].isUsed == false)
{
for (i = 0; i < OUTSTANDING_CALLS; i++) {
if (self->outstandingCalls[i].isUsed == false) {
self->outstandingCalls[i].isUsed = true;
self->outstandingCalls[i].invokeId = invokeId;
self->outstandingCalls[i].timeout = Hal_getTimeInMs() + self->requestTimeout;
@ -306,12 +302,9 @@ removeFromOutstandingCalls(MmsConnection self, uint32_t invokeId)
Semaphore_wait(self->outstandingCallsLock);
for (i = 0; i < self->maxOutstandingCalled; i++)
{
if (self->outstandingCalls[i].isUsed)
{
if (self->outstandingCalls[i].invokeId == invokeId)
{
for (i = 0; i < OUTSTANDING_CALLS; i++) {
if (self->outstandingCalls[i].isUsed) {
if (self->outstandingCalls[i].invokeId == invokeId) {
self->outstandingCalls[i].isUsed = false;
break;
}
@ -328,12 +321,11 @@ mmsClient_getMatchingObtainFileRequest(MmsConnection self, const char* filename)
Semaphore_wait(self->outstandingCallsLock);
for (i = 0; i < self->maxOutstandingCalled; i++)
{
if (self->outstandingCalls[i].isUsed)
{
if (self->outstandingCalls[i].type == MMS_CALL_TYPE_OBTAIN_FILE)
{
for (i = 0; i < OUTSTANDING_CALLS; i++) {
if (self->outstandingCalls[i].isUsed) {
if (self->outstandingCalls[i].type == MMS_CALL_TYPE_OBTAIN_FILE) {
char* storedFilename = (char*) self->outstandingCalls[i].internalParameter.ptr;
if (storedFilename) {
@ -1016,8 +1008,8 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload)
int i = 0;
for (i = 0; i < self->maxOutstandingCalled; i++)
{
for (i = 0; i < OUTSTANDING_CALLS; i++) {
Semaphore_wait(self->outstandingCallsLock);
if (self->outstandingCalls[i].isUsed) {
@ -1065,8 +1057,8 @@ mmsIsoCallback(IsoIndication indication, void* parameter, ByteBuffer* payload)
{
int i;
for (i = 0; i < self->maxOutstandingCalled; i++)
{
for (i = 0; i < OUTSTANDING_CALLS; i++) {
Semaphore_wait(self->outstandingCallsLock);
if (self->outstandingCalls[i].isUsed) {
@ -1501,9 +1493,7 @@ MmsConnection_createInternal(TLSConfiguration tlsConfig, bool createThread)
self->concludeHandlerParameter = NULL;
self->concludeTimeout = 0;
self->maxOutstandingCalling = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
self->maxOutstandingCalled = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
self->outstandingCalls = (MmsOutstandingCall) GLOBAL_CALLOC(CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED, sizeof(struct sMmsOutstandingCall));
self->outstandingCalls = (MmsOutstandingCall) GLOBAL_CALLOC(OUTSTANDING_CALLS, sizeof(struct sMmsOutstandingCall));
self->isoParameters = IsoConnectionParameters_create();
@ -1662,25 +1652,6 @@ MmsConnection_setRequestTimeout(MmsConnection self, uint32_t timeoutInMs)
self->requestTimeout = timeoutInMs;
}
void
MmsConnnection_setMaxOutstandingCalls(MmsConnection self, int calling, int called)
{
if (calling < 1)
calling = 1;
if (called < 1)
called = 1;
if (self->outstandingCalls)
{
GLOBAL_FREEMEM(self->outstandingCalls);
}
self->maxOutstandingCalling = calling;
self->maxOutstandingCalled = called;
self->outstandingCalls = (MmsOutstandingCall)GLOBAL_CALLOC(called, sizeof(struct sMmsOutstandingCall));
}
uint32_t
MmsConnection_getRequestTimeout(MmsConnection self)
{

@ -487,13 +487,8 @@ parseFileAttributes(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t* fileSi
break;
case 0x81: /* lastModified */
{
if (lastModified != NULL)
{
if (lastModified != NULL) {
char gtString[40];
if (length > sizeof(gtString) - 1)
return false; /* lastModified string too long */
memcpy(gtString, buffer + bufPos, length);
gtString[length] = 0;
*lastModified = Conversions_generalizedTimeToMsTime(gtString);
@ -520,14 +515,12 @@ parseDirectoryEntry(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t invokeI
uint32_t fileSize = 0;
uint64_t lastModified = 0;
while (bufPos < maxBufPos)
{
while (bufPos < maxBufPos) {
uint8_t tag = buffer[bufPos++];
int length;
bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos);
if (bufPos < 0)
{
if (bufPos < 0) {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: invalid length field\n");
return false;
@ -541,20 +534,12 @@ parseDirectoryEntry(uint8_t* buffer, int bufPos, int maxBufPos, uint32_t invokeI
tag = buffer[bufPos++];
bufPos = BerDecoder_decodeLength(buffer, &length, bufPos, maxBufPos);
if (bufPos < 0)
{
if (bufPos < 0) {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: invalid length field\n");
return false;
}
if (length > (sizeof(fileNameMemory) - 1))
{
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: filename too long\n");
return false;
}
memcpy(filename, buffer + bufPos, length);
filename[length] = 0;

@ -39,16 +39,18 @@ static uint8_t servicesSupported[] = { 0xee, 0x1c, 0x00, 0x00, 0x04, 0x08, 0x00,
void
mmsClient_createInitiateRequest(MmsConnection self, ByteBuffer* message)
{
int maxServerOutstandingCalling = DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
int maxServerOutstandingCalled = DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
int dataStructureNestingLevel = DEFAULT_DATA_STRUCTURE_NESTING_LEVEL;
uint32_t localDetailSize =
BerEncoder_UInt32determineEncodedSize(self->parameters.maxPduSize);
uint32_t proposedMaxServerOutstandingCallingSize =
BerEncoder_UInt32determineEncodedSize(self->maxOutstandingCalling);
BerEncoder_UInt32determineEncodedSize(maxServerOutstandingCalling);
uint32_t proposedMaxServerOutstandingCalledSize =
BerEncoder_UInt32determineEncodedSize(self->maxOutstandingCalled);
BerEncoder_UInt32determineEncodedSize(maxServerOutstandingCalled);
uint32_t dataStructureNestingLevelSize =
BerEncoder_UInt32determineEncodedSize(dataStructureNestingLevel);
@ -74,11 +76,11 @@ mmsClient_createInitiateRequest(MmsConnection self, ByteBuffer* message)
/* proposedMaxServerOutstandingCalling */
bufPos = BerEncoder_encodeTL(0x81, proposedMaxServerOutstandingCallingSize, buffer, bufPos);
bufPos = BerEncoder_encodeUInt32(self->maxOutstandingCalling, buffer, bufPos);
bufPos = BerEncoder_encodeUInt32(maxServerOutstandingCalling, buffer, bufPos);
/* proposedMaxServerOutstandingCalled */
bufPos = BerEncoder_encodeTL(0x82, proposedMaxServerOutstandingCalledSize, buffer, bufPos);
bufPos = BerEncoder_encodeUInt32(self->maxOutstandingCalled, buffer, bufPos);
bufPos = BerEncoder_encodeUInt32(maxServerOutstandingCalled, buffer, bufPos);
/* proposedDataStructureNestingLevel */
bufPos = BerEncoder_encodeTL(0x83, dataStructureNestingLevelSize, buffer, bufPos);
@ -167,8 +169,8 @@ mmsClient_parseInitiateResponse(MmsConnection self, ByteBuffer* response)
{
self->parameters.maxPduSize = CONFIG_MMS_MAXIMUM_PDU_SIZE;
self->parameters.dataStructureNestingLevel = DEFAULT_DATA_STRUCTURE_NESTING_LEVEL;
self->parameters.maxServOutstandingCalled = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
self->parameters.maxServOutstandingCalling = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
self->parameters.maxServOutstandingCalled = DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
self->parameters.maxServOutstandingCalling = DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
int bufPos = 1; /* ignore tag - already checked */
@ -201,16 +203,16 @@ mmsClient_parseInitiateResponse(MmsConnection self, ByteBuffer* response)
case 0x81: /* proposed-max-serv-outstanding-calling */
self->parameters.maxServOutstandingCalling = BerDecoder_decodeUint32(buffer, length, bufPos);
if (self->parameters.maxServOutstandingCalling > CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING)
self->parameters.maxServOutstandingCalling = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
if (self->parameters.maxServOutstandingCalling > DEFAULT_MAX_SERV_OUTSTANDING_CALLING)
self->parameters.maxServOutstandingCalling = DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
break;
case 0x82: /* proposed-max-serv-outstanding-called */
self->parameters.maxServOutstandingCalled = BerDecoder_decodeUint32(buffer, length, bufPos);
if (self->parameters.maxServOutstandingCalled > CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED)
self->parameters.maxServOutstandingCalled = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
if (self->parameters.maxServOutstandingCalled > DEFAULT_MAX_SERV_OUTSTANDING_CALLED)
self->parameters.maxServOutstandingCalled = DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
break;
case 0x83: /* proposed-data-structure-nesting-level */

@ -330,9 +330,9 @@ parseInitiateRequestPdu(MmsServerConnection self, uint8_t* buffer, int bufPos, i
self->dataStructureNestingLevel =
DEFAULT_DATA_STRUCTURE_NESTING_LEVEL;
self->maxServOutstandingCalled = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
self->maxServOutstandingCalled = DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
self->maxServOutstandingCalling = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
self->maxServOutstandingCalling = DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
self->negotiatedParameterCBC[0] = 0;
self->negotiatedParameterCBC[1] = 0;
@ -367,16 +367,16 @@ parseInitiateRequestPdu(MmsServerConnection self, uint8_t* buffer, int bufPos, i
case 0x81: /* proposed-max-serv-outstanding-calling */
self->maxServOutstandingCalling = BerDecoder_decodeUint32(buffer, length, bufPos);
if (self->maxServOutstandingCalling > CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING)
self->maxServOutstandingCalling = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
if (self->maxServOutstandingCalling > DEFAULT_MAX_SERV_OUTSTANDING_CALLING)
self->maxServOutstandingCalling = DEFAULT_MAX_SERV_OUTSTANDING_CALLING;
break;
case 0x82: /* proposed-max-serv-outstanding-called */
self->maxServOutstandingCalled = BerDecoder_decodeUint32(buffer, length, bufPos);
if (self->maxServOutstandingCalled > CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED)
self->maxServOutstandingCalled = CONFIG_DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
if (self->maxServOutstandingCalled > DEFAULT_MAX_SERV_OUTSTANDING_CALLED)
self->maxServOutstandingCalled = DEFAULT_MAX_SERV_OUTSTANDING_CALLED;
break;
case 0x83: /* proposed-data-structure-nesting-level */

@ -296,12 +296,9 @@ mmsServer_handleGetVariableAccessAttributesRequest(
rval = ber_decode(NULL, &asn_DEF_GetVariableAccessAttributesRequest,
(void**) &request, buffer + bufPos, maxBufPos - bufPos);
if (rval.code == RC_OK)
{
if (request->present == GetVariableAccessAttributesRequest_PR_name)
{
if (request->choice.name.present == ObjectName_PR_domainspecific)
{
if (rval.code == RC_OK) {
if (request->present == GetVariableAccessAttributesRequest_PR_name) {
if (request->choice.name.present == ObjectName_PR_domainspecific) {
Identifier_t domainId = request->choice.name.choice.domainspecific.domainId;
Identifier_t nameId = request->choice.name.choice.domainspecific.itemId;
@ -346,13 +343,6 @@ mmsServer_handleGetVariableAccessAttributesRequest(
asn_DEF_GetVariableAccessAttributesRequest.free_struct(&asn_DEF_GetVariableAccessAttributesRequest, request, 0);
if (ByteBuffer_getSize(response) > connection->maxPduSize)
{
ByteBuffer_setSize(response, 0);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER);
}
return retVal;
}

@ -141,12 +141,6 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
goto exit_function;
}
if (request->listOfVariableListName == NULL)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_function;
}
long scopeOfDelete = DeleteNamedVariableListRequest__scopeOfDelete_specific;
if (request->scopeOfDelete)
@ -681,8 +675,7 @@ createGetNamedVariableListAttributesResponse(int invokeId, ByteBuffer* response,
LinkedList variable = LinkedList_getNext(variables);
int i;
for (i = 0; i < variableCount; i++)
{
for (i = 0; i < variableCount; i++) {
MmsNamedVariableListEntry variableEntry = (MmsNamedVariableListEntry) variable->data;
varListResponse->listOfVariable.list.array[i] = (struct GetNamedVariableListAttributesResponse__listOfVariable__Member*)
@ -747,8 +740,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
goto exit_function;
}
if (request->present == ObjectName_PR_domainspecific)
{
if (request->present == ObjectName_PR_domainspecific) {
char domainName[65];
char itemName[65];
@ -768,15 +761,14 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
MmsDomain* domain = MmsDevice_getDomain(mmsDevice, domainName);
if (domain != NULL)
{
if (domain != NULL) {
MmsNamedVariableList variableList =
MmsDomain_getNamedVariableList(domain, itemName);
if (variableList != NULL)
{
if (createGetNamedVariableListAttributesResponse(invokeId, response, variableList) == false)
{
if (variableList != NULL) {
if (createGetNamedVariableListAttributesResponse(invokeId, response, variableList) == false) {
/* encoding failed - probably because buffer size is too small for message */
ByteBuffer_setSize(response, 0);
@ -791,8 +783,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
}
#if (MMS_DYNAMIC_DATA_SETS == 1)
else if (request->present == ObjectName_PR_aaspecific)
{
else if (request->present == ObjectName_PR_aaspecific) {
char listName[65];
if (request->choice.aaspecific.size > 64) {
@ -811,8 +803,7 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
}
#endif /* (MMS_DYNAMIC_DATA_SETS == 1) */
else if (request->present == ObjectName_PR_vmdspecific)
{
else if (request->present == ObjectName_PR_vmdspecific) {
char listName[65];
if (request->choice.vmdspecific.size > 64) {
@ -836,13 +827,6 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED);
}
if (ByteBuffer_getSize(response) > connection->maxPduSize)
{
ByteBuffer_setSize(response, 0);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER);
}
exit_function:
asn_DEF_GetVariableAccessAttributesRequest.free_struct(&asn_DEF_GetNamedVariableListAttributesRequest,

@ -528,7 +528,7 @@ encodeReadResponse(MmsServerConnection connection,
printf("MMS read: message to large! send error PDU!\n");
mmsMsg_createServiceErrorPdu(invokeId, response,
MMS_ERROR_RESOURCE_OTHER);
MMS_ERROR_SERVICE_OTHER);
goto exit_function;
}
@ -933,8 +933,7 @@ mmsServer_handleReadRequest(
goto exit_function;
}
if (request->variableAccessSpecification.present == VariableAccessSpecification_PR_listOfVariable)
{
if (request->variableAccessSpecification.present == VariableAccessSpecification_PR_listOfVariable) {
MmsServer_lockModel(connection->server);
handleReadListOfVariablesRequest(connection, request, invokeId, response);
@ -942,8 +941,7 @@ mmsServer_handleReadRequest(
MmsServer_unlockModel(connection->server);
}
#if (MMS_DATA_SET_SERVICE == 1)
else if (request->variableAccessSpecification.present == VariableAccessSpecification_PR_variableListName)
{
else if (request->variableAccessSpecification.present == VariableAccessSpecification_PR_variableListName) {
MmsServer_lockModel(connection->server);
handleReadNamedVariableListRequest(connection, request, invokeId, response);
@ -955,13 +953,6 @@ mmsServer_handleReadRequest(
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED);
}
if (ByteBuffer_getSize(response) > connection->maxPduSize)
{
ByteBuffer_setSize(response, 0);
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_RESOURCE_OTHER);
}
exit_function:
asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
}

@ -4,7 +4,7 @@ mkdir build
find src/ -name "*.java" > listFile.tmp
javac -target 1.8 -source 1.8 -d build @listFile.tmp
javac -target 1.6 -source 1.6 -d build @listFile.tmp
jar cfm genconfig.jar manifest-dynamic.mf -C build/ com/

@ -188,35 +188,19 @@ public class DataModelValue {
case TIMESTAMP:
case ENTRY_TIME:
{
try {
String modValueString = value.replace(',', '.');
try {
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-d'T'HH:mm:ss.SSS");
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = parser.parse(modValueString);
this.value = new Long(date.toInstant().toEpochMilli());
break;
}
catch (java.text.ParseException e) {};
try {
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-d'T'HH:mm:ss");
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = parser.parse(modValueString);
this.value = new Long(date.toInstant().toEpochMilli());
break;
}
catch (java.text.ParseException e) {};
catch (java.text.ParseException e) {
this.value = null;
System.out.println("Warning: Val element does not contain a valid time stamp: " + value);
System.out.println("Warning: Val element does not contain a valid time stamp: " + e.getMessage());
}
break;

@ -543,11 +543,6 @@ public class DynamicModelGenerator {
case FLOAT64:
output.print("=" + value.getValue());
break;
case TIMESTAMP:
case ENTRY_TIME:
output.print("=" + value.getLongValue());
break;
default:
System.out.println("Unknown default value for " + dataAttribute.getName() + " type: " + dataAttribute.getType());
break;

Loading…
Cancel
Save