knx/ip_parameter_object.cpp
2018-03-20 22:04:11 +01:00

302 lines
7.8 KiB
C++

#include "ip_parameter_object.h"
#include "device_object.h"
#include "platform.h"
#include "bits.h"
//224.0.23.12
#define DEFAULT_MULTICAST_ADDR 0xE000170C
IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platform): _deviceObject(deviceObject),
_platform(platform)
{}
void IpParameterObject::readProperty(PropertyID propertyId, uint32_t start, uint32_t count, uint8_t* data)
{
switch (propertyId)
{
case PID_LOAD_STATE_CONTROL:
data[0] = _state;
break;
case PID_OBJECT_TYPE:
pushWord(OT_IP_PARAMETER, data);
break;
case PID_PROJECT_INSTALLATION_ID:
pushWord(_projectInstallationId, data);
break;
case PID_KNX_INDIVIDUAL_ADDRESS:
pushWord(_deviceObject.induvidualAddress(), data);
break;
case PID_IP_ASSIGNMENT_METHOD:
data[0] = _ipAssignmentMethod;
break;
case PID_IP_CAPABILITIES:
data[0] = _ipCapabilities;
break;
case PID_CURRENT_IP_ADDRESS:
pushInt(_platform.currentIpAddress(), data);
break;
case PID_CURRENT_SUBNET_MASK:
pushInt(_platform.currentSubnetMask(), data);
break;
case PID_CURRENT_DEFAULT_GATEWAY:
pushInt(_platform.currentDefaultGateway(), data);
break;
case PID_IP_ADDRESS:
pushInt(_ipAddress, data);
break;
case PID_SUBNET_MASK:
pushInt(_subnetMask, data);
break;
case PID_DEFAULT_GATEWAY:
pushInt(_defaultGateway, data);
break;
case PID_MAC_ADDRESS:
{
uint8_t macAddr[6];
_platform.macAddress(macAddr);
pushByteArray(macAddr, 6, data);
break;
}
case PID_SYSTEM_SETUP_MULTICAST_ADDRESS:
pushInt(DEFAULT_MULTICAST_ADDR, data);
break;
case PID_ROUTING_MULTICAST_ADDRESS:
pushInt(_multicastAddress, data);
break;
case PID_TTL:
data[0] = ttl();
break;
case PID_KNXNETIP_DEVICE_CAPABILITIES:
data[0] = 0x1;
break;
case PID_FRIENDLY_NAME:
for (uint8_t i = start; i < start + count; i++)
data[i-start] = _friendlyName[i-1];
break;
}
}
void IpParameterObject::writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count)
{
switch (id)
{
case PID_LOAD_STATE_CONTROL:
loadEvent(data);
break;
case PID_PROJECT_INSTALLATION_ID:
_projectInstallationId = getWord(data);
break;
case PID_KNX_INDIVIDUAL_ADDRESS:
_deviceObject.induvidualAddress(getWord(data));
break;
case PID_IP_ASSIGNMENT_METHOD:
_ipAssignmentMethod = data[0];
break;
case PID_IP_ADDRESS:
_ipAddress = getInt(data);
break;
case PID_SUBNET_MASK:
_subnetMask = getInt(data);
break;
case PID_DEFAULT_GATEWAY:
_defaultGateway = getInt(data);
break;
case PID_ROUTING_MULTICAST_ADDRESS:
_multicastAddress = getInt(data);
break;
case PID_TTL:
_ttl = data[0];
break;
case PID_FRIENDLY_NAME:
for (uint8_t i = start; i < start + count; i++)
_friendlyName[i-1] = data[i - start];
break;
}
}
uint8_t IpParameterObject::propertySize(PropertyID id)
{
switch (id)
{
case PID_IP_ASSIGNMENT_METHOD:
case PID_LOAD_STATE_CONTROL:
case PID_IP_CAPABILITIES:
case PID_TTL:
case PID_KNXNETIP_DEVICE_CAPABILITIES:
case PID_FRIENDLY_NAME:
return 1;
case PID_OBJECT_TYPE:
case PID_PROJECT_INSTALLATION_ID:
case PID_KNX_INDIVIDUAL_ADDRESS:
return 2;
case PID_CURRENT_IP_ADDRESS:
case PID_CURRENT_SUBNET_MASK:
case PID_CURRENT_DEFAULT_GATEWAY:
case PID_IP_ADDRESS:
case PID_SUBNET_MASK:
case PID_DEFAULT_GATEWAY:
case PID_SYSTEM_SETUP_MULTICAST_ADDRESS:
case PID_ROUTING_MULTICAST_ADDRESS:
return 4;
case PID_MAC_ADDRESS:
return 6;
}
return 0;
}
uint8_t* IpParameterObject::save(uint8_t* buffer)
{
buffer = pushWord(_projectInstallationId, buffer);
buffer = pushByte(_ipAssignmentMethod, buffer);
buffer = pushByte(_ipCapabilities, buffer);
buffer = pushInt(_ipAddress, buffer);
buffer = pushInt(_subnetMask, buffer);
buffer = pushInt(_defaultGateway, buffer);
buffer = pushInt(_multicastAddress, buffer);
buffer = pushByte(_ttl, buffer);
buffer = pushByteArray((uint8_t*)_friendlyName, 30, buffer);
return buffer;
}
uint8_t* IpParameterObject::restore(uint8_t* buffer)
{
buffer = popWord(_projectInstallationId, buffer);
buffer = popByte(_ipAssignmentMethod, buffer);
buffer = popByte(_ipCapabilities, buffer);
buffer = popInt(_ipAddress, buffer);
buffer = popInt(_subnetMask, buffer);
buffer = popInt(_defaultGateway, buffer);
buffer = popInt(_multicastAddress, buffer);
buffer = popByte(_ttl, buffer);
buffer = popByteArray((uint8_t*)_friendlyName, 30, buffer);
return buffer;
}
uint32_t IpParameterObject::multicastAddress() const
{
if (_multicastAddress == 0)
return DEFAULT_MULTICAST_ADDR;
return _multicastAddress;
}
void IpParameterObject::loadEvent(uint8_t* data)
{
switch (_state)
{
case LS_UNLOADED:
loadEventUnloaded(data);
break;
case LS_LOADING:
loadEventLoading(data);
break;
case LS_LOADED:
loadEventLoaded(data);
break;
case LS_ERROR:
loadEventError(data);
break;
}
}
void IpParameterObject::loadState(LoadState newState)
{
if (newState == _state)
return;
//beforeStateChange(newState);
_state = newState;
}
void IpParameterObject::loadEventUnloaded(uint8_t* data)
{
uint8_t event = data[0];
switch (event)
{
case LE_NOOP:
case LE_LOAD_COMPLETED:
case LE_ADDITIONAL_LOAD_CONTROLS:
case LE_UNLOAD:
break;
case LE_START_LOADING:
loadState(LS_LOADING);
break;
default:
loadState(LS_ERROR);
_errorCode = E_GOT_UNDEF_LOAD_CMD;
}
}
void IpParameterObject::loadEventLoading(uint8_t* data)
{
uint8_t event = data[0];
switch (event)
{
case LE_NOOP:
case LE_START_LOADING:
break;
case LE_LOAD_COMPLETED:
loadState(LS_LOADED);
break;
case LE_UNLOAD:
loadState(LS_UNLOADED);
break;
case LE_ADDITIONAL_LOAD_CONTROLS:
additionalLoadControls(data);
break;
default:
loadState(LS_ERROR);
_errorCode = E_GOT_UNDEF_LOAD_CMD;
}
}
void IpParameterObject::loadEventLoaded(uint8_t* data)
{
uint8_t event = data[0];
switch (event)
{
case LE_NOOP:
case LE_LOAD_COMPLETED:
break;
case LE_START_LOADING:
loadState(LS_LOADING);
break;
case LE_UNLOAD:
loadState(LS_UNLOADED);
break;
case LE_ADDITIONAL_LOAD_CONTROLS:
loadState(LS_ERROR);
_errorCode = E_INVALID_OPCODE;
break;
default:
loadState(LS_ERROR);
_errorCode = E_GOT_UNDEF_LOAD_CMD;
}
}
void IpParameterObject::loadEventError(uint8_t* data)
{
uint8_t event = data[0];
switch (event)
{
case LE_NOOP:
case LE_LOAD_COMPLETED:
case LE_ADDITIONAL_LOAD_CONTROLS:
case LE_START_LOADING:
break;
case LE_UNLOAD:
loadState(LS_UNLOADED);
break;
default:
loadState(LS_ERROR);
_errorCode = E_GOT_UNDEF_LOAD_CMD;
}
}
void IpParameterObject::additionalLoadControls(uint8_t* data)
{
loadState(LS_ERROR);
_errorCode = E_INVALID_OPCODE;
return;
}