8478 lines
264 KiB
C
8478 lines
264 KiB
C
//
|
|
// --------------------------------------------------------------------------
|
|
// Gurux Ltd
|
|
//
|
|
//
|
|
//
|
|
// Filename: $HeadURL$
|
|
//
|
|
// Version: $Revision$,
|
|
// $Date$
|
|
// $Author$
|
|
//
|
|
// Copyright (c) Gurux Ltd
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// DESCRIPTION
|
|
//
|
|
// This file is a part of Gurux Device Framework.
|
|
//
|
|
// Gurux Device Framework is Open Source software; you can redistribute it
|
|
// and/or modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; version 2 of the License.
|
|
// Gurux Device Framework is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// This code is licensed under the GNU General Public License v2.
|
|
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include "gxignore.h"
|
|
#if !defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|
|
|
|
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
|
#include <assert.h>
|
|
#endif
|
|
|
|
#include "gxmem.h"
|
|
#if _MSC_VER > 1400
|
|
#include <crtdbg.h>
|
|
#endif
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include "gxset.h"
|
|
#include "dlms.h"
|
|
#include "gxkey.h"
|
|
#include "cosem.h"
|
|
#include "gxget.h"
|
|
#include "server.h"
|
|
|
|
#ifndef DLMS_IGNORE_DATA
|
|
int cosem_setData(gxValueEventArg* e)
|
|
{
|
|
int ret;
|
|
if (e->index == 2)
|
|
{
|
|
ret = var_copy(&((gxData*)e->target)->value, &e->value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_DATA
|
|
|
|
#ifndef DLMS_IGNORE_REGISTER
|
|
int cosem_setRegister(gxRegister* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
if (index == 2)
|
|
{
|
|
ret = var_copy(&object->value, value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
dlmsVARIANT* tmp;
|
|
if (value->vt != DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->scaler = (char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->unit = (unsigned char)var_toInteger(tmp);
|
|
object->unitRead = 1;
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_REGISTER
|
|
|
|
#ifndef DLMS_IGNORE_REGISTER_TABLE
|
|
int cosem_setRegistertable(gxRegisterTable* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
dlmsVARIANT_PTR tmp;
|
|
if (index == 2)
|
|
{
|
|
if (value->Arr != NULL)
|
|
{
|
|
dlmsVARIANT* tmp2;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
tmp2 = (dlmsVARIANT*)gxmalloc(sizeof(dlmsVARIANT));
|
|
var_init(tmp2);
|
|
ret = var_copy(tmp2, tmp);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
va_push(&object->tableCellValues, tmp2);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
if (value->vt != DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->scaler = (char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->unit = (unsigned char)var_toInteger(tmp);
|
|
object->unitRead = 1;
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_REGISTER_TABLE
|
|
|
|
#ifndef DLMS_IGNORE_CLOCK
|
|
int cosem_setClock(dlmsSettings* settings, gxClock* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
dlmsVARIANT tmp;
|
|
if (index == 2)
|
|
{
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
var_init(&tmp);
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->time, tmp.dateTime);
|
|
//If user set's new time transform it to the same time zone as the server is.
|
|
#ifndef DLMS_IGNORE_SERVER
|
|
if (settings->server)
|
|
{
|
|
//Convert time to UCT if time zone is given.
|
|
time_toUTC(&object->time);
|
|
clock_updateDST(object, &object->time);
|
|
}
|
|
#endif// DLMS_IGNORE_SERVER
|
|
var_clear(&tmp);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->time);
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->timeZone = (short)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->status = (DLMS_CLOCK_STATUS)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
var_init(&tmp);
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->begin, tmp.dateTime);
|
|
var_clear(&tmp);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->begin);
|
|
}
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
var_init(&tmp);
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->end, tmp.dateTime);
|
|
var_clear(&tmp);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->end);
|
|
}
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->deviation = (char)var_toInteger(value);
|
|
#ifndef DLMS_IGNORE_SERVER
|
|
if (settings->server)
|
|
{
|
|
clock_updateDST(object, &object->time);
|
|
}
|
|
#endif// DLMS_IGNORE_SERVER
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->enabled = (unsigned char)var_toInteger(value);
|
|
#ifndef DLMS_IGNORE_SERVER
|
|
if (settings->server)
|
|
{
|
|
clock_updateDST(object, &object->time);
|
|
}
|
|
#endif //DLMS_IGNORE_SERVER
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->clockBase = (DLMS_CLOCK_BASE)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif //DLMS_IGNORE_CLOCK
|
|
|
|
#ifndef DLMS_IGNORE_ACTIVITY_CALENDAR
|
|
|
|
|
|
// The season profiles list is sorted according to season_start (in increasing order).
|
|
int cosem_orderSeasonProfile(gxArray* profile)
|
|
{
|
|
int ret = 0;
|
|
uint16_t pos, pos2, minPos = 0;
|
|
gxSeasonProfile* sp, * sp2;
|
|
uint32_t tmp, next1, next2;
|
|
for (pos = 0; pos < profile->size - 1; ++pos)
|
|
{
|
|
if ((ret = arr_getByIndex(profile, pos, (void**)&sp)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
next1 = time_toUnixTime2(&sp->start);
|
|
next2 = 0xFFFFFFFF;
|
|
for (pos2 = pos + 1; pos2 < profile->size; ++pos2)
|
|
{
|
|
if ((ret = arr_getByIndex(profile, pos2, (void**)&sp2)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
tmp = time_toUnixTime2(&sp2->start);
|
|
if (tmp < next2)
|
|
{
|
|
next2 = tmp;
|
|
minPos = pos2;
|
|
}
|
|
}
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (next2 < next1)
|
|
{
|
|
if ((ret = arr_swap(profile, pos, minPos)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int updateSeasonProfile(gxArray* profile, dlmsVARIANT* data)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK, pos;
|
|
gxSeasonProfile* sp = NULL;
|
|
obj_clearSeasonProfile(profile);
|
|
dlmsVARIANT tm;
|
|
dlmsVARIANT* tmp, * it;
|
|
var_init(&tm);
|
|
for (pos = 0; pos != data->Arr->size; ++pos)
|
|
{
|
|
sp = (gxSeasonProfile*)gxmalloc(sizeof(gxSeasonProfile));
|
|
if (sp == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
ret = va_getByIndex(data->Arr, pos, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(it->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
BYTE_BUFFER_INIT(&sp->name);
|
|
bb_set2(&sp->name, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
|
|
ret = va_getByIndex(it->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = dlms_changeType2(tmp, DLMS_DATA_TYPE_DATETIME, &tm);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
time_copy(&sp->start, tm.dateTime);
|
|
var_clear(&tm);
|
|
ret = va_getByIndex(it->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
BYTE_BUFFER_INIT(&sp->weekName);
|
|
bb_set2(&sp->weekName, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
arr_push(profile, sp);
|
|
}
|
|
if (ret != 0 && sp != NULL)
|
|
{
|
|
gxfree(sp);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int updateWeekProfileTable(gxArray* profile, dlmsVARIANT* data)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK, pos;
|
|
gxWeekProfile* wp = NULL;
|
|
obj_clearWeekProfileTable(profile);
|
|
dlmsVARIANT* tmp, * it;
|
|
for (pos = 0; pos != data->Arr->size; ++pos)
|
|
{
|
|
wp = (gxWeekProfile*)gxmalloc(sizeof(gxWeekProfile));
|
|
if (wp == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
ret = va_getByIndex(data->Arr, pos, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(it->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
BYTE_BUFFER_INIT(&wp->name);
|
|
bb_set2(&wp->name, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
ret = va_getByIndex(it->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
wp->monday = (unsigned char)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(it->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
wp->tuesday = (unsigned char)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(it->Arr, 3, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
wp->wednesday = (unsigned char)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(it->Arr, 4, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
wp->thursday = (unsigned char)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(it->Arr, 5, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
wp->friday = (unsigned char)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(it->Arr, 6, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
wp->saturday = (unsigned char)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(it->Arr, 7, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
wp->sunday = (unsigned char)var_toInteger(tmp);
|
|
arr_push(profile, wp);
|
|
}
|
|
if (ret != 0 && wp != NULL)
|
|
{
|
|
gxfree(wp);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int updateDayProfileTable(dlmsSettings* settings, gxArray* profile, dlmsVARIANT* data)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK, pos, pos2;
|
|
gxDayProfile* dp = NULL;
|
|
gxDayProfileAction* ac = NULL;
|
|
obj_clearDayProfileTable(profile);
|
|
dlmsVARIANT* tmp, * tmp2, * it, * it2;
|
|
dlmsVARIANT tm;
|
|
for (pos = 0; pos != data->Arr->size; ++pos)
|
|
{
|
|
dp = (gxDayProfile*)gxmalloc(sizeof(gxDayProfile));
|
|
if (dp == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
arr_init(&dp->daySchedules);
|
|
ret = va_getByIndex(data->Arr, pos, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(it->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
dp->dayId = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(it->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
for (pos2 = 0; pos2 != tmp->Arr->size; ++pos2)
|
|
{
|
|
ac = (gxDayProfileAction*)gxmalloc(sizeof(gxDayProfileAction));
|
|
if (ac == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, pos2, &it2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
//Get start time.
|
|
ret = va_getByIndex(it2->Arr, 0, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
var_init(&tm);
|
|
ret = dlms_changeType2(tmp2, DLMS_DATA_TYPE_TIME, &tm);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
time_copy(&ac->startTime, tm.dateTime);
|
|
var_clear(&tm);
|
|
//Get script logical name.
|
|
ret = va_getByIndex(it2->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp2->vt == DLMS_DATA_TYPE_OCTET_STRING && tmp2->byteArr != NULL)
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SCRIPT_TABLE, tmp2->byteArr->data, &ac->script)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (ac->script == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(DLMS_OBJECT_TYPE_SCRIPT_TABLE, &ac->script)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
memcpy(ac->script->logicalName, tmp2->byteArr->data, tmp2->byteArr->size);
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, ac->script);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
#else
|
|
memcpy(ac->scriptLogicalName, tmp2->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
ret = va_getByIndex(it2->Arr, 2, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ac->scriptSelector = (uint16_t)var_toInteger(tmp2);
|
|
arr_push(&dp->daySchedules, ac);
|
|
}
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(profile, dp);
|
|
}
|
|
if (ret != 0)
|
|
{
|
|
if (dp)
|
|
{
|
|
gxfree(dp);
|
|
}
|
|
if (ac)
|
|
{
|
|
gxfree(ac);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int cosem_setActivityCalendar(dlmsSettings* settings, gxActivityCalendar* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
dlmsVARIANT tm;
|
|
if (index == 2)
|
|
{
|
|
bb_clear(&object->calendarNameActive);
|
|
ret = bb_set2(&object->calendarNameActive, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
ret = updateSeasonProfile(&object->seasonProfileActive, value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
ret = updateWeekProfileTable(&object->weekProfileTableActive, value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
ret = updateDayProfileTable(settings, &object->dayProfileTableActive, value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
bb_clear(&object->calendarNamePassive);
|
|
ret = bb_set2(&object->calendarNamePassive, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
ret = updateSeasonProfile(&object->seasonProfilePassive, value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
ret = updateWeekProfileTable(&object->weekProfileTablePassive, value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
ret = updateDayProfileTable(settings, &object->dayProfileTablePassive, value);
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
var_init(&tm);
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tm);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->time, tm.dateTime);
|
|
var_clear(&tm);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->time);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif // DLMS_IGNORE_ACTIVITY_CALENDAR
|
|
|
|
#ifndef DLMS_IGNORE_ACTION_SCHEDULE
|
|
int cosem_setActionSchedule(
|
|
dlmsSettings* settings,
|
|
gxActionSchedule* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
dlmsVARIANT* tmp;
|
|
gxtime* tm;
|
|
if (index == 2)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if (ret == 0)
|
|
{
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SCRIPT_TABLE, tmp->byteArr->data, (gxObject**)&object->executedScript)) != 0)
|
|
{
|
|
//Error code is returned at the end of the function.
|
|
}
|
|
if (object->executedScript == NULL)
|
|
{
|
|
//create object.
|
|
ret = cosem_createObject(DLMS_OBJECT_TYPE_SCRIPT_TABLE, (gxObject**)&object->executedScript);
|
|
if (ret == DLMS_ERROR_CODE_OK)
|
|
{
|
|
ret = cosem_setLogicalName((gxObject*)object->executedScript, tmp->byteArr->data);
|
|
if (ret == DLMS_ERROR_CODE_OK)
|
|
{
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, (gxObject*)object->executedScript);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
memcpy(object->executedScriptLogicalName, tmp->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->executedScriptSelector = (uint16_t)var_toInteger(tmp);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->type = (DLMS_SINGLE_ACTION_SCHEDULE_TYPE)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
arr_clear(&object->executionTime);
|
|
dlmsVARIANT time, date;
|
|
dlmsVARIANT* tmp2;
|
|
var_init(&time);
|
|
var_init(&date);
|
|
if (value->Arr != NULL)
|
|
{
|
|
arr_capacity(&object->executionTime, value->Arr->size);
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = dlms_changeType2(tmp2, DLMS_DATA_TYPE_TIME, &time);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = dlms_changeType2(tmp2, DLMS_DATA_TYPE_DATE, &date);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifdef DLMS_USE_EPOCH_TIME
|
|
time_addHours(date.dateTime, time_getHours(time.dateTime));
|
|
time_addMinutes(date.dateTime, time_getMinutes(time.dateTime));
|
|
time_addSeconds(date.dateTime, time_getSeconds(time.dateTime));
|
|
date.dateTime->skip = (DATETIME_SKIPS)(date.dateTime->skip & time.dateTime->skip);
|
|
#else
|
|
date.dateTime->value.tm_hour = time.dateTime->value.tm_hour;
|
|
date.dateTime->value.tm_min = time.dateTime->value.tm_min;
|
|
date.dateTime->value.tm_sec = time.dateTime->value.tm_sec;
|
|
date.dateTime->skip &= ~(DATETIME_SKIPS_HOUR | DATETIME_SKIPS_MINUTE | DATETIME_SKIPS_SECOND | DATETIME_SKIPS_MS);
|
|
date.dateTime->skip |= time.dateTime->skip & (DATETIME_SKIPS_HOUR | DATETIME_SKIPS_MINUTE | DATETIME_SKIPS_SECOND | DATETIME_SKIPS_MS);
|
|
#endif // DLMS_USE_EPOCH_TIME
|
|
date.dateTime->deviation = (short)0x8000;
|
|
date.dateTime->skip |= DATETIME_SKIPS_DEVITATION;
|
|
tm = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
if (tm == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
time_copy(tm, date.dateTime);
|
|
arr_push(&object->executionTime, tm);
|
|
var_clear(&time);
|
|
var_clear(&date);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_ACTION_SCHEDULE
|
|
|
|
int cosem_updateAttributeAccessModes(gxObject* object, variantArray* arr)
|
|
{
|
|
unsigned char id;
|
|
int ret;
|
|
uint16_t pos, cnt;
|
|
dlmsVARIANT* tmp, * it, * value;
|
|
//If accessmodes are not returned. Some meters do not return them.
|
|
if (arr->size != 2)
|
|
{
|
|
return 0;
|
|
}
|
|
ret = va_getByIndex(arr, 0, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
//If access modes are not retrieved yet.
|
|
if (object->access == NULL || object->access->attributeAccessModes.size == 0)
|
|
{
|
|
if (object->access == NULL)
|
|
{
|
|
object->access = (gxAccess*)gxcalloc(1, sizeof(gxAccess));
|
|
}
|
|
cnt = obj_attributeCount(object);
|
|
bb_capacity(&object->access->attributeAccessModes, cnt);
|
|
object->access->attributeAccessModes.size = object->access->attributeAccessModes.capacity;
|
|
|
|
cnt = obj_methodCount(object);
|
|
bb_capacity(&object->access->methodAccessModes, cnt);
|
|
object->access->methodAccessModes.size = object->access->methodAccessModes.capacity;
|
|
}
|
|
for (pos = 0; pos != tmp->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(tmp->Arr, pos, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (it->vt != DLMS_DATA_TYPE_STRUCTURE ||
|
|
it->Arr->size != 3)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
|
|
//Get ID.
|
|
ret = va_getByIndex(it->Arr, 0, &value);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
id = (unsigned char)var_toInteger(value);
|
|
if (!(id > object->access->attributeAccessModes.size))
|
|
{
|
|
ret = va_getByIndex(it->Arr, 1, &value);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
//DLMS_ACCESS_MODE
|
|
object->access->attributeAccessModes.data[id - 1] = (unsigned char)var_toInteger(value);
|
|
}
|
|
}
|
|
|
|
//Get method access modes.
|
|
ret = va_getByIndex(arr, 1, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
for (pos = 0; pos != tmp->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(tmp->Arr, pos, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (it->vt != DLMS_DATA_TYPE_STRUCTURE ||
|
|
it->Arr->size != 2)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
|
|
//Get ID.
|
|
ret = va_getByIndex(it->Arr, 0, &value);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
id = (unsigned char)var_toInteger(value);
|
|
if (!(id > object->access->methodAccessModes.size))
|
|
{
|
|
ret = va_getByIndex(it->Arr, 1, &value);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
//DLMS_METHOD_ACCESS_MODE
|
|
object->access->methodAccessModes.data[id - 1] = (unsigned char)var_toInteger(value);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#ifndef DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
|
|
|
int cosem_parseLNObjects(dlmsSettings* settings, gxByteBuffer* data, objectArray* objects)
|
|
{
|
|
gxObject* object;
|
|
int ret;
|
|
uint16_t pos, count;
|
|
unsigned char size;
|
|
oa_clear(&settings->objects, 1);
|
|
unsigned char version;
|
|
gxDataInfo info;
|
|
DLMS_OBJECT_TYPE class_id = 0;
|
|
dlmsVARIANT value;
|
|
dlmsVARIANT* it1 = NULL, * it2 = NULL, * it3 = NULL, * ln = NULL;
|
|
var_init(&value);
|
|
//Get array tag.
|
|
ret = bb_getUInt8(data, &size);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Check that data is in the array
|
|
if (size != DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_RESPONSE;
|
|
}
|
|
//get object count
|
|
if (hlp_getObjectCount2(data, &count) != 0)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
oa_capacity(objects, (uint16_t)count);
|
|
for (pos = 0; pos != count; ++pos)
|
|
{
|
|
var_clear(&value);
|
|
object = NULL;
|
|
di_init(&info);
|
|
if ((ret = dlms_getData(data, &info, &value)) != 0)
|
|
{
|
|
//This fixs Iskraemeco (MT-880) bug.
|
|
if (ret == DLMS_ERROR_CODE_OUTOFMEMORY)
|
|
{
|
|
ret = 0;
|
|
}
|
|
break;
|
|
}
|
|
if (value.vt != DLMS_DATA_TYPE_STRUCTURE || value.Arr->size != 4)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(value.Arr, 0, &it1)) != 0 ||
|
|
(ret = va_getByIndex(value.Arr, 1, &it2)) != 0 ||
|
|
(ret = va_getByIndex(value.Arr, 2, &ln)) != 0 ||
|
|
(ret = va_getByIndex(value.Arr, 3, &it3)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (it1->vt != DLMS_DATA_TYPE_UINT16 ||
|
|
it2->vt != DLMS_DATA_TYPE_UINT8 ||
|
|
ln->vt != DLMS_DATA_TYPE_OCTET_STRING ||
|
|
it3->vt != DLMS_DATA_TYPE_STRUCTURE ||
|
|
it3->Arr->size != 2)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
class_id = (DLMS_OBJECT_TYPE)var_toInteger(it1);
|
|
version = (unsigned char)var_toInteger(it2);
|
|
ret = cosem_createObject(class_id, &object);
|
|
//If known object.
|
|
if (ret == 0)
|
|
{
|
|
object->version = version;
|
|
ret = cosem_updateAttributeAccessModes(object, it3->Arr);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
cosem_setLogicalName(object, ln->byteArr->data);
|
|
oa_push(&settings->objects, object);
|
|
oa_push(&settings->releasedObjects, object);
|
|
}
|
|
else
|
|
{
|
|
if (ret != DLMS_ERROR_CODE_UNAVAILABLE_OBJECT)
|
|
{
|
|
break;
|
|
}
|
|
ret = 0;
|
|
}
|
|
}
|
|
var_clear(&value);
|
|
return ret;
|
|
}
|
|
|
|
int cosem_setAssociationLogicalName(
|
|
dlmsSettings* settings,
|
|
gxAssociationLogicalName* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos = 0;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
unsigned char ch;
|
|
if (index == 2)
|
|
{
|
|
gxObject* obj = NULL;
|
|
unsigned char version;
|
|
DLMS_OBJECT_TYPE type;
|
|
oa_empty(&object->objectList);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
type = (DLMS_OBJECT_TYPE)var_toInteger(tmp2);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
version = (unsigned char)var_toInteger(tmp2);
|
|
|
|
//Get Logical name.
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = oa_findByLN(&settings->objects, type, tmp2->byteArr->data, &obj);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
if (obj == NULL)
|
|
{
|
|
ret = cosem_createObject(type, &obj);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
//If unknown object.
|
|
if (ret == DLMS_ERROR_CODE_UNAVAILABLE_OBJECT ||
|
|
ret == DLMS_ERROR_CODE_INVALID_PARAMETER)
|
|
{
|
|
continue;
|
|
}
|
|
return ret;
|
|
}
|
|
ret = cosem_setLogicalName(obj, tmp2->byteArr->data);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
obj->version = (unsigned char)version;
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, obj);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 3, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
ret = cosem_updateAttributeAccessModes(obj, tmp2->Arr);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
oa_push(&object->objectList, obj);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->clientSAP = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->serverSAP = (uint16_t)var_toInteger(tmp);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
//Value of the object identifier encoded in BER
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
if (value->byteArr->data[0] == 0x60)
|
|
{
|
|
object->applicationContextName.jointIsoCtt = 0;
|
|
object->applicationContextName.country = 0;
|
|
object->applicationContextName.countryName = 0;
|
|
ret = bb_getUInt8ByIndex(value->byteArr, 3, &object->applicationContextName.identifiedOrganization);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = bb_getUInt8ByIndex(value->byteArr, 4, &object->applicationContextName.dlmsUA);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = bb_getUInt8ByIndex(value->byteArr, 5, &object->applicationContextName.applicationContext);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = bb_getUInt8ByIndex(value->byteArr, 6, &object->applicationContextName.contextId);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Get Tag.
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 2)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
//Get Len.
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 7)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
|
|
//Get tag
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 0x11)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
|
|
ret = bb_getUInt8(value->byteArr, &object->applicationContextName.jointIsoCtt);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
//Get tag
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 0x11)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = bb_getUInt8(value->byteArr, &object->applicationContextName.country);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
|
|
//Get tag
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 0x12)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = bb_getUInt16(value->byteArr, &object->applicationContextName.countryName);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 0x12)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
|
|
//Get tag
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 0x11)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = bb_getUInt8(value->byteArr, &object->applicationContextName.identifiedOrganization);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
|
|
//Get tag
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 0x11)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = bb_getUInt8(value->byteArr, &object->applicationContextName.dlmsUA);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
//Get tag
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 0x11)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = bb_getUInt8(value->byteArr, &object->applicationContextName.applicationContext);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
//Get tag
|
|
ret = bb_getUInt8(value->byteArr, &ch);
|
|
if (ret != DLMS_ERROR_CODE_OK || ch != 0x11)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = bb_getUInt8(value->byteArr, &object->applicationContextName.contextId);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
else if (value->vt == DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->applicationContextName.jointIsoCtt = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->applicationContextName.country = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->applicationContextName.countryName = (uint16_t)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 3, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->applicationContextName.identifiedOrganization = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 4, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->applicationContextName.dlmsUA = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 5, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->applicationContextName.applicationContext = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 6, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->applicationContextName.contextId = (unsigned char)var_toInteger(tmp);
|
|
}
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->xDLMSContextInfo.conformance = (DLMS_CONFORMANCE)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->xDLMSContextInfo.maxReceivePduSize = (uint16_t)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(value->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->xDLMSContextInfo.maxSendPduSize = (uint16_t)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(value->Arr, 3, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->xDLMSContextInfo.dlmsVersionNumber = (unsigned char)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(value->Arr, 4, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->xDLMSContextInfo.qualityOfService = (unsigned char)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(value->Arr, 5, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
bb_clear(&object->xDLMSContextInfo.cypheringInfo);
|
|
if (tmp->byteArr != NULL)
|
|
{
|
|
bb_set2(&object->xDLMSContextInfo.cypheringInfo, tmp->byteArr, 0, tmp->byteArr->size);
|
|
}
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
//Value of the object identifier encoded in BER
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
if (value->byteArr->data[0] == 0x60)
|
|
{
|
|
object->authenticationMechanismName.jointIsoCtt = 0;
|
|
object->authenticationMechanismName.country = 0;
|
|
object->authenticationMechanismName.countryName = 0;
|
|
pos += 2;
|
|
object->authenticationMechanismName.identifiedOrganization = value->byteArr->data[++pos];
|
|
object->authenticationMechanismName.dlmsUA = value->byteArr->data[++pos];
|
|
object->authenticationMechanismName.authenticationMechanismName = value->byteArr->data[++pos];
|
|
object->authenticationMechanismName.mechanismId = (DLMS_AUTHENTICATION)value->byteArr->data[++pos];
|
|
}
|
|
else
|
|
{
|
|
if ((ret = cosem_checkStructure(value->byteArr, 7)) == 0 &&
|
|
(ret = cosem_getUInt8(value->byteArr, &object->authenticationMechanismName.jointIsoCtt)) == 0 &&
|
|
(ret = cosem_getUInt8(value->byteArr, &object->authenticationMechanismName.country)) == 0 &&
|
|
(ret = cosem_getUInt16(value->byteArr, &object->authenticationMechanismName.countryName)) == 0 &&
|
|
(ret = cosem_getUInt8(value->byteArr, &object->authenticationMechanismName.identifiedOrganization)) == 0 &&
|
|
(ret = cosem_getUInt8(value->byteArr, &object->authenticationMechanismName.dlmsUA)) == 0 &&
|
|
(ret = cosem_getUInt8(value->byteArr, &object->authenticationMechanismName.authenticationMechanismName)) == 0 &&
|
|
(ret = cosem_getUInt8(value->byteArr, &ch)) == 0)
|
|
{
|
|
object->authenticationMechanismName.mechanismId = (DLMS_AUTHENTICATION)ch;
|
|
}
|
|
}
|
|
}
|
|
else if (value->vt == DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->authenticationMechanismName.jointIsoCtt = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->authenticationMechanismName.country = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->authenticationMechanismName.countryName = (uint16_t)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 3, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->authenticationMechanismName.identifiedOrganization = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 4, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->authenticationMechanismName.dlmsUA = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 5, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->authenticationMechanismName.authenticationMechanismName = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 6, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->authenticationMechanismName.mechanismId = (DLMS_AUTHENTICATION)var_toInteger(tmp);
|
|
}
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
bb_clear(&object->secret);
|
|
if (value->byteArr != NULL)
|
|
{
|
|
ret = bb_set2(&object->secret, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->associationStatus = (DLMS_ASSOCIATION_STATUS)var_toInteger(value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
if (bb_size(value->byteArr) != 6)
|
|
{
|
|
return DLMS_ERROR_CODE_UNMATCH_TYPE;
|
|
}
|
|
#if !(defined(DLMS_IGNORE_OBJECT_POINTERS) || defined(DLMS_IGNORE_SECURITY_SETUP))
|
|
ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SECURITY_SETUP, value->byteArr->data, (gxObject**)&object->securitySetup);
|
|
#else
|
|
memcpy(object->securitySetupReference, value->byteArr->data, 6);
|
|
#endif //!(defined(DLMS_IGNORE_OBJECT_POINTERS) || defined(DLMS_IGNORE_SECURITY_SETUP))
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
obj_clearUserList(&object->userList);
|
|
if (value->Arr != NULL)
|
|
{
|
|
gxKey2* it;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
it = (gxKey2*)gxmalloc(sizeof(gxKey2));
|
|
if (it == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
it->key = (unsigned char)var_toInteger(tmp2);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
it->value = (char*)gxmalloc(tmp->strVal->size + 1);
|
|
if (it->value == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
((char*)it->value)[tmp->strVal->size] = 0;
|
|
memcpy(it->value, tmp->strVal->data, tmp->strVal->size);
|
|
arr_push(&object->userList, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
if (object->currentUser.value != NULL)
|
|
{
|
|
gxfree(object->currentUser.value);
|
|
}
|
|
if (value->Arr->size == 2)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->currentUser.key = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
if (tmp->strVal != NULL && tmp->strVal->size != 0)
|
|
{
|
|
object->currentUser.value = gxmalloc(tmp->strVal->size + 1);
|
|
if (object->currentUser.value == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
memcpy(object->currentUser.value, tmp->strVal, tmp->strVal->size);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_ASSOCIATION_LOGICAL_NAME
|
|
|
|
#ifndef DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
|
int updateSNAccessRights(
|
|
objectArray* objectList,
|
|
variantArray* data)
|
|
{
|
|
uint16_t sn;
|
|
int pos, ret;
|
|
dlmsVARIANT* it, * tmp;
|
|
gxObject* obj = NULL;
|
|
for (pos = 0; pos != data->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(data, pos, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(it->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
sn = (uint16_t)var_toInteger(tmp);
|
|
|
|
ret = oa_findBySN(objectList, sn, &obj);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
if (obj != NULL)
|
|
{
|
|
ret = cosem_updateAttributeAccessModes(obj, it->Arr);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
/*
|
|
ret = va_getByIndex(it->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Update attribute Access
|
|
for(pos2 = 0; pos2 != tmp->Arr.size; ++pos2)
|
|
{
|
|
ret = va_getByIndex(tmp->Arr, pos, &access);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Get attribute ID.
|
|
ret = va_getByIndex(&access->Arr, 0, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//TODO: id = var_toInteger(tmp2);
|
|
//Get access mode.
|
|
ret = va_getByIndex(&access->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//TODO: obj->SetAccess(id, (DLMS_ACCESS_MODE) var_toInteger(tmp2));
|
|
}
|
|
|
|
//Update method Access
|
|
ret = va_getByIndex(it->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
for(pos2 = 0; pos2 != tmp->Arr.size; ++pos2)
|
|
{
|
|
ret = va_getByIndex(tmp->Arr, pos, &access);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Get attribute ID.
|
|
ret = va_getByIndex(&access->Arr, 0, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//TODO: id = var_toInteger(tmp2);
|
|
//Get access mode.
|
|
ret = va_getByIndex(&access->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//TODO: obj->SetMethodAccess(id, (DLMS_ACCESS_MODE) var_toInteger(tmp2));
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
|
|
int cosem_parseSNObjects(dlmsSettings* settings, gxByteBuffer* data, objectArray* objects)
|
|
{
|
|
gxDataInfo info;
|
|
short sn;
|
|
DLMS_OBJECT_TYPE class_id;
|
|
dlmsVARIANT value;
|
|
dlmsVARIANT* it1 = NULL, * it2 = NULL, * it3 = NULL, * ln = NULL;
|
|
gxObject* object;
|
|
int ret;
|
|
uint16_t count, pos;
|
|
unsigned char size, version;
|
|
var_init(&value);
|
|
//Get array tag.
|
|
if ((ret = bb_getUInt8(data, &size)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return 0;
|
|
}
|
|
//Check that data is in the array
|
|
if (size != 0x01)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_RESPONSE;
|
|
}
|
|
//get object count
|
|
if ((ret = hlp_getObjectCount2(data, &count)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
oa_capacity(objects, (uint16_t)count);
|
|
for (pos = 0; pos != count; ++pos)
|
|
{
|
|
var_clear(&value);
|
|
object = NULL;
|
|
di_init(&info);
|
|
if ((ret = dlms_getData(data, &info, &value)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (value.vt != DLMS_DATA_TYPE_STRUCTURE || value.Arr->size != 4)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(value.Arr, 0, &it1)) != 0 ||
|
|
(ret = va_getByIndex(value.Arr, 1, &it2)) != 0 ||
|
|
(ret = va_getByIndex(value.Arr, 2, &it3)) != 0 ||
|
|
(ret = va_getByIndex(value.Arr, 3, &ln)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (it1->vt != DLMS_DATA_TYPE_INT16 ||
|
|
it2->vt != DLMS_DATA_TYPE_UINT16 ||
|
|
it3->vt != DLMS_DATA_TYPE_UINT8 ||
|
|
ln->vt != DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
sn = (short)var_toInteger(it1);
|
|
class_id = (DLMS_OBJECT_TYPE)var_toInteger(it2);
|
|
version = (unsigned char)var_toInteger(it3);
|
|
ret = cosem_createObject(class_id, &object);
|
|
//If known object.
|
|
if (ret == 0)
|
|
{
|
|
object->shortName = sn;
|
|
object->version = version;
|
|
cosem_setLogicalName(object, ln->byteArr->data);
|
|
oa_push(objects, object);
|
|
oa_push(&settings->releasedObjects, object);
|
|
}
|
|
else
|
|
{
|
|
if (ret != DLMS_ERROR_CODE_UNAVAILABLE_OBJECT)
|
|
{
|
|
break;
|
|
}
|
|
ret = 0;
|
|
}
|
|
}
|
|
var_clear(&value);
|
|
return ret;
|
|
}
|
|
|
|
int cosem_setAssociationShortName(
|
|
dlmsSettings* settings,
|
|
gxAssociationShortName* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret;
|
|
int pos;
|
|
if (index == 2)
|
|
{
|
|
dlmsVARIANT* it, * it1 = NULL, * it2 = NULL, * it3 = NULL, * ln = NULL;
|
|
unsigned char version;
|
|
short sn;
|
|
DLMS_OBJECT_TYPE class_id;
|
|
gxObject* obj;
|
|
oa_empty(&object->objectList);
|
|
if ((ret = oa_capacity(&object->objectList, value->Arr->size)) == 0)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
obj = NULL;
|
|
if ((ret = va_getByIndex(value->Arr, 0, &it)) != 0 ||
|
|
(ret = va_getByIndex(it->Arr, 0, &it1)) != 0 ||
|
|
(ret = va_getByIndex(it->Arr, 1, &it2)) != 0 ||
|
|
(ret = va_getByIndex(it->Arr, 2, &it3)) != 0 ||
|
|
(ret = va_getByIndex(it->Arr, 3, &ln)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (it1->vt != DLMS_DATA_TYPE_INT16 ||
|
|
it2->vt != DLMS_DATA_TYPE_UINT16 ||
|
|
it3->vt != DLMS_DATA_TYPE_UINT8 ||
|
|
ln->vt != DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
sn = (short)var_toInteger(it1);
|
|
class_id = (DLMS_OBJECT_TYPE)var_toInteger(it2);
|
|
version = (unsigned char)var_toInteger(it3);
|
|
ret = cosem_createObject(class_id, &obj);
|
|
//If known object.
|
|
if (ret == 0)
|
|
{
|
|
obj->shortName = sn;
|
|
obj->version = version;
|
|
cosem_setLogicalName(obj, ln->byteArr->data);
|
|
oa_push(&object->objectList, obj);
|
|
oa_push(&settings->releasedObjects, obj);
|
|
}
|
|
else
|
|
{
|
|
if (ret != DLMS_ERROR_CODE_UNAVAILABLE_OBJECT)
|
|
{
|
|
break;
|
|
}
|
|
ret = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
ret = updateSNAccessRights(&object->objectList, value->Arr);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
if (bb_size(value->byteArr) != 6)
|
|
{
|
|
ret = DLMS_ERROR_CODE_UNMATCH_TYPE;
|
|
}
|
|
else
|
|
{
|
|
#ifndef DLMS_IGNORE_SECURITY_SETUP
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SECURITY_SETUP, value->byteArr->data, (gxObject**)&object->securitySetup);
|
|
#else
|
|
memcpy(object->securitySetupReference, value->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
#endif // DLMS_IGNORE_SECURITY_SETUP
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_ASSOCIATION_SHORT_NAME
|
|
|
|
#ifndef DLMS_IGNORE_AUTO_ANSWER
|
|
int cosem_setAutoAnswer(gxAutoAnswer* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
dlmsVARIANT* tmp;
|
|
if (index == 2)
|
|
{
|
|
object->mode = (DLMS_AUTO_ANSWER_MODE)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
arr_clearKeyValuePair(&object->listeningWindow);
|
|
dlmsVARIANT* tmp3;
|
|
dlmsVARIANT start, end;
|
|
gxtime* s, * e;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
var_init(&start);
|
|
var_init(&end);
|
|
ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATETIME, &start);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATETIME, &end);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
s = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
e = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
time_copy(s, start.dateTime);
|
|
time_copy(e, end.dateTime);
|
|
arr_push(&object->listeningWindow, key_init(s, e));
|
|
var_clear(&start);
|
|
var_clear(&end);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->status = (DLMS_AUTO_ANSWER_STATUS)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->numberOfCalls = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->numberOfRingsInListeningWindow = (unsigned char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->numberOfRingsOutListeningWindow = (unsigned char)var_toInteger(tmp);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_AUTO_ANSWER
|
|
|
|
#ifndef DLMS_IGNORE_AUTO_CONNECT
|
|
int cosem_setAutoConnect(gxAutoConnect* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
if (index == 2)
|
|
{
|
|
object->mode = (DLMS_AUTO_CONNECT_MODE)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->repetitions = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->repetitionDelay = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
dlmsVARIANT start, end;
|
|
arr_clearKeyValuePair(&object->callingWindow);
|
|
if (value->Arr != NULL)
|
|
{
|
|
if ((ret = arr_capacity(&object->callingWindow, value->Arr->size)) == 0)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
gxtime* s, * e;
|
|
var_init(&start);
|
|
var_init(&end);
|
|
ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATETIME, &start);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATETIME, &end);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
s = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
e = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
arr_push(&object->callingWindow, key_init(s, e));
|
|
time_copy(s, start.dateTime);
|
|
time_copy(e, end.dateTime);
|
|
var_clear(&start);
|
|
var_clear(&end);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
dlmsVARIANT* tmp;
|
|
gxByteBuffer* str;
|
|
arr_clearStrings(&object->destinations);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
str = (gxByteBuffer*)gxmalloc(sizeof(gxByteBuffer));
|
|
BYTE_BUFFER_INIT(str);
|
|
bb_set2(str, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
arr_push(&object->destinations, str);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_AUTO_CONNECT
|
|
|
|
#ifndef DLMS_IGNORE_DEMAND_REGISTER
|
|
int cosem_setDemandRegister(gxDemandRegister* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT tmp2;
|
|
if (index == 2)
|
|
{
|
|
ret = var_copy(&object->currentAverageValue, value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
ret = var_copy(&object->lastAverageValue, value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
if (value->vt != DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->scaler = (char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->unit = (unsigned char)var_toInteger(tmp);
|
|
object->unitRead = 1;
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
ret = var_copy(&object->status, value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
ret = var_init(&tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->captureTime, tmp2.dateTime);
|
|
var_clear(&tmp2);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->captureTime);
|
|
}
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
ret = var_init(&tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->startTimeCurrent, tmp2.dateTime);
|
|
var_clear(&tmp2);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->startTimeCurrent);
|
|
}
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->period = var_toInteger(value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->numberOfPeriods = (uint16_t)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_DEMAND_REGISTER
|
|
|
|
#ifndef DLMS_IGNORE_MAC_ADDRESS_SETUP
|
|
int cosem_setMacAddressSetup(gxMacAddressSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
if (index == 2)
|
|
{
|
|
bb_clear(&object->macAddress);
|
|
ret = bb_set2(&object->macAddress, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_MAC_ADDRESS_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_EXTENDED_REGISTER
|
|
int cosem_setExtendedRegister(gxExtendedRegister* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT tmp2;
|
|
if (index == 2)
|
|
{
|
|
ret = var_copy(&object->value, value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
if (value->vt != DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->scaler = (char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->unit = (unsigned char)var_toInteger(tmp);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
ret = var_copy(&object->status, value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
ret = var_init(&tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp2);
|
|
if (ret == 0)
|
|
{
|
|
time_copy(&object->captureTime, tmp2.dateTime);
|
|
var_clear(&tmp2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
time_copy(&object->captureTime, value->dateTime);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_EXTENDED_REGISTER
|
|
|
|
#ifndef DLMS_IGNORE_GPRS_SETUP
|
|
int cosem_setGprsSetup(gxGPRSSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret;
|
|
if (index == 2)
|
|
{
|
|
bb_clear(&object->apn);
|
|
if (value->vt == DLMS_DATA_TYPE_STRING)
|
|
{
|
|
bb_set(&object->apn, (unsigned char*)value->strVal->data, value->strVal->size);
|
|
}
|
|
else
|
|
{
|
|
bb_set2(&object->apn, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->pinCode = value->uiVal;
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT* tmp3;
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->defaultQualityOfService.precedence = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->defaultQualityOfService.delay = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->defaultQualityOfService.reliability = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 3, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->defaultQualityOfService.peakThroughput = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 4, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->defaultQualityOfService.meanThroughput = (unsigned char)var_toInteger(tmp3);
|
|
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->requestedQualityOfService.precedence = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->requestedQualityOfService.delay = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->requestedQualityOfService.reliability = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 3, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->requestedQualityOfService.peakThroughput = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 4, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->requestedQualityOfService.meanThroughput = (unsigned char)var_toInteger(tmp3);
|
|
}
|
|
else
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
#endif //DLMS_IGNORE_GPRS_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_SECURITY_SETUP
|
|
int cosem_setSecuritySetup(dlmsSettings* settings, gxSecuritySetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
gxCertificateInfo* it = NULL;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->securityPolicy = (DLMS_SECURITY_POLICY)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->securitySuite = (DLMS_SECURITY_SUITE)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
if ((ret = bb_clear(&object->clientSystemTitle)) == 0)
|
|
{
|
|
if (!(value->byteArr == NULL || bb_available(value->byteArr) != 8))
|
|
{
|
|
ret = bb_set2(&object->clientSystemTitle, value->byteArr, value->byteArr->position, 8);
|
|
}
|
|
}
|
|
break;
|
|
case 5:
|
|
if ((ret = bb_clear(&object->serverSystemTitle)) == 0)
|
|
{
|
|
if (!(value->byteArr == NULL || bb_available(value->byteArr) != 8))
|
|
{
|
|
ret = bb_set2(&object->serverSystemTitle, value->byteArr, value->byteArr->position, 8);
|
|
}
|
|
}
|
|
break;
|
|
case 6:
|
|
obj_clearCertificateInfo(&object->certificates);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxCertificateInfo*)gxmalloc(sizeof(gxCertificateInfo));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
//entity
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->entity = (DLMS_CERTIFICATE_ENTITY)var_toInteger(tmp3);
|
|
//type
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->type = (DLMS_CERTIFICATE_TYPE)var_toInteger(tmp3);
|
|
//serialNumber
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp3->byteArr != NULL && tmp3->byteArr->size != 0)
|
|
{
|
|
it->serialNumber = gxmalloc(tmp3->byteArr->size + 1);
|
|
if (it->serialNumber == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
memcpy(it->serialNumber, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
it->serialNumber[tmp3->byteArr->size] = 0;
|
|
}
|
|
else
|
|
{
|
|
it->serialNumber = NULL;
|
|
}
|
|
//issuer
|
|
if ((ret = va_getByIndex(tmp->Arr, 3, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp3->byteArr != NULL && tmp3->byteArr->size != 0)
|
|
{
|
|
it->issuer = gxmalloc(tmp3->byteArr->size + 1);
|
|
if (it->issuer == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
memcpy(it->issuer, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
it->issuer[tmp3->byteArr->size] = 0;
|
|
}
|
|
else
|
|
{
|
|
it->issuer = NULL;
|
|
}
|
|
//subject
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp3->byteArr != NULL && tmp3->byteArr->size != 0)
|
|
{
|
|
it->subject = gxmalloc(tmp3->byteArr->size + 1);
|
|
if (it->subject == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
memcpy(it->subject, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
it->subject[tmp3->byteArr->size] = 0;
|
|
}
|
|
else
|
|
{
|
|
it->subject = NULL;
|
|
}
|
|
//subjectAltName.
|
|
if ((ret = va_getByIndex(tmp->Arr, 5, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp3->byteArr != NULL && tmp3->byteArr->size != 0)
|
|
{
|
|
it->subjectAltName = gxmalloc(tmp3->byteArr->size + 1);
|
|
if (it->subjectAltName == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
memcpy(it->subjectAltName, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
it->subjectAltName[tmp3->byteArr->size] = 0;
|
|
}
|
|
else
|
|
{
|
|
it->subjectAltName = NULL;
|
|
}
|
|
arr_push(&object->certificates, it);
|
|
}
|
|
if (ret != 0 && it != NULL)
|
|
{
|
|
if (it->serialNumber != NULL)
|
|
{
|
|
gxfree(it->serialNumber);
|
|
}
|
|
if (it->subject != NULL)
|
|
{
|
|
gxfree(it->subject);
|
|
}
|
|
if (it->issuer != NULL)
|
|
{
|
|
gxfree(it->issuer);
|
|
}
|
|
gxfree(it);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_READ_WRITE_DENIED;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SECURITY_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_IEC_HDLC_SETUP
|
|
int cosem_setIecHdlcSetup(gxIecHdlcSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
if (index == 2)
|
|
{
|
|
object->communicationSpeed = (DLMS_BAUD_RATE)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->windowSizeTransmit = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->windowSizeReceive = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->maximumInfoLengthTransmit = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->maximumInfoLengthReceive = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->interCharachterTimeout = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->inactivityTimeout = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->deviceAddress = (uint16_t)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
#endif //DLMS_IGNORE_IEC_HDLC_SETUP
|
|
#ifndef DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
|
int cosem_setIecLocalPortSetup(gxLocalPortSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
if (index == 2)
|
|
{
|
|
object->defaultMode = (DLMS_OPTICAL_PROTOCOL_MODE)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->defaultBaudrate = (DLMS_BAUD_RATE)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->proposedBaudrate = (DLMS_BAUD_RATE)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->responseTime = (DLMS_LOCAL_PORT_RESPONSE_TIME)var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
bb_clear(&object->deviceAddress);
|
|
ret = bb_set2(&object->deviceAddress, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
bb_clear(&object->password1);
|
|
ret = bb_set2(&object->password1, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
bb_clear(&object->password2);
|
|
ret = bb_set2(&object->password2, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
bb_clear(&object->password5);
|
|
ret = bb_set2(&object->password5, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_IEC_LOCAL_PORT_SETUP
|
|
#ifndef DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
|
int cosem_setIecTwistedPairSetup(gxIecTwistedPairSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
dlmsVARIANT* tmp;
|
|
if (index == 2)
|
|
{
|
|
object->mode = var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->speed = var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
bb_clear(&object->primaryAddresses);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK ||
|
|
(ret = bb_setUInt8(&object->primaryAddresses, tmp->bVal)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
bb_clear(&object->tabis);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK ||
|
|
(ret = bb_setUInt8(&object->tabis, tmp->bVal)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_IEC_TWISTED_PAIR_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_IP4_SETUP
|
|
int cosem_setIP4Setup(dlmsSettings* settings, gxIp4Setup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
gxip4SetupIpOption* ipItem = NULL;
|
|
if (index == 2)
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_NONE, value->byteArr->data, &object->dataLinkLayer)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
#else
|
|
ret = bb_get(value->byteArr, object->dataLinkLayerReference, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->ipAddress = var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
va_clear(&object->multicastIPAddress);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
tmp3 = (dlmsVARIANT*)gxmalloc(sizeof(dlmsVARIANT));
|
|
|
|
if ((ret = var_init(tmp3)) != 0 ||
|
|
(ret = var_copy(tmp, tmp3)) != 0 ||
|
|
(ret = va_push(&object->multicastIPAddress, tmp3)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
arr_clear(&object->ipOptions);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ipItem = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ipItem = (gxip4SetupIpOption*)gxmalloc(sizeof(gxip4SetupIpOption));
|
|
if (ipItem == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
BYTE_BUFFER_INIT(&ipItem->data);
|
|
ipItem->type = (DLMS_IP_OPTION_TYPE)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ipItem->length = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
bb_set(&ipItem->data, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
arr_push(&object->ipOptions, ipItem);
|
|
}
|
|
if (ret != DLMS_ERROR_CODE_OK && ipItem != NULL)
|
|
{
|
|
gxfree(ipItem);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->subnetMask = var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->gatewayIPAddress = var_toInteger(value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->useDHCP = value->boolVal;
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->primaryDNSAddress = var_toInteger(value);
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
object->secondaryDNSAddress = var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_IP4_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_IP6_SETUP
|
|
int cosem_setIP6Setup(dlmsSettings* settings, gxIp6Setup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
IN6_ADDR* ip;
|
|
gxNeighborDiscoverySetup* it;
|
|
if (index == 2)
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_NONE, value->byteArr->data, &object->dataLinkLayer)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
#else
|
|
ret = bb_get(value->byteArr, object->dataLinkLayerReference, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->addressConfigMode = var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
arr_clear(&object->unicastIPAddress);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp->byteArr->size != 16)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INCONSISTENT_CLASS_OR_OBJECT;
|
|
break;
|
|
}
|
|
ip = (IN6_ADDR*)gxmalloc(sizeof(IN6_ADDR));
|
|
memcpy(ip, tmp->byteArr->data, tmp->byteArr->size);
|
|
if ((ret = arr_push(&object->unicastIPAddress, ip)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
arr_clear(&object->multicastIPAddress);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp->byteArr->size != 16)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INCONSISTENT_CLASS_OR_OBJECT;
|
|
break;
|
|
}
|
|
ip = (IN6_ADDR*)gxmalloc(sizeof(IN6_ADDR));
|
|
memcpy(ip, tmp->byteArr->data, tmp->byteArr->size);
|
|
if ((ret = arr_push(&object->multicastIPAddress, ip)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
arr_clear(&object->gatewayIPAddress);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp->byteArr->size != 16)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INCONSISTENT_CLASS_OR_OBJECT;
|
|
break;
|
|
}
|
|
ip = (IN6_ADDR*)gxmalloc(sizeof(IN6_ADDR));
|
|
memcpy(ip, tmp->byteArr->data, tmp->byteArr->size);
|
|
if ((ret = arr_push(&object->gatewayIPAddress, ip)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
if (bb_size(value->byteArr) == 0)
|
|
{
|
|
memset(&object->primaryDNSAddress, 0, sizeof(IN6_ADDR));
|
|
}
|
|
else if (bb_size(value->byteArr) != 16)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INCONSISTENT_CLASS_OR_OBJECT;
|
|
}
|
|
else
|
|
{
|
|
memcpy(&object->primaryDNSAddress, value->byteArr->data, value->byteArr->size);
|
|
}
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
if (bb_size(value->byteArr) == 0)
|
|
{
|
|
memset(&object->secondaryDNSAddress, 0, sizeof(IN6_ADDR));
|
|
}
|
|
else if (bb_size(value->byteArr) != 16)
|
|
{
|
|
ret = DLMS_ERROR_CODE_INCONSISTENT_CLASS_OR_OBJECT;
|
|
}
|
|
else
|
|
{
|
|
memcpy(&object->secondaryDNSAddress, value->byteArr->data, value->byteArr->size);
|
|
}
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->trafficClass = (DLMS_IP6_ADDRESS_CONFIG_MODE)var_toInteger(value);
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
arr_clear(&object->neighborDiscoverySetup);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxNeighborDiscoverySetup*)gxmalloc(sizeof(gxNeighborDiscoverySetup));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->maxRetry = (unsigned char)var_toInteger(tmp3);
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->retryWaitTime = (uint16_t)var_toInteger(tmp3);
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->sendPeriod = var_toInteger(tmp3);
|
|
if ((ret = arr_push(&object->neighborDiscoverySetup, it)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_IP6_SETUP
|
|
#ifndef DLMS_IGNORE_UTILITY_TABLES
|
|
int cosem_setUtilityTables(gxUtilityTables* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
if (index == 2)
|
|
{
|
|
object->tableId = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
//Skip length.
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
bb_clear(&object->buffer);
|
|
bb_set2(&object->buffer, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
#endif //DLMS_IGNORE_UTILITY_TABLES
|
|
|
|
#ifndef DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
|
int cosem_setMbusSlavePortSetup(gxMbusSlavePortSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
if (index == 2)
|
|
{
|
|
object->defaultBaud = (DLMS_BAUD_RATE)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->availableBaud = (DLMS_BAUD_RATE)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->addressState = (DLMS_ADDRESS_STATE)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->busAddress = (unsigned char)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
#endif //DLMS_IGNORE_MBUS_SLAVE_PORT_SETUP
|
|
#ifndef DLMS_IGNORE_DISCONNECT_CONTROL
|
|
int cosem_setDisconnectControl(gxDisconnectControl* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
if (index == 2)
|
|
{
|
|
object->outputState = value->boolVal;
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->controlState = (DLMS_CONTROL_STATE)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->controlMode = (DLMS_CONTROL_MODE)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
#endif //DLMS_IGNORE_DISCONNECT_CONTROL
|
|
#ifndef DLMS_IGNORE_LIMITER
|
|
int cosem_setLimiter(dlmsSettings* settings, gxLimiter* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
DLMS_OBJECT_TYPE ot;
|
|
int ret = DLMS_ERROR_CODE_OK, pos;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
dlmsVARIANT tmp2;
|
|
if (index == 2)
|
|
{
|
|
if (value->vt != DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
#if defined(_WIN32) || defined(_WIN64) || defined(__linux__)
|
|
assert(0);
|
|
#endif
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ot = (DLMS_OBJECT_TYPE)var_toInteger(tmp);
|
|
//Get LN.
|
|
ret = va_getByIndex(value->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Get attribute index.
|
|
ret = va_getByIndex(value->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->selectedAttributeIndex = (unsigned char)var_toInteger(tmp);
|
|
if (ot != 0)
|
|
{
|
|
if ((ret = oa_findByLN(&settings->objects, ot, tmp3->byteArr->data, &object->monitoredValue)) == 0 &&
|
|
object->monitoredValue == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(ot, &object->monitoredValue)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
memcpy(object->monitoredValue->logicalName, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, object->monitoredValue);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
object->monitoredValue = NULL;
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
ret = var_copy(&object->thresholdActive, value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
ret = var_copy(&object->thresholdNormal, value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
ret = var_copy(&object->thresholdEmergency, value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->minOverThresholdDuration = var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->minUnderThresholdDuration = var_toInteger(value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->emergencyProfile.id = (uint16_t)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = var_init(&tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = dlms_changeType2(tmp, DLMS_DATA_TYPE_DATETIME, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->emergencyProfile.activationTime, tmp2.dateTime);
|
|
var_clear(&tmp2);
|
|
ret = va_getByIndex(value->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->emergencyProfile.duration = var_toInteger(tmp);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
va_clear(&object->emergencyProfileGroupIDs);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
tmp3 = (dlmsVARIANT*)gxmalloc(sizeof(dlmsVARIANT));
|
|
var_init(tmp3);
|
|
ret = var_copy(tmp3, tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
va_push(&object->emergencyProfileGroupIDs, tmp3);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
object->emergencyProfileActive = value->boolVal;
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SCRIPT_TABLE, tmp3->byteArr->data, (gxObject**)&object->actionOverThreshold.script)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (object->actionOverThreshold.script == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(DLMS_OBJECT_TYPE_SCRIPT_TABLE, (gxObject**)&object->actionOverThreshold.script)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
memcpy(object->actionOverThreshold.script->base.logicalName, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, (gxObject*)object->actionOverThreshold.script);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
#else
|
|
memcpy(object->actionOverThreshold.logicalName, tmp3->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->actionOverThreshold.scriptSelector = (uint16_t)var_toInteger(tmp3);
|
|
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SCRIPT_TABLE, tmp3->byteArr->data, (gxObject**)&object->actionUnderThreshold.script)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (object->actionUnderThreshold.script == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(DLMS_OBJECT_TYPE_SCRIPT_TABLE, (gxObject**)&object->actionUnderThreshold.script)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
memcpy(object->actionUnderThreshold.script->base.logicalName, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, (gxObject*)object->actionUnderThreshold.script);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
#else
|
|
memcpy(object->actionUnderThreshold.logicalName, tmp3->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->actionUnderThreshold.scriptSelector = (uint16_t)var_toInteger(tmp3);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_LIMITER
|
|
#ifndef DLMS_IGNORE_MBUS_CLIENT
|
|
int cosem_setmMbusClient(dlmsSettings* settings, gxMBusClient* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK, pos;
|
|
if (index == 2)
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_MBUS_MASTER_PORT_SETUP, value->byteArr->data, &object->mBusPort)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (object->mBusPort == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(DLMS_OBJECT_TYPE_MBUS_MASTER_PORT_SETUP, &object->mBusPort)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
memcpy(object->mBusPort->logicalName, value->byteArr->data, value->byteArr->size);
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, object->mBusPort);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
#else
|
|
ret = bb_get(value->byteArr, object->mBusPortReference, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
arr_clearKeyValuePair(&object->captureDefinition);
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
gxByteBuffer* start, * end;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
start = (gxByteBuffer*)gxmalloc(sizeof(gxByteBuffer));
|
|
end = (gxByteBuffer*)gxmalloc(sizeof(gxByteBuffer));
|
|
BYTE_BUFFER_INIT(start);
|
|
BYTE_BUFFER_INIT(end);
|
|
bb_set(start, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(start);
|
|
gxfree(end);
|
|
break;
|
|
}
|
|
bb_set(end, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
arr_push(&object->captureDefinition, key_init(start, end));
|
|
}
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->capturePeriod = var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->primaryAddress = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->identificationNumber = var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->manufacturerID = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->dataHeaderVersion = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->deviceType = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
object->accessNumber = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
object->status = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 12)
|
|
{
|
|
object->alarm = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 13 && object->base.version != 0)
|
|
{
|
|
object->configuration = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 14 && object->base.version != 0)
|
|
{
|
|
object->encryptionKeyStatus = (DLMS_MBUS_ENCRYPTION_KEY_STATUS)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif //DLMS_IGNORE_MBUS_CLIENT
|
|
#ifndef DLMS_IGNORE_MODEM_CONFIGURATION
|
|
int cosem_setModemConfiguration(gxModemConfiguration* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
gxModemInitialisation* modemInit;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
gxByteBuffer* str;
|
|
if (index == 2)
|
|
{
|
|
object->communicationSpeed = (DLMS_BAUD_RATE)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
obj_clearModemConfigurationInitialisationStrings(&object->initialisationStrings);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
modemInit = (gxModemInitialisation*)gxmalloc(sizeof(gxModemInitialisation));
|
|
if (modemInit == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
BYTE_BUFFER_INIT(&modemInit->request);
|
|
BYTE_BUFFER_INIT(&modemInit->response);
|
|
bb_set(&modemInit->request, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
bb_set(&modemInit->response, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
if (tmp->Arr->size > 2)
|
|
{
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
modemInit->delay = tmp3->uiVal;
|
|
}
|
|
arr_push(&object->initialisationStrings, modemInit);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
arr_clearStrings(&object->modemProfile);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
str = (gxByteBuffer*)gxmalloc(sizeof(gxByteBuffer));
|
|
BYTE_BUFFER_INIT(str);
|
|
bb_set2(str, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
arr_push(&object->modemProfile, str);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_MODEM_CONFIGURATION
|
|
#ifndef DLMS_IGNORE_PPP_SETUP
|
|
int cosem_setPppSetup(dlmsSettings* settings, gxPppSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK, pos;
|
|
gxpppSetupLcpOption* lcpItem = NULL;
|
|
gxpppSetupIPCPOption* ipcpItem = NULL;
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT* tmp3;
|
|
if (index == 2)
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_NONE, value->byteArr->data, &object->phy)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (object->phy == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
#else
|
|
ret = bb_get(value->byteArr, object->PHYReference, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
arr_clear(&object->lcpOptions);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
lcpItem = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
lcpItem = (gxpppSetupLcpOption*)gxmalloc(sizeof(gxpppSetupLcpOption));
|
|
if (lcpItem == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
var_init(&lcpItem->data);
|
|
lcpItem->type = (DLMS_PPP_SETUP_LCP_OPTION_TYPE)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
lcpItem->length = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = var_copy(&lcpItem->data, tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->lcpOptions, lcpItem);
|
|
}
|
|
if (ret != 0 && lcpItem != NULL)
|
|
{
|
|
gxfree(lcpItem);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
arr_clear(&object->ipcpOptions);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ipcpItem = (gxpppSetupIPCPOption*)gxmalloc(sizeof(gxpppSetupIPCPOption));
|
|
if (ipcpItem == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
var_init(&ipcpItem->data);
|
|
ipcpItem->type = (DLMS_PPP_SETUP_IPCP_OPTION_TYPE)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ipcpItem->length = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = var_copy(&ipcpItem->data, tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->ipcpOptions, ipcpItem);
|
|
}
|
|
if (ret != 0 && ipcpItem != NULL)
|
|
{
|
|
gxfree(ipcpItem);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
if (value->Arr == NULL || value->Arr->size == 0)
|
|
{
|
|
bb_clear(&object->userName);
|
|
bb_clear(&object->password);
|
|
}
|
|
else if (value->Arr->size == 2)
|
|
{
|
|
//Get user name.
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
bb_clear(&object->userName);
|
|
bb_set2(&object->userName, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
//Get password.
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
bb_clear(&object->password);
|
|
bb_set2(&object->password, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_PPP_SETUP
|
|
#ifndef DLMS_IGNORE_REGISTER_ACTIVATION
|
|
int cosem_setRegisterActivation(dlmsSettings* settings,
|
|
gxValueEventArg* e)
|
|
{
|
|
int ret = 0, pos;
|
|
gxRegisterActivation* object = (gxRegisterActivation*)e->target;
|
|
unsigned char index = e->index;
|
|
dlmsVARIANT* value = &e->value;
|
|
#ifdef DLMS_IGNORE_OBJECT_POINTERS
|
|
gxObjectDefinition* objectDefinition;
|
|
#else
|
|
gxObject* objectDefinition;
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
if (index == 2)
|
|
{
|
|
obj_clearRegisterActivationAssignment(&object->registerAssignment);
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
if (value->Arr != NULL)
|
|
{
|
|
short type;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
objectDefinition = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
type = (short)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
unsigned char* ln = tmp3->byteArr->data;
|
|
#ifdef DLMS_IGNORE_OBJECT_POINTERS
|
|
objectDefinition = (gxObjectDefinition*)gxmalloc(sizeof(gxObjectDefinition));
|
|
objectDefinition->objectType = (DLMS_OBJECT_TYPE)type;
|
|
memcpy(objectDefinition->logicalName, ln, 6);
|
|
arr_push(&object->registerAssignment, objectDefinition);
|
|
#else
|
|
if (type != 0)
|
|
{
|
|
if ((ret = cosem_findObjectByLN(settings, type, ln, &objectDefinition)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
oa_push(&object->registerAssignment, objectDefinition);
|
|
}
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
#ifdef DLMS_IGNORE_OBJECT_POINTERS
|
|
if (ret != 0 && objectDefinition != NULL)
|
|
{
|
|
gxfree(objectDefinition);
|
|
}
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
obj_clearRegisterActivationMaskList(&object->maskList);
|
|
int pos2;
|
|
gxByteBuffer* start = NULL, * end = NULL;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
start = (gxByteBuffer*)gxmalloc(sizeof(gxByteBuffer));
|
|
BYTE_BUFFER_INIT(start);
|
|
end = (gxByteBuffer*)gxmalloc(sizeof(gxByteBuffer));
|
|
BYTE_BUFFER_INIT(end);
|
|
bb_set(start, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
for (pos2 = 0; pos2 != tmp3->Arr->size; ++pos2)
|
|
{
|
|
if ((ret = va_getByIndex(tmp3->Arr, pos2, &tmp)) != 0 ||
|
|
(ret = bb_setUInt8(end, (unsigned char)var_toInteger(tmp))) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->maskList, key_init(start, end));
|
|
}
|
|
if (ret != 0)
|
|
{
|
|
if (start != NULL)
|
|
{
|
|
gxfree(start);
|
|
}
|
|
if (end != NULL)
|
|
{
|
|
gxfree(end);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
bb_clear(&object->activeMask);
|
|
ret = bb_set2(&object->activeMask, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_REGISTER_ACTIVATION
|
|
#ifndef DLMS_IGNORE_REGISTER_MONITOR
|
|
int cosem_setRegisterMonitor(dlmsSettings* settings, gxRegisterMonitor* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
gxActionSet* actionSet = NULL;
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT* tmp3, * tmp4;
|
|
if (index == 2)
|
|
{
|
|
va_clear(&object->thresholds);
|
|
if (value->Arr != NULL)
|
|
{
|
|
va_capacity(&object->thresholds, value->Arr->size);
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
tmp3 = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
tmp3 = (dlmsVARIANT*)gxmalloc(sizeof(dlmsVARIANT));
|
|
if (tmp3 == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
var_init(tmp3);
|
|
ret = var_copy(tmp3, tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
va_push(&object->thresholds, tmp3);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
signed short type;
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
type = (short)var_toInteger(tmp);
|
|
#else
|
|
object->monitoredValue.objectType = (DLMS_OBJECT_TYPE)var_toInteger(tmp);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, type, tmp->byteArr->data, &object->monitoredValue.target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (object->monitoredValue.target == NULL)
|
|
{
|
|
ret = cosem_createObject(type, &object->monitoredValue.target);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = cosem_setLogicalName(object->monitoredValue.target, tmp->byteArr->data);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, object->monitoredValue.target);
|
|
}
|
|
#else
|
|
memcpy(object->monitoredValue.logicalName, tmp->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(value->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->monitoredValue.attributeIndex = (unsigned char)var_toInteger(tmp);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
obj_clearRegisterMonitorActions(&object->actions);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
actionSet = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp4);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
actionSet = (gxActionSet*)gxmalloc(sizeof(gxActionSet));
|
|
//Update action up.
|
|
ret = va_getByIndex(tmp4->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp3->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
actionSet->actionUp.script = NULL;
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SCRIPT_TABLE, tmp->byteArr->data, (gxObject**)&actionSet->actionUp.script)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (actionSet->actionUp.script == NULL)
|
|
{
|
|
ret = cosem_createObject(DLMS_OBJECT_TYPE_SCRIPT_TABLE, (gxObject**)&actionSet->actionUp.script);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = cosem_setLogicalName((gxObject*)actionSet->actionUp.script, tmp->byteArr->data);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, (gxObject*)actionSet->actionUp.script);
|
|
}
|
|
#else
|
|
memcpy(actionSet->actionUp.logicalName, tmp->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp3->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
actionSet->actionUp.scriptSelector = (uint16_t)var_toInteger(tmp);
|
|
//Update action down.
|
|
ret = va_getByIndex(tmp4->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp3->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
actionSet->actionDown.script = NULL;
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SCRIPT_TABLE, tmp->byteArr->data, (gxObject**)&actionSet->actionDown.script)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (actionSet->actionDown.script == NULL)
|
|
{
|
|
ret = cosem_createObject(DLMS_OBJECT_TYPE_SCRIPT_TABLE, (gxObject**)&actionSet->actionDown.script);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = cosem_setLogicalName((gxObject*)actionSet->actionDown.script, tmp->byteArr->data);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, (gxObject*)actionSet->actionDown.script);
|
|
}
|
|
#else
|
|
memcpy(actionSet->actionDown.logicalName, tmp->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp3->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
actionSet->actionDown.scriptSelector = (uint16_t)var_toInteger(tmp);
|
|
arr_push(&object->actions, actionSet);
|
|
}
|
|
if (ret != 0 && actionSet != NULL)
|
|
{
|
|
gxfree(actionSet);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif //DLMS_IGNORE_REGISTER_MONITOR
|
|
#ifndef DLMS_IGNORE_SAP_ASSIGNMENT
|
|
int cosem_setSapAssignment(gxSapAssignment* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK, pos;
|
|
gxSapItem* it = NULL;
|
|
if (index == 2)
|
|
{
|
|
obj_clearSapList(&object->sapAssignmentList);
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
it = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxSapItem*)gxmalloc(sizeof(gxSapItem));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
BYTE_BUFFER_INIT(&it->name);
|
|
it->id = (uint16_t)var_toInteger(tmp2);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
bb_set(&it->name, tmp2->byteArr->data, tmp2->byteArr->size);
|
|
arr_push(&object->sapAssignmentList, it);
|
|
}
|
|
if (ret != 0 && it != NULL)
|
|
{
|
|
gxfree(it);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SAP_ASSIGNMENT
|
|
#ifndef DLMS_IGNORE_SCHEDULE
|
|
int cosem_setSchedule(dlmsSettings* settings, gxSchedule* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
gxScheduleEntry* se;
|
|
int ret = 0, pos;
|
|
if (index == 2)
|
|
{
|
|
obj_clearScheduleEntries(&object->entries);
|
|
dlmsVARIANT* tmp, * it;
|
|
dlmsVARIANT tmp3;
|
|
var_init(&tmp3);
|
|
if (value->Arr != NULL)
|
|
{
|
|
se = NULL;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
se = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
se = (gxScheduleEntry*)gxmalloc(sizeof(gxScheduleEntry));
|
|
if (se == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
se->execWeekdays = 0;
|
|
ba_init(&se->execSpecDays);
|
|
ret = va_getByIndex(tmp->Arr, 0, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
se->index = (uint16_t)var_toInteger(it);
|
|
ret = va_getByIndex(tmp->Arr, 1, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
se->enable = (unsigned char)var_toInteger(it);
|
|
|
|
ret = va_getByIndex(tmp->Arr, 2, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SCRIPT_TABLE, it->byteArr->data, (gxObject**)&se->scriptTable)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (se->scriptTable == NULL)
|
|
{
|
|
ret = cosem_createObject(DLMS_OBJECT_TYPE_SCRIPT_TABLE, (gxObject**)&se->scriptTable);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = cosem_setLogicalName((gxObject*)se->scriptTable, tmp->byteArr->data);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, (gxObject*)se->scriptTable);
|
|
}
|
|
#else
|
|
memcpy(se->logicalName, it->byteArr->data, bb_size(it->byteArr));
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp->Arr, 3, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
se->scriptSelector = (uint16_t)var_toInteger(it);
|
|
ret = va_getByIndex(tmp->Arr, 4, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = dlms_changeType2(it, DLMS_DATA_TYPE_TIME, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
time_copy(&se->switchTime, tmp3.dateTime);
|
|
ret = va_getByIndex(tmp->Arr, 5, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
se->validityWindow = (uint16_t)var_toInteger(it);
|
|
|
|
ret = va_getByIndex(tmp->Arr, 6, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (it->bitArr != NULL)
|
|
{
|
|
uint32_t val;
|
|
if ((ret = ba_toInteger(it->bitArr, &val)) == 0)
|
|
{
|
|
se->execWeekdays = val;
|
|
}
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 7, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (it->bitArr != NULL)
|
|
{
|
|
ba_copy(&se->execSpecDays, it->bitArr->data, (uint16_t)it->bitArr->size);
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 8, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = dlms_changeType2(it, DLMS_DATA_TYPE_DATE, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
time_copy(&se->beginDate, tmp3.dateTime);
|
|
var_clear(&tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 9, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = dlms_changeType2(it, DLMS_DATA_TYPE_DATE, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
time_copy(&se->endDate, tmp3.dateTime);
|
|
arr_push(&object->entries, se);
|
|
var_clear(&tmp3);
|
|
}
|
|
if (ret != 0 && se != NULL)
|
|
{
|
|
gxfree(se);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SCHEDULE
|
|
|
|
#ifndef DLMS_IGNORE_SCRIPT_TABLE
|
|
int cosem_setScriptTable(dlmsSettings* settings, gxScriptTable* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos, pos2;
|
|
gxScriptAction* scriptAction;
|
|
gxScript* script;
|
|
if (index == 2)
|
|
{
|
|
obj_clearScriptTable(&object->scripts);
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
uint16_t type;
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
dlmsVARIANT* tmp, * tmp2, * tmp3;
|
|
if (value->Arr->size != 0)
|
|
{
|
|
script = NULL;
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Fix Xemex bug here.
|
|
//Xemex meters do not return array as they should be according standard.
|
|
if (value->vt == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
script = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
script = (gxScript*)gxmalloc(sizeof(gxScript));
|
|
if (script == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
arr_init(&script->actions);
|
|
script->id = (uint16_t)var_toInteger(tmp3);
|
|
arr_push(&object->scripts, script);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
scriptAction = NULL;
|
|
for (pos2 = 0; pos2 != tmp3->Arr->size; ++pos2)
|
|
{
|
|
scriptAction = NULL;
|
|
ret = va_getByIndex(tmp3->Arr, pos2, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp2->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
scriptAction = (gxScriptAction*)gxmalloc(sizeof(gxScriptAction));
|
|
if (scriptAction == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
var_init(&scriptAction->parameter);
|
|
scriptAction->type = (DLMS_SCRIPT_ACTION_TYPE)var_toInteger(tmp);
|
|
ret = va_getByIndex(tmp2->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
#ifdef DLMS_IGNORE_OBJECT_POINTERS
|
|
scriptAction->objectType = (DLMS_OBJECT_TYPE)var_toInteger(tmp);
|
|
#else
|
|
type = (DLMS_OBJECT_TYPE)var_toInteger(tmp);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp2->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
#ifdef DLMS_IGNORE_OBJECT_POINTERS
|
|
if (bb_size(tmp->byteArr) == 6)
|
|
{
|
|
memcpy(scriptAction->logicalName, tmp->byteArr->data, 6);
|
|
}
|
|
#else
|
|
if ((ret = oa_findByLN(&settings->objects, type, tmp->byteArr->data, &scriptAction->target)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp2->Arr, 3, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
scriptAction->index = (char)var_toInteger(tmp);
|
|
ret = va_getByIndex(tmp2->Arr, 4, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
var_copy(&scriptAction->parameter, tmp);
|
|
arr_push(&script->actions, scriptAction);
|
|
}
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
if (scriptAction != NULL)
|
|
{
|
|
gxfree(scriptAction);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (ret != 0 && script != NULL)
|
|
{
|
|
gxfree(script);
|
|
}
|
|
}
|
|
else //Read Xemex meter here.
|
|
{
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp2->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
script = (gxScript*)gxmalloc(sizeof(gxScript));
|
|
if (script == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
arr_init(&script->actions);
|
|
script->id = (uint16_t)var_toInteger(tmp3);
|
|
arr_push(&object->scripts, script);
|
|
ret = va_getByIndex(tmp->Arr, 3, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
scriptAction = (gxScriptAction*)gxmalloc(sizeof(gxScriptAction));
|
|
if (scriptAction == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
var_init(&scriptAction->parameter);
|
|
scriptAction->type = (DLMS_SCRIPT_ACTION_TYPE)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp2->Arr, 4, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
#ifdef DLMS_IGNORE_OBJECT_POINTERS
|
|
scriptAction->objectType = (DLMS_OBJECT_TYPE)var_toInteger(tmp3);
|
|
#else
|
|
type = (uint16_t)var_toInteger(tmp3);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp2->Arr, 5, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifdef DLMS_IGNORE_OBJECT_POINTERS
|
|
memcpy(scriptAction->logicalName, tmp3->byteArr->data, 6);
|
|
#else
|
|
if ((ret = oa_findByLN(&settings->objects, type, tmp3->byteArr->data, &scriptAction->target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
ret = va_getByIndex(tmp2->Arr, 6, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
scriptAction->index = (char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp2->Arr, 7, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
var_copy(&scriptAction->parameter, tmp);
|
|
arr_push(&script->actions, scriptAction);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SCRIPT_TABLE
|
|
#ifndef DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
|
int cosem_setSpecialDaysTable(gxSpecialDaysTable* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
gxSpecialDay* specialDay;
|
|
if (index == 2)
|
|
{
|
|
arr_clear(&object->entries);
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
dlmsVARIANT tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
specialDay = NULL;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
specialDay = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
specialDay = (gxSpecialDay*)gxmalloc(sizeof(gxSpecialDay));
|
|
if (specialDay == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
specialDay->index = (uint16_t)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
var_init(&tmp2);
|
|
ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATE, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&specialDay->date, tmp2.dateTime);
|
|
var_clear(&tmp2);
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
specialDay->dayId = (unsigned char)var_toInteger(tmp3);
|
|
arr_push(&object->entries, specialDay);
|
|
}
|
|
if (ret != 0 && specialDay != NULL)
|
|
{
|
|
gxfree(specialDay);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SPECIAL_DAYS_TABLE
|
|
#ifndef DLMS_IGNORE_TCP_UDP_SETUP
|
|
int cosem_setTcpUdpSetup(dlmsSettings* settings, gxTcpUdpSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
if (index == 2)
|
|
{
|
|
object->port = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
if (value->vt == DLMS_DATA_TYPE_NONE)
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
object->ipSetup = NULL;
|
|
#else
|
|
memset(object->ipReference, 0, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
else
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
unsigned char ln[6];
|
|
if ((ret = bb_get(value->byteArr, ln, 6)) != 0 ||
|
|
(ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_IP4_SETUP, ln, &object->ipSetup)) != 0)
|
|
{
|
|
|
|
}
|
|
#else
|
|
ret = bb_get(value->byteArr, object->ipReference, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->maximumSegmentSize = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->maximumSimultaneousConnections = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->inactivityTimeout = (uint16_t)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_TCP_UDP_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_MBUS_DIAGNOSTIC
|
|
int cosem_setMbusDiagnostic(gxMbusDiagnostic* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
gxBroadcastFrameCounter* item;
|
|
if (index == 2)
|
|
{
|
|
object->receivedSignalStrength = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->channelId = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->linkStatus = (DLMS_MBUS_LINK_STATUS)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
item = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
item = (gxBroadcastFrameCounter*)gxmalloc(sizeof(gxBroadcastFrameCounter));
|
|
if (item == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(item);
|
|
break;
|
|
}
|
|
item->clientId = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(item);
|
|
break;
|
|
}
|
|
item->counter = tmp3->ulVal;
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(item);
|
|
break;
|
|
}
|
|
item->timeStamp = *tmp3->dateTime;
|
|
arr_push(&object->broadcastFrames, item);
|
|
}
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->transmissions = value->ulVal;
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->receivedFrames = value->ulVal;
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->failedReceivedFrames = value->ulVal;
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, 0, &tmp)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->captureTime.attributeId = tmp->bVal;
|
|
if ((ret = va_getByIndex(value->Arr, 1, &tmp)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->captureTime.timeStamp = *tmp->dateTime;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_MBUS_DIAGNOSTIC
|
|
|
|
|
|
#ifndef DLMS_IGNORE_MBUS_PORT_SETUP
|
|
int cosem_setMbusPortSetup(gxMBusPortSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
if (index == 2)
|
|
{
|
|
memcpy(object->profileSelection, value->byteArr->data, value->byteArr->size);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->portCommunicationStatus = (DLMS_MBUS_PORT_COMMUNICATION_STATE)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->dataHeaderType = (DLMS_MBUS_DATA_HEADER_TYPE)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->primaryAddress = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->identificationNumber = (uint32_t)var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->manufacturerId = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->mBusVersion = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->deviceType = (DLMS_MBUS_METER_TYPE)var_toInteger(value);
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
object->maxPduSize = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
arr_clearKeyValuePair(&object->listeningWindow);
|
|
dlmsVARIANT start, end;
|
|
gxtime* s, * e;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
var_init(&start);
|
|
var_init(&end);
|
|
ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATETIME, &start);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATETIME, &end);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
s = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
e = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
time_copy(s, start.dateTime);
|
|
time_copy(e, end.dateTime);
|
|
arr_push(&object->listeningWindow, key_init(s, e));
|
|
var_clear(&start);
|
|
var_clear(&end);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_MBUS_PORT_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
|
int cosem_setMbusMasterPortSetup(gxMBusMasterPortSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
if (index == 2)
|
|
{
|
|
object->commSpeed = (DLMS_BAUD_RATE)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
#endif //DLMS_IGNORE_MBUS_MASTER_PORT_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
|
int cosem_setG3PlcMacLayerCounters(gxG3PlcMacLayerCounters* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
if (index == 2)
|
|
{
|
|
object->txDataPacketCount = value->ulVal;
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->rxDataPacketCount = value->ulVal;
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->txCmdPacketCount = value->ulVal;
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->rxCmdPacketCount = value->ulVal;
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->cSMAFailCount = value->ulVal;
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->cSMANoAckCount = value->ulVal;
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->badCrcCount = value->ulVal;
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->txDataBroadcastCount = value->ulVal;
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
object->rxDataBroadcastCount = value->ulVal;
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_G3_PLC_MAC_LAYER_COUNTERS
|
|
|
|
#ifndef DLMS_IGNORE_G3_PLC_MAC_SETUP
|
|
int cosem_setG3PlcMacSetup(gxG3PlcMacSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
if (index == 2)
|
|
{
|
|
object->shortAddress = value->uiVal;
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->rcCoord = value->uiVal;
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->panId = value->uiVal;
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
arr_clear(&object->keyTable);
|
|
gxG3MacKeyTable* it;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxG3MacKeyTable*)gxmalloc(sizeof(gxG3MacKeyTable));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->id = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
memcpy(it->key, tmp2->byteArr->data, bb_size(tmp2->byteArr));
|
|
arr_push(&object->keyTable, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->frameCounter = value->ulVal;
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
ba_clear(&object->toneMask);
|
|
if (value->bitArr != NULL)
|
|
{
|
|
ba_copy(&object->toneMask, value->bitArr->data, ba_size(value->bitArr));
|
|
}
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->tmrTtl = value->bVal;
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->maxFrameRetries = value->bVal;
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
object->neighbourTableEntryTtl = value->bVal;
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
gxNeighbourTable* it;
|
|
obj_clearNeighbourTable(&object->neighbourTable);
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxNeighbourTable*)gxmalloc(sizeof(gxNeighbourTable));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
ba_init(&it->txCoeff);
|
|
ba_init(&it->toneMap);
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->shortAddress = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->payloadModulationScheme = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp2->bitArr != NULL)
|
|
{
|
|
ba_copy(&it->toneMap, tmp2->bitArr->data, ba_size(tmp2->bitArr));
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 3, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->modulation = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->txGain = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 5, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->txRes = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 6, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp2->bitArr != NULL)
|
|
{
|
|
ba_copy(&it->txCoeff, tmp2->bitArr->data, ba_size(tmp2->bitArr));
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 7, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->lqi = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 8, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->phaseDifferential = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 9, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->tmrValidTime = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 10, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->neighbourTable, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 12)
|
|
{
|
|
object->highPriorityWindowSize = value->bVal;
|
|
}
|
|
else if (index == 13)
|
|
{
|
|
object->cscmFairnessLimit = value->bVal;
|
|
}
|
|
else if (index == 14)
|
|
{
|
|
object->beaconRandomizationWindowLength = value->bVal;
|
|
}
|
|
else if (index == 15)
|
|
{
|
|
object->macA = value->bVal;
|
|
}
|
|
else if (index == 16)
|
|
{
|
|
object->macK = value->bVal;
|
|
}
|
|
else if (index == 17)
|
|
{
|
|
object->minCwAttempts = value->bVal;
|
|
}
|
|
else if (index == 18)
|
|
{
|
|
object->cenelecLegacyMode = value->bVal;
|
|
}
|
|
else if (index == 19)
|
|
{
|
|
object->fccLegacyMode = value->bVal;
|
|
}
|
|
else if (index == 20)
|
|
{
|
|
object->maxBe = value->bVal;
|
|
}
|
|
else if (index == 21)
|
|
{
|
|
object->maxCsmaBackoffs = value->bVal;
|
|
}
|
|
else if (index == 22)
|
|
{
|
|
object->minBe = value->bVal;
|
|
}
|
|
else if (index == 23)
|
|
{
|
|
object->macBroadcastMaxCwEnabled = value->bVal;
|
|
}
|
|
else if (index == 24)
|
|
{
|
|
object->macTransmitAtten = value->bVal;
|
|
}
|
|
else if (index == 25)
|
|
{
|
|
arr_clear(&object->macPosTable);
|
|
gxMacPosTable* it;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxMacPosTable*)gxmalloc(sizeof(gxMacPosTable));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->shortAddress = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->lqi = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->validTime = tmp2->cVal;
|
|
arr_push(&object->macPosTable, it);
|
|
}
|
|
}
|
|
}
|
|
else if (object->base.version > 2 && index == 26)
|
|
{
|
|
object->macDuplicateDetectionTTL = value->bVal;
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_G3_PLC_MAC_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_G3_PLC_6LO_WPAN
|
|
|
|
int cosem_getUint16Array(variantArray* arr, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
dlmsVARIANT* it;
|
|
va_clear(arr);
|
|
dlmsVARIANT* tmp;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (dlmsVARIANT*)gxmalloc(sizeof(dlmsVARIANT));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
var_init(it);
|
|
ret = var_copy(it, tmp);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
va_push(arr, it);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int cosem_setG3Plc6LoWPAN(gxG3Plc6LoWPAN* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
if (index == 2)
|
|
{
|
|
object->maxHops = value->bVal;
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->weakLqiValue = value->bVal;
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->securityLevel = value->bVal;
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
bb_clear(&object->prefixTable);
|
|
dlmsVARIANT* tmp;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = bb_setUInt8(&object->prefixTable, tmp->bVal)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
arr_clear(&object->routingConfiguration);
|
|
gxRoutingConfiguration* it;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxRoutingConfiguration*)gxmalloc(sizeof(gxRoutingConfiguration));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->netTraversalTime = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->routingTableEntryTtl = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->kr = tmp2->cVal;
|
|
|
|
if ((ret = va_getByIndex(tmp->Arr, 3, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->km = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->kc = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 5, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->kq = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 6, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->kh = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 7, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->krt = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 8, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->rReqRetries = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 9, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->rReqReqWait = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 10, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->blacklistTableEntryTtl = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 11, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->unicastRreqGenEnable = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 12, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->rlcEnabled = tmp2->cVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 13, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->addRevLinkCost = tmp2->cVal;
|
|
arr_push(&object->routingConfiguration, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->broadcastLogTableEntryTtl = value->uiVal;
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
arr_clear(&object->routingTable);
|
|
gxRoutingTable* it;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxRoutingTable*)gxmalloc(sizeof(gxRoutingTable));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->destinationAddress = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->nextHopAddress = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->routeCost = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 3, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->hopCount = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->weakLinkCount = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 5, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->validTime = tmp2->uiVal;
|
|
arr_push(&object->routingTable, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
arr_clear(&object->contextInformationTable);
|
|
gxContextInformationTable* it;
|
|
uint32_t v;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxContextInformationTable*)gxmalloc(sizeof(gxContextInformationTable));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = ba_toInteger(tmp2->bitArr, &v)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->cid = (unsigned char)v;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->contextLength = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp2->byteArr != NULL)
|
|
{
|
|
int size = bb_size(tmp2->byteArr);
|
|
if (size > 16)
|
|
{
|
|
size = 16;
|
|
}
|
|
memcpy(it->context, tmp2->byteArr->data, size);
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 3, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->compression = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->validLifetime = tmp2->uiVal;
|
|
arr_push(&object->contextInformationTable, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
arr_clear(&object->blacklistTable);
|
|
gxBlacklistTable* it;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxBlacklistTable*)gxmalloc(sizeof(gxBlacklistTable));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->neighbourAddress = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->validTime = tmp2->uiVal;
|
|
arr_push(&object->blacklistTable, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
gxBroadcastLogTable* it;
|
|
arr_clear(&object->broadcastLogTable);
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxBroadcastLogTable*)gxmalloc(sizeof(gxBroadcastLogTable));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->sourceAddress = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->sequenceNumber = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->validTime = tmp2->uiVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->broadcastLogTable, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 12)
|
|
{
|
|
ret = cosem_getUint16Array(&object->groupTable, value);
|
|
}
|
|
else if (index == 13)
|
|
{
|
|
object->maxJoinWaitTime = value->uiVal;
|
|
}
|
|
else if (index == 14)
|
|
{
|
|
object->pathDiscoveryTime = value->bVal;
|
|
}
|
|
else if (index == 15)
|
|
{
|
|
object->activeKeyIndex = value->bVal;
|
|
}
|
|
else if (index == 16)
|
|
{
|
|
object->metricType = value->bVal;
|
|
}
|
|
else if (index == 17)
|
|
{
|
|
object->coordShortAddress = value->uiVal;
|
|
}
|
|
else if (index == 18)
|
|
{
|
|
object->disableDefaultRouting = value->bVal;
|
|
}
|
|
else if (index == 19)
|
|
{
|
|
object->deviceType = (DLMS_PAN_DEVICE_TYPE)value->bVal;
|
|
}
|
|
else if (index == 20)
|
|
{
|
|
object->defaultCoordRouteEnabled = value->bVal;
|
|
}
|
|
else if (index == 21)
|
|
{
|
|
ret = cosem_getUint16Array(&object->destinationAddress, value);
|
|
}
|
|
else if (index == 22)
|
|
{
|
|
object->lowLQI = value->bVal;
|
|
}
|
|
else if (index == 23)
|
|
{
|
|
object->highLQI = value->bVal;
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_G3_PLC_6LO_WPAN
|
|
|
|
#ifndef DLMS_IGNORE_FUNCTION_CONTROL
|
|
int cosem_setFunctionControl(
|
|
dlmsSettings* settings,
|
|
gxFunctionControl* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int pos, pos2, ret = 0;
|
|
if (index == 2)
|
|
{
|
|
functionStatus* it;
|
|
obj_clearActivationStatus(&object->activationStatus);
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (functionStatus*)gxmalloc(sizeof(functionStatus));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
bb_init(&it->name);
|
|
bb_set2(&it->name, tmp2->byteArr, 0, bb_size(tmp2->byteArr));
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->status = tmp2->bVal;
|
|
arr_push(&object->activationStatus, it);
|
|
}
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
functionalBlock* it;
|
|
gxObject* target;
|
|
obj_clearFunctionList(&object->functions);
|
|
dlmsVARIANT* tmp, * tmp2, * tmp3, * tmp4;
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (functionalBlock*)gxmalloc(sizeof(functionalBlock));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
oa_init(&it->functionSpecifications);
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
bb_init(&it->name);
|
|
bb_set2(&it->name, tmp2->byteArr, 0, bb_size(tmp2->byteArr));
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
for (pos2 = 0; pos2 != tmp2->Arr->size; ++pos2)
|
|
{
|
|
if ((ret = va_getByIndex(tmp2->Arr, pos, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp3->Arr, 0, &tmp4)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
uint16_t ot = tmp4->uiVal;
|
|
//Get LN.
|
|
if ((ret = va_getByIndex(tmp3->Arr, 1, &tmp4)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = oa_findByLN(&settings->objects, ot, tmp4->byteArr->data, &target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (target == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(ot, &target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
oa_push(&settings->releasedObjects, target);
|
|
memcpy(target->logicalName, tmp4->byteArr->data, bb_size(tmp4->byteArr));
|
|
}
|
|
oa_push(&it->functionSpecifications, target);
|
|
}
|
|
arr_push(&object->functions, it);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif //DLMS_IGNORE_FUNCTION_CONTROL
|
|
|
|
#ifndef DLMS_IGNORE_ARRAY_MANAGER
|
|
|
|
int cosem_setArrayManager(
|
|
dlmsSettings* settings,
|
|
gxArrayManager* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
if (index == 2)
|
|
{
|
|
arr_clear(&object->elements);
|
|
gxArrayManagerItem* it;
|
|
dlmsVARIANT* tmp, * tmp2, * tmp3;
|
|
uint16_t ot;
|
|
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxArrayManagerItem*)gxmalloc(sizeof(gxArrayManagerItem));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->id = tmp2->bVal;
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp2->Arr, 0, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ot = tmp3->uiVal;
|
|
if ((ret = va_getByIndex(tmp2->Arr, 2, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->element.attributeIndex = tmp3->bVal;
|
|
//Get LN.
|
|
if ((ret = va_getByIndex(tmp2->Arr, 1, &tmp3)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->element.target = NULL;
|
|
if ((ret = oa_findByLN(&settings->objects, ot, tmp3->byteArr->data, &it->element.target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (it->element.target == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(ot, &it->element.target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
oa_push(&settings->releasedObjects, it->element.target);
|
|
memcpy(it->element.target->logicalName, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
}
|
|
arr_push(&object->elements, it);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_ARRAY_MANAGER
|
|
|
|
#ifndef DLMS_IGNORE_PUSH_SETUP
|
|
int cosem_setPushSetup(dlmsSettings* settings, gxPushSetup* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret, pos;
|
|
gxTarget* it;
|
|
gxObject* obj;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
gxtime* s, * e;
|
|
if (index == 2)
|
|
{
|
|
DLMS_OBJECT_TYPE type = DLMS_OBJECT_TYPE_NONE;
|
|
obj_clearPushObjectList(&object->pushObjectList);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
type = (DLMS_OBJECT_TYPE)var_toInteger(tmp3);
|
|
//Get LN.
|
|
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
obj = NULL;
|
|
if ((ret = oa_findByLN(&settings->objects, type, tmp3->byteArr->data, &obj)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (obj == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(type, &obj)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
oa_push(&settings->releasedObjects, obj);
|
|
memcpy(obj->logicalName, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
}
|
|
it = (gxTarget*)gxmalloc(sizeof(gxTarget));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->attributeIndex = (unsigned char)var_toInteger(tmp3);
|
|
ret = va_getByIndex(tmp->Arr, 3, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->dataIndex = (unsigned char)var_toInteger(tmp3);
|
|
arr_push(&object->pushObjectList, key_init(obj, it));
|
|
}
|
|
}
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
bb_clear(&object->destination);
|
|
//Get service.
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->service = (DLMS_SERVICE_TYPE)var_toInteger(tmp);
|
|
//Destination.
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
if (tmp->byteArr != NULL && tmp->byteArr->size != 0)
|
|
{
|
|
bb_clear(&object->destination);
|
|
bb_set(&object->destination, tmp->byteArr->data, tmp->byteArr->size);
|
|
}
|
|
//Message.
|
|
ret = va_getByIndex(value->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->message = (DLMS_MESSAGE_TYPE)var_toInteger(tmp);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
arr_clearKeyValuePair(&object->communicationWindow);
|
|
if (value->Arr != NULL)
|
|
{
|
|
dlmsVARIANT start, end;
|
|
var_init(&start);
|
|
var_init(&end);
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != 0 ||
|
|
(ret = va_getByIndex(tmp->Arr, 0, &tmp3)) != 0 ||
|
|
(ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATETIME, &start)) != 0 ||
|
|
(ret = va_getByIndex(tmp->Arr, 1, &tmp3)) != 0 ||
|
|
(ret = dlms_changeType2(tmp3, DLMS_DATA_TYPE_DATETIME, &end)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
s = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
e = (gxtime*)gxmalloc(sizeof(gxtime));
|
|
time_copy(s, start.dateTime);
|
|
time_copy(e, end.dateTime);
|
|
arr_push(&object->communicationWindow, key_init(s, e));
|
|
}
|
|
var_clear(&start);
|
|
var_clear(&end);
|
|
}
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->randomisationStartInterval = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->numberOfRetries = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->repetitionDelay = (uint16_t)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
#endif //DLMS_IGNORE_PUSH_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_CHARGE
|
|
int setUnitCharge(dlmsSettings* settings, gxUnitCharge* target, dlmsVARIANT* value)
|
|
{
|
|
gxChargeTable* ct;
|
|
int ret, pos;
|
|
ret = obj_clearChargeTables(&target->chargeTables);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
signed short type;
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
dlmsVARIANT* it, * it2, * tmp;
|
|
//charge per unit scaling
|
|
ret = va_getByIndex(value->Arr, 0, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
//commodity scale
|
|
ret = va_getByIndex(it->Arr, 0, &it2);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
target->chargePerUnitScaling.commodityScale = (char)var_toInteger(it2);
|
|
//price scale
|
|
ret = va_getByIndex(it->Arr, 1, &it2);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
target->chargePerUnitScaling.priceScale = (char)var_toInteger(it2);
|
|
//commodity
|
|
ret = va_getByIndex(value->Arr, 1, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
//type
|
|
ret = va_getByIndex(it->Arr, 0, &it2);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
type = (DLMS_OBJECT_TYPE)var_toInteger(it2);
|
|
#else
|
|
target->commodity.type = (DLMS_OBJECT_TYPE)var_toInteger(it2);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
//LN
|
|
ret = va_getByIndex(it->Arr, 1, &it2);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if (bb_size(it2->byteArr) == 6)
|
|
{
|
|
if ((ret = oa_findByLN(&settings->objects, type, it2->byteArr->data, &target->commodity.target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
target->commodity.target = NULL;
|
|
}
|
|
#else
|
|
memset(target->commodity.logicalName, 0, 6);
|
|
if (it2->byteArr != NULL && it2->byteArr->size == 6)
|
|
{
|
|
memcpy(target->commodity.logicalName, it2->byteArr->data, 6);
|
|
}
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
//attribute index
|
|
ret = va_getByIndex(it->Arr, 2, &it2);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
target->commodity.attributeIndex = (unsigned char)var_toInteger(it2);
|
|
//chargeTables
|
|
obj_clearChargeTables(&target->chargeTables);
|
|
ret = va_getByIndex(value->Arr, 2, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
for (pos = 0; pos != it->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(it->Arr, pos, &it2);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
ct = (gxChargeTable*)gxmalloc(sizeof(gxChargeTable));
|
|
if (ct == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
arr_push(&target->chargeTables, ct);
|
|
BYTE_BUFFER_INIT(&ct->index);
|
|
//index
|
|
ret = va_getByIndex(it2->Arr, 0, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
bb_set2(&ct->index, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
//chargePerUnit
|
|
ret = va_getByIndex(it2->Arr, 1, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
ct->chargePerUnit = (short)var_toInteger(tmp);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int cosem_setCharge(dlmsSettings* settings, gxCharge* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
dlmsVARIANT tmp;
|
|
if (index == 2)
|
|
{
|
|
object->totalAmountPaid = (short)var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->chargeType = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->priority = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
ret = setUnitCharge(settings, &object->unitChargeActive, value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
ret = setUnitCharge(settings, &object->unitChargePassive, value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
var_init(&tmp);
|
|
if ((ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp)) != 0)
|
|
{
|
|
var_clear(&tmp);
|
|
return ret;
|
|
}
|
|
time_copy(&object->unitChargeActivationTime, tmp.dateTime);
|
|
var_clear(&tmp);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->unitChargeActivationTime);
|
|
}
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->period = var_toInteger(value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->chargeConfiguration = var_toInteger(value);
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
if (value->vt == DLMS_DATA_TYPE_DATETIME)
|
|
{
|
|
object->lastCollectionTime = *value->dateTime;
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
object->lastCollectionAmount = var_toInteger(value);
|
|
}
|
|
else if (index == 12)
|
|
{
|
|
object->totalAmountRemaining = var_toInteger(value);
|
|
}
|
|
else if (index == 13)
|
|
{
|
|
object->proportion = (uint16_t)var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_CHARGE
|
|
#ifndef DLMS_IGNORE_CREDIT
|
|
int cosem_setCredit(gxCredit* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
dlmsVARIANT tmp;
|
|
if (index == 2)
|
|
{
|
|
object->currentCreditAmount = var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->type = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->priority = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->warningThreshold = var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->limit = var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->creditConfiguration = var_toInteger(value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->status = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
object->presetCreditAmount = var_toInteger(value);
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
object->creditAvailableThreshold = var_toInteger(value);
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
var_init(&tmp);
|
|
ret = dlms_changeType(value->byteArr, DLMS_DATA_TYPE_DATETIME, &tmp);
|
|
if (ret == 0)
|
|
{
|
|
time_copy(&object->period, tmp.dateTime);
|
|
}
|
|
var_clear(&tmp);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_CREDIT
|
|
#ifndef DLMS_IGNORE_ACCOUNT
|
|
int cosem_setAccount(gxAccount* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
unsigned char* ba;
|
|
dlmsVARIANT* it;
|
|
dlmsVARIANT tmp;
|
|
dlmsVARIANT* tmp2;
|
|
gxCreditChargeConfiguration* ccc;
|
|
gxTokenGatewayConfiguration* gwc;
|
|
if (index == 2)
|
|
{
|
|
//payment mode
|
|
ret = va_getByIndex(value->Arr, 0, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->paymentMode = (DLMS_ACCOUNT_PAYMENT_MODE)var_toInteger(it);
|
|
//account status
|
|
ret = va_getByIndex(value->Arr, 1, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->accountStatus = (DLMS_ACCOUNT_STATUS)var_toInteger(it);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->currentCreditInUse = (unsigned char)var_toInteger(value);
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
if (value->bitArr == NULL || value->bitArr->size == 0)
|
|
{
|
|
return DLMS_ERROR_CODE_READ_WRITE_DENIED;
|
|
}
|
|
else
|
|
{
|
|
object->currentCreditStatus = (DLMS_ACCOUNT_CREDIT_STATUS)var_toInteger(value);
|
|
}
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->availableCredit = var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->amountToClear = var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->clearanceThreshold = var_toInteger(value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->aggregatedDebt = var_toInteger(value);
|
|
}
|
|
else if (index == 9)
|
|
{
|
|
arr_clear(&object->creditReferences);
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (it->byteArr == NULL || it->byteArr->size != 6)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ba = (unsigned char*)gxmalloc(6);
|
|
memcpy(ba, it->byteArr->data, 6);
|
|
arr_push(&object->creditReferences, ba);
|
|
}
|
|
}
|
|
else if (index == 10)
|
|
{
|
|
arr_clear(&object->chargeReferences);
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (it->byteArr == NULL || it->byteArr->size != 6)
|
|
{
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ba = (unsigned char*)gxmalloc(6);
|
|
memcpy(ba, it->byteArr->data, 6);
|
|
arr_push(&object->chargeReferences, ba);
|
|
}
|
|
}
|
|
else if (index == 11)
|
|
{
|
|
ccc = NULL;
|
|
obj_clearCreditChargeConfigurations(&object->creditChargeConfigurations);
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &it);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
ccc = (gxCreditChargeConfiguration*)gxmalloc(sizeof(gxCreditChargeConfiguration));
|
|
if (ccc == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
//credit reference
|
|
ret = va_getByIndex(it->Arr, 0, &tmp2);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
memcpy(ccc->creditReference, tmp2->byteArr->data, tmp2->byteArr->size);
|
|
//charge reference
|
|
ret = va_getByIndex(it->Arr, 1, &tmp2);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
memcpy(ccc->chargeReference, tmp2->byteArr->data, tmp2->byteArr->size);
|
|
//collection configuration
|
|
ret = va_getByIndex(it->Arr, 2, &tmp2);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
ccc->collectionConfiguration = (DLMS_CREDIT_COLLECTION_CONFIGURATION)var_toInteger(tmp2);
|
|
arr_push(&object->creditChargeConfigurations, ccc);
|
|
}
|
|
if (ret != 0 && ccc != NULL)
|
|
{
|
|
gxfree(ccc);
|
|
}
|
|
}
|
|
else if (index == 12)
|
|
{
|
|
obj_clearTokenGatewayConfigurations(&object->tokenGatewayConfigurations);
|
|
gwc = NULL;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
gwc = NULL;
|
|
if ((ret = va_getByIndex(value->Arr, pos, &it)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
gwc = (gxTokenGatewayConfiguration*)gxmalloc(sizeof(gxTokenGatewayConfiguration));
|
|
if (gwc == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
memset(gwc->creditReference, 0, 6);
|
|
//credit reference
|
|
if ((ret = va_getByIndex(it->Arr, 0, &tmp2)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (tmp2->byteArr->size == 6)
|
|
{
|
|
memcpy(gwc->creditReference, tmp2->byteArr->data, tmp2->byteArr->size);
|
|
}
|
|
//token proportion
|
|
if ((ret = va_getByIndex(it->Arr, 1, &tmp2)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
gwc->tokenProportion = (unsigned char)var_toInteger(tmp2);
|
|
arr_push(&object->tokenGatewayConfigurations, gwc);
|
|
}
|
|
if (ret != 0 && gwc != NULL)
|
|
{
|
|
gxfree(gwc);
|
|
}
|
|
}
|
|
else if (index == 13)
|
|
{
|
|
var_init(&tmp);
|
|
ret = dlms_changeType(value->byteArr, DLMS_DATA_TYPE_DATETIME, &tmp);
|
|
if (ret == 0)
|
|
{
|
|
time_copy(&object->accountActivationTime, tmp.dateTime);
|
|
}
|
|
var_clear(&tmp);
|
|
}
|
|
else if (index == 14)
|
|
{
|
|
var_init(&tmp);
|
|
ret = dlms_changeType(value->byteArr, DLMS_DATA_TYPE_DATETIME, &tmp);
|
|
if (ret == 0)
|
|
{
|
|
time_copy(&object->accountClosureTime, tmp.dateTime);
|
|
}
|
|
var_clear(&tmp);
|
|
}
|
|
else if (index == 15)
|
|
{
|
|
bb_clear(&object->currency.name);
|
|
//Name
|
|
ret = va_getByIndex(value->Arr, 0, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (it->strVal != NULL && it->strVal->size != 0)
|
|
{
|
|
bb_set2(&object->currency.name, it->strVal, 0, bb_size(it->strVal));
|
|
}
|
|
//scale
|
|
ret = va_getByIndex(value->Arr, 1, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->currency.scale = (char)var_toInteger(it);
|
|
//unit
|
|
ret = va_getByIndex(value->Arr, 2, &it);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->currency.unit = (DLMS_CURRENCY)var_toInteger(it);
|
|
}
|
|
else if (index == 16)
|
|
{
|
|
object->lowCreditThreshold = var_toInteger(value);
|
|
}
|
|
else if (index == 17)
|
|
{
|
|
object->nextCreditAvailableThreshold = var_toInteger(value);
|
|
}
|
|
else if (index == 18)
|
|
{
|
|
object->maxProvision = (uint16_t)var_toInteger(value);
|
|
}
|
|
else if (index == 19)
|
|
{
|
|
object->maxProvisionPeriod = var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_ACCOUNT
|
|
#ifndef DLMS_IGNORE_IMAGE_TRANSFER
|
|
int cosem_setImageTransfer(gxImageTransfer* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
gxImageActivateInfo* item;
|
|
dlmsVARIANT* it, * tmp;
|
|
if (index == 2)
|
|
{
|
|
object->imageBlockSize = var_toInteger(value);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
ba_clear(&object->imageTransferredBlocksStatus);
|
|
if (value->bitArr != NULL)
|
|
{
|
|
ba_copy(&object->imageTransferredBlocksStatus, value->bitArr->data, (uint16_t)value->bitArr->size);
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->imageFirstNotTransferredBlockNumber = var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->imageTransferEnabled = var_toInteger(value) == 0 ? 0 : 1;
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
object->imageTransferStatus = (DLMS_IMAGE_TRANSFER_STATUS)var_toInteger(value);
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
arr_clear(&object->imageActivateInfo);
|
|
item = NULL;
|
|
if (value->Arr != NULL)
|
|
{
|
|
item = NULL;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &it);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
item = (gxImageActivateInfo*)gxmalloc(sizeof(gxImageActivateInfo));
|
|
if (item == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
BYTE_BUFFER_INIT(&item->identification);
|
|
BYTE_BUFFER_INIT(&item->signature);
|
|
ret = va_getByIndex(it->Arr, 0, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
item->size = var_toInteger(tmp);
|
|
ret = va_getByIndex(it->Arr, 1, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
bb_set2(&item->identification, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
ret = va_getByIndex(it->Arr, 2, &tmp);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
bb_set2(&item->signature, tmp->byteArr, 0, bb_size(tmp->byteArr));
|
|
arr_push(&object->imageActivateInfo, item);
|
|
}
|
|
if (ret != 0 && item != NULL)
|
|
{
|
|
gxfree(item);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_IMAGE_TRANSFER
|
|
|
|
#if !(defined(DLMS_IGNORE_PROFILE_GENERIC) && defined(DLMS_IGNORE_COMPACT_DATA))
|
|
int setCaptureObjects(
|
|
dlmsSettings* settings,
|
|
gxArray* objects,
|
|
dlmsVARIANT* value)
|
|
{
|
|
gxObject* obj;
|
|
DLMS_OBJECT_TYPE type;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
gxTarget* co;
|
|
int pos, ret;
|
|
if ((ret = obj_clearProfileGenericCaptureObjects(objects)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
arr_capacity(objects, value->Arr->size);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp->Arr->size != 4)
|
|
{
|
|
//Invalid structure format.
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
type = (DLMS_OBJECT_TYPE)var_toInteger(tmp2);
|
|
//Get LN.
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = oa_findByLN(&settings->objects, type, tmp2->byteArr->data, &obj);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (obj == NULL)
|
|
{
|
|
ret = cosem_createObject(type, &obj);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = cosem_setLogicalName(obj, tmp2->byteArr->data);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, obj);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
co = (gxTarget*)gxmalloc(sizeof(gxTarget));
|
|
if (co == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
co->attributeIndex = (unsigned char)var_toInteger(tmp2);
|
|
ret = va_getByIndex(tmp->Arr, 3, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
co->dataIndex = (unsigned char)var_toInteger(tmp2);
|
|
arr_push(objects, key_init(obj, co));
|
|
}
|
|
}
|
|
//Trim array.
|
|
arr_capacity(objects, objects->size);
|
|
return ret;
|
|
}
|
|
#endif //!(defined(DLMS_IGNORE_PROFILE_GENERIC) && defined(DLMS_IGNORE_CONPACT_DATA))
|
|
|
|
#ifndef DLMS_IGNORE_PROFILE_GENERIC
|
|
int cosem_setProfileGeneric(
|
|
dlmsSettings* settings,
|
|
gxProfileGeneric* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
uint16_t pos, pos2;
|
|
DLMS_OBJECT_TYPE type;
|
|
dlmsVARIANT* tmp, * row, * data;
|
|
variantArray* va;
|
|
if (index == 2)
|
|
{
|
|
static unsigned char UNIX_TIME[6] = { 0, 0, 1, 1, 0, 255 };
|
|
if (object->captureObjects.size == 0)
|
|
{
|
|
//Read capture objects first.
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
if ((ret = obj_clearProfileGenericBuffer(&object->buffer)) == 0)
|
|
{
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
uint16_t rIndex, rCount = arr_getCapacity(&object->buffer);
|
|
dlmsVARIANT* row;
|
|
if ((ret = cosem_checkArray(value->byteArr, &rCount)) == 0)
|
|
{
|
|
object->buffer.size = rCount;
|
|
if (rCount != 0 && (ret = arr_getByIndex(&object->buffer, 0, (void**)&row)) == 0)
|
|
{
|
|
uint16_t cCount = row->Arr->size;
|
|
if (cCount > object->captureObjects.size)
|
|
{
|
|
//Number of columns do not match.
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
for (rIndex = 0; rIndex != rCount; ++rIndex)
|
|
{
|
|
if ((ret = arr_getByIndex(&object->buffer, rIndex, (void**)&row)) != 0 ||
|
|
(ret = cosem_checkStructure(value->byteArr, (unsigned char)cCount)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (value->vt == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
gxtime lastDate;
|
|
time_initUnix(&lastDate, 0);
|
|
//Allocate array.
|
|
arr_capacity(&object->buffer, value->Arr->size);
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &row);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
if (row->Arr->size != object->captureObjects.size)
|
|
{
|
|
//Number of columns do not match.
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
for (pos2 = 0; pos2 < row->Arr->size; ++pos2)
|
|
{
|
|
ret = va_getByIndex(row->Arr, pos2, &data);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
if (data->vt == DLMS_DATA_TYPE_NONE || data->vt == DLMS_DATA_TYPE_OCTET_STRING || data->vt == DLMS_DATA_TYPE_UINT32)
|
|
{
|
|
gxObject* obj;
|
|
gxTarget* t;
|
|
gxKey* k;
|
|
if ((ret = arr_getByIndex(&object->captureObjects, pos2, (void**)&k)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
obj = (gxObject*)k->key;
|
|
t = (gxTarget*)k->value;
|
|
if (obj->objectType == DLMS_OBJECT_TYPE_CLOCK && t->attributeIndex == 2)
|
|
{
|
|
if (data->vt == DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
dlmsVARIANT tmp3;
|
|
var_init(&tmp3);
|
|
var_attach(&tmp3, data->byteArr);
|
|
ret = dlms_changeType(tmp3.byteArr, DLMS_DATA_TYPE_DATETIME, data);
|
|
var_clear(&tmp3);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
lastDate = *data->dateTime;
|
|
}
|
|
//Some meters returns NULL date time to save bytes.
|
|
else if (data->vt == DLMS_DATA_TYPE_NONE)
|
|
{
|
|
if (object->sortMethod == DLMS_SORT_METHOD_FIFO || object->sortMethod == DLMS_SORT_METHOD_SMALLEST)
|
|
{
|
|
time_addSeconds(&lastDate, object->capturePeriod);
|
|
}
|
|
else
|
|
{
|
|
int tm = object->capturePeriod;
|
|
time_addSeconds(&lastDate, -tm);
|
|
}
|
|
var_setDateTime(data, &lastDate);
|
|
}
|
|
}
|
|
else if (data->vt == DLMS_DATA_TYPE_UINT32 && obj->objectType == DLMS_OBJECT_TYPE_DATA && t->attributeIndex == 2 &&
|
|
memcmp(obj->logicalName, UNIX_TIME, 6) == 0)
|
|
{
|
|
gxtime tmp4;
|
|
time_initUnix(&tmp4, data->ulVal);
|
|
var_setDateTime(data, &tmp4);
|
|
lastDate = *data->dateTime;
|
|
}
|
|
}
|
|
}
|
|
//Attach rows from parser.
|
|
va = (variantArray*)gxmalloc(sizeof(variantArray));
|
|
va_init(va);
|
|
va_attach2(va, row->Arr);
|
|
arr_push(&object->buffer, va);
|
|
}
|
|
}
|
|
if (settings->server)
|
|
{
|
|
object->entriesInUse = object->buffer.size;
|
|
}
|
|
//Trim array.
|
|
arr_capacity(&object->buffer, object->buffer.size);
|
|
}
|
|
else if (index == 3)
|
|
{
|
|
object->entriesInUse = 0;
|
|
ret = obj_clearProfileGenericBuffer(&object->buffer);
|
|
if (ret == DLMS_ERROR_CODE_OK)
|
|
{
|
|
ret = setCaptureObjects(settings, &object->captureObjects, value);
|
|
}
|
|
}
|
|
else if (index == 4)
|
|
{
|
|
object->capturePeriod = var_toInteger(value);
|
|
}
|
|
else if (index == 5)
|
|
{
|
|
object->sortMethod = (DLMS_SORT_METHOD)var_toInteger(value);
|
|
}
|
|
else if (index == 6)
|
|
{
|
|
if (value->vt == DLMS_DATA_TYPE_NONE)
|
|
{
|
|
object->sortObject = NULL;
|
|
}
|
|
else
|
|
{
|
|
if (value->Arr == NULL || value->Arr->size != 4)
|
|
{
|
|
//Invalid structure format.
|
|
return DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
ret = va_getByIndex(value->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
type = (DLMS_OBJECT_TYPE)var_toInteger(tmp);
|
|
|
|
ret = va_getByIndex(value->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
object->sortObject = NULL;
|
|
ret = oa_findByLN(&settings->objects, type, tmp->byteArr->data, &object->sortObject);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
if (object->sortObject == NULL)
|
|
{
|
|
ret = cosem_createObject(type, &object->sortObject);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = cosem_setLogicalName(object->sortObject, tmp->byteArr->data);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, object->sortObject);
|
|
}
|
|
ret = va_getByIndex(value->Arr, 2, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->sortObjectAttributeIndex = (char)var_toInteger(tmp);
|
|
ret = va_getByIndex(value->Arr, 3, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
object->sortObjectDataIndex = (uint16_t)var_toInteger(tmp);
|
|
}
|
|
}
|
|
else if (index == 7)
|
|
{
|
|
object->entriesInUse = var_toInteger(value);
|
|
}
|
|
else if (index == 8)
|
|
{
|
|
object->profileEntries = var_toInteger(value);
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_PROFILE_GENERIC
|
|
#ifndef DLMS_IGNORE_GSM_DIAGNOSTIC
|
|
int cosem_setGsmDiagnostic(gxGsmDiagnostic* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
dlmsVARIANT tmp2;
|
|
dlmsVARIANT* tmp, * it;
|
|
gxAdjacentCell* ac;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
if (object->operatorName != NULL)
|
|
{
|
|
gxfree(object->operatorName);
|
|
object->operatorName = NULL;
|
|
}
|
|
|
|
if (value->byteArr != NULL && bb_size(value->byteArr) != 0)
|
|
{
|
|
object->operatorName = (char*)gxmalloc(value->byteArr->size + 1);
|
|
if (object->operatorName == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
memcpy(object->operatorName, value->strVal->data, value->byteArr->size);
|
|
object->operatorName[value->byteArr->size] = '\0';
|
|
}
|
|
}
|
|
else if (value->vt == DLMS_DATA_TYPE_STRING)
|
|
{
|
|
if (object->operatorName != NULL)
|
|
{
|
|
gxfree(object->operatorName);
|
|
object->operatorName = NULL;
|
|
}
|
|
object->operatorName = NULL;
|
|
if (value->strVal != NULL && bb_size(value->strVal) != 0)
|
|
{
|
|
object->operatorName = (char*)gxmalloc(value->strVal->size + 1);
|
|
if (object->operatorName == NULL)
|
|
{
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
memcpy(object->operatorName, value->strVal->data, value->strVal->size);
|
|
object->operatorName[value->strVal->size] = '\0';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
break;
|
|
case 3:
|
|
object->status = (DLMS_GSM_STATUS)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->circuitSwitchStatus = (DLMS_GSM_CIRCUIT_SWITCH_STATUS)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->packetSwitchStatus = (DLMS_GSM_PACKET_SWITCH_STATUS)var_toInteger(value);
|
|
break;
|
|
case 6:
|
|
if (value != NULL && value->vt == DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, 0, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->cellInfo.cellId = (uint32_t)var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 1, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->cellInfo.locationId = (uint16_t)var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 2, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->cellInfo.signalQuality = (unsigned char)var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 3, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->cellInfo.ber = (unsigned char)var_toInteger(tmp);
|
|
if (object->base.version != 0)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, 4, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->cellInfo.mobileCountryCode = (uint16_t)var_toInteger(tmp);
|
|
|
|
if ((ret = va_getByIndex(value->Arr, 5, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->cellInfo.mobileNetworkCode = (uint16_t)var_toInteger(tmp);
|
|
|
|
if ((ret = va_getByIndex(value->Arr, 6, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->cellInfo.channelNumber = tmp->ulVal;
|
|
}
|
|
}
|
|
break;
|
|
case 7:
|
|
arr_clear(&object->adjacentCells);
|
|
if (value != NULL && value->vt == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
ac = NULL;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ac = NULL;
|
|
ret = va_getByIndex(value->Arr, pos, &it);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ret = va_getByIndex(it->Arr, 0, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ac = (gxAdjacentCell*)gxmalloc(sizeof(gxAdjacentCell));
|
|
if (ac == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
ac->cellId = var_toInteger(tmp);
|
|
ret = va_getByIndex(it->Arr, 1, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ac->signalQuality = (unsigned char)var_toInteger(tmp);
|
|
arr_push(&object->adjacentCells, ac);
|
|
}
|
|
if (ret != 0 && ac != NULL)
|
|
{
|
|
gxfree(ac);
|
|
}
|
|
}
|
|
break;
|
|
case 8:
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
var_init(&tmp2);
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp2);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->captureTime, tmp2.dateTime);
|
|
var_clear(&tmp2);
|
|
}
|
|
else if (value->vt == DLMS_DATA_TYPE_DATETIME)
|
|
{
|
|
time_copy(&object->captureTime, value->dateTime);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->captureTime);
|
|
}
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_GSM_DIAGNOSTIC
|
|
#ifndef DLMS_IGNORE_TOKEN_GATEWAY
|
|
int cosem_setTokenGateway(gxTokenGateway* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK, pos;
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT tmp2;
|
|
dlmsVARIANT* it;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
bb_clear(&object->token);
|
|
ret = bb_set2(&object->token, value->byteArr, 0, bb_size(value->byteArr));
|
|
break;
|
|
case 3:
|
|
time_clear(&object->time);
|
|
if (value->byteArr == NULL)
|
|
{
|
|
time_clear(&object->time);
|
|
}
|
|
else
|
|
{
|
|
var_init(&tmp2);
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp2);
|
|
if (ret != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->time, tmp2.dateTime);
|
|
var_clear(&tmp2);
|
|
}
|
|
break;
|
|
case 4:
|
|
obj_clearByteBufferList(&object->descriptions);
|
|
if (value != NULL)
|
|
{
|
|
gxByteBuffer* d;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &it)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
d = (gxByteBuffer*)gxmalloc(sizeof(gxByteBuffer));
|
|
if (d == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
BYTE_BUFFER_INIT(d);
|
|
bb_set2(d, it->strVal, 0, it->strVal->size);
|
|
arr_push(&object->descriptions, d);
|
|
}
|
|
}
|
|
break;
|
|
case 5:
|
|
object->deliveryMethod = (DLMS_TOKEN_DELIVERY)var_toInteger(value);
|
|
break;
|
|
case 6:
|
|
if ((ret = va_getByIndex(value->Arr, 0, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->status = (DLMS_TOKEN_STATUS_CODE)var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 1, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
ba_clear(&object->dataValue);
|
|
if (tmp->strVal != NULL && tmp->strVal->size != 0)
|
|
{
|
|
ba_copy(&object->dataValue, tmp->bitArr->data, tmp->bitArr->size);
|
|
}
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_TOKEN_GATEWAY
|
|
|
|
#ifndef DLMS_IGNORE_COMPACT_DATA
|
|
|
|
int compactData_updateTemplateDescription(
|
|
dlmsSettings* settings,
|
|
gxCompactData* object)
|
|
{
|
|
int ret;
|
|
uint16_t pos;
|
|
gxByteBuffer tmp;
|
|
gxValueEventCollection args;
|
|
gxValueEventArg e;
|
|
ve_init(&e);
|
|
gxKey* kv;
|
|
bb_clear(&object->buffer);
|
|
bb_clear(&object->templateDescription);
|
|
e.action = 1;
|
|
e.target = &object->base;
|
|
e.index = 2;
|
|
vec_init(&args);
|
|
BYTE_BUFFER_INIT(&tmp);
|
|
vec_push(&args, &e);
|
|
if (!e.handled)
|
|
{
|
|
if ((ret = bb_setUInt8(&object->templateDescription, DLMS_DATA_TYPE_STRUCTURE)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
bb_clear(&object->buffer);
|
|
return ret;
|
|
}
|
|
hlp_setObjectCount(object->captureObjects.size, &object->templateDescription);
|
|
for (pos = 0; pos != object->captureObjects.size; ++pos)
|
|
{
|
|
ret = arr_getByIndex(&object->captureObjects, pos, (void**)&kv);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
bb_clear(&object->buffer);
|
|
return ret;
|
|
}
|
|
e.target = (gxObject*)kv->key;
|
|
e.index = ((gxTarget*)kv->value)->attributeIndex;
|
|
if ((ret = cosem_getValue(settings, &e)) != 0)
|
|
{
|
|
var_clear(&e.value);
|
|
bb_clear(&object->buffer);
|
|
return ret;
|
|
}
|
|
if (e.byteArray)
|
|
{
|
|
if (bb_size(e.value.byteArr) == 0)
|
|
{
|
|
bb_setUInt8(&object->templateDescription, 0);
|
|
}
|
|
else
|
|
{
|
|
if (e.value.byteArr->data[0] == DLMS_DATA_TYPE_ARRAY ||
|
|
e.value.byteArr->data[0] == DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
gxDataInfo info;
|
|
dlmsVARIANT value;
|
|
uint16_t count;
|
|
di_init(&info);
|
|
var_init(&value);
|
|
e.value.byteArr->position = 1;
|
|
if ((ret = hlp_getObjectCount2(e.value.byteArr, &count)) != 0 ||
|
|
((gxTarget*)kv->value)->dataIndex > count)
|
|
{
|
|
var_clear(&e.value);
|
|
bb_clear(&object->buffer);
|
|
return DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
}
|
|
//If all data is captured.
|
|
if (((gxTarget*)kv->value)->dataIndex == 0)
|
|
{
|
|
bb_setUInt8(&object->templateDescription, e.value.byteArr->data[0]);
|
|
if (e.value.byteArr->data[0] == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
bb_setUInt16(&object->templateDescription, e.value.byteArr->data[1]);
|
|
}
|
|
else
|
|
{
|
|
bb_setUInt8(&object->templateDescription, e.value.byteArr->data[1]);
|
|
}
|
|
for (unsigned char pos = 0; pos < count; ++pos)
|
|
{
|
|
di_init(&info);
|
|
var_clear(&value);
|
|
if ((ret = dlms_getData(e.value.byteArr, &info, &value)) != 0)
|
|
{
|
|
var_clear(&value);
|
|
var_clear(&e.value);
|
|
bb_clear(&object->buffer);
|
|
return ret;
|
|
}
|
|
if (info.type == DLMS_DATA_TYPE_STRUCTURE || info.type == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
dlmsVARIANT* value2;
|
|
bb_setUInt8(&object->templateDescription, info.type);
|
|
bb_setUInt8(&object->templateDescription, (unsigned char)value.Arr->size);
|
|
for (uint16_t pos = 0; pos < value.Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value.Arr, pos, &value2)) != 0)
|
|
{
|
|
var_clear(&value);
|
|
var_clear(&e.value);
|
|
bb_clear(&object->buffer);
|
|
return ret;
|
|
}
|
|
bb_setUInt8(&object->templateDescription, value2->vt);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bb_setUInt8(&object->templateDescription, info.type);
|
|
}
|
|
if (e.value.byteArr->data[0] == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (unsigned char pos = 0; pos < ((gxTarget*)kv->value)->dataIndex; ++pos)
|
|
{
|
|
var_clear(&value);
|
|
di_init(&info);
|
|
if ((ret = dlms_getData(e.value.byteArr, &info, &value)) != 0)
|
|
{
|
|
var_clear(&value);
|
|
var_clear(&e.value);
|
|
bb_clear(&object->buffer);
|
|
return ret;
|
|
}
|
|
if (!info.complete)
|
|
{
|
|
return DLMS_ERROR_CODE_READ_WRITE_DENIED;
|
|
}
|
|
}
|
|
if (info.type == DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
dlmsVARIANT* value2;
|
|
bb_setUInt8(&object->templateDescription, DLMS_DATA_TYPE_STRUCTURE);
|
|
bb_setUInt8(&object->templateDescription, (unsigned char)value.Arr->size);
|
|
for (uint16_t pos = 0; pos < value.Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value.Arr, pos, &value2)) != 0)
|
|
{
|
|
var_clear(&value);
|
|
var_clear(&e.value);
|
|
bb_clear(&object->buffer);
|
|
return ret;
|
|
}
|
|
bb_setUInt8(&object->templateDescription, value2->vt);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bb_setUInt8(&object->templateDescription, info.type);
|
|
}
|
|
}
|
|
var_clear(&value);
|
|
}
|
|
else
|
|
{
|
|
bb_setUInt8(&object->templateDescription, e.value.byteArr->data[0]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((ret = dlms_setData(&tmp, e.value.vt, &e.value)) != 0)
|
|
{
|
|
var_clear(&e.value);
|
|
bb_clear(&tmp);
|
|
bb_clear(&object->buffer);
|
|
return ret;
|
|
}
|
|
bb_setUInt8(&object->templateDescription, tmp.data[0]);
|
|
bb_clear(&tmp);
|
|
}
|
|
var_clear(&e.value);
|
|
ve_clear(&e);
|
|
}
|
|
}
|
|
bb_clear(&tmp);
|
|
//svr_postGet(settings, &args);
|
|
vec_empty(&args);
|
|
return 0;
|
|
}
|
|
|
|
int cosem_setCompactData(
|
|
dlmsSettings* settings,
|
|
gxCompactData* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
bb_clear(&object->buffer);
|
|
if (value->byteArr != NULL)
|
|
{
|
|
ret = bb_set(&object->buffer, value->byteArr->data, value->byteArr->size);
|
|
}
|
|
break;
|
|
case 3:
|
|
ret = setCaptureObjects(settings, &object->captureObjects, value);
|
|
if (ret == 0 && settings->server)
|
|
{
|
|
ret = compactData_updateTemplateDescription(settings, object);
|
|
}
|
|
break;
|
|
case 4:
|
|
object->templateId = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
bb_clear(&object->templateDescription);
|
|
if (value->byteArr != NULL)
|
|
{
|
|
ret = bb_set(&object->templateDescription, value->byteArr->data, value->byteArr->size);
|
|
}
|
|
break;
|
|
case 6:
|
|
object->captureMethod = (DLMS_CAPTURE_METHOD)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_COMPACT_DATA
|
|
|
|
#ifndef DLMS_IGNORE_PARAMETER_MONITOR
|
|
int cosem_setParameterMonitor(
|
|
dlmsSettings* settings,
|
|
gxParameterMonitor* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0, pos;
|
|
dlmsVARIANT* tmp, * tmp3;
|
|
dlmsVARIANT tmp2;
|
|
DLMS_OBJECT_TYPE type;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
object->changedParameter.target = NULL;
|
|
#else
|
|
object->changedParameter.type = DLMS_OBJECT_TYPE_NONE;
|
|
memset(object->changedParameter.logicalName, 0, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
if (value->Arr != NULL)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, 0, &tmp3)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
type = (DLMS_OBJECT_TYPE)var_toInteger(tmp3);
|
|
//Get LN.
|
|
if ((ret = va_getByIndex(value->Arr, 1, &tmp3)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, type, tmp3->byteArr->data, &object->changedParameter.target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (object->changedParameter.target == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(type, &object->changedParameter.target)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
oa_push(&settings->releasedObjects, object->changedParameter.target);
|
|
memcpy(object->changedParameter.target->logicalName, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
}
|
|
if ((ret = va_getByIndex(value->Arr, 2, &tmp3)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->changedParameter.attributeIndex = (unsigned char)var_toInteger(tmp3);
|
|
if ((ret = va_getByIndex(value->Arr, 3, &tmp3)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
ret = var_copy(&object->changedParameter.value, tmp3);
|
|
}
|
|
}
|
|
#else
|
|
object->changedParameter.type = type;
|
|
memcpy(object->changedParameter.logicalName, tmp3->byteArr->data, 6);
|
|
if ((ret = va_getByIndex(value->Arr, 2, &tmp3)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->changedParameter.attributeIndex = (unsigned char)var_toInteger(tmp3);
|
|
if ((ret = va_getByIndex(value->Arr, 3, &tmp3)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
ret = var_copy(&object->changedParameter.value, tmp3);
|
|
}
|
|
}
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
//Some meters are returning empty octet string here.
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING && value->byteArr != NULL)
|
|
{
|
|
ret = var_init(&tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = dlms_changeType2(value, DLMS_DATA_TYPE_DATETIME, &tmp2);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->captureTime, tmp2.dateTime);
|
|
var_clear(&tmp2);
|
|
}
|
|
else
|
|
{
|
|
time_clear(&object->captureTime);
|
|
}
|
|
}
|
|
break;
|
|
case 4:
|
|
{
|
|
obj_clearParametersList(&object->parameters);
|
|
if (value->Arr != NULL)
|
|
{
|
|
gxTarget* it;
|
|
gxObject* obj;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 0, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
type = (DLMS_OBJECT_TYPE)var_toInteger(tmp3);
|
|
//Get LN.
|
|
|
|
ret = va_getByIndex(tmp->Arr, 1, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
obj = NULL;
|
|
if ((ret = oa_findByLN(&settings->objects, type, tmp3->byteArr->data, &obj)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if (obj == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(type, &obj)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
oa_push(&settings->releasedObjects, obj);
|
|
memcpy(obj->logicalName, tmp3->byteArr->data, tmp3->byteArr->size);
|
|
}
|
|
it = (gxTarget*)gxmalloc(sizeof(gxTarget));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
ret = va_getByIndex(tmp->Arr, 2, &tmp3);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->attributeIndex = (unsigned char)var_toInteger(tmp3);
|
|
arr_push(&object->parameters, key_init(obj, it));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_PARAMETER_MONITOR
|
|
|
|
#ifndef DLMS_IGNORE_LLC_SSCS_SETUP
|
|
int cosem_setLlcSscsSetup(
|
|
dlmsSettings* settings,
|
|
gxLlcSscsSetup* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->serviceNodeAddress = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->baseNodeAddress = (uint16_t)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_LLC_SSCS_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
|
int cosem_setPrimeNbOfdmPlcPhysicalLayerCounters(
|
|
dlmsSettings* settings,
|
|
gxPrimeNbOfdmPlcPhysicalLayerCounters* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->crcIncorrectCount = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->crcFailedCount = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->txDropCount = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->rxDropCount = (uint16_t)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_PHYSICAL_LAYER_COUNTERS
|
|
|
|
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
|
int cosem_setPrimeNbOfdmPlcMacSetup(
|
|
dlmsSettings* settings,
|
|
gxPrimeNbOfdmPlcMacSetup* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->macMinSwitchSearchTime = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->macMaxPromotionPdu = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->macPromotionPduTxPeriod = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->macBeaconsPerFrame = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 6:
|
|
object->macScpMaxTxAttempts = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 7:
|
|
object->macCtlReTxTimer = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 8:
|
|
object->macMaxCtlReTx = (unsigned char)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_SETUP
|
|
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
|
int cosem_setPrimeNbOfdmPlcMacFunctionalParameters(
|
|
dlmsSettings* settings,
|
|
gxPrimeNbOfdmPlcMacFunctionalParameters* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->lnId = (short)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->lsId = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->sId = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->sna.size = 0;
|
|
ret = bb_set2(&object->sna, value->byteArr, 0, bb_size(value->byteArr));
|
|
break;
|
|
case 6:
|
|
object->state = (DLMS_MAC_STATE)var_toInteger(value);
|
|
break;
|
|
case 7:
|
|
object->scpLength = (short)var_toInteger(value);
|
|
break;
|
|
case 8:
|
|
object->nodeHierarchyLevel = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 9:
|
|
object->beaconSlotCount = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 10:
|
|
object->beaconRxSlot = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 11:
|
|
object->beaconTxSlot = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 12:
|
|
object->beaconRxFrequency = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 13:
|
|
object->beaconTxFrequency = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 14:
|
|
object->capabilities = (DLMS_MAC_CAPABILITIES)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_FUNCTIONAL_PARAMETERS
|
|
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
|
int cosem_setPrimeNbOfdmPlcMacCounters(
|
|
dlmsSettings* settings,
|
|
gxPrimeNbOfdmPlcMacCounters* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->txDataPktCount = var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->rxDataPktCount = var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->txCtrlPktCount = var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->rxCtrlPktCount = var_toInteger(value);
|
|
break;
|
|
case 6:
|
|
object->csmaFailCount = var_toInteger(value);
|
|
break;
|
|
case 7:
|
|
object->csmaChBusyCount = var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_COUNTERS
|
|
|
|
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
|
|
|
int cosem_setMulticastEntries(gxPrimeNbOfdmPlcMacNetworkAdministrationData* object, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
int pos;
|
|
gxMacMulticastEntry* it;
|
|
arr_clear(&object->multicastEntries);
|
|
if (value->Arr != NULL)
|
|
{
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT* tmp2;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxMacMulticastEntry*)gxmalloc(sizeof(gxMacMulticastEntry));
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->id = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->members = (short)var_toInteger(tmp2);
|
|
arr_push(&object->multicastEntries, it);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int cosem_setSwitchTable(gxPrimeNbOfdmPlcMacNetworkAdministrationData* object, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
int pos;
|
|
arr_empty(&object->switchTable);
|
|
if (value->Arr != NULL)
|
|
{
|
|
dlmsVARIANT* it;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &it)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
uint16_t* tmp = (uint16_t*)gxmalloc(sizeof(uint16_t));
|
|
*tmp = (uint16_t)var_toInteger(it);
|
|
arr_push(&object->switchTable, tmp);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int cosem_setDirectTable(gxPrimeNbOfdmPlcMacNetworkAdministrationData* object, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
int pos;
|
|
gxMacDirectTable* it;
|
|
arr_clear(&object->directTable);
|
|
if (value->Arr != NULL)
|
|
{
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT* tmp2;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxMacDirectTable*)gxmalloc(sizeof(gxMacDirectTable));
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->sourceSId = (short)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->sourceLnId = (short)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->sourceLcId = (short)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 3, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->destinationSId = (short)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->destinationLnId = (short)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 5, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->destinationLcId = (short)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 6, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = bb_get(tmp2->byteArr, it->did, sizeof(it->did))) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->directTable, it);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int cosem_setAvailableSwitches(gxPrimeNbOfdmPlcMacNetworkAdministrationData* object, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
int pos;
|
|
gxMacAvailableSwitch* it;
|
|
obj_clearAvailableSwitches(&object->availableSwitches);
|
|
if (value->Arr != NULL)
|
|
{
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT* tmp2;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxMacAvailableSwitch*)gxmalloc(sizeof(gxMacAvailableSwitch));
|
|
BYTE_BUFFER_INIT(&it->sna);
|
|
bb_capacity(&it->sna, tmp2->byteArr->size);
|
|
if ((ret = bb_set(&it->sna, tmp2->byteArr->data, tmp2->byteArr->size)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(it);
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(it);
|
|
break;
|
|
}
|
|
it->lsId = (short)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(it);
|
|
break;
|
|
}
|
|
it->level = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 3, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(it);
|
|
break;
|
|
}
|
|
it->rxLevel = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
gxfree(it);
|
|
break;
|
|
}
|
|
it->rxSnr = (signed char)var_toInteger(tmp2);
|
|
arr_push(&object->availableSwitches, it);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int cosem_setCommunications(gxPrimeNbOfdmPlcMacNetworkAdministrationData* object, dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
int pos;
|
|
gxMacPhyCommunication* it;
|
|
arr_clear(&object->communications);
|
|
if (value->Arr != NULL)
|
|
{
|
|
dlmsVARIANT* tmp;
|
|
dlmsVARIANT* tmp2;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxMacPhyCommunication*)gxmalloc(sizeof(gxMacPhyCommunication));
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = bb_get(tmp2->byteArr, it->eui, sizeof(it->eui))) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->txPower = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 2, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->txCoding = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 3, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->rxCoding = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 4, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->rxLvl = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 5, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->snr = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 6, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->txPowerModified = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 7, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->txCodingModified = (signed char)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 8, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->rxCodingModified = (signed char)var_toInteger(tmp2);
|
|
arr_push(&object->communications, it);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int cosem_setPrimeNbOfdmPlcMacNetworkAdministrationData(
|
|
dlmsSettings* settings,
|
|
gxPrimeNbOfdmPlcMacNetworkAdministrationData* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
ret = cosem_setMulticastEntries(object, value);
|
|
break;
|
|
case 3:
|
|
ret = cosem_setSwitchTable(object, value);
|
|
break;
|
|
case 4:
|
|
ret = cosem_setDirectTable(object, value);
|
|
break;
|
|
case 5:
|
|
ret = cosem_setAvailableSwitches(object, value);
|
|
break;
|
|
case 6:
|
|
ret = cosem_setCommunications(object, value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_MAC_NETWORK_ADMINISTRATION_DATA
|
|
|
|
#ifndef DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
|
int cosem_setPrimeNbOfdmPlcApplicationsIdentification(
|
|
dlmsSettings* settings,
|
|
gxPrimeNbOfdmPlcApplicationsIdentification* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
{
|
|
bb_clear(&object->firmwareVersion);
|
|
bb_set2(&object->firmwareVersion, value->byteArr, 0, bb_size(value->byteArr));
|
|
}
|
|
break;
|
|
case 3:
|
|
object->vendorId = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->productId = (uint16_t)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_PRIME_NB_OFDM_PLC_APPLICATIONS_IDENTIFICATION
|
|
|
|
#ifndef DLMS_IGNORE_ARBITRATOR
|
|
int cosem_setArbitrator(
|
|
dlmsSettings* settings,
|
|
gxArbitrator* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
gxActionItem* it;
|
|
bitArray* ba;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
{
|
|
arr_clear(&object->actions);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
it = (gxActionItem*)gxmalloc(sizeof(gxActionItem));
|
|
it->script = NULL;
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
#ifndef DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = oa_findByLN(&settings->objects, DLMS_OBJECT_TYPE_SCRIPT_TABLE, tmp2->byteArr->data, (gxObject**)&it->script)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (it->script == NULL)
|
|
{
|
|
if ((ret = cosem_createObject(DLMS_OBJECT_TYPE_SCRIPT_TABLE, (gxObject**)&it->script)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
memcpy(it->script->base.logicalName, tmp2->byteArr->data, tmp2->byteArr->size);
|
|
//Add object to released objects list.
|
|
ret = oa_push(&settings->releasedObjects, &it->script->base);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
#else
|
|
memcpy(it->scriptLogicalName, tmp2->byteArr->data, 6);
|
|
#endif //DLMS_IGNORE_OBJECT_POINTERS
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->scriptSelector = (uint16_t)var_toInteger(tmp2);
|
|
arr_push(&object->actions, it);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
obj_clearBitArrayList(&object->permissionsTable);
|
|
if (value->Arr != NULL)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
ba = (bitArray*)gxmalloc(sizeof(bitArray));
|
|
ba_init(ba);
|
|
if ((ba_copy(ba, tmp->bitArr->data, tmp->bitArr->size)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->permissionsTable, ba);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 4:
|
|
{
|
|
arr_clear(&object->weightingsTable);
|
|
if (value->Arr != NULL)
|
|
{
|
|
dlmsVARIANT* tmp2;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
ret = va_getByIndex(value->Arr, pos, &tmp);
|
|
if (ret != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
tmp2 = (dlmsVARIANT*)gxmalloc(sizeof(dlmsVARIANT));
|
|
var_init(tmp2);
|
|
ret = var_copy(tmp2, tmp);
|
|
if (ret != 0)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->weightingsTable, tmp2);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 5:
|
|
{
|
|
obj_clearBitArrayList(&object->mostRecentRequestsTable);
|
|
if (value->Arr != NULL)
|
|
{
|
|
bitArray* it;
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (bitArray*)gxmalloc(sizeof(bitArray));
|
|
ba_init(it);
|
|
if ((ba_copy(it, tmp->bitArr->data, tmp->bitArr->size)) != 0)
|
|
{
|
|
break;
|
|
}
|
|
arr_push(&object->mostRecentRequestsTable, it);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 6:
|
|
object->lastOutcome = (unsigned char)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_ARBITRATOR
|
|
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
|
int cosem_setIec8802LlcType1Setup(
|
|
dlmsSettings* settings,
|
|
gxIec8802LlcType1Setup* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->maximumOctetsUiPdu = (uint16_t)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE1_SETUP
|
|
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
|
int cosem_setIec8802LlcType2Setup(
|
|
dlmsSettings* settings,
|
|
gxIec8802LlcType2Setup* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->transmitWindowSizeK = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->transmitWindowSizeRW = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->maximumOctetsPdu = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->maximumNumberTransmissions = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 6:
|
|
object->acknowledgementTimer = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 7:
|
|
object->bitTimer = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 8:
|
|
object->rejectTimer = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 9:
|
|
object->busyStateTimer = (uint16_t)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE2_SETUP
|
|
#ifndef DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
|
int cosem_setIec8802LlcType3Setup(
|
|
dlmsSettings* settings,
|
|
gxIec8802LlcType3Setup* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = DLMS_ERROR_CODE_OK;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->maximumOctetsACnPdu = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->maximumTransmissions = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->acknowledgementTime = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->receiveLifetime = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 6:
|
|
object->transmitLifetime = (uint16_t)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_IEC_8802_LLC_TYPE3_SETUP
|
|
#ifndef DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
|
int cosem_setSFSKActiveInitiator(
|
|
dlmsSettings* settings,
|
|
gxSFSKActiveInitiator* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
dlmsVARIANT* tmp;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
if (value->vt == DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
bb_clear(&object->systemTitle);
|
|
if ((ret = va_getByIndex(value->Arr, 0, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
if (tmp->byteArr != NULL)
|
|
{
|
|
if ((ret = bb_set(&object->systemTitle, tmp->byteArr->data, bb_size(tmp->byteArr))) != 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if ((ret = va_getByIndex(value->Arr, 1, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
object->macAddress = (uint16_t)var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 2, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
object->lSapSelector = (unsigned char)var_toInteger(tmp);
|
|
}
|
|
else
|
|
{
|
|
bb_clear(&object->systemTitle);
|
|
object->macAddress = 0;
|
|
object->lSapSelector = 0;
|
|
}
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SFSK_ACTIVE_INITIATOR
|
|
#ifndef DLMS_IGNORE_SFSK_MAC_COUNTERS
|
|
int cosem_setFSKMacCounters(
|
|
dlmsSettings* settings,
|
|
gxFSKMacCounters* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = DLMS_ERROR_CODE_OK;
|
|
gxUint16PairUint32* it;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
{
|
|
arr_clear(&object->synchronizationRegister);
|
|
if (value->vt == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxUint16PairUint32*)gxmalloc(sizeof(gxUint16PairUint32));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->first = (uint16_t)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->second = var_toInteger(tmp2);
|
|
arr_push(&object->synchronizationRegister, it);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
if (value->vt == DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, 0, &tmp)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->physicalLayerDesynchronization = var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 1, &tmp)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->timeOutNotAddressedDesynchronization = var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 2, &tmp)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->timeOutFrameNotOkDesynchronization = var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 3, &tmp)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->writeRequestDesynchronization = var_toInteger(tmp);
|
|
if ((ret = va_getByIndex(value->Arr, 4, &tmp)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->wrongInitiatorDesynchronization = var_toInteger(tmp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
object->physicalLayerDesynchronization = 0;
|
|
object->timeOutNotAddressedDesynchronization = 0;
|
|
object->timeOutFrameNotOkDesynchronization = 0;
|
|
object->writeRequestDesynchronization = 0;
|
|
object->wrongInitiatorDesynchronization = 0;
|
|
}
|
|
}
|
|
break;
|
|
case 4:
|
|
{
|
|
arr_clear(&object->broadcastFramesCounter);
|
|
if (value->vt == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxUint16PairUint32*)gxmalloc(sizeof(gxUint16PairUint32));
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->first = (uint16_t)var_toInteger(tmp2);
|
|
if ((ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it->second = var_toInteger(tmp2);
|
|
arr_push(&object->broadcastFramesCounter, it);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 5:
|
|
object->repetitionsCounter = var_toInteger(value);
|
|
break;
|
|
case 6:
|
|
object->transmissionsCounter = var_toInteger(value);
|
|
break;
|
|
case 7:
|
|
object->crcOkFramesCounter = var_toInteger(value);
|
|
break;
|
|
case 8:
|
|
object->crcNOkFramesCounter = var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SFSK_MAC_COUNTERS
|
|
#ifndef DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
|
int cosem_setSFSKMacSynchronizationTimeouts(
|
|
dlmsSettings* settings,
|
|
gxSFSKMacSynchronizationTimeouts* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int ret = 0;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->searchInitiatorTimeout = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->synchronizationConfirmationTimeout = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->timeOutNotAddressed = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->timeOutFrameNotOK = (uint16_t)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SFSK_MAC_SYNCHRONIZATION_TIMEOUTS
|
|
#ifndef DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
|
int cosem_setSFSKPhyMacSetUp(
|
|
dlmsSettings* settings,
|
|
gxSFSKPhyMacSetUp* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
dlmsVARIANT* it;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
object->initiatorElectricalPhase = (DLMS_INITIATOR_ELECTRICAL_PHASE)var_toInteger(value);
|
|
break;
|
|
case 3:
|
|
object->deltaElectricalPhase = (DLMS_DELTA_ELECTRICAL_PHASE)var_toInteger(value);
|
|
break;
|
|
case 4:
|
|
object->maxReceivingGain = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 5:
|
|
object->maxTransmittingGain = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 6:
|
|
object->searchInitiatorThreshold = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 7:
|
|
{
|
|
if (value->vt == DLMS_DATA_TYPE_STRUCTURE)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, 0, &it)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->markFrequency = var_toInteger(it);
|
|
if ((ret = va_getByIndex(value->Arr, 1, &it)) == DLMS_ERROR_CODE_OK)
|
|
{
|
|
object->spaceFrequency = var_toInteger(it);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
object->markFrequency = 0;
|
|
object->spaceFrequency = 0;
|
|
}
|
|
break;
|
|
}
|
|
case 8:
|
|
object->macAddress = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 9:
|
|
{
|
|
arr_clear(&object->macGroupAddresses);
|
|
if (value->vt == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &it)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
uint16_t* v = gxmalloc(sizeof(uint16_t));
|
|
*v = (uint16_t)var_toInteger(it);
|
|
arr_push(&object->macGroupAddresses, v);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 10:
|
|
object->repeater = (DLMS_REPEATER)var_toInteger(value);
|
|
break;
|
|
case 11:
|
|
object->repeaterStatus = value->boolVal;
|
|
break;
|
|
case 12:
|
|
object->minDeltaCredit = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 13:
|
|
object->initiatorMacAddress = (uint16_t)var_toInteger(value);
|
|
break;
|
|
case 14:
|
|
object->synchronizationLocked = (unsigned char)var_toInteger(value);
|
|
break;
|
|
case 15:
|
|
object->transmissionSpeed = (DLMS_BAUD_RATE)var_toInteger(value);
|
|
break;
|
|
default:
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SFSK_PHY_MAC_SETUP
|
|
|
|
#ifndef DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
|
int cosem_setSFSKReportingSystemList(
|
|
dlmsSettings* settings,
|
|
gxSFSKReportingSystemList* object,
|
|
unsigned char index,
|
|
dlmsVARIANT* value)
|
|
{
|
|
int pos, ret = 0;
|
|
dlmsVARIANT* tmp;
|
|
gxByteBuffer* it;
|
|
if (index == 2)
|
|
{
|
|
obj_clearByteBufferList(&object->reportingSystemList);
|
|
if (value->vt == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
if (value->vt == DLMS_DATA_TYPE_ARRAY)
|
|
{
|
|
for (pos = 0; pos != value->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, pos, &tmp)) != DLMS_ERROR_CODE_OK)
|
|
{
|
|
break;
|
|
}
|
|
it = (gxByteBuffer*)gxmalloc(sizeof(gxByteBuffer));
|
|
BYTE_BUFFER_INIT(it);
|
|
bb_set(it, tmp->byteArr->data, tmp->byteArr->size);
|
|
if (it == NULL)
|
|
{
|
|
ret = DLMS_ERROR_CODE_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
arr_push(&object->reportingSystemList, it);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_INVALID_PARAMETER;
|
|
}
|
|
return ret;
|
|
}
|
|
#endif //DLMS_IGNORE_SFSK_REPORTING_SYSTEM_LIST
|
|
|
|
#ifdef DLMS_ITALIAN_STANDARD
|
|
int updateIntervals(gxInterval* interval, gxByteBuffer* value)
|
|
{
|
|
int ret;
|
|
unsigned char b;
|
|
if ((ret = bb_getUInt8(value, &b)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
interval[0].startHour = (unsigned char)(b >> 3);
|
|
interval[0].intervalTariff = (DLMS_DEFAULT_TARIFF_BAND)((b >> 1) & 0x3);
|
|
interval[0].useInterval = (b & 0x1) != 0;
|
|
if ((ret = bb_getUInt8(value, &b)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
interval[1].startHour = (unsigned char)(b >> 3);
|
|
interval[1].intervalTariff = (DLMS_DEFAULT_TARIFF_BAND)((b >> 1) & 0x3);
|
|
interval[1].useInterval = (b & 0x1) != 0;
|
|
if ((ret = bb_getUInt8(value, &b)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
interval[2].startHour = (unsigned char)(b >> 3);
|
|
interval[2].intervalTariff = (DLMS_DEFAULT_TARIFF_BAND)((b >> 1) & 0x3);
|
|
interval[2].useInterval = (b & 0x1) != 0;
|
|
if ((ret = bb_getUInt8(value, &b)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
interval[3].startHour = (unsigned char)(b >> 3);
|
|
interval[3].intervalTariff = (DLMS_DEFAULT_TARIFF_BAND)((b >> 1) & 0x3);
|
|
interval[3].useInterval = (b & 0x1) != 0;
|
|
if ((ret = bb_getUInt8(value, &b)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
interval[4].startHour = (unsigned char)(b >> 3);
|
|
interval[4].intervalTariff = (DLMS_DEFAULT_TARIFF_BAND)((b >> 1) & 0x3);
|
|
interval[4].useInterval = (b & 0x1) != 0;
|
|
return 0;
|
|
}
|
|
|
|
int updateSeason(gxBandDescriptor* season, variantArray* value)
|
|
{
|
|
int ret;
|
|
dlmsVARIANT* tmp;
|
|
if (value->size == 5)
|
|
{
|
|
if ((ret = va_getByIndex(value, 0, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
season->dayOfMonth = tmp->bVal;
|
|
if ((ret = va_getByIndex(value, 1, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
season->month = tmp->bVal;
|
|
if ((ret = va_getByIndex(value, 2, &tmp)) != 0 ||
|
|
(ret = updateIntervals(season->workingDayIntervals, tmp->byteArr)) != 0 ||
|
|
(ret = va_getByIndex(value, 3, &tmp)) != 0 ||
|
|
(ret = updateIntervals(season->saturdayIntervals, tmp->byteArr)) != 0 ||
|
|
(ret = va_getByIndex(value, 4, &tmp)) != 0 ||
|
|
(ret = updateIntervals(season->holidayIntervals, tmp->byteArr)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = DLMS_ERROR_CODE_UNMATCH_TYPE;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int cosem_setTariffPlan(gxTariffPlan* object, unsigned char index, dlmsVARIANT* value)
|
|
{
|
|
dlmsVARIANT tmp3;
|
|
dlmsVARIANT* tmp, * tmp2;
|
|
int ret, pos, h, m, s;
|
|
switch (index)
|
|
{
|
|
case 2:
|
|
if (value->vt == DLMS_DATA_TYPE_OCTET_STRING)
|
|
{
|
|
object->calendarName = (char*)gxmalloc(value->byteArr->size);
|
|
memcpy(object->calendarName, value->byteArr->data, value->byteArr->size);
|
|
object->calendarName[value->byteArr->size] = 0;
|
|
}
|
|
else
|
|
{
|
|
object->calendarName = (char*)gxmalloc(value->strVal->size + 1);
|
|
memcpy(object->calendarName, value->strVal->data, value->strVal->size);
|
|
object->calendarName[value->strVal->size] = 0;
|
|
}
|
|
break;
|
|
case 3:
|
|
object->enabled = value->boolVal;
|
|
break;
|
|
case 4:
|
|
{
|
|
if (value->Arr->size == 4)
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, 0, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
object->plan.defaultTariffBand = tmp->bVal;
|
|
if ((ret = va_getByIndex(value->Arr, 1, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if ((ret = va_getByIndex(tmp->Arr, 0, &tmp2)) != 0 ||
|
|
(ret = updateSeason(&object->plan.winterSeason, tmp2->Arr)) != 0 ||
|
|
(ret = va_getByIndex(tmp->Arr, 1, &tmp2)) != 0 ||
|
|
(ret = updateSeason(&object->plan.summerSeason, tmp2->Arr)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
ba_clear(&object->plan.weeklyActivation);
|
|
if ((ret = va_getByIndex(value->Arr, 2, &tmp)) != 0 ||
|
|
(ret = ba_copy(&object->plan.weeklyActivation, tmp->bitArr->data, tmp->bitArr->size)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if ((ret = va_getByIndex(value->Arr, 3, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
arr_clear(&object->plan.specialDays);
|
|
arr_capacity(&object->plan.specialDays, tmp->Arr->size);
|
|
for (pos = 0; pos != tmp->Arr->size; ++pos)
|
|
{
|
|
if ((ret = va_getByIndex(tmp->Arr, pos, &tmp2)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
arr_push(&object->plan.specialDays, (void*)tmp2->ulVal);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 5:
|
|
{
|
|
if ((ret = va_getByIndex(value->Arr, 0, &tmp)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
var_init(&tmp3);
|
|
if ((ret = dlms_changeType2(tmp, DLMS_DATA_TYPE_TIME, &tmp3)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
if ((tmp3.dateTime->skip & DATETIME_SKIPS_HOUR) == 0)
|
|
{
|
|
h = time_getHours(tmp3.dateTime);
|
|
}
|
|
else
|
|
{
|
|
h = 0;
|
|
}
|
|
if ((tmp3.dateTime->skip & DATETIME_SKIPS_MINUTE) == 0)
|
|
{
|
|
m = time_getMinutes(tmp3.dateTime);
|
|
}
|
|
else
|
|
{
|
|
m = 0;
|
|
}
|
|
if ((tmp3.dateTime->skip & DATETIME_SKIPS_SECOND) == 0)
|
|
{
|
|
s = time_getSeconds(tmp3.dateTime);
|
|
}
|
|
else
|
|
{
|
|
s = 0;
|
|
}
|
|
if ((ret = va_getByIndex(value->Arr, 1, &tmp2)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
var_clear(&tmp3);
|
|
if ((ret = dlms_changeType2(tmp2, DLMS_DATA_TYPE_DATE, &tmp3)) != 0)
|
|
{
|
|
return ret;
|
|
}
|
|
time_copy(&object->activationTime, tmp3.dateTime);
|
|
object->activationTime.skip &= ~(DATETIME_SKIPS_HOUR | DATETIME_SKIPS_MINUTE | DATETIME_SKIPS_SECOND | DATETIME_SKIPS_MS);
|
|
time_addHours(&object->activationTime, h);
|
|
time_addMinutes(&object->activationTime, m);
|
|
time_addSeconds(&object->activationTime, s);
|
|
}
|
|
break;
|
|
default:
|
|
return DLMS_ERROR_CODE_READ_WRITE_DENIED;
|
|
}
|
|
return DLMS_ERROR_CODE_OK;
|
|
}
|
|
#endif //DLMS_ITALIAN_STANDARD
|
|
|
|
#endif //!defined(DLMS_IGNORE_MALLOC) && !defined(DLMS_COSEM_EXACT_DATA_TYPES)
|