add logging

This commit is contained in:
Thomas Kunze 2024-08-17 17:27:27 +02:00
parent cd62a78eb4
commit 2585deb52c
16 changed files with 925 additions and 54 deletions

View File

@ -16,6 +16,8 @@
#include "fdsk.h"
#define LOGGER Logger::logger("App")
volatile sig_atomic_t loopActive = 1;
void signalHandler(int sig)
{
@ -109,20 +111,20 @@ void setup()
GO_MAX.valueNoSend(-273.0);
GO_RESET.dataPointType(Dpt(1, 15));
GO_RESET.callback(resetCallback);
printf("Timeout: %d\n", knx.paramWord(0));
printf("Zykl. senden: %d\n", knx.paramByte(2));
printf("Min/Max senden: %d\n", knx.paramByte(3));
printf("Aenderung senden: %d\n", knx.paramByte(4));
printf("Abgleich %d\n", knx.paramByte(5));
LOGGER.info("Timeout: %d", knx.paramWord(0));
LOGGER.info("Zykl. senden: %d", knx.paramByte(2));
LOGGER.info("Min/Max senden: %d", knx.paramByte(3));
LOGGER.info("Aenderung senden: %d", knx.paramByte(4));
LOGGER.info("Abgleich %d", knx.paramByte(5));
}
else
println("not configured");
LOGGER.info("not configured");
knx.start();
}
int main(int argc, char **argv)
{
printf("main() start.\n");
LOGGER.info("main() start.");
uint8_t serialNumber[] = { 0x00, 0xFA, 0x01, 0x02, 0x03, 0x04};
uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
@ -130,7 +132,7 @@ int main(int argc, char **argv)
FdskCalculator calc;
char fdskString[42]; // 6 * 6 chars + 5 dashes + nullbyte = 42
calc.snprintFdsk(fdskString, sizeof(fdskString), serialNumber, key);
printf("FDSK: %s\n", fdskString);
LOGGER.info("FDSK: %s", fdskString);
// Prevent swapping of this process
struct sched_param sp;
@ -160,5 +162,5 @@ int main(int argc, char **argv)
// opens the "value" sysfs file to read or write the GPIO pin value.
// The following calls will close the "value" sysfs fiel for the pin
// and unexport the GPIO pin.
printf("main() exit.\n");
LOGGER.info("main() exit.");
}

View File

@ -124,6 +124,7 @@ knx/ip/knx_ip_tunnel_connection.cpp
knx/ip/knx_ip_tunnel_connection.h
knx/ip/service_families.h
knx/knx_types.h
knx/knx_types.cpp
knx/knx_value.cpp
knx/knx_value.h
knx/memory.cpp

View File

@ -6,7 +6,7 @@ APDU::APDU(uint8_t* data, CemiFrame& frame): _data(data), _frame(frame)
{
}
ApduType APDU::type()
ApduType APDU::type() const
{
uint16_t apci;
apci = getWord(_data);
@ -40,20 +40,18 @@ uint8_t APDU::length() const
return _frame.npdu().octetCount();
}
void APDU::printPDU()
APDU::operator std::string() const
{
print("APDU: ");
print(type(), HEX);
print(" ");
print(_data[0] & 0x3, HEX);
string value = "APDU: " + enum_name(type()) + " ";
value += hex(_data[0] & 0x3);
for (uint8_t i = 1; i < length() + 1; ++i)
{
if (i)
print(" ");
value += " ";
print(_data[i], HEX);
value += hex(_data[i]);
}
println();
return value;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
#include <string>
#include "knx_types.h"
class CemiFrame;
@ -16,7 +17,7 @@ class APDU
/**
* Get the type of the APDU.
*/
ApduType type();
ApduType type() const;
/**
* Set the type of the APDU.
*/
@ -34,9 +35,9 @@ class APDU
*/
uint8_t length() const;
/**
* Print the contents of the APDU to console.
* Convert APDU to string.
*/
void printPDU();
operator std::string() const;
protected:
/**

View File

@ -7,6 +7,8 @@
#include "string.h"
#include "bits.h"
#include <stdio.h>
#include "util/logger.h"
#define LOGGER Logger::logger("ApplicationLayer")
const SecurityControl ApplicationLayer::noSecurity {.toolAccess = false, .dataSecurity = DataSecurity::None};
@ -1360,8 +1362,7 @@ void ApplicationLayer::individualIndication(HopCountType hopType, Priority prior
}
default:
print("Individual-indication: unhandled APDU-Type: ");
apdu.printPDU();
LOGGER.warning("Individual-indication: unhandled APDU-Type: %s", ((std::string)apdu).c_str());
}
}

View File

@ -9,6 +9,15 @@ const uint8_t* popByte(uint8_t& b, const uint8_t* data)
}
#ifndef KNX_NO_PRINT
std::string hex(uint8_t byte)
{
const char* hex = "0123456789ABCDEF";
char out[3] = {0};
out[0] = hex[(byte >> 4) & 0xF];
out[1] = hex[ byte & 0xF];
return std::string(out);
}
void printHex(const char* suffix, const uint8_t* data, size_t length, bool newline)
{
print(suffix);

View File

@ -2,6 +2,7 @@
#include <cstddef>
#include <cstdint>
#include <string>
#if defined(__linux__)
#include <arpa/inet.h>
@ -70,6 +71,7 @@
#endif
#ifndef KNX_NO_PRINT
std::string hex(uint8_t byte);
void print(const char[]);
void print(char);
void print(unsigned char, int = DEC);

View File

@ -5,6 +5,9 @@
#include "device_object.h"
#include "cemi_server.h"
#include "cemi_frame.h"
#include "util/logger.h"
#define LOGGER Logger::logger("DataLinkLayer")
void DataLinkLayerCallbacks::activity(uint8_t info)
@ -36,22 +39,22 @@ void DataLinkLayer::cemiServer(CemiServer& cemiServer)
#ifdef KNX_TUNNELING
void DataLinkLayer::dataRequestToTunnel(CemiFrame& frame)
{
println("default dataRequestToTunnel");
LOGGER.info("default dataRequestToTunnel");
}
void DataLinkLayer::dataConfirmationToTunnel(CemiFrame& frame)
{
println("default dataConfirmationToTunnel");
LOGGER.info("default dataConfirmationToTunnel");
}
void DataLinkLayer::dataIndicationToTunnel(CemiFrame& frame)
{
println("default dataIndicationToTunnel");
LOGGER.info("default dataIndicationToTunnel");
}
bool DataLinkLayer::isTunnelAddress(uint16_t addr)
{
println("default IsTunnelAddress");
LOGGER.info("default IsTunnelAddress");
return false;
}
#endif
@ -157,6 +160,11 @@ void DataLinkLayer::frameReceived(CemiFrame& frame)
uint16_t ownAddr = _deviceObject.individualAddress();
SystemBroadcast systemBroadcast = frame.systemBroadcast();
if (frame.npdu().octetCount() > 0)
{
LOGGER.info("-> %s", ((string)frame.apdu()).c_str());
}
#ifdef USE_CEMI_SERVER
// Do not send our own message back to the tunnel
#ifdef KNX_TUNNELING
@ -207,7 +215,7 @@ bool DataLinkLayer::sendTelegram(NPDU& npdu, AckType ack, uint16_t destinationAd
frame.sourceAddress(sourceAddr);
frame.addressType(addrType);
frame.priority(priority);
frame.repetition(doNotRepeat ? NoRepitiion : RepetitionAllowed);
frame.repetition(doNotRepeat ? NoRepetiion : RepetitionAllowed);
frame.systemBroadcast(systemBroadcast);
if (npdu.octetCount() <= 15)
@ -218,15 +226,14 @@ bool DataLinkLayer::sendTelegram(NPDU& npdu, AckType ack, uint16_t destinationAd
if (!frame.valid())
{
println("invalid frame");
LOGGER.warning("invalid frame");
return false;
}
// if (frame.npdu().octetCount() > 0)
// {
// _print("<- DLL ");
// frame.apdu().printPDU();
// }
if (frame.npdu().octetCount() > 0)
{
LOGGER.info("<- %s", ((string)frame.apdu()).c_str());
}
bool sendTheFrame = true;
bool success = true;

View File

@ -1,4 +1,6 @@
#include "dpt.h"
#include "util/logger.h"
#define LOGGER Logger::logger("Dpt")
#include "bits.h"

706
src/knx/knx_types.cpp Normal file
View File

@ -0,0 +1,706 @@
#include "knx_types.h"
const string enum_name(const LCCONFIG enum_val)
{
switch (enum_val)
{
case PHYS_FRAME:
return "PHYS_FRAME(ROUT)";
case PHYS_FRAME_UNLOCK:
return "PHYS_FRAME_UNLOCK";
case PHYS_FRAME_LOCK:
return "PHYS_FRAME_LOCK";
case PHYS_REPEAT:
return "PHYS_REPEAT";
case BROADCAST_LOCK:
return "BROADCAST_LOCK";
case BROADCAST_REPEAT:
return "BROADCAST_REPEAT";
case GROUP_IACK_ROUT:
return "GROUP_IACK_ROUT";
case PHYS_IACK:
return "PHYS_IACK/NACK";
case PHYS_IACK_NORMAL:
return "PHYS_IACK_NORMAL";
case PHYS_IACK_ALL:
return "PHYS_IACK_ALL";
}
return to_string(enum_val);
}
const string enum_name(const LCGRPCONFIG enum_val)
{
switch (enum_val)
{
case GROUP_6FFF:
return "GROUP_6FFF(ROUTE)";
case GROUP_7000:
return "GROUP_7000(ROUTE)";
case GROUP_REPEAT:
return "GROUP_REPEAT";
case GROUP_6FFFUNLOCK:
return "GROUP_6FFFUNLOCK";
case GROUP_6FFFLOCK:
return "GROUP_6FFFLOCK";
case GROUP_7000UNLOCK:
return "GROUP_7000UNLOCK";
case GROUP_7000LOCK:
return "GROUP_7000LOCK";
}
return to_string(enum_val);
}
const string enum_name(const DptMedium enum_val)
{
switch (enum_val)
{
case KNX_TP1:
return "KNX_TP1";
case KNX_PL110:
return "KNX_PL110";
case KNX_RF:
return "KNX_RF";
case KNX_IP:
return "KNX_IP";
}
return to_string(enum_val);
}
const string enum_name(const EraseCode enum_val)
{
switch (enum_val)
{
case Void:
return "Void";
case ConfirmedRestart:
return "ConfirmedRestart";
case FactoryReset:
return "FactoryReset";
case ResetIA:
return "ResetIA";
case ResetAP:
return "ResetAP";
case ResetParam:
return "ResetParam";
case ResetLinks:
return "ResetLinks";
case FactoryResetWithoutIA:
return "FactoryResetWithoutIA";
}
return to_string(enum_val);
}
const string enum_name(const RestartType enum_val)
{
switch (enum_val)
{
case BasicRestart:
return "BasicRestart";
case MasterReset:
return "MasterReset";
}
return to_string(enum_val);
}
const string enum_name(const DataSecurity enum_val)
{
switch (enum_val)
{
case None:
return "None";
case Auth:
return "Auth";
case AuthConf:
return "AuthConf";
}
return to_string(enum_val);
}
const string enum_name(const ApduType enum_val)
{
switch (enum_val)
{
case GroupValueRead:
return "GroupValueRead";
case GroupValueResponse:
return "GroupValueResponse";
case GroupValueWrite:
return "GroupValueWrite";
case IndividualAddressWrite:
return "IndividualAddressWrite";
case IndividualAddressRead:
return "IndividualAddressRead";
case IndividualAddressResponse:
return "IndividualAddressResponse";
case IndividualAddressSerialNumberRead:
return "IndividualAddressSerialNumberRead";
case IndividualAddressSerialNumberResponse:
return "IndividualAddressSerialNumberResponse";
case IndividualAddressSerialNumberWrite:
return "IndividualAddressSerialNumberWrite";
case SystemNetworkParameterRead:
return "SystemNetworkParameterRead";
case SystemNetworkParameterResponse:
return "SystemNetworkParameterResponse";
case SystemNetworkParameterWrite:
return "SystemNetworkParameterWrite";
case DomainAddressWrite:
return "DomainAddressWrite";
case DomainAddressRead:
return "DomainAddressRead";
case DomainAddressResponse:
return "DomainAddressResponse";
case DomainAddressSelectiveRead:
return "DomainAddressSelectiveRead";
case DomainAddressSerialNumberRead:
return "DomainAddressSerialNumberRead";
case DomainAddressSerialNumberResponse:
return "DomainAddressSerialNumberResponse";
case DomainAddressSerialNumberWrite:
return "DomainAddressSerialNumberWrite";
case ADCRead:
return "ADCRead";
case ADCResponse:
return "ADCResponse";
case PropertyValueExtRead:
return "PropertyValueExtRead";
case PropertyValueExtResponse:
return "PropertyValueExtResponse";
case PropertyValueExtWriteCon:
return "PropertyValueExtWriteCon";
case PropertyValueExtWriteConResponse:
return "PropertyValueExtWriteConResponse";
case PropertyValueExtWriteUnCon:
return "PropertyValueExtWriteUnCon";
case PropertyExtDescriptionRead:
return "PropertyExtDescriptionRead";
case PropertyExtDescriptionResponse:
return "PropertyExtDescriptionResponse";
case FunctionPropertyExtCommand:
return "FunctionPropertyExtCommand";
case FunctionPropertyExtState:
return "FunctionPropertyExtState";
case FunctionPropertyExtStateResponse:
return "FunctionPropertyExtStateResponse";
case MemoryExtWrite:
return "MemoryExtWrite";
case MemoryExtWriteResponse:
return "MemoryExtWriteResponse";
case MemoryExtRead:
return "MemoryExtRead";
case MemoryExtReadResponse:
return "MemoryExtReadResponse";
case MemoryRead:
return "MemoryRead";
case MemoryResponse:
return "MemoryResponse";
case MemoryWrite:
return "MemoryWrite";
case UserMemoryRead:
return "UserMemoryRead";
case UserMemoryResponse:
return "UserMemoryResponse";
case UserMemoryWrite:
return "UserMemoryWrite";
case UserManufacturerInfoRead:
return "UserManufacturerInfoRead";
case UserManufacturerInfoResponse:
return "UserManufacturerInfoResponse";
case FunctionPropertyCommand:
return "FunctionPropertyCommand";
case FunctionPropertyState:
return "FunctionPropertyState";
case FunctionPropertyStateResponse:
return "FunctionPropertyStateResponse";
case DeviceDescriptorRead:
return "DeviceDescriptorRead";
case DeviceDescriptorResponse:
return "DeviceDescriptorResponse";
case Restart:
return "Restart";
case RestartMasterReset:
return "RestartMasterReset";
case RoutingTableOpen:
return "RoutingTableOpen";
case RoutingTableRead:
return "RoutingTableRead";
case RoutingTableReadResponse:
return "RoutingTableReadResponse";
case RoutingTableWrite:
return "RoutingTableWrite";
case MemoryRouterWrite:
return "MemoryRouterWrite";
case MemoryRouterReadResponse:
return "MemoryRouterReadResponse";
case AuthorizeRequest:
return "AuthorizeRequest";
case AuthorizeResponse:
return "AuthorizeResponse";
case KeyWrite:
return "KeyWrite";
case KeyResponse:
return "KeyResponse";
case PropertyValueRead:
return "PropertyValueRead";
case PropertyValueResponse:
return "PropertyValueResponse";
case PropertyValueWrite:
return "PropertyValueWrite";
case PropertyDescriptionRead:
return "PropertyDescriptionRead";
case PropertyDescriptionResponse:
return "PropertyDescriptionResponse";
case SecureService:
return "SecureService";
}
return to_string(enum_val);
}
const string enum_name(const TpduType enum_val)
{
switch (enum_val)
{
case DataBroadcast:
return "DataBroadcast";
case DataGroup:
return "DataGroup";
case DataInduvidual:
return "DataInduvidual";
case DataConnected:
return "DataConnected";
case Connect:
return "Connect";
case Disconnect:
return "Disconnect";
case Ack:
return "Ack";
case Nack:
return "Nack";
}
return to_string(enum_val);
}
const string enum_name(const HopCountType enum_val)
{
switch (enum_val)
{
case UnlimitedRouting:
return "UnlimitedRouting";
case NetworkLayerParameter:
return "NetworkLayerParameter";
}
return to_string(enum_val);
}
const string enum_name(const Confirm enum_val)
{
switch (enum_val)
{
case ConfirmNoError:
return "ConfirmNoError";
case ConfirmError:
return "ConfirmError";
}
return to_string(enum_val);
}
const string enum_name(const SystemBroadcast enum_val)
{
switch (enum_val)
{
case SysBroadcast:
return "SysBroadcast";
case Broadcast:
return "Broadcast";
}
return to_string(enum_val);
}
const string enum_name_in(Repetition enum_val)
{
switch (enum_val)
{
case WasRepeated:
return "WasRepeated";
case WasNotRepeated:
return "WasNotRepeated";
}
return to_string(enum_val);
}
const string enum_name_out(Repetition enum_val)
{
switch (enum_val)
{
case NoRepetiion:
return "NoRepetiion";
case RepetitionAllowed:
return "RepetitionAllowed";
}
return to_string(enum_val);
}
const string enum_name(const ReturnCodes enum_val)
{
switch (enum_val)
{
case Success:
return "Success";
case SuccessWithCrc:
return "SuccessWithCrc";
case MemoryError:
return "MemoryError";
case InvalidCommand:
return "InvalidCommand";
case ImpossibleCommand:
return "ImpossibleCommand";
case ExceedsMaxApduLength:
return "ExceedsMaxApduLength";
case DataOverflow:
return "DataOverflow";
case OutOfMinRange:
return "OutOfMinRange";
case OutOfMaxRange:
return "OutOfMaxRange";
case DataVoid:
return "DataVoid";
case TemporarilyNotAvailable:
return "TemporarilyNotAvailable";
case AccessWriteOnly:
return "AccessWriteOnly";
case AccessReadOnly:
return "AccessReadOnly";
case AccessDenied:
return "AccessDenied";
case AddressVoid:
return "AddressVoid";
case DataTypeConflict:
return "DataTypeConflict";
case GenericError:
return "GenericError";
}
return to_string(enum_val);
}
const string enum_name(const cEmiErrorCode enum_val)
{
switch (enum_val)
{
case Unspecified_Error:
return "Unspecified_Error";
case Out_Of_Range:
return "Out_Of_Range";
case Out_Of_Max_Range:
return "Out_Of_Max_Range";
case Out_Of_Min_Range:
return "Out_Of_Min_Range";
case Memory_Error:
return "Memory_Error";
case Read_Only:
return "Read_Only";
case Illegal_Command:
return "Illegal_Command";
case Void_DP:
return "Void_DP";
case Type_Conflict:
return "Type_Conflict";
case Prop_Index_Range_Error:
return "Prop_Index_Range_Error";
case Value_temp_not_writeable:
return "Value_temp_not_writeable";
}
return to_string(enum_val);
}
const string enum_name(const MessageCode enum_val)
{
switch (enum_val)
{
case L_data_req:
return "L_data_req";
case L_data_con:
return "L_data_con";
case L_data_ind:
return "L_data_ind";
case M_PropRead_req:
return "M_PropRead_req";
case M_PropRead_con:
return "M_PropRead_con";
case M_PropWrite_req:
return "M_PropWrite_req";
case M_PropWrite_con:
return "M_PropWrite_con";
case M_PropInfo_ind:
return "M_PropInfo_ind";
case M_FuncPropCommand_req:
return "M_FuncPropCommand_req";
case M_FuncPropCommand_con:
return "M_FuncPropCommand/StateRead_con";
case M_FuncPropStateRead_req:
return "M_FuncPropStateRead_req";
case M_Reset_req:
return "M_Reset_req";
case M_Reset_ind:
return "M_Reset_ind";
}
return to_string(enum_val);
}
const string enum_name(const AddressType enum_val)
{
switch (enum_val)
{
case IndividualAddress:
return "IndividualAddress";
case GroupAddress:
return "GroupAddress";
}
return to_string(enum_val);
}
const string enum_name(const TPAckType enum_val)
{
switch (enum_val)
{
case AckReqNack:
return "AckReqNack";
case AckReqBusy:
return "AckReqBusy";
case AckReqAck:
return "AckReqAck";
case AckReqNone:
return "AckReqNone";
}
return to_string(enum_val);
}
const string enum_name(const AckType enum_val)
{
switch (enum_val)
{
case AckDontCare:
return "AckDontCare";
case AckRequested:
return "AckRequested";
}
return to_string(enum_val);
}
const string enum_name(const Priority enum_val)
{
switch (enum_val)
{
case LowPriority:
return "LowPriority";
case NormalPriority:
return "NormalPriority";
case UrgentPriority:
return "UrgentPriority";
case SystemPriority:
return "SystemPriority";
}
return to_string(enum_val);
}
const string enum_name(const FrameFormat enum_val)
{
switch (enum_val)
{
case ExtendedFrame:
return "ExtendedFrame";
case StandardFrame:
return "StandardFrame";
}
return to_string(enum_val);
}

View File

@ -1,10 +1,13 @@
#pragma once
#include <string>
using namespace std;
enum FrameFormat
{
ExtendedFrame = 0,
StandardFrame = 0x80
};
const string enum_name(const FrameFormat enum_val);
enum Priority
{
@ -13,12 +16,14 @@ enum Priority
UrgentPriority = 0x8, //!< Used for alarms.
SystemPriority = 0x0 //!< Mainly used by ETS for device programming.
};
const string enum_name(const Priority enum_val);
enum AckType
{
AckDontCare = 0, //!< We don't care about DataLinkLayer acknowledgement.
AckRequested = 0x2, //!< We want a DataLinkLayer acknowledgement.
};
const string enum_name(const AckType enum_val);
enum TPAckType
{
@ -28,12 +33,14 @@ enum TPAckType
AckReqAck = 0x01,
AckReqNone = 0x0,
};
const string enum_name(const TPAckType enum_val);
enum AddressType
{
IndividualAddress = 0,
GroupAddress = 0x80,
};
const string enum_name(const AddressType enum_val);
enum MessageCode
{
@ -59,6 +66,7 @@ enum MessageCode
M_Reset_req = 0xF1,
M_Reset_ind = 0xF0,
};
const string enum_name(const MessageCode enum_val);
enum cEmiErrorCode
{
@ -74,6 +82,7 @@ enum cEmiErrorCode
Prop_Index_Range_Error = 0x09, // read or write access to a non existing Property array index (R/W)
Value_temp_not_writeable = 0x0A, // The Property exists but can at this moment not be written with a new value (W)
};
const string enum_name(const cEmiErrorCode enum_val);
// Unified return codes for KNX services and functions
// Note, that several older KNX services and functions do not use these return codes.
@ -99,32 +108,38 @@ enum ReturnCodes
DataTypeConflict = 0xFE, // write access with wrong datatype (datapoint length)
GenericError = 0xFF // service, function or command failed
};
const string enum_name(const ReturnCodes enum_val);
enum Repetition
{
NoRepitiion = 0,
NoRepetiion = 0,
WasRepeated = 0,
RepetitionAllowed = 0x20,
WasNotRepeated = 0x20,
};
const string enum_name_in(Repetition enum_val);
const string enum_name_out(Repetition enum_val);
enum SystemBroadcast
{
SysBroadcast = 0,
Broadcast = 0x10,
};
const string enum_name(const SystemBroadcast enum_val);
enum Confirm
{
ConfirmNoError = 0,
ConfirmError = 1,
};
const string enum_name(const Confirm enum_val);
enum HopCountType
{
UnlimitedRouting, //!< NPDU::hopCount is set to 7. This means that the frame never expires. This could be a problem if your bus contains a circle.
NetworkLayerParameter //!< use NetworkLayer::hopCount as NPDU::hopCount
};
const string enum_name(const HopCountType enum_val);
enum TpduType
{
@ -137,6 +152,7 @@ enum TpduType
Ack,
Nack,
};
const string enum_name(const TpduType enum_val);
enum ApduType
{
@ -218,6 +234,7 @@ enum ApduType
// Secure Service
SecureService = 0x3F1
};
const string enum_name(const ApduType enum_val);
enum DataSecurity
{
@ -225,6 +242,7 @@ enum DataSecurity
Auth,
AuthConf
};
const string enum_name(const DataSecurity enum_val);
struct SecurityControl
{
@ -237,6 +255,7 @@ enum RestartType
BasicRestart = 0x0,
MasterReset = 0x1
};
const string enum_name(const RestartType enum_val);
enum EraseCode
{
@ -249,6 +268,7 @@ enum EraseCode
ResetLinks = 0x06,
FactoryResetWithoutIA = 0x07
};
const string enum_name(const EraseCode enum_val);
enum DptMedium
{
@ -259,6 +279,7 @@ enum DptMedium
KNX_RF = 0x02,
KNX_IP = 0x05
};
const string enum_name(const DptMedium enum_val);
enum LCGRPCONFIG
{
@ -272,6 +293,7 @@ enum LCGRPCONFIG
GROUP_7000LOCK = 0b00001000,
GROUP_7000ROUTE = 0b00001100
};
const string enum_name(const LCGRPCONFIG enum_val);
enum LCCONFIG
{
@ -287,4 +309,5 @@ enum LCCONFIG
PHYS_IACK_NORMAL = 0b01000000,
PHYS_IACK_ALL = 0b10000000,
PHYS_IACK_NACK = 0b11000000
};
};
const string enum_name(const LCCONFIG enum_val);

View File

@ -1,4 +1,4 @@
#include "knx/platform.h"
#include "../platform.h"
#include "Arduino.h"

View File

@ -6,7 +6,7 @@
#include <ti/drivers/UART.h>
#include <ti/drivers/dpl/ClockP.h>
#include "knx/platform.h"
#include "../platform.h"
class CC1310Platform : public Platform
{

View File

@ -12,6 +12,8 @@
#include "bau.h"
#include "string.h"
#include "bits.h"
#include "util/logger.h"
#define LOGGER Logger::logger("SecureApplicationLayer")
// Select what cipher modes to include. We need AES128-CBC and AES128-CTR modes.
#define CBC 1
@ -658,8 +660,7 @@ void SecureApplicationLayer::sendSyncRequest(uint16_t dstAddr, bool dstAddrIsGro
if (secure(request.data() + APDU_LPDU_DIFF, kSecureSyncRequest, _deviceObj.individualAddress(), dstAddr, dstAddrIsGroupAddr, tpci, asdu, sizeof(asdu), secCtrl, systemBcast))
{
println("SyncRequest: ");
request.apdu().printPDU();
LOGGER.info("SyncRequest: %s", ((string)request.apdu()).c_str());
if (_syncReqBroadcastOutgoing)
{
@ -722,8 +723,7 @@ void SecureApplicationLayer::sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGr
{
_lastSyncRes = millis();
println("SyncResponse: ");
response.apdu().printPDU();
LOGGER.info("SyncResponse: %s", ((string)response.apdu()).c_str());
if (_syncReqBroadcastIncoming)
{
@ -1063,9 +1063,7 @@ bool SecureApplicationLayer::decrypt(uint8_t* plainApdu, uint16_t plainApduLengt
bool SecureApplicationLayer::decodeSecureApdu(APDU& secureApdu, APDU& plainApdu, SecurityControl& secCtrl)
{
// Decode secure APDU
println("decodeSecureApdu: Secure APDU: ");
secureApdu.printPDU();
LOGGER.info("decodeSecureApdu: Secure APDU: %s", ((string)secureApdu).c_str());
uint16_t srcAddress = secureApdu.frame().sourceAddress();
uint16_t dstAddress = secureApdu.frame().destinationAddress();
@ -1087,9 +1085,7 @@ bool SecureApplicationLayer::decodeSecureApdu(APDU& secureApdu, APDU& plainApdu,
// We are starting from TPCI octet (including): plainApdu.frame().data()+APDU_LPDU_DIFF
if (decrypt(plainApdu.frame().data() + APDU_LPDU_DIFF, plainApdu.length() + 1, srcAddress, dstAddress, isDstAddrGroupAddr, tpci, secureApdu.data() + 1, secCtrl, isSystemBroadcast))
{
println("decodeSecureApdu: Plain APDU: ");
plainApdu.frame().apdu().printPDU();
LOGGER.info("decodeSecureApdu: Plain APDU: %s", ((string)plainApdu.frame().apdu()).c_str());
return true;
}
@ -1264,8 +1260,7 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
{
// Create secure APDU
println("createSecureApdu: Plain APDU: ");
plainApdu.printPDU();
LOGGER.info("createSecureApdu: Plain APDU: %s", ((string)plainApdu.frame().apdu()).c_str());
uint16_t srcAddress = plainApdu.frame().sourceAddress();
uint16_t dstAddress = plainApdu.frame().destinationAddress();
@ -1301,8 +1296,7 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
println(nextSequenceNumber(secCtrl.toolAccess), HEX);
updateSequenceNumber(secCtrl.toolAccess, nextSequenceNumber(secCtrl.toolAccess) + 1);
println("createSecureApdu: Secure APDU: ");
secureApdu.frame().apdu().printPDU();
LOGGER.info("createSecureApdu: Secure APDU: %s", ((string)secureApdu.frame().apdu()).c_str());
return true;
}

124
src/knx/util/logger.h Normal file
View File

@ -0,0 +1,124 @@
#include "../bits.h"
#include <stdarg.h>
#include <string>
using namespace std;
class Logger
{
public:
static Logger logger(const string name)
{
return Logger(name);
}
inline void info(const string message, ...)
{
#ifndef KNX_NO_PRINT
va_list objects;
va_start( objects, message);
log(LogType::Info, message.c_str(), objects);
va_end(objects);
#endif
}
inline void warning(const string message, ...)
{
#ifndef KNX_NO_PRINT
va_list objects;
va_start( objects, message);
log(LogType::Warning, message.c_str(), objects);
va_end(objects);
#endif
}
inline void error(const string message, ...)
{
#ifndef KNX_NO_PRINT
va_list objects;
va_start( objects, message);
log(LogType::Error, message.c_str(), objects);
va_end(objects);
#endif
}
inline void critical(const string message, ...)
{
#ifndef KNX_NO_PRINT
va_list objects;
va_start( objects, message);
log(LogType::Critical, message.c_str(), objects);
va_end(objects);
#endif
}
inline void exception(const string message, ...)
{
#ifndef KNX_NO_PRINT
va_list objects;
va_start( objects, message);
log(LogType::Exception, message.c_str(), objects);
va_end(objects);
#endif
}
private:
enum LogType { Info, Warning, Error, Critical, Exception};
const string enum_name(LogType type)
{
switch (type)
{
case LogType::Info:
return "INFO";
case LogType::Warning:
return "WARNING";
case LogType::Error:
return "ERROR";
case LogType::Critical:
return "CRITICAL";
case LogType::Exception:
return "EXCEPTION";
}
return to_string(type);
}
const string _name;
Logger(const string name) : _name(name) {}
inline void log(LogType type, const char* format, va_list args)
{
#ifndef KNX_NO_PRINT
print(millis());
print("\t");
print(_name.c_str());
print("\t");
print(enum_name(type).c_str());
print("\t");
while (*format)
{
if (*format == '%')
{
format++;
if (*format == 'd')
{
print(va_arg(args, int));
}
else if (*format == 's')
{
print(va_arg(args, char*));
}
else if (*format == 'f')
{
print(va_arg(args, double));
}
}
else
{
print(*format);
}
format++;
}
va_end(args);
println();
#endif
}
};

View File

@ -1,6 +1,7 @@
#pragma once
#include "knx/bits.h"
#include "knx/util/logger.h"
#include "knx/config.h"
#include "knx/bau.h"
#include "knx/bau07B0.h"
@ -201,12 +202,12 @@ template <class P, class B> class KnxFacade : private SaveRestore
if (_progLedState)
{
println("progmode on");
Logger::logger("KnxFacade").info("progmode on");
progLedOn();
}
else
{
println("progmode off");
Logger::logger("KnxFacade").info("progmode off");
progLedOff();
}
}