Save work

This commit is contained in:
nanosonde 2019-11-09 12:12:56 +01:00
parent 380d5e91ce
commit 270ee6f5b2
21 changed files with 149 additions and 63 deletions

View File

@ -21,6 +21,8 @@ class AddressTableObject : public TableObject
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
uint8_t* save(uint8_t* buffer);
uint8_t* restore(uint8_t* buffer);
ObjectType objectType() { return OT_ADDR_TABLE; }
/**
* returns the number of group addresses of the object.
*/

View File

@ -9,6 +9,7 @@ class ApplicationProgramObject : public TableObject
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count);
uint8_t propertySize(PropertyID id);
ObjectType objectType() { return OT_APPLICATION_PROG; }
uint8_t* data(uint32_t addr);
uint8_t getByte(uint32_t addr);
uint16_t getWord(uint32_t addr);

View File

@ -7,6 +7,7 @@ class AssociationTableObject : public TableObject
public:
AssociationTableObject(Platform& platform);
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
ObjectType objectType() { return OT_ASSOC_TABLE; }
uint8_t* save(uint8_t* buffer);
uint8_t* restore(uint8_t* buffer);

View File

@ -256,6 +256,9 @@ void BusAccessUnit::domainAddressSerialNumberReadIndication(Priority priority, H
{
}
void BusAccessUnit::propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint32_t &numberOfElements, uint16_t startIndex,
uint8_t *data, uint32_t &dataSize)
{
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
#include "knx_types.h"
#include "interface_object.h"
class BusAccessUnit
{
@ -117,4 +118,7 @@ class BusAccessUnit
uint8_t* knxSerialNumber);
virtual void domainAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, uint8_t* knxSerialNumber);
virtual void propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint32_t &numberOfElements, uint16_t startIndex,
uint8_t *data, uint32_t &dataSize);
};

View File

@ -10,14 +10,13 @@ using namespace std;
Bau27B0::Bau27B0(Platform& platform)
: BauSystemB(platform),
_dlLayer(_deviceObj, _rfMediumObj, _addrTable, _netLayer, _platform)
#ifdef USE_USBIF
, _cemiServer(_tunnelInterface, *this)
, _tunnelInterface(_deviceObj, _cemiServer, _platform)
#ifdef USE_CEMI_SERVER
, _cemiServer(*this)
#endif
{
_netLayer.dataLinkLayer(_dlLayer);
_memory.addSaveRestore(&_rfMediumObj);
#ifdef USE_USBIF
#ifdef USE_CEMI_SERVER
_cemiServer.dataLinkLayer(_dlLayer);
_dlLayer.cemiServer(_cemiServer);
_memory.addSaveRestore(&_cemiServerObject);
@ -60,7 +59,7 @@ InterfaceObject* Bau27B0::getInterfaceObject(uint8_t idx)
return nullptr;
case 6:
return &_rfMediumObj;
#ifdef USE_USBIF
#ifdef USE_CEMI_SERVER
case 7:
return &_cemiServerObject;
#endif
@ -69,6 +68,35 @@ InterfaceObject* Bau27B0::getInterfaceObject(uint8_t idx)
}
}
InterfaceObject* Bau27B0::getInterfaceObject(ObjectType objectType, uint8_t objectInstance)
{
// We do not use it right now.
// Required for coupler mode as there are multiple router objects for example
(void) objectInstance;
switch (objectType)
{
case OT_DEVICE:
return &_deviceObj;
case OT_ADDR_TABLE:
return &_addrTable;
case OT_ASSOC_TABLE:
return &_assocTable;
case OT_GRP_OBJ_TABLE:
return &_groupObjTable;
case OT_APPLICATION_PROG:
return &_appProgram;
case OT_RF_MEDIUM:
return &_rfMediumObj;
#ifdef USE_CEMI_SERVER
case OT_CEMI_SERVER:
return &_cemiServerObject;
#endif
default:
return nullptr;
}
}
uint8_t* Bau27B0::descriptor()
{
return _descriptor;
@ -82,13 +110,13 @@ DataLinkLayer& Bau27B0::dataLinkLayer()
void Bau27B0::enabled(bool value)
{
::BauSystemB::enabled(value);
_tunnelInterface.enabled(value);
//_tunnelInterface.enabled(value);
}
void Bau27B0::loop()
{
::BauSystemB::loop();
_tunnelInterface.loop();
//_tunnelInterface.loop();
}
void Bau27B0::domainAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, uint8_t* rfDoA,

View File

@ -4,8 +4,7 @@
#include "rf_medium_object.h"
#include "rf_physical_layer.h"
#include "rf_data_link_layer.h"
#ifdef USE_USBIF
#include "usb_data_link_layer.h"
#ifdef USE_CEMI_SERVER
#include "cemi_server.h"
#include "cemi_server_object.h"
#endif
@ -19,20 +18,20 @@ class Bau27B0 : public BauSystemB
protected:
InterfaceObject* getInterfaceObject(uint8_t idx);
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
uint8_t* descriptor();
DataLinkLayer& dataLinkLayer();
private:
RfDataLinkLayer _dlLayer;
RfMediumObject _rfMediumObj;
#ifdef USE_USBIF
#ifdef USE_CEMI_SERVER
CemiServer _cemiServer;
UsbDataLinkLayer _tunnelInterface;
CemiServerObject _cemiServerObject;
#endif
uint8_t _descriptor[2] = {0x27, 0xB0};
#ifdef USE_USBIF
#ifdef USE_CEMI_SERVER
const uint32_t _ifObjs[8] = { 7, // length
OT_DEVICE, OT_ADDR_TABLE, OT_ASSOC_TABLE, OT_GRP_OBJ_TABLE, OT_APPLICATION_PROG, OT_RF_MEDIUM, OT_CEMI_SERVER};
#else

View File

@ -218,7 +218,7 @@ void BauSystemB::propertyValueWriteIndication(Priority priority, HopCountType ho
void BauSystemB::propertyValueReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex,
uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex)
{
uint8_t size = 0;
uint8_t size = 0;
uint32_t elementCount = numberOfElements;
InterfaceObject* obj = getInterfaceObject(objectIndex);
if (obj)
@ -391,3 +391,28 @@ void BauSystemB::systemNetworkParameterReadIndication(Priority priority, HopCoun
break;
}
}
void BauSystemB::propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId,
uint32_t &numberOfElements, uint16_t startIndex, uint8_t *data, uint32_t &dataSize)
{
uint32_t size = 0;
uint32_t elementCount = numberOfElements;
InterfaceObject* obj = getInterfaceObject(objectType, objectInstance);
if (obj)
{
uint8_t elementSize = obj->propertySize((PropertyID)propertyId);
size = elementSize * numberOfElements;
data = new uint8_t [size];
obj->readProperty((PropertyID)propertyId, startIndex, elementCount, data);
}
else
{
elementCount = 0;
data = nullptr;
}
numberOfElements = elementCount;
dataSize = size;
}

View File

@ -59,10 +59,13 @@ class BauSystemB : protected BusAccessUnit
void groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType,
uint8_t* data, uint8_t dataLength) override;
void systemNetworkParameterReadIndication(Priority priority, HopCountType hopType, uint16_t objectType,
uint16_t propertyId, uint8_t* testInfo, uint16_t testinfoLength);
uint16_t propertyId, uint8_t* testInfo, uint16_t testinfoLength) override;
void connectConfirm(uint16_t tsap) override;
void propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint32_t &numberOfElements, uint16_t startIndex,
uint8_t *data, uint32_t &dataSize) override;
virtual InterfaceObject* getInterfaceObject(uint8_t idx) = 0;
virtual InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance) = 0;
void sendNextGroupTelegram();
void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length);
void nextRestartState();

View File

@ -2,13 +2,14 @@
#include "cemi_frame.h"
#include "bau.h"
#include "usb_data_link_layer.h"
#include "data_link_layer.h"
#include "string.h"
#include "bits.h"
#include <stdio.h>
CemiServer::CemiServer(UsbDataLinkLayer& tunnelInterface, BusAccessUnit& bau):
_tunnelInterface(tunnelInterface),
_bau(bau)
CemiServer::CemiServer(BusAccessUnit& bau)
: _bau(bau),
_usbTunnelInterface(*this)
{
}
@ -19,9 +20,19 @@ void CemiServer::dataLinkLayer(DataLinkLayer& layer)
void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
{
_tunnelInterface.sendCemiFrame(frame);
_usbTunnelInterface.sendCemiFrame(frame);
}
/*
void CemiServer::localManagmentRequestFromTunnel(CemiFrame& frame)
{
// called from KNXNET/IP for Management Services
// Send response to IP data link layer
_dataLinkLayer->localManagmentResponseToTunnel();
}
*/
void CemiServer::frameReceived(CemiFrame& frame)
{
switch(frame.messageCode())
@ -34,12 +45,16 @@ void CemiServer::frameReceived(CemiFrame& frame)
// Send local reply to tunnel
frame.messageCode(L_data_con);
_tunnelInterface.sendCemiFrame(frame);
_usbTunnelInterface.sendCemiFrame(frame);
break;
}
case M_PropRead_req:
{
uint8_t* data;
uint32_t dataSize;
//ObjectType opjectType = data[]
//_bau.propertyValueRead()
break;
}

View File

@ -2,8 +2,8 @@
#include <stdint.h>
#include "knx_types.h"
#include "usb_data_link_layer.h"
class UsbDataLinkLayer;
class BusAccessUnit;
class DataLinkLayer;
class CemiFrame;
@ -24,7 +24,7 @@ class CemiServer
* @param tunnelInterface The TunnelInterface of the KNX tunnel (e.g. USB or KNXNET/IP)
* @param bau methods are called here depending of the content of the APDU
*/
CemiServer(UsbDataLinkLayer& tunnelInterface, BusAccessUnit& bau);
CemiServer(BusAccessUnit& bau);
void dataLinkLayer(DataLinkLayer& layer);
@ -58,6 +58,6 @@ class CemiServer
void individualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status);
*/
DataLinkLayer* _dataLinkLayer;
UsbDataLinkLayer& _tunnelInterface;
BusAccessUnit& _bau;
UsbDataLinkLayer _usbTunnelInterface;
};

View File

@ -11,6 +11,7 @@ public:
uint8_t* save(uint8_t* buffer);
uint8_t* restore(uint8_t* buffer);
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
ObjectType objectType() { return OT_CEMI_SERVER; }
protected:
uint8_t propertyCount();

View File

@ -94,9 +94,12 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame)
uint16_t ownAddr = _deviceObject.induvidualAddress();
SystemBroadcast systemBroadcast = frame.systemBroadcast();
if (_cemiServer)
{
// if (source != _cemiServerObj.tunnelAddress)
_cemiServer->dataIndicationToTunnel(frame);
}
if (source == ownAddr)
_deviceObject.induvidualAddressDuplication(true);

View File

@ -11,7 +11,7 @@ public:
uint8_t* save(uint8_t* buffer);
uint8_t* restore(uint8_t* buffer);
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
ObjectType objectType() { return OT_DEVICE; }
uint16_t induvidualAddress();
void induvidualAddress(uint16_t value);

View File

@ -11,6 +11,7 @@ class GroupObjectTableObject : public TableObject
GroupObjectTableObject(Platform& platform);
virtual ~GroupObjectTableObject();
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
ObjectType objectType() { return OT_GRP_OBJ_TABLE; }
uint16_t entryCount();
GroupObject& get(uint16_t asap);
GroupObject& nextUpdatedObject(bool& valid);

View File

@ -68,4 +68,5 @@ uint8_t InterfaceObject::propertyCount()
PropertyDescription* InterfaceObject::propertyDescriptions()
{
return nullptr;
}
}

View File

@ -118,6 +118,13 @@ class InterfaceObject : public SaveRestore
void readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
/**
* Gets object type.
*
* @returns object type
*/
virtual ObjectType objectType() = 0;
protected:
/**
* Returns the number of properties the interface object has.

View File

@ -11,6 +11,7 @@ class IpParameterObject : public InterfaceObject
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count);
uint8_t propertySize(PropertyID id);
ObjectType objectType() { return OT_IP_PARAMETER; }
uint8_t* save(uint8_t* buffer);
uint8_t* restore(uint8_t* buffer);

View File

@ -11,6 +11,7 @@ public:
uint8_t* save(uint8_t* buffer);
uint8_t* restore(uint8_t* buffer);
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
ObjectType objectType() { return OT_RF_MEDIUM; }
uint8_t* rfDomainAddress();
void rfDomainAddress(uint8_t* value);

View File

@ -1,17 +1,15 @@
#include "usb_data_link_layer.h"
#include "bits.h"
#include "platform.h"
#include "device_object.h"
#include "address_table_object.h"
#include "usb_data_link_layer.h"
#include "cemi_server.h"
#include "cemi_frame.h"
#include <stdio.h>
#include <string.h>
#include <Adafruit_TinyUSB.h>
#define MIN(a, b) ((a < b) ? (a) : (b))
Adafruit_USBD_HID usb_hid;
static Adafruit_USBD_HID usb_hid;
// HID report descriptor using TinyUSB's template
// Generic In Out with 64 bytes report (max)
@ -57,8 +55,8 @@ struct _rx_queue_frame_t
static struct _rx_queue_t
{
_rx_queue_frame_t* front = NULL;
_rx_queue_frame_t* back = NULL;
_rx_queue_frame_t* front = nullptr;
_rx_queue_frame_t* back = nullptr;
} _rx_queue;
static void addFrameRxQueue(CemiFrame& frame)
@ -67,7 +65,7 @@ static void addFrameRxQueue(CemiFrame& frame)
rx_frame->length = frame.totalLenght();
rx_frame->data = new uint8_t[rx_frame->length];
rx_frame->next = NULL;
rx_frame->next = nullptr;
/*
print("cEMI USB RX len: ");
@ -75,7 +73,7 @@ static void addFrameRxQueue(CemiFrame& frame)
printHex(" data:", rx_frame->data, rx_frame->length);
*/
if (_rx_queue.back == NULL)
if (_rx_queue.back == nullptr)
{
_rx_queue.front = _rx_queue.back = rx_frame;
}
@ -88,7 +86,7 @@ static void addFrameRxQueue(CemiFrame& frame)
static bool isRxQueueEmpty()
{
if (_rx_queue.front == NULL)
if (_rx_queue.front == nullptr)
{
return true;
}
@ -97,7 +95,7 @@ static bool isRxQueueEmpty()
static void loadNextRxFrame(uint8_t** receiveBuffer, uint16_t* receiveBufferLength)
{
if (_rx_queue.front == NULL)
if (_rx_queue.front == nullptr)
{
return;
}
@ -106,9 +104,9 @@ static void loadNextRxFrame(uint8_t** receiveBuffer, uint16_t* receiveBufferLeng
*receiveBufferLength = rx_frame->length;
_rx_queue.front = rx_frame->next;
if (_rx_queue.front == NULL)
if (_rx_queue.front == nullptr)
{
_rx_queue.back = NULL;
_rx_queue.back = nullptr;
}
delete rx_frame;
}
@ -322,8 +320,8 @@ static void set_report_callback(uint8_t report_id, hid_report_type_t report_type
// class UsbDataLinkLayer
UsbDataLinkLayer::UsbDataLinkLayer(DeviceObject& deviceObject, CemiServer& cemiServer, Platform& platform)
: _deviceObject(deviceObject), _cemiServer(cemiServer), _platform(platform)
UsbDataLinkLayer::UsbDataLinkLayer(CemiServer& cemiServer)
: _cemiServer(cemiServer)
{
}
@ -393,14 +391,13 @@ void UsbDataLinkLayer::enabled(bool value)
while( !USBDevice.mounted() ) delay(1);
_enabled = true;
print("ownaddr ");
println(_deviceObject.induvidualAddress(), HEX);
println("KNX USB Interface enabled.");
return;
}
if (!value && _enabled)
{
println("USB data link layer cannot be disabled once enabled!");
println("KNX USB Interface cannot be disabled once enabled!");
return;
}
}
@ -416,7 +413,7 @@ void UsbDataLinkLayer::addFrameTxQueue(CemiFrame& frame)
tx_frame->length = frame.totalLenght();
tx_frame->data = new uint8_t[tx_frame->length];
tx_frame->next = NULL;
tx_frame->next = nullptr;
/*
print("cEMI USB TX len: ");
@ -424,7 +421,7 @@ void UsbDataLinkLayer::addFrameTxQueue(CemiFrame& frame)
printHex(" data:", tx_frame->data, tx_frame->length);
*/
if (_tx_queue.back == NULL)
if (_tx_queue.back == nullptr)
{
_tx_queue.front = _tx_queue.back = tx_frame;
}
@ -437,7 +434,7 @@ void UsbDataLinkLayer::addFrameTxQueue(CemiFrame& frame)
bool UsbDataLinkLayer::isTxQueueEmpty()
{
if (_tx_queue.front == NULL)
if (_tx_queue.front == nullptr)
{
return true;
}
@ -446,7 +443,7 @@ bool UsbDataLinkLayer::isTxQueueEmpty()
void UsbDataLinkLayer::loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBufferLength)
{
if (_tx_queue.front == NULL)
if (_tx_queue.front == nullptr)
{
return;
}
@ -455,9 +452,9 @@ void UsbDataLinkLayer::loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBuffe
*sendBufferLength = tx_frame->length;
_tx_queue.front = tx_frame->next;
if (_tx_queue.front == NULL)
if (_tx_queue.front == nullptr)
{
_tx_queue.back = NULL;
_tx_queue.back = nullptr;
}
delete tx_frame;
}

View File

@ -1,21 +1,16 @@
#pragma once
#include <stdint.h>
#include <Adafruit_TinyUSB.h>
#include "data_link_layer.h"
#include "cemi_server.h"
#define MAX_KNX_TELEGRAM_SIZE 263
extern Adafruit_USBD_HID usb_hid;
class DeviceObject;
class Platform;
class CemiServer;
class CemiFrame;
class UsbDataLinkLayer
{
public:
UsbDataLinkLayer(DeviceObject& deviceObject, CemiServer& cemiServer, Platform& platform);
UsbDataLinkLayer(CemiServer& cemiServer);
void loop();
void enabled(bool value);
@ -36,13 +31,11 @@ class UsbDataLinkLayer
struct _tx_queue_t
{
_tx_queue_frame_t* front = NULL;
_tx_queue_frame_t* back = NULL;
_tx_queue_frame_t* front = nullptr;
_tx_queue_frame_t* back = nullptr;
} _tx_queue;
DeviceObject& _deviceObject;
CemiServer& _cemiServer;
Platform& _platform;
void addFrameTxQueue(CemiFrame& frame);
bool isTxQueueEmpty();