mirror of
https://github.com/thelsing/knx.git
synced 2025-06-17 01:17:18 +02:00
frame logging data link layer
This commit is contained in:
parent
2585deb52c
commit
59a76b7c3f
@ -40,17 +40,17 @@ uint8_t APDU::length() const
|
|||||||
return _frame.npdu().octetCount();
|
return _frame.npdu().octetCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
APDU::operator std::string() const
|
string APDU::to_string() const
|
||||||
{
|
{
|
||||||
string value = "APDU: " + enum_name(type()) + " ";
|
string value = "APDU: " + enum_name(type()) + " ";
|
||||||
value += hex(_data[0] & 0x3);
|
value += byte2hex(_data[0] & 0x3);
|
||||||
|
|
||||||
for (uint8_t i = 1; i < length() + 1; ++i)
|
for (uint8_t i = 1; i < length() + 1; ++i)
|
||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
value += " ";
|
value += " ";
|
||||||
|
|
||||||
value += hex(_data[i]);
|
value += byte2hex(_data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
@ -37,7 +37,7 @@ class APDU
|
|||||||
/**
|
/**
|
||||||
* Convert APDU to string.
|
* Convert APDU to string.
|
||||||
*/
|
*/
|
||||||
operator std::string() const;
|
std::string to_string() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -1362,7 +1362,7 @@ void ApplicationLayer::individualIndication(HopCountType hopType, Priority prior
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGGER.warning("Individual-indication: unhandled APDU-Type: %s", ((std::string)apdu).c_str());
|
LOGGER.warning("Individual-indication: unhandled APDU-Type: %s", apdu.to_string().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ const uint8_t* popByte(uint8_t& b, const uint8_t* data)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef KNX_NO_PRINT
|
|
||||||
std::string hex(uint8_t byte)
|
std::string byte2hex(uint8_t byte)
|
||||||
{
|
{
|
||||||
const char* hex = "0123456789ABCDEF";
|
const char* hex = "0123456789ABCDEF";
|
||||||
char out[3] = {0};
|
char out[3] = {0};
|
||||||
@ -18,6 +18,12 @@ std::string hex(uint8_t byte)
|
|||||||
return std::string(out);
|
return std::string(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string word2hex(uint16_t value)
|
||||||
|
{
|
||||||
|
return byte2hex((uint8_t) (value & 0xFF00) >> 8) + byte2hex((uint8_t) (value & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef KNX_NO_PRINT
|
||||||
void printHex(const char* suffix, const uint8_t* data, size_t length, bool newline)
|
void printHex(const char* suffix, const uint8_t* data, size_t length, bool newline)
|
||||||
{
|
{
|
||||||
print(suffix);
|
print(suffix);
|
||||||
|
@ -70,8 +70,10 @@
|
|||||||
void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode);
|
void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::string byte2hex(uint8_t byte);
|
||||||
|
std::string word2hex(uint16_t value);
|
||||||
|
|
||||||
#ifndef KNX_NO_PRINT
|
#ifndef KNX_NO_PRINT
|
||||||
std::string hex(uint8_t byte);
|
|
||||||
void print(const char[]);
|
void print(const char[]);
|
||||||
void print(char);
|
void print(char);
|
||||||
void print(unsigned char, int = DEC);
|
void print(unsigned char, int = DEC);
|
||||||
|
@ -399,3 +399,21 @@ bool CemiFrame::valid() const
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CemiFrame::to_string() const
|
||||||
|
{
|
||||||
|
std::string value = enum_name(frameType()) + " ";
|
||||||
|
value += enum_name(systemBroadcast()) + " ";
|
||||||
|
value += enum_name(ack()) + " ";
|
||||||
|
value += enum_name(repetition()) + " ";
|
||||||
|
value += enum_name(priority()) + " from ";
|
||||||
|
value += format_ia(sourceAddress()) + " to ";
|
||||||
|
value += enum_name(addressType()) + " ";
|
||||||
|
|
||||||
|
if (addressType() == AddressType::IndividualAddress)
|
||||||
|
value += format_ia(destinationAddress());
|
||||||
|
else
|
||||||
|
value += format_ga(destinationAddress());
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
@ -72,6 +72,8 @@ class CemiFrame
|
|||||||
uint8_t calcCrcTP(uint8_t* buffer, uint16_t len);
|
uint8_t calcCrcTP(uint8_t* buffer, uint16_t len);
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|
||||||
|
std::string to_string() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t buffer[0xff + NPDU_LPDU_DIFF] = {0}; //only valid of add info is zero
|
uint8_t buffer[0xff + NPDU_LPDU_DIFF] = {0}; //only valid of add info is zero
|
||||||
uint8_t* _data = 0;
|
uint8_t* _data = 0;
|
||||||
|
@ -160,10 +160,9 @@ void DataLinkLayer::frameReceived(CemiFrame& frame)
|
|||||||
uint16_t ownAddr = _deviceObject.individualAddress();
|
uint16_t ownAddr = _deviceObject.individualAddress();
|
||||||
SystemBroadcast systemBroadcast = frame.systemBroadcast();
|
SystemBroadcast systemBroadcast = frame.systemBroadcast();
|
||||||
|
|
||||||
if (frame.npdu().octetCount() > 0)
|
|
||||||
{
|
LOGGER.info("frameReceived %s", frame.to_string().c_str());
|
||||||
LOGGER.info("-> %s", ((string)frame.apdu()).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_CEMI_SERVER
|
#ifdef USE_CEMI_SERVER
|
||||||
// Do not send our own message back to the tunnel
|
// Do not send our own message back to the tunnel
|
||||||
@ -189,7 +188,7 @@ void DataLinkLayer::frameReceived(CemiFrame& frame)
|
|||||||
// println();
|
// println();
|
||||||
// print("frameReceived: frame valid? :");
|
// print("frameReceived: frame valid? :");
|
||||||
// println(npdu.frame().valid() ? "true" : "false");
|
// println(npdu.frame().valid() ? "true" : "false");
|
||||||
if (source == ownAddr)
|
if (source == ownAddr)
|
||||||
_deviceObject.individualAddressDuplication(true);
|
_deviceObject.individualAddressDuplication(true);
|
||||||
|
|
||||||
if (addrType == GroupAddress && destination == 0)
|
if (addrType == GroupAddress && destination == 0)
|
||||||
@ -223,6 +222,7 @@ bool DataLinkLayer::sendTelegram(NPDU& npdu, AckType ack, uint16_t destinationAd
|
|||||||
else
|
else
|
||||||
frame.frameType(format);
|
frame.frameType(format);
|
||||||
|
|
||||||
|
LOGGER.info("sendTelegram %s", frame.to_string().c_str());
|
||||||
|
|
||||||
if (!frame.valid())
|
if (!frame.valid())
|
||||||
{
|
{
|
||||||
@ -230,14 +230,10 @@ bool DataLinkLayer::sendTelegram(NPDU& npdu, AckType ack, uint16_t destinationAd
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame.npdu().octetCount() > 0)
|
|
||||||
{
|
|
||||||
LOGGER.info("<- %s", ((string)frame.apdu()).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sendTheFrame = true;
|
bool sendTheFrame = true;
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
|
|
||||||
#ifdef KNX_TUNNELING
|
#ifdef KNX_TUNNELING
|
||||||
// TunnelOpti
|
// TunnelOpti
|
||||||
// Optimize performance when sending unicast data over tunnel wich is not meant to be used on the physical TP line
|
// Optimize performance when sending unicast data over tunnel wich is not meant to be used on the physical TP line
|
||||||
@ -253,6 +249,7 @@ bool DataLinkLayer::sendTelegram(NPDU& npdu, AckType ack, uint16_t destinationAd
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// The data link layer might be an open media link layer
|
// The data link layer might be an open media link layer
|
||||||
// and will setup rfSerialOrDoA, rfInfo and rfLfn that we also
|
// and will setup rfSerialOrDoA, rfInfo and rfLfn that we also
|
||||||
// have to send through the cEMI server tunnel
|
// have to send through the cEMI server tunnel
|
||||||
|
@ -8,8 +8,16 @@
|
|||||||
#include "knx_ip_search_response.h"
|
#include "knx_ip_search_response.h"
|
||||||
#include "knx_ip_search_request_extended.h"
|
#include "knx_ip_search_request_extended.h"
|
||||||
#include "knx_ip_search_response_extended.h"
|
#include "knx_ip_search_response_extended.h"
|
||||||
|
#include "../util/logger.h"
|
||||||
|
|
||||||
|
const std::string ipaddr2str(const uint32_t addr)
|
||||||
|
{
|
||||||
|
return to_string(addr & 0xFF000000 >> 24) + "." + to_string(addr & 0xFF0000 >> 16) + "." + to_string(addr & 0xFF00 >> 8) + "." + to_string(addr & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOGGER Logger::logger("IpDataLinkLayer")
|
||||||
|
|
||||||
|
|
||||||
#ifdef KNX_TUNNELING
|
|
||||||
#include "knx_ip_connect_request.h"
|
#include "knx_ip_connect_request.h"
|
||||||
#include "knx_ip_connect_response.h"
|
#include "knx_ip_connect_response.h"
|
||||||
#include "knx_ip_state_request.h"
|
#include "knx_ip_state_request.h"
|
||||||
@ -21,7 +29,7 @@
|
|||||||
#include "knx_ip_description_request.h"
|
#include "knx_ip_description_request.h"
|
||||||
#include "knx_ip_description_response.h"
|
#include "knx_ip_description_response.h"
|
||||||
#include "knx_ip_config_request.h"
|
#include "knx_ip_config_request.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -44,7 +52,7 @@ bool IpDataLinkLayer::sendFrame(CemiFrame& frame)
|
|||||||
if (isSendLimitReached())
|
if (isSendLimitReached())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool success = sendBytes(packet.data(), packet.totalLength());
|
bool success = sendMulicast(packet);
|
||||||
#ifdef KNX_ACTIVITYCALLBACK
|
#ifdef KNX_ACTIVITYCALLBACK
|
||||||
|
|
||||||
if (_dllcb)
|
if (_dllcb)
|
||||||
@ -55,7 +63,6 @@ bool IpDataLinkLayer::sendFrame(CemiFrame& frame)
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KNX_TUNNELING
|
|
||||||
void IpDataLinkLayer::dataRequestToTunnel(CemiFrame& frame)
|
void IpDataLinkLayer::dataRequestToTunnel(CemiFrame& frame)
|
||||||
{
|
{
|
||||||
if (frame.addressType() == AddressType::GroupAddress)
|
if (frame.addressType() == AddressType::GroupAddress)
|
||||||
@ -228,7 +235,8 @@ void IpDataLinkLayer::sendFrameToTunnel(KnxIpTunnelConnection* tunnel, CemiFrame
|
|||||||
if (frame.messageCode() != L_data_req && frame.messageCode() != L_data_con && frame.messageCode() != L_data_ind)
|
if (frame.messageCode() != L_data_req && frame.messageCode() != L_data_con && frame.messageCode() != L_data_ind)
|
||||||
req.serviceTypeIdentifier(DeviceConfigurationRequest);
|
req.serviceTypeIdentifier(DeviceConfigurationRequest);
|
||||||
|
|
||||||
_platform.sendBytesUniCast(tunnel->IpAddress, tunnel->PortData, req.data(), req.totalLength());
|
|
||||||
|
sendUnicast(tunnel->IpAddress, tunnel->PortData, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpDataLinkLayer::isTunnelAddress(uint16_t addr)
|
bool IpDataLinkLayer::isTunnelAddress(uint16_t addr)
|
||||||
@ -262,14 +270,14 @@ bool IpDataLinkLayer::isSentToTunnel(uint16_t address, bool isGrpAddr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void IpDataLinkLayer::loop()
|
void IpDataLinkLayer::loop()
|
||||||
{
|
{
|
||||||
if (!_enabled)
|
if (!_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef KNX_TUNNELING
|
|
||||||
|
|
||||||
for (int i = 0; i < KNX_TUNNELING; i++)
|
for (int i = 0; i < KNX_TUNNELING; i++)
|
||||||
{
|
{
|
||||||
@ -288,7 +296,7 @@ void IpDataLinkLayer::loop()
|
|||||||
discReq.hpaiCtrl().code(IPV4_UDP);
|
discReq.hpaiCtrl().code(IPV4_UDP);
|
||||||
discReq.hpaiCtrl().ipAddress(tunnels[i].IpAddress);
|
discReq.hpaiCtrl().ipAddress(tunnels[i].IpAddress);
|
||||||
discReq.hpaiCtrl().ipPortNumber(tunnels[i].PortCtrl);
|
discReq.hpaiCtrl().ipPortNumber(tunnels[i].PortCtrl);
|
||||||
_platform.sendBytesUniCast(tunnels[i].IpAddress, tunnels[i].PortCtrl, discReq.data(), discReq.totalLength());
|
sendUnicast(tunnels[i].IpAddress, tunnels[i].PortCtrl, discReq);
|
||||||
tunnels[i].Reset();
|
tunnels[i].Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,9 +304,6 @@ void IpDataLinkLayer::loop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t buffer[512];
|
uint8_t buffer[512];
|
||||||
uint16_t remotePort = 0;
|
uint16_t remotePort = 0;
|
||||||
uint32_t remoteAddr = 0;
|
uint32_t remoteAddr = 0;
|
||||||
@ -324,6 +329,8 @@ void IpDataLinkLayer::loop()
|
|||||||
uint16_t code;
|
uint16_t code;
|
||||||
popWord(code, buffer + 2);
|
popWord(code, buffer + 2);
|
||||||
|
|
||||||
|
LOGGER.info("loop: %s", enum_name((KnxIpServiceType)code).c_str());
|
||||||
|
|
||||||
switch ((KnxIpServiceType)code)
|
switch ((KnxIpServiceType)code)
|
||||||
{
|
{
|
||||||
case RoutingIndication:
|
case RoutingIndication:
|
||||||
@ -345,7 +352,7 @@ void IpDataLinkLayer::loop()
|
|||||||
_dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST));
|
_dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
_platform.sendBytesUniCast(hpai.ipAddress(), hpai.ipPortNumber(), searchResponse.data(), searchResponse.totalLength());
|
sendUnicast(hpai.ipAddress(), hpai.ipPortNumber(), searchResponse);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +362,7 @@ void IpDataLinkLayer::loop()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KNX_TUNNELING
|
|
||||||
|
|
||||||
case ConnectRequest:
|
case ConnectRequest:
|
||||||
{
|
{
|
||||||
@ -407,11 +414,8 @@ void IpDataLinkLayer::loop()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
print("Unhandled service identifier: ");
|
LOGGER.warning("Unhandled service identifier: %s", word2hex(code).c_str());
|
||||||
println(code, HEX);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -545,9 +549,12 @@ void IpDataLinkLayer::loopHandleSearchRequestExtended(uint8_t* buffer, uint16_t
|
|||||||
{
|
{
|
||||||
//println("requested MANUFACTURER_DATA but not implemented");
|
//println("requested MANUFACTURER_DATA but not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KNX_TUNNELING
|
#ifdef KNX_TUNNELING
|
||||||
|
|
||||||
if (searchRequest.requestedDIB(TUNNELING_INFO))
|
if (searchRequest.requestedDIB(TUNNELING_INFO))
|
||||||
searchResponse.setTunnelingInfo(_ipParameters, _deviceObject, tunnels);
|
searchResponse.setTunnelingInfo(_ipParameters, _deviceObject, tunnels);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,11 +564,11 @@ void IpDataLinkLayer::loopHandleSearchRequestExtended(uint8_t* buffer, uint16_t
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_platform.sendBytesUniCast(searchRequest.hpai().ipAddress(), searchRequest.hpai().ipPortNumber(), searchResponse.data(), searchResponse.totalLength());
|
sendUnicast(searchRequest.hpai().ipAddress(), searchRequest.hpai().ipPortNumber(), searchResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef KNX_TUNNELING
|
|
||||||
void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length, uint32_t& src_addr, uint16_t& src_port)
|
void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length, uint32_t& src_addr, uint16_t& src_port)
|
||||||
{
|
{
|
||||||
KnxIpConnectRequest connRequest(buffer, length);
|
KnxIpConnectRequest connRequest(buffer, length);
|
||||||
@ -622,7 +629,7 @@ void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length,
|
|||||||
println("Only Tunnel/DeviceMgmt Connection ist supported!");
|
println("Only Tunnel/DeviceMgmt Connection ist supported!");
|
||||||
#endif
|
#endif
|
||||||
KnxIpConnectResponse connRes(0x00, E_CONNECTION_TYPE);
|
KnxIpConnectResponse connRes(0x00, E_CONNECTION_TYPE);
|
||||||
_platform.sendBytesUniCast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes.data(), connRes.totalLength());
|
sendUnicast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,7 +640,7 @@ void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length,
|
|||||||
println("Only LinkLayer ist supported!");
|
println("Only LinkLayer ist supported!");
|
||||||
#endif
|
#endif
|
||||||
KnxIpConnectResponse connRes(0x00, E_TUNNELING_LAYER);
|
KnxIpConnectResponse connRes(0x00, E_TUNNELING_LAYER);
|
||||||
_platform.sendBytesUniCast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes.data(), connRes.totalLength());
|
sendUnicast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,7 +784,7 @@ void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length,
|
|||||||
discReq.hpaiCtrl().code(IPV4_UDP);
|
discReq.hpaiCtrl().code(IPV4_UDP);
|
||||||
discReq.hpaiCtrl().ipAddress(tunnels[firstResAndOccTunnel].IpAddress);
|
discReq.hpaiCtrl().ipAddress(tunnels[firstResAndOccTunnel].IpAddress);
|
||||||
discReq.hpaiCtrl().ipPortNumber(tunnels[firstResAndOccTunnel].PortCtrl);
|
discReq.hpaiCtrl().ipPortNumber(tunnels[firstResAndOccTunnel].PortCtrl);
|
||||||
_platform.sendBytesUniCast(tunnels[firstResAndOccTunnel].IpAddress, tunnels[firstResAndOccTunnel].PortCtrl, discReq.data(), discReq.totalLength());
|
sendUnicast(tunnels[firstResAndOccTunnel].IpAddress, tunnels[firstResAndOccTunnel].PortCtrl, discReq);
|
||||||
tunnels[firstResAndOccTunnel].Reset();
|
tunnels[firstResAndOccTunnel].Reset();
|
||||||
|
|
||||||
|
|
||||||
@ -837,7 +844,7 @@ void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length,
|
|||||||
{
|
{
|
||||||
println("no free tunnel availible");
|
println("no free tunnel availible");
|
||||||
KnxIpConnectResponse connRes(0x00, E_NO_MORE_CONNECTIONS);
|
KnxIpConnectResponse connRes(0x00, E_NO_MORE_CONNECTIONS);
|
||||||
_platform.sendBytesUniCast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes.data(), connRes.totalLength());
|
sendUnicast(connRequest.hpaiCtrl().ipAddress(), connRequest.hpaiCtrl().ipPortNumber(), connRes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,7 +912,7 @@ void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length,
|
|||||||
|
|
||||||
|
|
||||||
KnxIpConnectResponse connRes(_ipParameters, tun->IndividualAddress, 3671, tun->ChannelId, connRequest.cri().type());
|
KnxIpConnectResponse connRes(_ipParameters, tun->IndividualAddress, 3671, tun->ChannelId, connRequest.cri().type());
|
||||||
_platform.sendBytesUniCast(tun->IpAddress, tun->PortCtrl, connRes.data(), connRes.totalLength());
|
sendUnicast(tun->IpAddress, tun->PortCtrl, connRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpDataLinkLayer::loopHandleConnectionStateRequest(uint8_t* buffer, uint16_t length)
|
void IpDataLinkLayer::loopHandleConnectionStateRequest(uint8_t* buffer, uint16_t length)
|
||||||
@ -930,7 +937,7 @@ void IpDataLinkLayer::loopHandleConnectionStateRequest(uint8_t* buffer, uint16_t
|
|||||||
println(stateRequest.channelId());
|
println(stateRequest.channelId());
|
||||||
#endif
|
#endif
|
||||||
KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
|
KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
|
||||||
_platform.sendBytesUniCast(stateRequest.hpaiCtrl().ipAddress(), stateRequest.hpaiCtrl().ipPortNumber(), stateRes.data(), stateRes.totalLength());
|
sendUnicast(stateRequest.hpaiCtrl().ipAddress(), stateRequest.hpaiCtrl().ipPortNumber(), stateRes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -941,7 +948,7 @@ void IpDataLinkLayer::loopHandleConnectionStateRequest(uint8_t* buffer, uint16_t
|
|||||||
|
|
||||||
tun->lastHeartbeat = millis();
|
tun->lastHeartbeat = millis();
|
||||||
KnxIpStateResponse stateRes(tun->ChannelId, E_NO_ERROR);
|
KnxIpStateResponse stateRes(tun->ChannelId, E_NO_ERROR);
|
||||||
_platform.sendBytesUniCast(stateRequest.hpaiCtrl().ipAddress(), stateRequest.hpaiCtrl().ipPortNumber(), stateRes.data(), stateRes.totalLength());
|
sendUnicast(stateRequest.hpaiCtrl().ipAddress(), stateRequest.hpaiCtrl().ipPortNumber(), stateRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpDataLinkLayer::loopHandleDisconnectRequest(uint8_t* buffer, uint16_t length)
|
void IpDataLinkLayer::loopHandleDisconnectRequest(uint8_t* buffer, uint16_t length)
|
||||||
@ -971,13 +978,13 @@ void IpDataLinkLayer::loopHandleDisconnectRequest(uint8_t* buffer, uint16_t leng
|
|||||||
println(discReq.channelId());
|
println(discReq.channelId());
|
||||||
#endif
|
#endif
|
||||||
KnxIpDisconnectResponse discRes(0x00, E_CONNECTION_ID);
|
KnxIpDisconnectResponse discRes(0x00, E_CONNECTION_ID);
|
||||||
_platform.sendBytesUniCast(discReq.hpaiCtrl().ipAddress(), discReq.hpaiCtrl().ipPortNumber(), discRes.data(), discRes.totalLength());
|
sendUnicast(discReq.hpaiCtrl().ipAddress(), discReq.hpaiCtrl().ipPortNumber(), discRes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
KnxIpDisconnectResponse discRes(tun->ChannelId, E_NO_ERROR);
|
KnxIpDisconnectResponse discRes(tun->ChannelId, E_NO_ERROR);
|
||||||
_platform.sendBytesUniCast(discReq.hpaiCtrl().ipAddress(), discReq.hpaiCtrl().ipPortNumber(), discRes.data(), discRes.totalLength());
|
sendUnicast(discReq.hpaiCtrl().ipAddress(), discReq.hpaiCtrl().ipPortNumber(), discRes);
|
||||||
tun->Reset();
|
tun->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -985,7 +992,7 @@ void IpDataLinkLayer::loopHandleDescriptionRequest(uint8_t* buffer, uint16_t len
|
|||||||
{
|
{
|
||||||
KnxIpDescriptionRequest descReq(buffer, length);
|
KnxIpDescriptionRequest descReq(buffer, length);
|
||||||
KnxIpDescriptionResponse descRes(_ipParameters, _deviceObject);
|
KnxIpDescriptionResponse descRes(_ipParameters, _deviceObject);
|
||||||
_platform.sendBytesUniCast(descReq.hpaiCtrl().ipAddress(), descReq.hpaiCtrl().ipPortNumber(), descRes.data(), descRes.totalLength());
|
sendUnicast(descReq.hpaiCtrl().ipAddress(), descReq.hpaiCtrl().ipPortNumber(), descRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpDataLinkLayer::loopHandleDeviceConfigurationRequest(uint8_t* buffer, uint16_t length)
|
void IpDataLinkLayer::loopHandleDeviceConfigurationRequest(uint8_t* buffer, uint16_t length)
|
||||||
@ -1008,7 +1015,7 @@ void IpDataLinkLayer::loopHandleDeviceConfigurationRequest(uint8_t* buffer, uint
|
|||||||
print("Channel ID nicht gefunden: ");
|
print("Channel ID nicht gefunden: ");
|
||||||
println(confReq.connectionHeader().channelId());
|
println(confReq.connectionHeader().channelId());
|
||||||
KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
|
KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
|
||||||
_platform.sendBytesUniCast(0, 0, stateRes.data(), stateRes.totalLength());
|
sendUnicast(0, 0, stateRes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1018,7 +1025,7 @@ void IpDataLinkLayer::loopHandleDeviceConfigurationRequest(uint8_t* buffer, uint
|
|||||||
tunnAck.connectionHeader().channelId(tun->ChannelId);
|
tunnAck.connectionHeader().channelId(tun->ChannelId);
|
||||||
tunnAck.connectionHeader().sequenceCounter(confReq.connectionHeader().sequenceCounter());
|
tunnAck.connectionHeader().sequenceCounter(confReq.connectionHeader().sequenceCounter());
|
||||||
tunnAck.connectionHeader().status(E_NO_ERROR);
|
tunnAck.connectionHeader().status(E_NO_ERROR);
|
||||||
_platform.sendBytesUniCast(tun->IpAddress, tun->PortData, tunnAck.data(), tunnAck.totalLength());
|
sendUnicast(tun->IpAddress, tun->PortData, tunnAck);
|
||||||
|
|
||||||
tun->lastHeartbeat = millis();
|
tun->lastHeartbeat = millis();
|
||||||
_cemiServer->frameReceived(confReq.frame());
|
_cemiServer->frameReceived(confReq.frame());
|
||||||
@ -1046,7 +1053,7 @@ void IpDataLinkLayer::loopHandleTunnelingRequest(uint8_t* buffer, uint16_t lengt
|
|||||||
println(tunnReq.connectionHeader().channelId());
|
println(tunnReq.connectionHeader().channelId());
|
||||||
#endif
|
#endif
|
||||||
KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
|
KnxIpStateResponse stateRes(0x00, E_CONNECTION_ID);
|
||||||
_platform.sendBytesUniCast(0, 0, stateRes.data(), stateRes.totalLength());
|
sendUnicast(0, 0, stateRes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1065,7 +1072,7 @@ void IpDataLinkLayer::loopHandleTunnelingRequest(uint8_t* buffer, uint16_t lengt
|
|||||||
tunnAck.connectionHeader().channelId(tun->ChannelId);
|
tunnAck.connectionHeader().channelId(tun->ChannelId);
|
||||||
tunnAck.connectionHeader().sequenceCounter(tunnReq.connectionHeader().sequenceCounter());
|
tunnAck.connectionHeader().sequenceCounter(tunnReq.connectionHeader().sequenceCounter());
|
||||||
tunnAck.connectionHeader().status(E_NO_ERROR);
|
tunnAck.connectionHeader().status(E_NO_ERROR);
|
||||||
_platform.sendBytesUniCast(tun->IpAddress, tun->PortData, tunnAck.data(), tunnAck.totalLength());
|
sendUnicast(tun->IpAddress, tun->PortData, tunnAck);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((uint8_t)(sequence - 1) != tun->SequenceCounter_R)
|
else if ((uint8_t)(sequence - 1) != tun->SequenceCounter_R)
|
||||||
@ -1085,7 +1092,7 @@ void IpDataLinkLayer::loopHandleTunnelingRequest(uint8_t* buffer, uint16_t lengt
|
|||||||
tunnAck.connectionHeader().channelId(tun->ChannelId);
|
tunnAck.connectionHeader().channelId(tun->ChannelId);
|
||||||
tunnAck.connectionHeader().sequenceCounter(tunnReq.connectionHeader().sequenceCounter());
|
tunnAck.connectionHeader().sequenceCounter(tunnReq.connectionHeader().sequenceCounter());
|
||||||
tunnAck.connectionHeader().status(E_NO_ERROR);
|
tunnAck.connectionHeader().status(E_NO_ERROR);
|
||||||
_platform.sendBytesUniCast(tun->IpAddress, tun->PortData, tunnAck.data(), tunnAck.totalLength());
|
sendUnicast(tun->IpAddress, tun->PortData, tunnAck);
|
||||||
|
|
||||||
tun->SequenceCounter_R = tunnReq.connectionHeader().sequenceCounter();
|
tun->SequenceCounter_R = tunnReq.connectionHeader().sequenceCounter();
|
||||||
|
|
||||||
@ -1094,7 +1101,7 @@ void IpDataLinkLayer::loopHandleTunnelingRequest(uint8_t* buffer, uint16_t lengt
|
|||||||
|
|
||||||
_cemiServer->frameReceived(tunnReq.frame());
|
_cemiServer->frameReceived(tunnReq.frame());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void IpDataLinkLayer::enabled(bool value)
|
void IpDataLinkLayer::enabled(bool value)
|
||||||
{
|
{
|
||||||
@ -1125,12 +1132,24 @@ DptMedium IpDataLinkLayer::mediumType() const
|
|||||||
return DptMedium::KNX_IP;
|
return DptMedium::KNX_IP;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpDataLinkLayer::sendBytes(uint8_t* bytes, uint16_t length)
|
bool IpDataLinkLayer::sendMulicast(KnxIpFrame& ipFrame)
|
||||||
{
|
{
|
||||||
if (!_enabled)
|
if (!_enabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return _platform.sendBytesMultiCast(bytes, length);
|
LOGGER.info("sendMulicast %s", ipFrame.to_string().c_str());
|
||||||
|
|
||||||
|
return _platform.sendBytesMultiCast(ipFrame.data(), ipFrame.totalLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IpDataLinkLayer::sendUnicast(uint32_t addr, uint16_t port, KnxIpFrame& ipFrame)
|
||||||
|
{
|
||||||
|
if (!_enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LOGGER.info("sendUnicast to %s:%d %s", ipaddr2str(addr).c_str(), port, ipFrame.to_string().c_str());
|
||||||
|
|
||||||
|
return _platform.sendBytesMultiCast(ipFrame.data(), ipFrame.totalLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IpDataLinkLayer::isSendLimitReached()
|
bool IpDataLinkLayer::isSendLimitReached()
|
||||||
@ -1171,7 +1190,7 @@ bool IpDataLinkLayer::isSendLimitReached()
|
|||||||
|
|
||||||
if (sum > 50)
|
if (sum > 50)
|
||||||
{
|
{
|
||||||
println("Dropping packet due to 50p/s limit");
|
LOGGER.warning("Dropping packet due to 50p/s limit");
|
||||||
return true; // drop packet
|
return true; // drop packet
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "ip_parameter_object.h"
|
#include "ip_parameter_object.h"
|
||||||
#include "knx_ip_tunnel_connection.h"
|
#include "knx_ip_tunnel_connection.h"
|
||||||
#include "service_families.h"
|
#include "service_families.h"
|
||||||
|
#include "knx_ip_frame.h"
|
||||||
|
|
||||||
class IpDataLinkLayer : public DataLinkLayer
|
class IpDataLinkLayer : public DataLinkLayer
|
||||||
{
|
{
|
||||||
@ -18,13 +19,11 @@ class IpDataLinkLayer : public DataLinkLayer
|
|||||||
void enabled(bool value);
|
void enabled(bool value);
|
||||||
bool enabled() const;
|
bool enabled() const;
|
||||||
DptMedium mediumType() const override;
|
DptMedium mediumType() const override;
|
||||||
#ifdef KNX_TUNNELING
|
|
||||||
void dataRequestToTunnel(CemiFrame& frame) override;
|
void dataRequestToTunnel(CemiFrame& frame) override;
|
||||||
void dataConfirmationToTunnel(CemiFrame& frame) override;
|
void dataConfirmationToTunnel(CemiFrame& frame) override;
|
||||||
void dataIndicationToTunnel(CemiFrame& frame) override;
|
void dataIndicationToTunnel(CemiFrame& frame) override;
|
||||||
bool isTunnelAddress(uint16_t addr) override;
|
bool isTunnelAddress(uint16_t addr) override;
|
||||||
bool isSentToTunnel(uint16_t address, bool isGrpAddr);
|
bool isSentToTunnel(uint16_t address, bool isGrpAddr);
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _enabled = false;
|
bool _enabled = false;
|
||||||
@ -32,7 +31,6 @@ class IpDataLinkLayer : public DataLinkLayer
|
|||||||
uint8_t _frameCountBase = 0;
|
uint8_t _frameCountBase = 0;
|
||||||
uint32_t _frameCountTimeBase = 0;
|
uint32_t _frameCountTimeBase = 0;
|
||||||
bool sendFrame(CemiFrame& frame);
|
bool sendFrame(CemiFrame& frame);
|
||||||
#ifdef KNX_TUNNELING
|
|
||||||
void sendFrameToTunnel(KnxIpTunnelConnection* tunnel, CemiFrame& frame);
|
void sendFrameToTunnel(KnxIpTunnelConnection* tunnel, CemiFrame& frame);
|
||||||
void loopHandleConnectRequest(uint8_t* buffer, uint16_t length, uint32_t& src_addr, uint16_t& src_port);
|
void loopHandleConnectRequest(uint8_t* buffer, uint16_t length, uint32_t& src_addr, uint16_t& src_port);
|
||||||
void loopHandleConnectionStateRequest(uint8_t* buffer, uint16_t length);
|
void loopHandleConnectionStateRequest(uint8_t* buffer, uint16_t length);
|
||||||
@ -40,9 +38,9 @@ class IpDataLinkLayer : public DataLinkLayer
|
|||||||
void loopHandleDescriptionRequest(uint8_t* buffer, uint16_t length);
|
void loopHandleDescriptionRequest(uint8_t* buffer, uint16_t length);
|
||||||
void loopHandleDeviceConfigurationRequest(uint8_t* buffer, uint16_t length);
|
void loopHandleDeviceConfigurationRequest(uint8_t* buffer, uint16_t length);
|
||||||
void loopHandleTunnelingRequest(uint8_t* buffer, uint16_t length);
|
void loopHandleTunnelingRequest(uint8_t* buffer, uint16_t length);
|
||||||
#endif
|
|
||||||
void loopHandleSearchRequestExtended(uint8_t* buffer, uint16_t length);
|
void loopHandleSearchRequestExtended(uint8_t* buffer, uint16_t length);
|
||||||
bool sendBytes(uint8_t* buffer, uint16_t length);
|
bool sendMulicast(KnxIpFrame& ipFrame);
|
||||||
|
bool sendUnicast(uint32_t addr, uint16_t port, KnxIpFrame& ipFrame);
|
||||||
bool isSendLimitReached();
|
bool isSendLimitReached();
|
||||||
IpParameterObject& _ipParameters;
|
IpParameterObject& _ipParameters;
|
||||||
DataLinkLayerCallbacks* _dllcb;
|
DataLinkLayerCallbacks* _dllcb;
|
||||||
|
@ -33,14 +33,14 @@ void KnxIpFrame::protocolVersion(KnxIpVersion version)
|
|||||||
_data[1] = (uint8_t)version;
|
_data[1] = (uint8_t)version;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t KnxIpFrame::serviceTypeIdentifier() const
|
KnxIpServiceType KnxIpFrame::serviceTypeIdentifier() const
|
||||||
{
|
{
|
||||||
return getWord(_data + 2);
|
return (KnxIpServiceType)getWord(_data + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KnxIpFrame::serviceTypeIdentifier(uint16_t identifier)
|
void KnxIpFrame::serviceTypeIdentifier(KnxIpServiceType identifier)
|
||||||
{
|
{
|
||||||
pushWord(identifier, _data + 2);
|
pushWord((uint16_t) identifier, _data + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t KnxIpFrame::totalLength() const
|
uint16_t KnxIpFrame::totalLength() const
|
||||||
@ -76,3 +76,81 @@ KnxIpFrame::KnxIpFrame(uint16_t length)
|
|||||||
protocolVersion(KnxIp1_0);
|
protocolVersion(KnxIp1_0);
|
||||||
totalLength(length);
|
totalLength(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string KnxIpFrame::to_string() const
|
||||||
|
{
|
||||||
|
return enum_name(protocolVersion()) + " " + enum_name(serviceTypeIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
const string enum_name(const KnxIpVersion enum_val)
|
||||||
|
{
|
||||||
|
switch (enum_val)
|
||||||
|
{
|
||||||
|
case KnxIp1_0:
|
||||||
|
return "KnxIp1_0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return to_string(enum_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
const string enum_name(const KnxIpServiceType enum_val)
|
||||||
|
{
|
||||||
|
switch (enum_val)
|
||||||
|
{
|
||||||
|
case SearchRequest:
|
||||||
|
return "SearchRequest";
|
||||||
|
|
||||||
|
case SearchResponse:
|
||||||
|
return "SearchResponse";
|
||||||
|
|
||||||
|
case DescriptionRequest:
|
||||||
|
return "DescriptionRequest";
|
||||||
|
|
||||||
|
case DescriptionResponse:
|
||||||
|
return "DescriptionResponse";
|
||||||
|
|
||||||
|
case ConnectRequest:
|
||||||
|
return "ConnectRequest";
|
||||||
|
|
||||||
|
case ConnectResponse:
|
||||||
|
return "ConnectResponse";
|
||||||
|
|
||||||
|
case ConnectionStateRequest:
|
||||||
|
return "ConnectionStateRequest";
|
||||||
|
|
||||||
|
case ConnectionStateResponse:
|
||||||
|
return "ConnectionStateResponse";
|
||||||
|
|
||||||
|
case DisconnectRequest:
|
||||||
|
return "DisconnectRequest";
|
||||||
|
|
||||||
|
case DisconnectResponse:
|
||||||
|
return "DisconnectResponse";
|
||||||
|
|
||||||
|
case SearchRequestExt:
|
||||||
|
return "SearchRequestExt";
|
||||||
|
|
||||||
|
case SearchResponseExt:
|
||||||
|
return "SearchResponseExt";
|
||||||
|
|
||||||
|
case DeviceConfigurationRequest:
|
||||||
|
return "DeviceConfigurationRequest";
|
||||||
|
|
||||||
|
case DeviceConfigurationAck:
|
||||||
|
return "DeviceConfigurationAck";
|
||||||
|
|
||||||
|
case TunnelingRequest:
|
||||||
|
return "TunnelingRequest";
|
||||||
|
|
||||||
|
case TunnelingAck:
|
||||||
|
return "TunnelingAck";
|
||||||
|
|
||||||
|
case RoutingIndication:
|
||||||
|
return "RoutingIndication";
|
||||||
|
|
||||||
|
case RoutingLostMessage:
|
||||||
|
return "RoutingLostMessage";
|
||||||
|
}
|
||||||
|
|
||||||
|
return to_string(enum_val);
|
||||||
|
}
|
@ -8,6 +8,7 @@ enum KnxIpVersion
|
|||||||
{
|
{
|
||||||
KnxIp1_0 = 0x10
|
KnxIp1_0 = 0x10
|
||||||
};
|
};
|
||||||
|
const string enum_name(const KnxIpVersion enum_val);
|
||||||
|
|
||||||
enum KnxIpServiceType
|
enum KnxIpServiceType
|
||||||
{
|
{
|
||||||
@ -30,6 +31,7 @@ enum KnxIpServiceType
|
|||||||
RoutingIndication = 0x530,
|
RoutingIndication = 0x530,
|
||||||
RoutingLostMessage = 0x531,
|
RoutingLostMessage = 0x531,
|
||||||
};
|
};
|
||||||
|
const string enum_name(const KnxIpServiceType enum_val);
|
||||||
|
|
||||||
class KnxIpFrame
|
class KnxIpFrame
|
||||||
{
|
{
|
||||||
@ -41,12 +43,12 @@ class KnxIpFrame
|
|||||||
void headerLength(uint8_t length);
|
void headerLength(uint8_t length);
|
||||||
KnxIpVersion protocolVersion() const;
|
KnxIpVersion protocolVersion() const;
|
||||||
void protocolVersion(KnxIpVersion version);
|
void protocolVersion(KnxIpVersion version);
|
||||||
uint16_t serviceTypeIdentifier() const;
|
KnxIpServiceType serviceTypeIdentifier() const;
|
||||||
void serviceTypeIdentifier(uint16_t identifier);
|
void serviceTypeIdentifier(KnxIpServiceType identifier);
|
||||||
uint16_t totalLength() const;
|
uint16_t totalLength() const;
|
||||||
void totalLength(uint16_t length);
|
void totalLength(uint16_t length);
|
||||||
uint8_t* data();
|
uint8_t* data();
|
||||||
|
const std::string to_string() const;
|
||||||
protected:
|
protected:
|
||||||
bool _freeData = false;
|
bool _freeData = false;
|
||||||
uint8_t* _data = 0;
|
uint8_t* _data = 0;
|
||||||
|
@ -441,29 +441,15 @@ const string enum_name(const SystemBroadcast enum_val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string enum_name_in(Repetition enum_val)
|
const string enum_name(Repetition enum_val)
|
||||||
{
|
{
|
||||||
switch (enum_val)
|
switch (enum_val)
|
||||||
{
|
{
|
||||||
case WasRepeated:
|
case WasRepeated:
|
||||||
return "WasRepeated";
|
return "WasRepeated/NoRepetiion";
|
||||||
|
|
||||||
case WasNotRepeated:
|
case WasNotRepeated:
|
||||||
return "WasNotRepeated";
|
return "WasNotRepeated/RepetitionAllowed";
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
return to_string(enum_val);
|
||||||
@ -704,3 +690,13 @@ const string enum_name(const FrameFormat enum_val)
|
|||||||
|
|
||||||
return to_string(enum_val);
|
return to_string(enum_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string format_ia(uint16_t ia)
|
||||||
|
{
|
||||||
|
return to_string(ia & 0xF000 >> 24) + "/" + to_string(ia & 0x0F00 >> 16) + "/" + to_string(ia & 0x00FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
const string format_ga(uint16_t ga)
|
||||||
|
{
|
||||||
|
return to_string(ga & 0xF800 >> 23) + "/" + to_string(ga & 0x70 >> 16) + "/" + to_string(ga & 0x00FF);
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdint.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
enum FrameFormat
|
enum FrameFormat
|
||||||
@ -117,8 +118,7 @@ enum Repetition
|
|||||||
RepetitionAllowed = 0x20,
|
RepetitionAllowed = 0x20,
|
||||||
WasNotRepeated = 0x20,
|
WasNotRepeated = 0x20,
|
||||||
};
|
};
|
||||||
const string enum_name_in(Repetition enum_val);
|
const string enum_name(Repetition enum_val);
|
||||||
const string enum_name_out(Repetition enum_val);
|
|
||||||
|
|
||||||
enum SystemBroadcast
|
enum SystemBroadcast
|
||||||
{
|
{
|
||||||
@ -310,4 +310,7 @@ enum LCCONFIG
|
|||||||
PHYS_IACK_ALL = 0b10000000,
|
PHYS_IACK_ALL = 0b10000000,
|
||||||
PHYS_IACK_NACK = 0b11000000
|
PHYS_IACK_NACK = 0b11000000
|
||||||
};
|
};
|
||||||
const string enum_name(const LCCONFIG enum_val);
|
const string enum_name(const LCCONFIG enum_val);
|
||||||
|
|
||||||
|
const string format_ia(uint16_t ia);
|
||||||
|
const string format_ga(uint16_t ga);
|
@ -660,7 +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))
|
if (secure(request.data() + APDU_LPDU_DIFF, kSecureSyncRequest, _deviceObj.individualAddress(), dstAddr, dstAddrIsGroupAddr, tpci, asdu, sizeof(asdu), secCtrl, systemBcast))
|
||||||
{
|
{
|
||||||
LOGGER.info("SyncRequest: %s", ((string)request.apdu()).c_str());
|
LOGGER.info("SyncRequest: %s", request.apdu().to_string().c_str());
|
||||||
|
|
||||||
if (_syncReqBroadcastOutgoing)
|
if (_syncReqBroadcastOutgoing)
|
||||||
{
|
{
|
||||||
@ -723,7 +723,7 @@ void SecureApplicationLayer::sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGr
|
|||||||
{
|
{
|
||||||
_lastSyncRes = millis();
|
_lastSyncRes = millis();
|
||||||
|
|
||||||
LOGGER.info("SyncResponse: %s", ((string)response.apdu()).c_str());
|
LOGGER.info("SyncResponse: %s", response.apdu().to_string().c_str());
|
||||||
|
|
||||||
if (_syncReqBroadcastIncoming)
|
if (_syncReqBroadcastIncoming)
|
||||||
{
|
{
|
||||||
@ -1063,7 +1063,7 @@ bool SecureApplicationLayer::decrypt(uint8_t* plainApdu, uint16_t plainApduLengt
|
|||||||
bool SecureApplicationLayer::decodeSecureApdu(APDU& secureApdu, APDU& plainApdu, SecurityControl& secCtrl)
|
bool SecureApplicationLayer::decodeSecureApdu(APDU& secureApdu, APDU& plainApdu, SecurityControl& secCtrl)
|
||||||
{
|
{
|
||||||
// Decode secure APDU
|
// Decode secure APDU
|
||||||
LOGGER.info("decodeSecureApdu: Secure APDU: %s", ((string)secureApdu).c_str());
|
LOGGER.info("decodeSecureApdu: Secure APDU: %s", secureApdu.to_string().c_str());
|
||||||
|
|
||||||
uint16_t srcAddress = secureApdu.frame().sourceAddress();
|
uint16_t srcAddress = secureApdu.frame().sourceAddress();
|
||||||
uint16_t dstAddress = secureApdu.frame().destinationAddress();
|
uint16_t dstAddress = secureApdu.frame().destinationAddress();
|
||||||
@ -1085,7 +1085,7 @@ bool SecureApplicationLayer::decodeSecureApdu(APDU& secureApdu, APDU& plainApdu,
|
|||||||
// We are starting from TPCI octet (including): plainApdu.frame().data()+APDU_LPDU_DIFF
|
// 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))
|
if (decrypt(plainApdu.frame().data() + APDU_LPDU_DIFF, plainApdu.length() + 1, srcAddress, dstAddress, isDstAddrGroupAddr, tpci, secureApdu.data() + 1, secCtrl, isSystemBroadcast))
|
||||||
{
|
{
|
||||||
LOGGER.info("decodeSecureApdu: Plain APDU: %s", ((string)plainApdu.frame().apdu()).c_str());
|
LOGGER.info("decodeSecureApdu: Plain APDU: %s", plainApdu.frame().apdu().to_string().c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1260,7 +1260,7 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
|
|||||||
{
|
{
|
||||||
// Create secure APDU
|
// Create secure APDU
|
||||||
|
|
||||||
LOGGER.info("createSecureApdu: Plain APDU: %s", ((string)plainApdu.frame().apdu()).c_str());
|
LOGGER.info("createSecureApdu: Plain APDU: %s", plainApdu.frame().apdu().to_string().c_str());
|
||||||
|
|
||||||
uint16_t srcAddress = plainApdu.frame().sourceAddress();
|
uint16_t srcAddress = plainApdu.frame().sourceAddress();
|
||||||
uint16_t dstAddress = plainApdu.frame().destinationAddress();
|
uint16_t dstAddress = plainApdu.frame().destinationAddress();
|
||||||
@ -1296,7 +1296,7 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
|
|||||||
println(nextSequenceNumber(secCtrl.toolAccess), HEX);
|
println(nextSequenceNumber(secCtrl.toolAccess), HEX);
|
||||||
updateSequenceNumber(secCtrl.toolAccess, nextSequenceNumber(secCtrl.toolAccess) + 1);
|
updateSequenceNumber(secCtrl.toolAccess, nextSequenceNumber(secCtrl.toolAccess) + 1);
|
||||||
|
|
||||||
LOGGER.info("createSecureApdu: Secure APDU: %s", ((string)secureApdu.frame().apdu()).c_str());
|
LOGGER.info("createSecureApdu: Secure APDU: %s", secureApdu.frame().apdu().to_string().c_str());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user