From 479a7e4d36d46ac87f6a9bfb62378eefff41fba4 Mon Sep 17 00:00:00 2001 From: Petr Bravenec Date: Thu, 9 Apr 2020 13:07:42 +0200 Subject: [PATCH 1/2] Make the source compiled in Linux, fixed SIGSEGV, fixed typos, added parameter for Formula in example --- GuruxDLMSClientExample/makefile | 4 +- .../src/GuruxDLMSClientExample.cpp | 132 ++++++++++-------- GuruxDLMSClientExample/src/communication.cpp | 25 ++-- development/include/GXDLMSSeasonProfile.h | 2 +- development/include/GXDLMSWeekProfile.h | 4 +- development/makefile | 4 +- development/src/GXDLMSClient.cpp | 5 +- development/src/GXSerialNumberCounter.cpp | 2 +- 8 files changed, 99 insertions(+), 79 deletions(-) diff --git a/GuruxDLMSClientExample/makefile b/GuruxDLMSClientExample/makefile index 35c4ff52..a06e3841 100644 --- a/GuruxDLMSClientExample/makefile +++ b/GuruxDLMSClientExample/makefile @@ -4,9 +4,9 @@ TARGET = gurux.dlms.client.bin CC = g++ # compiling flags here -CFLAGS = -c +CFLAGS = -ggdb -c -LINKER = g++ -o +LINKER = g++ -ggdb -o # linking flags here LFLAGS = -L../development/lib diff --git a/GuruxDLMSClientExample/src/GuruxDLMSClientExample.cpp b/GuruxDLMSClientExample/src/GuruxDLMSClientExample.cpp index cbe2709c..1bf7df47 100644 --- a/GuruxDLMSClientExample/src/GuruxDLMSClientExample.cpp +++ b/GuruxDLMSClientExample/src/GuruxDLMSClientExample.cpp @@ -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"); @@ -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; @@ -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) { @@ -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; @@ -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 { @@ -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); @@ -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 @@ -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()); @@ -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); diff --git a/GuruxDLMSClientExample/src/communication.cpp b/GuruxDLMSClientExample/src/communication.cpp index f94ba732..bea0f797 100644 --- a/GuruxDLMSClientExample/src/communication.cpp +++ b/GuruxDLMSClientExample/src/communication.cpp @@ -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); } @@ -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); @@ -829,14 +829,21 @@ int CGXCommunication::InitializeConnection() } std::vector 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 || @@ -1638,4 +1645,4 @@ int CGXCommunication::ReadAll(char* outputFile) ret = m_Parser->GetObjects().Save(outputFile, settings); } return ret; -} \ No newline at end of file +} diff --git a/development/include/GXDLMSSeasonProfile.h b/development/include/GXDLMSSeasonProfile.h index 514fc267..1fd30210 100644 --- a/development/include/GXDLMSSeasonProfile.h +++ b/development/include/GXDLMSSeasonProfile.h @@ -36,7 +36,7 @@ #define GXDLMSSEASONPROFILE_H #include "GXDateTime.h" -#include "GXByteBuffer.h" +#include "GXBytebuffer.h" class CGXDLMSSeasonProfile { diff --git a/development/include/GXDLMSWeekProfile.h b/development/include/GXDLMSWeekProfile.h index 1377fe00..490ba6ae 100644 --- a/development/include/GXDLMSWeekProfile.h +++ b/development/include/GXDLMSWeekProfile.h @@ -35,7 +35,7 @@ #define GXDLMSWEEKPROFILE_H #include -#include "GXByteBuffer.h" +#include "GXBytebuffer.h" class CGXDLMSWeekProfile { @@ -97,4 +97,4 @@ class CGXDLMSWeekProfile std::string ToString(); }; -#endif //GXDLMSWEEKPROFILE_H \ No newline at end of file +#endif //GXDLMSWEEKPROFILE_H diff --git a/development/makefile b/development/makefile index 282a1186..3bdbd37a 100644 --- a/development/makefile +++ b/development/makefile @@ -35,12 +35,12 @@ TARGET = libgurux_dlms_cpp.a CC = g++ # compiling flags here -CFLAGS = -O3 -Wall -fPIC +CFLAGS = -O3 -Wall -fPIC LINKER = ar rvs # linking flags here -LFLAGS = +LFLAGS = # change these to set the proper directories where each files shoould be diff --git a/development/src/GXDLMSClient.cpp b/development/src/GXDLMSClient.cpp index df01224a..bfa4fbae 100644 --- a/development/src/GXDLMSClient.cpp +++ b/development/src/GXDLMSClient.cpp @@ -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; @@ -2004,4 +2005,4 @@ void CGXDLMSClient::SetCtoSChallenge(CGXByteBuffer& value) CGXByteBuffer& CGXDLMSClient::GetCtoSChallenge() { return m_Settings.GetCtoSChallenge(); -} \ No newline at end of file +} diff --git a/development/src/GXSerialNumberCounter.cpp b/development/src/GXSerialNumberCounter.cpp index a5bf4201..f9ab8ae3 100644 --- a/development/src/GXSerialNumberCounter.cpp +++ b/development/src/GXSerialNumberCounter.cpp @@ -181,4 +181,4 @@ int CGXSerialNumberCounter::Count(unsigned long sn, const char* formula) } } return value; -} \ No newline at end of file +} From 57ded42d489f5e7fcdf4431e0a6427353fb95f4e Mon Sep 17 00:00:00 2001 From: Petr Bravenec Date: Tue, 14 Apr 2020 10:48:27 +0200 Subject: [PATCH 2/2] Added script to create debian package --- GuruxDLMSClientExample/makefile | 4 ++-- debian-control | 8 +++++++ debian/DEBIAN/postinst | 3 +++ development/include/GXCipher.h | 1 + development/makefile | 2 +- makedeb | 41 +++++++++++++++++++++++++++++++++ 6 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 debian-control create mode 100755 debian/DEBIAN/postinst create mode 100755 makedeb diff --git a/GuruxDLMSClientExample/makefile b/GuruxDLMSClientExample/makefile index a06e3841..50d715a1 100644 --- a/GuruxDLMSClientExample/makefile +++ b/GuruxDLMSClientExample/makefile @@ -4,9 +4,9 @@ TARGET = gurux.dlms.client.bin CC = g++ # compiling flags here -CFLAGS = -ggdb -c +CFLAGS = --std=c++11 -c -LINKER = g++ -ggdb -o +LINKER = g++ -o # linking flags here LFLAGS = -L../development/lib diff --git a/debian-control b/debian-control new file mode 100644 index 00000000..cf9f119a --- /dev/null +++ b/debian-control @@ -0,0 +1,8 @@ +Section: other +Priority: optional +Maintainer: Petr Bravenec +Homepage: +Package: dlms-client +Architecture: AAAA +Version: XXXX +Description: Reads values from DLMS metering device diff --git a/debian/DEBIAN/postinst b/debian/DEBIAN/postinst new file mode 100755 index 00000000..c52d3c26 --- /dev/null +++ b/debian/DEBIAN/postinst @@ -0,0 +1,3 @@ +#!/bin/sh + +exit 0 diff --git a/development/include/GXCipher.h b/development/include/GXCipher.h index 26bbfc41..c1375293 100644 --- a/development/include/GXCipher.h +++ b/development/include/GXCipher.h @@ -35,6 +35,7 @@ #ifndef GXCIPHER_H #define GXCIPHER_H +// #include #include "GXBytebuffer.h" class CGXCipher diff --git a/development/makefile b/development/makefile index 3bdbd37a..c10396d2 100644 --- a/development/makefile +++ b/development/makefile @@ -35,7 +35,7 @@ TARGET = libgurux_dlms_cpp.a CC = g++ # compiling flags here -CFLAGS = -O3 -Wall -fPIC +CFLAGS = -O3 -Wall -fPIC -std=c++11 LINKER = ar rvs diff --git a/makedeb b/makedeb new file mode 100755 index 00000000..7e8da2d4 --- /dev/null +++ b/makedeb @@ -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 +