Skip to main content
Home
for DLMS smart meters

Main navigation

  • Home
  • Products
  • About us
  • Open Source
  • Community
  • Forum
  • Downloads
User account menu
  • Log in

Breadcrumb

  1. Home
  2. Invocation Counter
Profile picture for user Kurumi
By Kurumi, 18 March, 2020
Getting started

Invocation counter

Invocation counter a.k.a Frame counter is a counter value that is increased every time when a message is ciphered. Increasing invocation counter causes that messages are encrypted differently, even the content is the same.
The invocation counter is not used non-ciphered messages. Invocation counter value is usually saved to the data-object. If invocation counter is not correct, the meter will not accept the message. There might be several invocation counters on the meter. There is usually one invocation counter for each secured association. With some meters, there might be own invocation counter for optical port connection and own invocation counter for TCP/IP connection.

Client side

Before starting the ciphered connection client must establish a normal connection (usually this is done without authentication) and read the invocation counter from the meter. After reading the counter value connection is closed. There is a -I parameter in client examples that is reading invocation counter from the meter. You can use parameter like this:
-I 0.0.43.1.0.255

  • Java
  • C#
  • Delphi
  • ANSI C++
  • ANSI C
  • Python
GXDLMSData client = new GXDLMSClient();
// Is used Logican Name or Short Name referencing.
client.setUseLogicalNameReferencing(true);
client.setInterfaceType(InterfaceType.HDLC);
client.setClientAddress(16);
client.setServerAddress(1);
//Send SNRM request and parse UA response
//Send AARQ request and parse AARE response
//Read invocation counter.
GXDLMSData d = new GXDLMSData("OBIS_CODE");
read(d, 2);
client.getCiphering().setInvocationCounter(1 + ((Number)d.Value));
//Close the connection.
disconnect();
GXDLMSClient client = new GXDLMSClient();
// Is used Logican Name or Short Name referencing.
client.UseLogicalNameReferencing = true;
// Is used HDLC or COSEM transport layers for IPv4 networks (IEC 62056-47)
client.InterfaceType = InterfaceType.Hdlc;
client.ClientAddress = 16;
client.ServerAddress = 1;
//Send SNRM request and parse UA response
//Send AARQ request and parse AARE response
//Read invocation counter.
GXDLMSData d = new GXDLMSData("OBIS_CODE");
Read(d, 2);
Client.Ciphering.InvocationCounter = 1 + Convert.ToUInt32(d.Value);
//Close the connection.
Disconnect();
Client := TGXDLMSClient.Create(
  // Is used Logican Name or Short Name referencing.
    True, 
  //Client ID
    16, 
  //Server ID
    1,
  //Authentication Level.
    TAuthentication.None, 
  //PassWord
    Nil, 
  // Is used HDLC or COSEM transport layers for IPv4 networks (IEC 62056-47)
  TInterfaceType.General);
//Send SNRM request and parse UA response
//Send AARQ request and parse AARE response
//Read invocation counter.
d := TGXDLMSData.Create("OBIS_CODE");
Read(d, 2);
Client.Ciphering.InvocationCounter := 1 + d.Value.AsInteger;
FreeAndNil(d);
//Close the connection.
Disconnect();
CGXDLMSClient cl(
// Is used Logican Name or Short Name referencing.
true, 
//Client ID
16, 
//Server ID
1, 
//Authentication Level.
GXDLMS_AUTHENTICATION_LOW, 
//PassWord
"ABCDEFGH", 
// Is used HDLC or COSEM transport layers for IPv4 networks (IEC 62056-47)
GXDLMS_INTERFACETYPE_HDLC);	
//Send SNRM request and parse UA response
//Send AARQ request and parse AARE response
//Read invocation counter.
CGXDLMSData d("OBIS_CODE");
Read(d, 2);
client.GetCiphering()->SetInvocationCounter(1 + d.GetValue().ToInteger());
//Close the connection.
Disconnect();
connection con;
//Support trace.
con_init(&con, 1);
//Initialize settings using Logican Name referencing and WRAPPER.
cl_init(&con.settings, 
// Is used Logican Name or Short Name referencing.
1, 
//Client ID
16, 
//Server ID
1, 
//Authentication Level.
DLMS_AUTHENTICATION_NONE, 
//Password
NULL, 
// Is used HDLC or COSEM transport layers for IPv4 networks (IEC 62056-47)
DLMS_INTERFACE_TYPE_HDLC);
/Send SNRM request and parse UA response
//Send AARQ request and parse AARE response
//Read invocation counter.
gxData d;
const unsigned char ln[6] = { 0,0,43, 1, 0, 255};
cosem_init(BASE(d), DLMS_OBJECT_TYPE_DATA, ln);
if ((ret = com_read(&con, BASE(d), 2)) == 0)
{
    con.settings.cipher.invocationCounter = 1 + var_toInteger(&d.value);
}
//Close the connection.
com_disconnect(&con);
client = GXDLMSClient()
#Is used Logican Name or Short Name referencing.
client.useLogicalNameReferencing = True
 
#Is used HDLC or COSEM transport layers for IPv4 networks (IEC 62056-47)
client.interfaceType = InterfaceType.HDLC
client.clientAddress = 16
client.serverAddress = 1
//Send SNRM request and parse UA response
//Send AARQ request and parse AARE response
//Read invocation counter.
d = GXDLMSData("OBIS_CODE")
read(d, 2)
client.ciphering.invocationCounter = 1 + d.value

Server side

There is no link from the Security Setup object to the invocation counter data object. This causes that this must add manually to the server side code. This is done adding association view and invocation counter object as normal.

  • Java
  • C#
  • ANSI C++
  • ANSI C
//Add logical name association object.
GXDLMSAssociationLogicalName ln = new GXDLMSAssociationLogicalName();
ln.setSecuritySetupReference("0.0.43.0.0.255");
getItems().add(ln);
//Add security setup object.
GXDLMSSecuritySetup ss = new GXDLMSSecuritySetup("0.0.43.0.0.255");
ss.setServerSystemTitle(getCiphering().getSystemTitle());
getItems().add(ss);
//Add invocation counter
GXDLMSData d = new GXDLMSData("0.0.43.1.0.255");
d.setDataType(2, DataType.UInt32);
//Set initial value for invocation counter.
d.setValue(100);
getItems().add(d);
//Add logical name association object.
GXDLMSAssociationLogicalName ln = new GXDLMSAssociationLogicalName();
ln.SecuritySetupReference = "0.0.43.0.0.255";
Items.Add(ln);
//Add security setup object.
GXDLMSSecuritySetup ss = new GXDLMSSecuritySetup("0.0.43.0.0.255");
ss.ServerSystemTitle = this.Ciphering.SystemTitle;
Items.Add(ss);
//Add invocation counter
GXDLMSData d = new GXDLMSData("0.0.43.1.0.255");
d.SetDataType(2, DataType.UInt32);
//Set initial value for invocation counter.
d.Value = (UInt32)100;
Items.Add(d);
//Add logical name association object.
CGXDLMSAssociationLogicalName* ln = new CGXDLMSAssociationLogicalName();
ln->SetSecuritySetupReference("0.0.43.0.0.255");
GetItems().push_back(ln);
//Add security setup object.
CGXDLMSSecuritySetup* ss = new CGXDLMSSecuritySetup("0.0.43.0.0.255");
ss->SetServerSystemTitle(GetCiphering()->GtSystemTitle());
GetItems().push_back(ss);
//Add invocation counter
CGXDLMSData* d = new CGXDLMSData("0.0.43.1.0.255");
d->SetDataType(2, DLMS_DATA_TYPE_UINT32);
//Set initial value for invocation counter.
CGXDLMSVariant v = (unsigned short)100;
d->SetValue(v);
GetItems().push_back(d);
int ret;
//User list.
static gxUser USER_LIST[10] = { 0 };
//Dedicated key.
static unsigned char CYPHERING_INFO[20] = { 0 };
const unsigned char ln[6] = { 0, 0, 40, 0, 3, 255 };
if ((ret = INIT_OBJECT(highAssociation, DLMS_OBJECT_TYPE_ASSOCIATION_LOGICAL_NAME, ln)) == 0)
{
    highAssociation.authenticationMechanismName.mechanismId = DLMS_AUTHENTICATION_HIGH;
    OA_ATTACH(highAssociation.objectList, ALL_OBJECTS);
#ifndef DLMS_IGNORE_OBJECT_POINTERS
    highAssociation.securitySetup = &securitySetup;
#else
    memcpy(highAssociation.securitySetupReference, securitySetup.base.logicalName, 6);
#endif //DLMS_IGNORE_OBJECT_POINTERS
    BB_ATTACH(highAssociation.xDLMSContextInfo.cypheringInfo, CYPHERING_INFO, 0);
    //All objects are add for this Association View later.
    ARR_ATTACH(highAssociation.userList, USER_LIST, 0);
    highAssociation.clientSAP = 0x30;
    static char HLS_PASSWORD[20] = "Gurux";
    BB_ATTACH(highAssociation.secret, (unsigned char*)HLS_PASSWORD, (unsigned short)strlen(HLS_PASSWORD));

    const unsigned char ln[6] = { 0,0,43, 1, 0, 255};
    cosem_init2(&frameCounterHigh.base, DLMS_OBJECT_TYPE_DATA, ln);
    var_setUInt32(&frameCounterHigh.value, 100);
}

Because there is no link from security setup to Invacation counter in the DLMS stadard it must update manually when client establish the connection.

  • Java
  • C#
  • ANSI C++
  • ANSI C
@Override
public final boolean isTarget(final int serverAddress, final int clientAddress) {
    //Update invocation counter.
    if (clientAddress == 1)
    {
        getCiphering().setInvocationCounter(((Number) frameCounterHigh.getValue()).intValue());
    }
    return true;
}
protected override bool IsTarget(int serverAddress, int clientAddress)
{
    //Update invocation counter.
    if (clientAddress == 1)
    {
        Ciphering.InvocationCounter = Convert.ToUInt32(frameCounterHigh.Value);
    }
    return true;
}
bool CGXDLMSBase::IsTarget(
    unsigned long int serverAddress,
    unsigned long clientAddress)
{
    //Update invocation counter.
    if (clientAddress == 1)
    {
        GetCipher()->SetInvocationCounter(frameCounterHigh.GetValue().ToInteger());
    }
    return true;
}

unsigned char svr_isTarget(
    dlmsSettings* settings,
    unsigned long serverAddress,
    unsigned long clientAddress)
{
    //Update invocation counter.
    if (clientAddress == 1)
    {
        settings->cipher.invocationCounter = frameCounterHigh.value.lVal;
    }
}

Invocation counter is saved to the Flash, etc. memory after update. This can be done after the connection is closed. This debends from the used hardware, etc. There is no single solution for this.

Book traversal links for Invocation counter

  • Security setup
  • Up
  • Single action schedule
  • Log in or register to post comments
  • Create new account
  • Reset your password

Book navigation

  • Activity calendar
  • Association Logical Name
  • Auto Connect
  • Auto answer
  • Clock
  • Compact data
  • Data
  • Demand register
  • Disconnect control
  • Extended register
  • GPRS modem setup
  • GSM diagnostic
  • IEC HDLC setup
  • IEC local port setup
  • IPv4 setup
  • IPv6 setup
  • Image transfer
  • Limiter
  • M-Bus Client
  • M-Bus master port setup
  • M-Bus slave port setup
  • MAC address setup
  • Modem configuration
  • PPP setup
  • Profile generic
  • Push Setup
  • Register
  • Register Monitor
  • Register activation
  • Register table
  • SAP assignment
  • Script table
  • Security setup
    • Invocation counter
  • Single action schedule
  • Special days table
  • Status mapping
  • Tcp Udp Setup
  • Utility tables
  • Manufacturer custom objects

Hire Us!

Latest Releases

  • Thu, 06/19/2025 - 09:33
    Gurux.DLMS.Python 1.0.185
  • Wed, 06/18/2025 - 15:11
    Gurux.DLMS.Python 1.0.184
  • Wed, 06/18/2025 - 10:05
    Gurux.DLMS.Python 1.0.183
  • Wed, 06/18/2025 - 09:06
    GXDLMSDirector 9.0.2506.1801
  • Wed, 06/18/2025 - 08:41
    Gurux.DLMS.Net 9.0.2506.1801

New forum topics

  • Unable to read parameter values from Landis+Gyr E550 meter using GXDLMSDirector - NoAccess status
  • data.SetComplete(false); But all data recieved
  • Crash (endless loop)
  • Server is not able to download object list with maxPduSize 64 or 128 (or anything below 156-bytes PDU size)
  • Day profile action item add error (String is not recognized as valid DateTime value)
More
RSS feed
Privacy FAQ GXDN Issues Contact
Follow Gurux on Twitter Follow Gurux on Linkedin