Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion GuruxDLMSClientExample/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ TARGET = gurux.dlms.client.bin
CC = g++

# compiling flags here
CFLAGS = -c
CFLAGS = --std=c++11 -c

LINKER = g++ -o

Expand Down
132 changes: 72 additions & 60 deletions GuruxDLMSClientExample/src/GuruxDLMSClientExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,26 @@ static void ShowHelp()
printf("GuruxDlmsSample -h [Meter IP Address] -p [Meter Port No] -c 16 -s 1 -r SN\r\n");
printf(" -h \t host name or IP address.\r\n");
printf(" -p \t port number or name (Example: 1000).\r\n");
printf(" -S [COM1:9600:8None1]\t serial port.");
printf(" -i IEC is a start protocol.\r\n");
printf(" -S [COM1:9600:8None1]\t serial port.\r\n");
printf(" -i \t IEC is a start protocol.\r\n");
printf(" -a \t Authentication (None, Low, High, HighMd5, HighSha1, HighGmac, HighSha256).\r\n");
printf(" -P \t Password for authentication.\r\n");
printf(" -c \t Client address. (Default: 16)\r\n");
printf(" -s \t Server address. (Default: 1)\r\n");
printf(" -n \t Server address as serial number.\r\n");
printf(" -r [sn, sn]\t Short name or Logican Name (default) referencing is used.\r\n");
printf(" -w WRAPPER profile is used. HDLC is default.\r\n");
printf(" -f \t Formula to create address from serial number. (Default: SN%%10000+1000)\r\n");
printf(" -r [sn, ln]\t Short name or Logican Name (default) referencing is used.\r\n");
printf(" -w \t WRAPPER profile is used. HDLC is default.\r\n");
printf(" -t Trace messages.\r\n");
printf(" -g \"0.0.1.0.0.255:1; 0.0.1.0.0.255:2\" Get selected object(s) with given attribute index.\r\n");
printf(" -C \t Security Level. (None, Authentication, Encrypted, AuthenticationEncryption)");
printf(" -v \t Invocation counter data object Logical Name. Ex. 0.0.43.1.1.255");
printf(" -I \t Auto increase invoke ID");
printf(" -o \t Cache association view to make reading faster. Ex. -o C:\\device.xml");
printf(" -T \t System title that is used with chiphering. Ex -D 4775727578313233");
printf(" -A \t Authentication key that is used with chiphering. Ex -D D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF");
printf(" -B \t Block cipher key that is used with chiphering. Ex -D 000102030405060708090A0B0C0D0E0F");
printf(" -D \t Dedicated key that is used with chiphering. Ex -D 00112233445566778899AABBCCDDEEFF");
printf(" -C \t Security Level. (None, Authentication, Encrypted, AuthenticationEncryption)\r\n");
printf(" -v \t Invocation counter data object Logical Name. Ex. 0.0.43.1.1.255\r\n");
printf(" -I \t Auto increase invoke ID\r\n");
printf(" -o \t Cache association view to make reading faster. Ex. -o C:\\device.xml\r\n");
printf(" -T \t System title that is used with chiphering. Ex -D 4775727578313233\r\n");
printf(" -A \t Authentication key that is used with chiphering. Ex -D D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF\r\n");
printf(" -B \t Block cipher key that is used with chiphering. Ex -D 000102030405060708090A0B0C0D0E0F\r\n");
printf(" -D \t Dedicated key that is used with chiphering. Ex -D 00112233445566778899AABBCCDDEEFF\r\n");
printf("Example:\r\n");
printf("Read LG device using TCP/IP connection.\r\n");
printf("GuruxDlmsSample -r SN -c 16 -s 1 -h [Meter IP Address] -p [Meter Port No]\r\n");
Expand Down Expand Up @@ -104,6 +105,7 @@ int main(int argc, char* argv[])
int index, a, b, c, d, e, f;
int opt = 0;
int port = 0;
int serialNumber = -1;
char* address = NULL;
char* serialPort = NULL;
bool iec = false;
Expand All @@ -114,8 +116,9 @@ int main(int argc, char* argv[])
char* authenticationKey = NULL;
char* blockCipherKey = NULL;
char* dedicatedKey = NULL;
char* formula = (char *)"SN%10000+1000";

while ((opt = getopt(argc, argv, "h:p:c:s:r:iIt:a:wP:g:S:n:C:v:o:T:A:B:D:")) != -1)
while ((opt = getopt(argc, argv, "h:p:c:s:r:iIt:a:wP:g:S:n:C:f:v:o:T:A:B:D:")) != -1)
{
switch (opt)
{
Expand Down Expand Up @@ -245,6 +248,9 @@ int main(int argc, char* argv[])
} while ((p = strchr(p, ',')) != NULL);
readObjects = optarg;
break;
case 'f':
formula = optarg;
break;
case 'S':
serialPort = optarg;
break;
Expand Down Expand Up @@ -290,51 +296,53 @@ int main(int argc, char* argv[])
serverAddress = atoi(optarg);
break;
case 'n':
serverAddress = CGXDLMSClient::GetServerAddress(atoi(optarg));
serialNumber = atoi(optarg);
break;
case '?':
{
if (optarg[0] == 'c') {
printf("Missing mandatory client option.\n");
}
else if (optarg[0] == 's') {
printf("Missing mandatory server option.\n");
}
else if (optarg[0] == 'h') {
printf("Missing mandatory host name option.\n");
}
else if (optarg[0] == 'p') {
printf("Missing mandatory port option.\n");
}
else if (optarg[0] == 'r') {
printf("Missing mandatory reference option.\n");
}
else if (optarg[0] == 'a') {
printf("Missing mandatory authentication option.\n");
}
else if (optarg[0] == 'S') {
printf("Missing mandatory Serial port option.\n");
}
else if (optarg[0] == 'g') {
printf("Missing mandatory OBIS code option.\n");
}
else if (optarg[0] == 'C') {
printf("Missing mandatory Ciphering option.\n");
}
else if (optarg[0] == 'v') {
printf("Missing mandatory invocation counter logical name option.\n");
}
else if (optarg[0] == 'T') {
printf("Missing mandatory system title option.");
}
else if (optarg[0] == 'A') {
printf("Missing mandatory authentication key option.");
}
else if (optarg[0] == 'B') {
printf("Missing mandatory block cipher key option.");
}
else if (optarg[0] == 'D') {
printf("Missing mandatory dedicated key option.");
if (optarg != nullptr) {
if (optarg[0] == 'c') {
printf("Missing mandatory client option.\n");
}
else if (optarg[0] == 's') {
printf("Missing mandatory server option.\n");
}
else if (optarg[0] == 'h') {
printf("Missing mandatory host name option.\n");
}
else if (optarg[0] == 'p') {
printf("Missing mandatory port option.\n");
}
else if (optarg[0] == 'r') {
printf("Missing mandatory reference option.\n");
}
else if (optarg[0] == 'a') {
printf("Missing mandatory authentication option.\n");
}
else if (optarg[0] == 'S') {
printf("Missing mandatory Serial port option.\n");
}
else if (optarg[0] == 'g') {
printf("Missing mandatory OBIS code option.\n");
}
else if (optarg[0] == 'C') {
printf("Missing mandatory Ciphering option.\n");
}
else if (optarg[0] == 'v') {
printf("Missing mandatory invocation counter logical name option.\n");
}
else if (optarg[0] == 'T') {
printf("Missing mandatory system title option.");
}
else if (optarg[0] == 'A') {
printf("Missing mandatory authentication key option.");
}
else if (optarg[0] == 'B') {
printf("Missing mandatory block cipher key option.");
}
else if (optarg[0] == 'D') {
printf("Missing mandatory dedicated key option.");
}
}
else
{
Expand All @@ -348,6 +356,10 @@ int main(int argc, char* argv[])
return 1;
}
}
if (serialNumber > 0)
{
serverAddress = CGXDLMSClient::GetServerAddress(serialNumber, formula);
}
CGXDLMSSecureClient cl(useLogicalNameReferencing, clientAddress, serverAddress, authentication, password, interfaceType);
cl.GetCiphering()->SetSecurity(security);
cl.SetAutoIncreaseInvokeID(autoIncreaseInvokeID);
Expand Down Expand Up @@ -461,7 +473,7 @@ int main(int argc, char* argv[])
if ((ret = comm.Read(obj, index, value)) != DLMS_ERROR_CODE_OK)
{
#if _MSC_VER > 1000
sprintf_s(buff, 100, "Error! Index: %d %s\r\n", index, CGXDLMSConverter::GetErrorMessage(ret));
sprintf_s(buff, 200, "Error! Index: %d %s\r\n", index, CGXDLMSConverter::GetErrorMessage(ret));
#else
sprintf(buff, "Error! Index: %d read failed: %s\r\n", index, CGXDLMSConverter::GetErrorMessage(ret));
#endif
Expand All @@ -471,9 +483,9 @@ int main(int argc, char* argv[])
else
{
#if _MSC_VER > 1000
sprintf_s(buff, 100, "Index: %d Value: ", index);
sprintf_s(buff, 100, "Object: %s%d Value: ", index);
#else
sprintf(buff, "Index: %d Value: ", index);
sprintf(buff, "Object: %s%d Value: ", str.data(), index);
#endif
comm.WriteValue(trace, buff);
comm.WriteValue(trace, value.c_str());
Expand All @@ -483,9 +495,9 @@ int main(int argc, char* argv[])
else
{
#if _MSC_VER > 1000
sprintf_s(buff, 100, "Unknown object: %s", str.c_str());
snprintf_s(buff, 100, "Unknown object: %s", str.c_str());
#else
sprintf(buff, 100, "Unknown object: %s", str.c_str());
snprintf(buff, 100, "Unknown object: %s", str.c_str());
#endif
str = buff;
comm.WriteValue(GX_TRACE_LEVEL_ERROR, str);
Expand Down
25 changes: 16 additions & 9 deletions GuruxDLMSClientExample/src/communication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void CGXCommunication::WriteValue(GX_TRACE_LEVEL trace, std::string line)
{
if (trace > GX_TRACE_LEVEL_WARNING)
{
printf(line.c_str());
printf("%s",line.c_str());
}
GXHelpers::Write("LogFile.txt", line);
}
Expand Down Expand Up @@ -803,7 +803,7 @@ int CGXCommunication::UpdateFrameCounter()
{
m_Parser->GetCiphering()->SetInvocationCounter(1 + d.GetValue().ToInteger());
}
printf("Invocation counter: %d\r\n", m_Parser->GetCiphering()->GetInvocationCounter());
printf("Invocation counter: %li\r\n", m_Parser->GetCiphering()->GetInvocationCounter());
reply.Clear();
Disconnect();
m_Parser->SetClientAddress(add);
Expand All @@ -829,14 +829,21 @@ int CGXCommunication::InitializeConnection()
}
std::vector<CGXByteBuffer> data;
CGXReplyData reply;

//Get meter's send and receive buffers size.
if ((ret = m_Parser->SNRMRequest(data)) != 0 ||
(ret = ReadDataBlock(data, reply)) != 0 ||
(ret = m_Parser->ParseUAResponse(reply.GetData())) != 0)
{
printf("SNRMRequest failed %d.\r\n", ret);
if ((ret = m_Parser->SNRMRequest(data)) != 0) {
printf("SNRMRequest failed %d.SNRMRequest(data)\r\n", ret);
return ret;
}
}
if ((ret = ReadDataBlock(data, reply)) != 0) {
printf("SNRMRequest failed %d.ReadDataBlock\r\n", ret);
return ret;
}
if ((ret = m_Parser->ParseUAResponse(reply.GetData())) != 0) {
printf("SNRMRequest failed %d.ParseUAResponse(reply.GetData())\r\n", ret);
return ret;
}

reply.Clear();
if ((ret = m_Parser->AARQRequest(data)) != 0 ||
(ret = ReadDataBlock(data, reply)) != 0 ||
Expand Down Expand Up @@ -1638,4 +1645,4 @@ int CGXCommunication::ReadAll(char* outputFile)
ret = m_Parser->GetObjects().Save(outputFile, settings);
}
return ret;
}
}
8 changes: 8 additions & 0 deletions debian-control
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Section: other
Priority: optional
Maintainer: Petr Bravenec <petr.bravenec@hobrasoft.cz>
Homepage: <https>
Package: dlms-client
Architecture: AAAA
Version: XXXX
Description: Reads values from DLMS metering device
3 changes: 3 additions & 0 deletions debian/DEBIAN/postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

exit 0
1 change: 1 addition & 0 deletions development/include/GXCipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#ifndef GXCIPHER_H
#define GXCIPHER_H

// #include <stdint.h>
#include "GXBytebuffer.h"

class CGXCipher
Expand Down
2 changes: 1 addition & 1 deletion development/include/GXDLMSSeasonProfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#define GXDLMSSEASONPROFILE_H

#include "GXDateTime.h"
#include "GXByteBuffer.h"
#include "GXBytebuffer.h"

class CGXDLMSSeasonProfile
{
Expand Down
4 changes: 2 additions & 2 deletions development/include/GXDLMSWeekProfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#define GXDLMSWEEKPROFILE_H

#include <string>
#include "GXByteBuffer.h"
#include "GXBytebuffer.h"

class CGXDLMSWeekProfile
{
Expand Down Expand Up @@ -97,4 +97,4 @@ class CGXDLMSWeekProfile
std::string ToString();
};

#endif //GXDLMSWEEKPROFILE_H
#endif //GXDLMSWEEKPROFILE_H
4 changes: 2 additions & 2 deletions development/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@
TARGET = libgurux_dlms_cpp.a
CC = g++
# compiling flags here
CFLAGS = -O3 -Wall -fPIC
CFLAGS = -O3 -Wall -fPIC -std=c++11

LINKER = ar rvs

# linking flags here
LFLAGS =
LFLAGS =

# change these to set the proper directories where each files shoould be

Expand Down
5 changes: 3 additions & 2 deletions development/src/GXDLMSClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1333,8 +1333,9 @@ int CGXDLMSClient::ReadList(
sn += (it->second - 1) * 8;
bb.SetUInt16(sn);
}
// NULL istead of new CGXBytesBuffer() caused SIGSEGV
CGXDLMSSNParameters p(&m_Settings, DLMS_COMMAND_READ_REQUEST,
(unsigned long)list.size(), 0xFF, &bb, NULL);
(unsigned long)list.size(), 0xFF, &bb, new CGXByteBuffer());
ret = CGXDLMS::GetSnMessages(p, reply);
}
return ret;
Expand Down Expand Up @@ -2004,4 +2005,4 @@ void CGXDLMSClient::SetCtoSChallenge(CGXByteBuffer& value)
CGXByteBuffer& CGXDLMSClient::GetCtoSChallenge()
{
return m_Settings.GetCtoSChallenge();
}
}
2 changes: 1 addition & 1 deletion development/src/GXSerialNumberCounter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,4 @@ int CGXSerialNumberCounter::Count(unsigned long sn, const char* formula)
}
}
return value;
}
}
41 changes: 41 additions & 0 deletions makedeb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

(
cd development
make clean
make
)

(
cd GuruxDLMSClientExample
mkdir obj
mkdir bin
make clean
make
)

if [ "$1" != "armhf" -a "$1" != "i386" -a "$1" != "amd64" ]; then
echo nutno zadat architekturu armhf nebo i386 nebo amd64
exit
fi

ARCH=$1
VERZE=1.0.0
APPNAME=dlms-client

mkdir -p debian/usr/bin


DIR=/tmp/dlms-client.$$
(
rm -fr $DIR
find debian -print | cpio -pudm $DIR
sed "s/XXXX/$VERZE/; s/AAAA/$ARCH/;" < debian-control > $DIR/debian/DEBIAN/control
cp GuruxDLMSClientExample/bin/gurux.dlms.client.bin $DIR/debian/usr/bin/dlms-client
cd $DIR
fakeroot dpkg-deb --build debian
)

mv $DIR/debian.deb $APPNAME-$VERZE-$ARCH.deb
rm -fr $DIR