Save work

This commit is contained in:
nanosonde 2019-11-08 16:06:05 +01:00
parent 8756e683a9
commit 2b9057b6d2
10 changed files with 171 additions and 79 deletions

View File

@ -10,9 +10,18 @@ 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)
#endif
{
_netLayer.dataLinkLayer(_dlLayer);
_memory.addSaveRestore(&_rfMediumObj);
#ifdef USE_USBIF
_cemiServer.dataLinkLayer(_dlLayer);
_dlLayer.cemiServer(_cemiServer);
_memory.addSaveRestore(&_cemiServerObject);
#endif
// Set Mask Version in Device Object depending on the BAU
uint16_t maskVersion;
@ -70,6 +79,18 @@ DataLinkLayer& Bau27B0::dataLinkLayer()
return _dlLayer;
}
void Bau27B0::enabled(bool value)
{
::BauSystemB::enabled(value);
_tunnelInterface.enabled(value);
}
void Bau27B0::loop()
{
::BauSystemB::loop();
_tunnelInterface.loop();
}
void Bau27B0::domainAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, uint8_t* rfDoA,
uint8_t* knxSerialNumber)
{

View File

@ -4,11 +4,18 @@
#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"
#include "cemi_server.h"
#include "cemi_server_object.h"
#endif
class Bau27B0 : public BauSystemB
{
public:
Bau27B0(Platform& platform);
void enabled(bool value);
void loop();
protected:
InterfaceObject* getInterfaceObject(uint8_t idx);
@ -18,6 +25,11 @@ class Bau27B0 : public BauSystemB
private:
RfDataLinkLayer _dlLayer;
RfMediumObject _rfMediumObj;
#ifdef USE_USBIF
CemiServer _cemiServer;
UsbDataLinkLayer _tunnelInterface;
CemiServerObject _cemiServerObject;
#endif
uint8_t _descriptor[2] = {0x27, 0xB0};
#ifdef USE_USBIF

View File

@ -15,10 +15,6 @@ BauSystemB::BauSystemB(Platform& platform): _memory(platform), _addrTable(platfo
_assocTable(platform), _groupObjTable(platform), _appProgram(platform),
_platform(platform), _appLayer(_assocTable, *this),
_transLayer(_appLayer, _addrTable), _netLayer(_transLayer)
#ifdef USE_USBIF
, _dlLayerUsb(_deviceObj, _addrTable, _netLayer, _platform),
_cemiServer(_dlLayerUsb, *this)
#endif
{
_appLayer.transportLayer(_transLayer);
_transLayer.networkLayer(_netLayer);
@ -27,17 +23,11 @@ BauSystemB::BauSystemB(Platform& platform): _memory(platform), _addrTable(platfo
_memory.addSaveRestore(&_addrTable);
_memory.addSaveRestore(&_assocTable);
_memory.addSaveRestore(&_groupObjTable);
#ifdef USE_USBIF
_memory.addSaveRestore(&_cemiServerObject);
#endif
}
void BauSystemB::loop()
{
dataLinkLayer().loop();
#ifdef USE_USBIF
_dlLayerUsb.loop();
#endif
_transLayer.loop();
sendNextGroupTelegram();
nextRestartState();
@ -51,9 +41,6 @@ bool BauSystemB::enabled()
void BauSystemB::enabled(bool value)
{
dataLinkLayer().enabled(value);
#ifdef USE_USBIF
_dlLayerUsb.enabled(value);
#endif
}
void BauSystemB::sendNextGroupTelegram()

View File

@ -12,11 +12,6 @@
#include "tpuart_data_link_layer.h"
#include "platform.h"
#include "memory.h"
#ifdef USE_USBIF
#include "usb_data_link_layer.h"
#include "cemi_server.h"
#include "cemi_server_object.h"
#endif
class BauSystemB : protected BusAccessUnit
{
@ -93,9 +88,4 @@ class BauSystemB : protected BusAccessUnit
bool _configured = true;
RestartState _restartState = Idle;
uint32_t _restartDelay = 0;
#ifdef USE_USBIF
UsbDataLinkLayer _dlLayerUsb;
CemiServer _cemiServer;
CemiServerObject _cemiServerObject;
#endif
};

View File

@ -6,14 +6,79 @@
#include "bits.h"
#include <stdio.h>
CemiServer::CemiServer(UsbDataLinkLayer& dlLayer, BusAccessUnit& bau):
_dlLayer(dlLayer),
CemiServer::CemiServer(UsbDataLinkLayer& tunnelInterface, BusAccessUnit& bau):
_tunnelInterface(tunnelInterface),
_bau(bau)
{
}
#pragma region DLL Callbacks
void CemiServer::dataLinkLayer(DataLinkLayer& layer)
{
_dataLinkLayer = &layer;
}
void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
{
_tunnelInterface.sendCemiFrame(frame);
}
void CemiServer::frameReceived(CemiFrame& frame)
{
switch(frame.messageCode())
{
case L_data_req:
{
// Send as indication to data link layer
frame.messageCode(L_data_ind);
_dataLinkLayer->dataIndicationFromTunnel(frame);
// Send local reply to tunnel
frame.messageCode(L_data_con);
_tunnelInterface.sendCemiFrame(frame);
break;
}
case M_PropRead_req:
{
break;
}
case M_PropWrite_req:
{
break;
}
case M_FuncPropCommand_req:
{
break;
}
case M_FuncPropStateRead_req:
{
break;
}
case M_Reset_req:
{
break;
}
// we should not receive this: server -> client
case L_data_con:
case L_data_ind:
case M_PropInfo_ind:
case M_PropRead_con:
case M_PropWrite_con:
case M_FuncPropCommand_con:
//case M_FuncPropStateRead_con: // same value as M_FuncPropCommand_con
case M_Reset_ind:
default:
break;
}
_dataLinkLayer->dataIndicationFromTunnel(frame);
}
/*
void CemiServer::propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex)
{
@ -176,3 +241,5 @@ void CemiServer::individualConfirm(AckType ack, HopCountType hopType, Priority p
break;
}
}
*/

View File

@ -5,6 +5,9 @@
class UsbDataLinkLayer;
class BusAccessUnit;
class DataLinkLayer;
class CemiFrame;
/**
* This is an implementation of the cEMI server as specified in @cite knx:3/6/3.
* Overview on page 57.
@ -18,18 +21,22 @@ class CemiServer
public:
/**
* The constructor.
* @param assocTable The AssociationTable is used to translate between asap (i.e. group objects) and group addresses.
* @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& dlLayer, BusAccessUnit& bau);
CemiServer(UsbDataLinkLayer& tunnelInterface, BusAccessUnit& bau);
void dataLinkLayer(DataLinkLayer& layer);
// from data link layer
#pragma region Data - Link - Layer - Callbacks
void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu);
void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status);
#pragma endregion
// Only L_Data service
void dataIndicationToTunnel(CemiFrame& frame);
#pragma region from bau
// From tunnel interface
void frameReceived(CemiFrame& frame);
/*
void propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex);
void propertyValueReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex,
@ -41,15 +48,16 @@ class CemiServer
void propertyDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex, bool writeEnable, uint8_t type,
uint16_t maxNumberOfElements, uint8_t access);
#pragma endregion
*/
private:
/*
void propertyDataSend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data,
uint8_t length);
void individualIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu);
void individualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status);
UsbDataLinkLayer& _dlLayer;
*/
DataLinkLayer* _dataLinkLayer;
UsbDataLinkLayer& _tunnelInterface;
BusAccessUnit& _bau;
};

View File

@ -4,7 +4,7 @@
#include "platform.h"
#include "device_object.h"
#include "address_table_object.h"
#include "cemi_server.h"
DataLinkLayer::DataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab,
NetworkLayer& layer, Platform& platform) :
@ -12,6 +12,16 @@ DataLinkLayer::DataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab,
{
}
void DataLinkLayer::cemiServer(CemiServer& cemiServer)
{
_cemiServer = &cemiServer;
}
void DataLinkLayer::dataIndicationFromTunnel(CemiFrame& frame)
{
}
void DataLinkLayer::dataRequest(AckType ack, AddressType addrType, uint16_t destinationAddr, FrameFormat format, Priority priority, NPDU& npdu)
{
// Normal data requests and broadcasts will always be transmitted as (domain) broadcast with domain address for open media (e.g. RF medium)

View File

@ -5,6 +5,7 @@
#include "address_table_object.h"
#include "knx_types.h"
#include "network_layer.h"
#include "cemi_server.h"
class DataLinkLayer
{
@ -12,6 +13,10 @@ class DataLinkLayer
DataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, NetworkLayer& layer,
Platform& platform);
void cemiServer(CemiServer& cemiServer);
void dataIndicationFromTunnel(CemiFrame& frame);
// from network layer
void dataRequest(AckType ack, AddressType addrType, uint16_t destinationAddr, FrameFormat format,
Priority priority, NPDU& npdu);
@ -30,4 +35,5 @@ class DataLinkLayer
AddressTableObject& _groupAddressTable;
NetworkLayer& _networkLayer;
Platform& _platform;
CemiServer* _cemiServer;
};

View File

@ -15,7 +15,7 @@ Adafruit_USBD_HID usb_hid;
// HID report descriptor using TinyUSB's template
// Generic In Out with 64 bytes report (max)
uint8_t const desc_hid_report[] =
static uint8_t const desc_hid_report[] =
{
//TUD_HID_REPORT_DESC_GENERIC_INOUT(64)
0x06, 0xA0, 0xFF, // Usage Page (Vendor Defined 0xFFA0)
@ -235,10 +235,18 @@ void set_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8
void UsbDataLinkLayer::loop()
{
if (!_enabled)
{
return;
}
if (!isTxQueueEmpty())
{
//loadNextTxFrame();
//sendKnxHidReport();
}
}
bool UsbDataLinkLayer::sendFrame(CemiFrame& frame)
bool UsbDataLinkLayer::sendCemiFrame(CemiFrame& frame)
{
if (!_enabled)
return false;
@ -248,18 +256,11 @@ bool UsbDataLinkLayer::sendFrame(CemiFrame& frame)
// the L_Data.con for the previous L_Data.req.
addFrameTxQueue(frame);
// TODO: For now L_data.req is confirmed immediately (L_Data.con)
// see 3.6.3 p.80: L_Data.con shall be generated AFTER transmission of the corresponsing frame
// RF sender will never generate L_Data.con with C=1 (Error), but only if the TX buffer overflows
// The RF sender cannot detect if the RF frame was transmitted successfully or not according to the spec.
dataConReceived(frame, true);
return true;
}
UsbDataLinkLayer::UsbDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab,
NetworkLayer& layer, Platform& platform)
: DataLinkLayer(devObj, addrTab, layer, platform)
UsbDataLinkLayer::UsbDataLinkLayer(DeviceObject& deviceObject, CemiServer& cemiServer, Platform& platform)
: _deviceObject(deviceObject), _cemiServer(cemiServer), _platform(platform)
{
}
@ -267,26 +268,14 @@ void UsbDataLinkLayer::frameBytesReceived(uint8_t* _buffer, uint16_t length)
{
// Prepare the cEMI frame
CemiFrame frame(_buffer, length);
/*
frame.frameType(ExtendedFrame); // KNX RF uses only extended frame format
frame.priority(SystemPriority); // Not used in KNX RF
frame.ack(AckDontCare); // Not used in KNX RF
frame.systemBroadcast(systemBroadcast); // Mapped from flag AddrExtensionType (KNX serial(0) or Domain Address(1))
frame.hopCount(hopCount); // Hop count from routing counter
frame.addressType(addressType); // Group address or individual address
frame.rfSerialOrDoA(&rfPacketBuf[4]); // Copy pointer to field Serial or Domain Address (check broadcast flag what it is exactly)
frame.rfInfo(rfPacketBuf[3]); // RF-info field (1 byte)
frame.rfLfn(lfn); // Data link layer frame number (LFN field)
*/
/*
print(" len: ");
print(newLength);
print("cEMI USB RX len: ");
print(length);
print(" data: ");
printHex(" data: ", _buffer, newLength);
*/
frameRecieved(frame);
printHex(" data: ", _buffer, length);
_cemiServer.frameReceived(frame);
}
void UsbDataLinkLayer::enabled(bool value)
@ -329,12 +318,11 @@ void UsbDataLinkLayer::addFrameTxQueue(CemiFrame& frame)
tx_frame->data = new uint8_t[tx_frame->length];
tx_frame->next = NULL;
/*
print(" len: ");
print(totalLength);
print("cEMI USB TX len: ");
print(tx_frame->length);
printHex(" data:", tx_frame->data, tx_frame->length);
printHex(" data:", tx_frame->data, totalLength);
*/
if (_tx_queue.back == NULL)
{
_tx_queue.front = _tx_queue.back = tx_frame;

View File

@ -3,25 +3,26 @@
#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 UsbDataLinkLayer : public DataLinkLayer
{
using DataLinkLayer::_deviceObject;
using DataLinkLayer::_groupAddressTable;
using DataLinkLayer::_platform;
class DeviceObject;
class Platform;
class UsbDataLinkLayer
{
public:
UsbDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, NetworkLayer& layer,
Platform& platform);
UsbDataLinkLayer(DeviceObject& deviceObject, CemiServer& cemiServer, Platform& platform);
void loop();
void enabled(bool value);
bool enabled() const;
bool sendCemiFrame(CemiFrame& frame);
private:
bool _enabled = false;
uint8_t _loopState = 0;
@ -43,10 +44,12 @@ class UsbDataLinkLayer : public DataLinkLayer
_tx_queue_frame_t* back = NULL;
} _tx_queue;
DeviceObject& _deviceObject;
CemiServer& _cemiServer;
Platform& _platform;
void addFrameTxQueue(CemiFrame& frame);
bool isTxQueueEmpty();
void loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBufferLength);
bool sendFrame(CemiFrame& frame);
void frameBytesReceived(uint8_t* buffer, uint16_t length);
};