You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libiec61850/src/mms/iso_mms/client/mms_client_common.c

221 lines
9.3 KiB
C

/*
* mms_client_common.c
*
* Copyright 2013-2018 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include "libiec61850_platform_includes.h"
#include <MmsPdu.h>
#include "mms_common.h"
#include "mms_client_connection.h"
#include "byte_buffer.h"
#include "mms_client_internal.h"
int
mmsClient_write_out(void *buffer, size_t size, void *app_key)
{
ByteBuffer* writeBuffer = (ByteBuffer*) app_key;
int appendedBytes = ByteBuffer_append(writeBuffer, (uint8_t*) buffer, size);
if (appendedBytes == -1) {
if (DEBUG_MMS_CLIENT)
printf("MMS_CLIENT: message exceeds maximum PDU size!\n");
}
return appendedBytes;
}
uint32_t
mmsClient_getInvokeId(ConfirmedResponsePdu_t* confirmedResponse)
{
long invokeId;
asn_INTEGER2long(&confirmedResponse->invokeID, &invokeId);
return (uint32_t) invokeId;
}
MmsPdu_t*
mmsClient_createConfirmedRequestPdu(uint32_t invokeId)
{
MmsPdu_t* mmsPdu = (MmsPdu_t*) GLOBAL_CALLOC(1, sizeof(MmsPdu_t));
mmsPdu->present = MmsPdu_PR_confirmedRequestPdu;
asn_long2INTEGER(&(mmsPdu->choice.confirmedRequestPdu.invokeID), invokeId);
return mmsPdu;
}
AlternateAccess_t*
mmsClient_createAlternateAccess(uint32_t index, uint32_t elementCount)
{
AlternateAccess_t* alternateAccess = (AlternateAccess_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccess_t));
alternateAccess->list.count = 1;
alternateAccess->list.array = (struct AlternateAccess__Member**) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member*));
alternateAccess->list.array[0] = (struct AlternateAccess__Member*) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member));
alternateAccess->list.array[0]->present = AlternateAccess__Member_PR_unnamed;
alternateAccess->list.array[0]->choice.unnamed = (AlternateAccessSelection_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccessSelection_t));
alternateAccess->list.array[0]->choice.unnamed->present = AlternateAccessSelection_PR_selectAccess;
if (elementCount > 0) {
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present =
AlternateAccessSelection__selectAccess_PR_indexRange;
INTEGER_t* asnIndex =
&(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.indexRange.lowIndex);
asn_long2INTEGER(asnIndex, index);
asnIndex =
&(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.indexRange.numberOfElements);
asn_long2INTEGER(asnIndex, elementCount);
}
else {
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present =
AlternateAccessSelection__selectAccess_PR_index;
INTEGER_t* asnIndex =
&(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.index);
asn_long2INTEGER(asnIndex, index);
}
return alternateAccess;
}
void
mmsClient_deleteAlternateAccess(AlternateAccess_t* alternateAccess)
{
if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.indexRange.lowIndex.buf != NULL) {
GLOBAL_FREEMEM(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.indexRange.lowIndex.buf);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.indexRange.lowIndex.buf = NULL;
}
if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.indexRange.numberOfElements.buf != NULL) {
GLOBAL_FREEMEM(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.indexRange.numberOfElements.buf);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.indexRange.numberOfElements.buf = NULL;
}
if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.index.buf != NULL) {
GLOBAL_FREEMEM(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.index.buf);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.index.buf = NULL;
}
if (alternateAccess->list.array[0]->choice.unnamed->present == AlternateAccessSelection_PR_selectAlternateAccess) {
if (alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess != NULL) {
mmsClient_deleteAlternateAccess(alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess);
}
}
GLOBAL_FREEMEM(alternateAccess->list.array[0]->choice.unnamed);
GLOBAL_FREEMEM(alternateAccess->list.array[0]);
GLOBAL_FREEMEM(alternateAccess->list.array);
GLOBAL_FREEMEM(alternateAccess);
}
AlternateAccess_t*
mmsClient_createAlternateAccessComponent(const char* componentName)
{
AlternateAccess_t* alternateAccess = (AlternateAccess_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccess_t));
alternateAccess->list.count = 1;
alternateAccess->list.array = (struct AlternateAccess__Member**) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member*));
alternateAccess->list.array[0] = (struct AlternateAccess__Member*) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member));
alternateAccess->list.array[0]->present = AlternateAccess__Member_PR_unnamed;
alternateAccess->list.array[0]->choice.unnamed = (AlternateAccessSelection_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccessSelection_t));
const char* separator = strchr(componentName, '$');
if (separator) {
int size = separator - componentName;
alternateAccess->list.array[0]->choice.unnamed->present = AlternateAccessSelection_PR_selectAlternateAccess;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.present =
AlternateAccessSelection__selectAlternateAccess__accessSelection_PR_component;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.choice.component.buf =
(uint8_t*) StringUtils_copySubString((char*) componentName, (char*) separator);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.choice.component.size = size;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess = mmsClient_createAlternateAccessComponent(separator + 1);
}
else {
int size = strlen(componentName);
alternateAccess->list.array[0]->choice.unnamed->present = AlternateAccessSelection_PR_selectAccess;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present =
AlternateAccessSelection__selectAccess_PR_component;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.component.buf =
(uint8_t*) StringUtils_copyString(componentName);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.component.size = size;
}
return alternateAccess;
}
AlternateAccess_t*
mmsClient_createAlternateAccessIndexComponent(uint32_t index, const char* componentName)
{
AlternateAccess_t* alternateAccess = (AlternateAccess_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccess_t));
alternateAccess->list.count = 1;
alternateAccess->list.array = (struct AlternateAccess__Member**) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member*));
alternateAccess->list.array[0] = (struct AlternateAccess__Member*) GLOBAL_CALLOC(1, sizeof(struct AlternateAccess__Member));
alternateAccess->list.array[0]->present = AlternateAccess__Member_PR_unnamed;
alternateAccess->list.array[0]->choice.unnamed = (AlternateAccessSelection_t*) GLOBAL_CALLOC(1, sizeof(AlternateAccessSelection_t));
if (componentName) {
alternateAccess->list.array[0]->choice.unnamed->present = AlternateAccessSelection_PR_selectAlternateAccess;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.accessSelection.present =
AlternateAccessSelection__selectAlternateAccess__accessSelection_PR_index;
INTEGER_t* asnIndex =
&(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.index);
asn_long2INTEGER(asnIndex, index);
alternateAccess->list.array[0]->choice.unnamed->choice.selectAlternateAccess.alternateAccess = mmsClient_createAlternateAccessComponent(componentName);
}
else {
alternateAccess->list.array[0]->choice.unnamed->present = AlternateAccessSelection_PR_selectAccess;
alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.present =
AlternateAccessSelection__selectAccess_PR_index;
INTEGER_t* asnIndex =
&(alternateAccess->list.array[0]->choice.unnamed->choice.selectAccess.choice.index);
asn_long2INTEGER(asnIndex, index);
}
return alternateAccess;
}