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. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v1
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # 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). # 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) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@ -68,4 +68,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - 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 */ /* enable to configure MmsServer at runtime */
#define CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME 1 #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! * 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 (MMS_JOURNAL_SERVICE != 1)
#if (CONFIG_IEC61850_LOG_SERVICE == 1) #if (CONFIG_IEC61850_LOG_SERVICE == 1)

@ -232,24 +232,10 @@
/* enable to configure MmsServer at runtime */ /* enable to configure MmsServer at runtime */
#define CONFIG_MMS_SERVER_CONFIG_SERVICES_AT_RUNTIME 1 #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! * 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 (MMS_JOURNAL_SERVICE != 1)
#if (CONFIG_IEC61850_LOG_SERVICE == 1) #if (CONFIG_IEC61850_LOG_SERVICE == 1)

@ -431,9 +431,6 @@ namespace IEC61850
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)] [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern UInt32 IedConnection_getRequestTimeout(IntPtr self); 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)] [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); 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> /// <summary>
/// Gets or sets the maximum size if a PDU (has to be set before calling connect!). /// Gets or sets the maximum size if a PDU (has to be set before calling connect!).
/// </summary> /// </summary>
@ -1188,9 +1175,6 @@ namespace IEC61850
private static List<MmsJournalEntry> WrapNativeLogQueryResult(IntPtr linkedList) private static List<MmsJournalEntry> WrapNativeLogQueryResult(IntPtr linkedList)
{ {
if (linkedList == IntPtr.Zero)
return null;
List<MmsJournalEntry> journalEntries = new List<MmsJournalEntry>(); List<MmsJournalEntry> journalEntries = new List<MmsJournalEntry>();
IntPtr element = LinkedList_getNext(linkedList); IntPtr element = LinkedList_getNext(linkedList);
@ -2254,28 +2238,23 @@ namespace IEC61850
GetDataSetDirectoryHandler handler = callbackInfo.Item1; GetDataSetDirectoryHandler handler = callbackInfo.Item1;
object handlerParameter = callbackInfo.Item2; object handlerParameter = callbackInfo.Item2;
IntPtr element = LinkedList_getNext(dataSetDirectory);
handle.Free(); handle.Free();
List<string> newList = null; List<string> newList = new List<string>();
if (dataSetDirectory != IntPtr.Zero) while (element != IntPtr.Zero)
{ {
newList = new List<string>(); string dataObject = Marshal.PtrToStringAnsi(LinkedList_getData(element));
IntPtr element = LinkedList_getNext(dataSetDirectory);
while (element != IntPtr.Zero)
{
string dataObject = Marshal.PtrToStringAnsi(LinkedList_getData(element));
newList.Add(dataObject);
element = LinkedList_getNext(element); newList.Add(dataObject);
}
LinkedList_destroy(dataSetDirectory); element = LinkedList_getNext(element);
} }
LinkedList_destroy(dataSetDirectory);
handler.Invoke(invokeId, handlerParameter, (IedClientError)err, newList, isDeletable); handler.Invoke(invokeId, handlerParameter, (IedClientError)err, newList, isDeletable);
} }
@ -2449,9 +2428,11 @@ namespace IEC61850
dataSet = new DataSet(nativeDataSet); dataSet = new DataSet(nativeDataSet);
} }
handler(invokeId, handlerParameter, clientError, dataSet); handler(invokeId, handlerParameter, clientError, dataSet);
} }
public delegate void ReadDataSetHandler(UInt32 invokeId,object parameter,IedClientError err,DataSet dataSet); public delegate void ReadDataSetHandler(UInt32 invokeId,object parameter,IedClientError err,DataSet dataSet);
/// <summary> /// <summary>
@ -2585,6 +2566,7 @@ namespace IEC61850
{ {
handler(invokeId, handlerParameter, clientError, null, moreFollows); handler(invokeId, handlerParameter, clientError, null, moreFollows);
} }
} }
/// <summary> /// <summary>
@ -2650,6 +2632,7 @@ namespace IEC61850
return GetLogicalDeviceDataSetsAsync(null, ldName, continueAfter, handler, parameter); return GetLogicalDeviceDataSetsAsync(null, ldName, continueAfter, handler, parameter);
} }
public UInt32 GetLogicalDeviceDataSetsAsync(List<string> result, string ldName, string continueAfter, GetNameListHandler handler, object parameter) public UInt32 GetLogicalDeviceDataSetsAsync(List<string> result, string ldName, string continueAfter, GetNameListHandler handler, object parameter)
{ {
int error; int error;

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

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

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

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

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

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

@ -1,7 +1,7 @@
/* /*
* iec61850_client.h * iec61850_client.h
* *
* Copyright 2013-2023 Michael Zillgith * Copyright 2013-2021 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -255,16 +255,6 @@ IedConnection_setLocalAddress(IedConnection self, const char* localIpAddress, in
LIB61850_API void LIB61850_API void
IedConnection_setConnectTimeout(IedConnection self, uint32_t timeoutInMs); 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 * \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 * Otherwise the internal data structures storing the received data set values will not be updated
* correctly. * 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. * 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 self the connection object
* \param rcbReference object reference of the report control block * \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 * \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) * \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 self the connection object
* \param rcbReference object reference of the report control block * \param rcbReference object reference of the report control block
*/ */

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

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

@ -160,16 +160,6 @@ MmsConnection_setFilestoreBasepath(MmsConnection self, const char* basepath);
LIB61850_API void LIB61850_API void
MmsConnection_setRequestTimeout(MmsConnection self, uint32_t timeoutInMs); 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 * \brief Get the request timeout in ms for this connection
* *

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

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

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

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

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

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

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

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

@ -296,12 +296,9 @@ mmsServer_handleGetVariableAccessAttributesRequest(
rval = ber_decode(NULL, &asn_DEF_GetVariableAccessAttributesRequest, rval = ber_decode(NULL, &asn_DEF_GetVariableAccessAttributesRequest,
(void**) &request, buffer + bufPos, maxBufPos - bufPos); (void**) &request, buffer + bufPos, maxBufPos - bufPos);
if (rval.code == RC_OK) if (rval.code == RC_OK) {
{ if (request->present == GetVariableAccessAttributesRequest_PR_name) {
if (request->present == GetVariableAccessAttributesRequest_PR_name) if (request->choice.name.present == ObjectName_PR_domainspecific) {
{
if (request->choice.name.present == ObjectName_PR_domainspecific)
{
Identifier_t domainId = request->choice.name.choice.domainspecific.domainId; Identifier_t domainId = request->choice.name.choice.domainspecific.domainId;
Identifier_t nameId = request->choice.name.choice.domainspecific.itemId; 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); 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; return retVal;
} }

@ -141,12 +141,6 @@ mmsServer_handleDeleteNamedVariableListRequest(MmsServerConnection connection,
goto exit_function; goto exit_function;
} }
if (request->listOfVariableListName == NULL)
{
mmsMsg_createMmsRejectPdu(&invokeId, MMS_ERROR_REJECT_INVALID_PDU, response);
goto exit_function;
}
long scopeOfDelete = DeleteNamedVariableListRequest__scopeOfDelete_specific; long scopeOfDelete = DeleteNamedVariableListRequest__scopeOfDelete_specific;
if (request->scopeOfDelete) if (request->scopeOfDelete)
@ -681,8 +675,7 @@ createGetNamedVariableListAttributesResponse(int invokeId, ByteBuffer* response,
LinkedList variable = LinkedList_getNext(variables); LinkedList variable = LinkedList_getNext(variables);
int i; int i;
for (i = 0; i < variableCount; i++) for (i = 0; i < variableCount; i++) {
{
MmsNamedVariableListEntry variableEntry = (MmsNamedVariableListEntry) variable->data; MmsNamedVariableListEntry variableEntry = (MmsNamedVariableListEntry) variable->data;
varListResponse->listOfVariable.list.array[i] = (struct GetNamedVariableListAttributesResponse__listOfVariable__Member*) varListResponse->listOfVariable.list.array[i] = (struct GetNamedVariableListAttributesResponse__listOfVariable__Member*)
@ -747,8 +740,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
goto exit_function; goto exit_function;
} }
if (request->present == ObjectName_PR_domainspecific) if (request->present == ObjectName_PR_domainspecific) {
{
char domainName[65]; char domainName[65];
char itemName[65]; char itemName[65];
@ -768,15 +761,14 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
MmsDomain* domain = MmsDevice_getDomain(mmsDevice, domainName); MmsDomain* domain = MmsDevice_getDomain(mmsDevice, domainName);
if (domain != NULL) if (domain != NULL) {
{
MmsNamedVariableList variableList = MmsNamedVariableList variableList =
MmsDomain_getNamedVariableList(domain, itemName); MmsDomain_getNamedVariableList(domain, itemName);
if (variableList != NULL) if (variableList != NULL) {
{
if (createGetNamedVariableListAttributesResponse(invokeId, response, variableList) == false) if (createGetNamedVariableListAttributesResponse(invokeId, response, variableList) == false) {
{
/* encoding failed - probably because buffer size is too small for message */ /* encoding failed - probably because buffer size is too small for message */
ByteBuffer_setSize(response, 0); ByteBuffer_setSize(response, 0);
@ -791,8 +783,8 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
} }
#if (MMS_DYNAMIC_DATA_SETS == 1) #if (MMS_DYNAMIC_DATA_SETS == 1)
else if (request->present == ObjectName_PR_aaspecific) else if (request->present == ObjectName_PR_aaspecific) {
{
char listName[65]; char listName[65];
if (request->choice.aaspecific.size > 64) { if (request->choice.aaspecific.size > 64) {
@ -811,8 +803,7 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT); mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_NON_EXISTENT);
} }
#endif /* (MMS_DYNAMIC_DATA_SETS == 1) */ #endif /* (MMS_DYNAMIC_DATA_SETS == 1) */
else if (request->present == ObjectName_PR_vmdspecific) else if (request->present == ObjectName_PR_vmdspecific) {
{
char listName[65]; char listName[65];
if (request->choice.vmdspecific.size > 64) { if (request->choice.vmdspecific.size > 64) {
@ -836,13 +827,6 @@ mmsServer_handleGetNamedVariableListAttributesRequest(
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); 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: exit_function:
asn_DEF_GetVariableAccessAttributesRequest.free_struct(&asn_DEF_GetNamedVariableListAttributesRequest, 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"); printf("MMS read: message to large! send error PDU!\n");
mmsMsg_createServiceErrorPdu(invokeId, response, mmsMsg_createServiceErrorPdu(invokeId, response,
MMS_ERROR_RESOURCE_OTHER); MMS_ERROR_SERVICE_OTHER);
goto exit_function; goto exit_function;
} }
@ -933,8 +933,7 @@ mmsServer_handleReadRequest(
goto exit_function; goto exit_function;
} }
if (request->variableAccessSpecification.present == VariableAccessSpecification_PR_listOfVariable) if (request->variableAccessSpecification.present == VariableAccessSpecification_PR_listOfVariable) {
{
MmsServer_lockModel(connection->server); MmsServer_lockModel(connection->server);
handleReadListOfVariablesRequest(connection, request, invokeId, response); handleReadListOfVariablesRequest(connection, request, invokeId, response);
@ -942,8 +941,7 @@ mmsServer_handleReadRequest(
MmsServer_unlockModel(connection->server); MmsServer_unlockModel(connection->server);
} }
#if (MMS_DATA_SET_SERVICE == 1) #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); MmsServer_lockModel(connection->server);
handleReadNamedVariableListRequest(connection, request, invokeId, response); handleReadNamedVariableListRequest(connection, request, invokeId, response);
@ -955,13 +953,6 @@ mmsServer_handleReadRequest(
mmsMsg_createServiceErrorPdu(invokeId, response, MMS_ERROR_ACCESS_OBJECT_ACCESS_UNSUPPORTED); 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: exit_function:
asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0); asn_DEF_MmsPdu.free_struct(&asn_DEF_MmsPdu, mmsPdu, 0);
} }

@ -4,7 +4,7 @@ mkdir build
find src/ -name "*.java" > listFile.tmp 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/ jar cfm genconfig.jar manifest-dynamic.mf -C build/ com/

@ -188,35 +188,19 @@ public class DataModelValue {
case TIMESTAMP: case TIMESTAMP:
case ENTRY_TIME: case ENTRY_TIME:
{ try {
String modValueString = value.replace(',', '.'); String modValueString = value.replace(',', '.');
try { SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-d'T'HH:mm:ss.SSS");
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-d'T'HH:mm:ss.SSS"); parser.setTimeZone(TimeZone.getTimeZone("UTC"));
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = parser.parse(modValueString);
this.value = new Long(date.toInstant().toEpochMilli());
break;
}
catch (java.text.ParseException e) {};
try { Date date = parser.parse(modValueString);
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) {};
this.value = new Long(date.toInstant().toEpochMilli());
}
catch (java.text.ParseException e) {
this.value = null; 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; break;

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

Loading…
Cancel
Save