mirror of
https://github.com/thelsing/knx.git
synced 2025-04-23 01:16:29 +02:00
- add some knx-ip classes
- return no data if Property has no elements - implement get{ipAddress, netmask, defaultGw, macAddress) for linux platform
This commit is contained in:
parent
8f61ef8608
commit
6ae000482f
@ -51,6 +51,8 @@ add_executable(knx-linux
|
|||||||
../../src/knx/ip_parameter_object.h
|
../../src/knx/ip_parameter_object.h
|
||||||
../../src/knx/knx_ip_frame.cpp
|
../../src/knx/knx_ip_frame.cpp
|
||||||
../../src/knx/knx_ip_routing_indication.cpp
|
../../src/knx/knx_ip_routing_indication.cpp
|
||||||
|
../../src/knx/knx_ip_search_request.cpp
|
||||||
|
../../src/knx/ip_host_protocol_address_information.cpp
|
||||||
../../src/knx/knx_value.cpp
|
../../src/knx/knx_value.cpp
|
||||||
../../src/knx/knx_value.h
|
../../src/knx/knx_value.h
|
||||||
../../src/knx/memory.cpp
|
../../src/knx/memory.cpp
|
||||||
|
@ -97,9 +97,13 @@
|
|||||||
<ClInclude Include="..\..\src\knx\group_object_table_object.h" />
|
<ClInclude Include="..\..\src\knx\group_object_table_object.h" />
|
||||||
<ClInclude Include="..\..\src\knx\interface_object.h" />
|
<ClInclude Include="..\..\src\knx\interface_object.h" />
|
||||||
<ClInclude Include="..\..\src\knx\ip_data_link_layer.h" />
|
<ClInclude Include="..\..\src\knx\ip_data_link_layer.h" />
|
||||||
|
<ClInclude Include="..\..\src\knx\ip_host_protocol_address_information.h" />
|
||||||
<ClInclude Include="..\..\src\knx\ip_parameter_object.h" />
|
<ClInclude Include="..\..\src\knx\ip_parameter_object.h" />
|
||||||
|
<ClInclude Include="..\..\src\knx\knx_ip_dib.h" />
|
||||||
<ClInclude Include="..\..\src\knx\knx_ip_frame.h" />
|
<ClInclude Include="..\..\src\knx\knx_ip_frame.h" />
|
||||||
<ClInclude Include="..\..\src\knx\knx_ip_routing_indication.h" />
|
<ClInclude Include="..\..\src\knx\knx_ip_routing_indication.h" />
|
||||||
|
<ClInclude Include="..\..\src\knx\knx_ip_search_request.h" />
|
||||||
|
<ClInclude Include="..\..\src\knx\knx_ip_search_response.h" />
|
||||||
<ClInclude Include="..\..\src\knx\knx_types.h" />
|
<ClInclude Include="..\..\src\knx\knx_types.h" />
|
||||||
<ClInclude Include="..\..\src\knx\knx_value.h" />
|
<ClInclude Include="..\..\src\knx\knx_value.h" />
|
||||||
<ClInclude Include="..\..\src\knx\memory.h" />
|
<ClInclude Include="..\..\src\knx\memory.h" />
|
||||||
@ -151,9 +155,13 @@
|
|||||||
<ClCompile Include="..\..\src\knx\group_object_table_object.cpp" />
|
<ClCompile Include="..\..\src\knx\group_object_table_object.cpp" />
|
||||||
<ClCompile Include="..\..\src\knx\interface_object.cpp" />
|
<ClCompile Include="..\..\src\knx\interface_object.cpp" />
|
||||||
<ClCompile Include="..\..\src\knx\ip_data_link_layer.cpp" />
|
<ClCompile Include="..\..\src\knx\ip_data_link_layer.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\knx\ip_host_protocol_address_information.cpp" />
|
||||||
<ClCompile Include="..\..\src\knx\ip_parameter_object.cpp" />
|
<ClCompile Include="..\..\src\knx\ip_parameter_object.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\knx\knx_ip_dib.cpp" />
|
||||||
<ClCompile Include="..\..\src\knx\knx_ip_frame.cpp" />
|
<ClCompile Include="..\..\src\knx\knx_ip_frame.cpp" />
|
||||||
<ClCompile Include="..\..\src\knx\knx_ip_routing_indication.cpp" />
|
<ClCompile Include="..\..\src\knx\knx_ip_routing_indication.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\knx\knx_ip_search_request.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\knx\knx_ip_search_response.cpp" />
|
||||||
<ClCompile Include="..\..\src\knx\knx_value.cpp" />
|
<ClCompile Include="..\..\src\knx\knx_value.cpp" />
|
||||||
<ClCompile Include="..\..\src\knx\memory.cpp" />
|
<ClCompile Include="..\..\src\knx\memory.cpp" />
|
||||||
<ClCompile Include="..\..\src\knx\network_layer.cpp" />
|
<ClCompile Include="..\..\src\knx\network_layer.cpp" />
|
||||||
|
@ -176,6 +176,18 @@
|
|||||||
<ClInclude Include="..\..\src\knx\knx_ip_routing_indication.h">
|
<ClInclude Include="..\..\src\knx\knx_ip_routing_indication.h">
|
||||||
<Filter>Header files\knx</Filter>
|
<Filter>Header files\knx</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\knx\knx_ip_search_request.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\knx\ip_host_protocol_address_information.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\knx\knx_ip_search_response.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\knx\knx_ip_dib.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
@ -310,5 +322,17 @@
|
|||||||
<ClCompile Include="..\..\src\knx\knx_ip_routing_indication.cpp">
|
<ClCompile Include="..\..\src\knx\knx_ip_routing_indication.cpp">
|
||||||
<Filter>Source files\knx</Filter>
|
<Filter>Source files\knx</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\knx\ip_host_protocol_address_information.cpp">
|
||||||
|
<Filter>Source files\knx</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\knx\knx_ip_search_request.cpp">
|
||||||
|
<Filter>Source files\knx</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\knx\knx_ip_search_response.cpp">
|
||||||
|
<Filter>Source files\knx</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\knx\knx_ip_dib.cpp">
|
||||||
|
<Filter>Source files\knx</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -232,6 +232,10 @@ void BauSystemB::propertyValueReadIndication(Priority priority, HopCountType hop
|
|||||||
uint8_t data[size];
|
uint8_t data[size];
|
||||||
if(obj)
|
if(obj)
|
||||||
obj->readProperty((PropertyID)propertyId, startIndex, elementCount, data);
|
obj->readProperty((PropertyID)propertyId, startIndex, elementCount, data);
|
||||||
|
|
||||||
|
if (elementCount == 0)
|
||||||
|
size = 0;
|
||||||
|
|
||||||
_appLayer.propertyValueReadResponse(AckRequested, priority, hopType, asap, objectIndex, propertyId, elementCount,
|
_appLayer.propertyValueReadResponse(AckRequested, priority, hopType, asap, objectIndex, propertyId, elementCount,
|
||||||
startIndex, data, size);
|
startIndex, data, size);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "device_object.h"
|
#include "device_object.h"
|
||||||
#include "address_table_object.h"
|
#include "address_table_object.h"
|
||||||
#include "knx_ip_routing_indication.h"
|
#include "knx_ip_routing_indication.h"
|
||||||
|
#include "knx_ip_search_request.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -55,9 +56,19 @@ void IpDataLinkLayer::loop()
|
|||||||
switch ((KnxIpServiceType)code)
|
switch ((KnxIpServiceType)code)
|
||||||
{
|
{
|
||||||
case RoutingIndication:
|
case RoutingIndication:
|
||||||
|
{
|
||||||
KnxIpRoutingIndication routingIndication(buffer, len);
|
KnxIpRoutingIndication routingIndication(buffer, len);
|
||||||
frameRecieved(routingIndication.frame());
|
frameRecieved(routingIndication.frame());
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case SearchRequest:
|
||||||
|
{
|
||||||
|
KnxIpSearchRequest searchRequest(buffer, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
print("Unhandled service identifier: ");
|
||||||
|
println(code, HEX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
src/knx/ip_host_protocol_address_information.cpp
Normal file
31
src/knx/ip_host_protocol_address_information.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "ip_host_protocol_address_information.h"
|
||||||
|
#include "bits.h"
|
||||||
|
#ifdef USE_IP
|
||||||
|
IpHostProtocolAddressInformation::IpHostProtocolAddressInformation(uint8_t* data)
|
||||||
|
: _data(data)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t IpHostProtocolAddressInformation::length()
|
||||||
|
{
|
||||||
|
return *_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HostProtocolCode IpHostProtocolAddressInformation::code()
|
||||||
|
{
|
||||||
|
return (HostProtocolCode)_data[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t IpHostProtocolAddressInformation::ipAddress()
|
||||||
|
{
|
||||||
|
return getInt(_data + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t IpHostProtocolAddressInformation::ipPortNumber()
|
||||||
|
{
|
||||||
|
return getWord(_data + 6);
|
||||||
|
}
|
||||||
|
#endif
|
24
src/knx/ip_host_protocol_address_information.h
Normal file
24
src/knx/ip_host_protocol_address_information.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
enum HostProtocolCode : uint8_t
|
||||||
|
{
|
||||||
|
IPV4_UDP = 1,
|
||||||
|
IPV4_TCP = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef USE_IP
|
||||||
|
class IpHostProtocolAddressInformation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IpHostProtocolAddressInformation(uint8_t* data);
|
||||||
|
uint8_t length();
|
||||||
|
HostProtocolCode code();
|
||||||
|
uint32_t ipAddress();
|
||||||
|
uint16_t ipPortNumber();
|
||||||
|
private:
|
||||||
|
uint8_t* _data;
|
||||||
|
};
|
||||||
|
#endif
|
15
src/knx/knx_ip_dib.cpp
Normal file
15
src/knx/knx_ip_dib.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "knx_ip_dib.h"
|
||||||
|
|
||||||
|
DIB::DIB(uint8_t* data) : _data(data)
|
||||||
|
{}
|
||||||
|
|
||||||
|
DescriptionTypeCode DIB::code()
|
||||||
|
{
|
||||||
|
return (DescriptionTypeCode)_data[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t DIB::length()
|
||||||
|
{
|
||||||
|
return *_data;
|
||||||
|
}
|
27
src/knx/knx_ip_dib.h
Normal file
27
src/knx/knx_ip_dib.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef USE_IP
|
||||||
|
|
||||||
|
enum DescriptionTypeCode : uint8_t
|
||||||
|
{
|
||||||
|
DEVICE_INFO = 0x01,
|
||||||
|
SUPP_SVC_FAMILIES = 0x02,
|
||||||
|
IP_CONFIG = 0x03,
|
||||||
|
IP_CUR_CONFIG = 0x04,
|
||||||
|
KNX_ADDRESSES = 0x05,
|
||||||
|
MFR_DATA = 0xFE
|
||||||
|
};
|
||||||
|
|
||||||
|
class DIB
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DIB(uint8_t* data);
|
||||||
|
DescriptionTypeCode code();
|
||||||
|
uint8_t length();
|
||||||
|
private:
|
||||||
|
uint8_t* _data = 0;
|
||||||
|
};
|
||||||
|
#endif
|
@ -10,6 +10,7 @@ KnxIpFrame::KnxIpFrame(uint8_t* data,
|
|||||||
uint16_t length)
|
uint16_t length)
|
||||||
{
|
{
|
||||||
_data = data;
|
_data = data;
|
||||||
|
_dataLength = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t KnxIpFrame::headerLength() const
|
uint8_t KnxIpFrame::headerLength() const
|
||||||
@ -62,13 +63,14 @@ uint8_t* KnxIpFrame::data()
|
|||||||
KnxIpFrame::~KnxIpFrame()
|
KnxIpFrame::~KnxIpFrame()
|
||||||
{
|
{
|
||||||
if (_freeData)
|
if (_freeData)
|
||||||
delete _data;
|
delete[] _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
KnxIpFrame::KnxIpFrame(uint16_t length)
|
KnxIpFrame::KnxIpFrame(uint16_t length)
|
||||||
{
|
{
|
||||||
_data = new uint8_t[length];
|
_data = new uint8_t[length];
|
||||||
|
_dataLength = length;
|
||||||
_freeData = true;
|
_freeData = true;
|
||||||
headerLength(KNXIP_HEADER_LEN);
|
headerLength(KNXIP_HEADER_LEN);
|
||||||
protocolVersion(KnxIp1_0);
|
protocolVersion(KnxIp1_0);
|
||||||
|
@ -53,5 +53,6 @@ class KnxIpFrame
|
|||||||
protected:
|
protected:
|
||||||
bool _freeData = false;
|
bool _freeData = false;
|
||||||
uint8_t* _data = 0;
|
uint8_t* _data = 0;
|
||||||
|
uint16_t _dataLength;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
13
src/knx/knx_ip_search_request.cpp
Normal file
13
src/knx/knx_ip_search_request.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "knx_ip_search_request.h"
|
||||||
|
#ifdef USE_IP
|
||||||
|
KnxIpSearchRequest::KnxIpSearchRequest(uint8_t* data, uint16_t length)
|
||||||
|
: KnxIpFrame(data, length), _hpai(data + KNXIP_HEADER_LEN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IpHostProtocolAddressInformation& KnxIpSearchRequest::hpai()
|
||||||
|
{
|
||||||
|
return _hpai;
|
||||||
|
}
|
||||||
|
#endif
|
14
src/knx/knx_ip_search_request.h
Normal file
14
src/knx/knx_ip_search_request.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "knx_ip_frame.h"
|
||||||
|
#include "ip_host_protocol_address_information.h"
|
||||||
|
#ifdef USE_IP
|
||||||
|
class KnxIpSearchRequest : public KnxIpFrame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KnxIpSearchRequest(uint8_t* data, uint16_t length);
|
||||||
|
IpHostProtocolAddressInformation& hpai();
|
||||||
|
private:
|
||||||
|
IpHostProtocolAddressInformation _hpai;
|
||||||
|
};
|
||||||
|
#endif
|
4
src/knx/knx_ip_search_response.cpp
Normal file
4
src/knx/knx_ip_search_response.cpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include "knx_ip_search_response.h"
|
||||||
|
#ifdef USE_IP
|
||||||
|
|
||||||
|
#endif
|
13
src/knx/knx_ip_search_response.h
Normal file
13
src/knx/knx_ip_search_response.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "knx_ip_frame.h"
|
||||||
|
#include "ip_host_protocol_address_information.h"
|
||||||
|
#ifdef USE_IP
|
||||||
|
|
||||||
|
class KnxIpSearchResponse : public KnxIpFrame
|
||||||
|
{
|
||||||
|
IpHostProtocolAddressInformation& controlEndpoint();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -87,3 +87,21 @@ int Platform::readBytesMultiCast(uint8_t *buffer, uint16_t maxLen)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Platform::setupUniCast(uint32_t addr, uint16_t port, uint8_t type)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
void Platform::closeUniCast()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
bool Platform::sendBytesUniCast(uint8_t* buffer, uint16_t len)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Platform::readBytesUniCast(uint8_t *buffer, uint16_t maxLen)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
@ -30,6 +30,12 @@ class Platform
|
|||||||
virtual bool sendBytesMultiCast(uint8_t* buffer, uint16_t len);
|
virtual bool sendBytesMultiCast(uint8_t* buffer, uint16_t len);
|
||||||
virtual int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen);
|
virtual int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen);
|
||||||
|
|
||||||
|
//unicast socket
|
||||||
|
virtual void setupUniCast(uint32_t addr, uint16_t port, uint8_t type);
|
||||||
|
virtual void closeUniCast();
|
||||||
|
virtual bool sendBytesUniCast(uint8_t* buffer, uint16_t len);
|
||||||
|
virtual int readBytesUniCast(uint8_t* buffer, uint16_t maxLen);
|
||||||
|
|
||||||
//UART
|
//UART
|
||||||
virtual void setupUart();
|
virtual void setupUart();
|
||||||
virtual void closeUart();
|
virtual void closeUart();
|
||||||
|
@ -15,14 +15,17 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <sys/ioctl.h> // Needed for SPI port
|
#include <sys/ioctl.h> // Needed for SPI port
|
||||||
#include <linux/spi/spidev.h> // Needed for SPI port
|
#include <linux/spi/spidev.h> // Needed for SPI port
|
||||||
#include <poll.h> // Needed for GPIO edge detection
|
#include <poll.h> // Needed for GPIO edge detection
|
||||||
#include <sys/time.h> // Needed for delayMicroseconds()
|
#include <sys/time.h> // Needed for delayMicroseconds()
|
||||||
|
|
||||||
#include "knx/device_object.h"
|
#include "knx/device_object.h"
|
||||||
#include "knx/address_table_object.h"
|
#include "knx/address_table_object.h"
|
||||||
@ -31,18 +34,97 @@
|
|||||||
#include "knx/application_program_object.h"
|
#include "knx/application_program_object.h"
|
||||||
#include "knx/ip_parameter_object.h"
|
#include "knx/ip_parameter_object.h"
|
||||||
#include "knx/bits.h"
|
#include "knx/bits.h"
|
||||||
|
#include "knx/ip_host_protocol_address_information.h"
|
||||||
|
|
||||||
#define MAX_MEM 4096
|
#define MAX_MEM 4096
|
||||||
|
|
||||||
LinuxPlatform::LinuxPlatform()
|
LinuxPlatform::LinuxPlatform()
|
||||||
{}
|
{
|
||||||
|
int socketMac = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||||
|
if (socketMac < 0)
|
||||||
|
{
|
||||||
|
printf("Lookup socket creation failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ifreq ifr;
|
||||||
|
struct ifconf ifc;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
ifc.ifc_len = sizeof(buf);
|
||||||
|
ifc.ifc_buf = buf;
|
||||||
|
if (ioctl(socketMac, SIOCGIFCONF, &ifc) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct ifreq* it = ifc.ifc_req;
|
||||||
|
const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq));
|
||||||
|
|
||||||
|
for (; it != end; ++it)
|
||||||
|
{
|
||||||
|
strcpy(ifr.ifr_name, it->ifr_name);
|
||||||
|
if (ioctl(socketMac, SIOCGIFFLAGS, &ifr))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ifr.ifr_flags & IFF_LOOPBACK) // don't count loopback
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ioctl(socketMac, SIOCGIFHWADDR, &ifr))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memcpy(_macAddress, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
|
||||||
|
|
||||||
|
ioctl(socketMac, SIOCGIFADDR, &ifr);
|
||||||
|
|
||||||
|
struct sockaddr_in* ipaddr = (struct sockaddr_in*)&ifr.ifr_addr;
|
||||||
|
_ipAddress = ntohl(ipaddr->sin_addr.s_addr);
|
||||||
|
|
||||||
|
//printf("IP address: %s\n", inet_ntoa(ipaddr->sin_addr));
|
||||||
|
ioctl(socketMac, SIOCGIFNETMASK, &ifr);
|
||||||
|
struct sockaddr_in* netmask = (struct sockaddr_in*)&ifr.ifr_netmask;
|
||||||
|
_netmask = ntohl(netmask->sin_addr.s_addr);
|
||||||
|
//printf("Netmask: %s\n", inet_ntoa(ipaddr->sin_addr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(socketMac);
|
||||||
|
|
||||||
|
// default GW
|
||||||
|
FILE* f;
|
||||||
|
char line[100], *p, *c, *g, *saveptr;
|
||||||
|
|
||||||
|
f = fopen("/proc/net/route", "r");
|
||||||
|
|
||||||
|
while (fgets(line, 100, f))
|
||||||
|
{
|
||||||
|
p = strtok_r(line, " \t", &saveptr);
|
||||||
|
c = strtok_r(NULL, " \t", &saveptr);
|
||||||
|
g = strtok_r(NULL, " \t", &saveptr);
|
||||||
|
|
||||||
|
if (p != NULL && c != NULL)
|
||||||
|
{
|
||||||
|
if (strcmp(c, "00000000") == 0)
|
||||||
|
{
|
||||||
|
//printf("Default interface is : %s \n" , p);
|
||||||
|
if (g)
|
||||||
|
{
|
||||||
|
char* pEnd;
|
||||||
|
_defaultGateway = ntohl(strtol(g, &pEnd, 16));
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
LinuxPlatform::~LinuxPlatform()
|
LinuxPlatform::~LinuxPlatform()
|
||||||
{
|
{
|
||||||
delete[] _args;
|
delete[] _args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t millis()
|
uint32_t millis()
|
||||||
{
|
{
|
||||||
struct timespec spec;
|
struct timespec spec;
|
||||||
@ -59,8 +141,6 @@ void delay(uint32_t millis)
|
|||||||
nanosleep(&ts, NULL);
|
nanosleep(&ts, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void LinuxPlatform::restart()
|
void LinuxPlatform::restart()
|
||||||
{
|
{
|
||||||
execv(_args[0], _args);
|
execv(_args[0], _args);
|
||||||
@ -75,8 +155,11 @@ void LinuxPlatform::fatalError()
|
|||||||
|
|
||||||
void LinuxPlatform::setupMultiCast(uint32_t addr, uint16_t port)
|
void LinuxPlatform::setupMultiCast(uint32_t addr, uint16_t port)
|
||||||
{
|
{
|
||||||
|
if (_multicastSocketFd >= 0)
|
||||||
|
closeMultiCast();
|
||||||
|
|
||||||
_multicastAddr = addr;
|
_multicastAddr = addr;
|
||||||
_port = port;
|
_multicastPort = port;
|
||||||
|
|
||||||
struct ip_mreq command;
|
struct ip_mreq command;
|
||||||
uint32_t loop = 1;
|
uint32_t loop = 1;
|
||||||
@ -87,21 +170,22 @@ void LinuxPlatform::setupMultiCast(uint32_t addr, uint16_t port)
|
|||||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
sin.sin_port = htons(port);
|
sin.sin_port = htons(port);
|
||||||
|
|
||||||
_socketFd = socket(AF_INET, SOCK_DGRAM, 0);
|
_multicastSocketFd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (_socketFd == -1) {
|
if (_multicastSocketFd == -1)
|
||||||
|
{
|
||||||
perror("socket()");
|
perror("socket()");
|
||||||
fatalError();
|
fatalError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mehr Prozessen erlauben, denselben Port zu nutzen */
|
/* Mehr Prozessen erlauben, denselben Port zu nutzen */
|
||||||
loop = 1;
|
loop = 1;
|
||||||
if (setsockopt(_socketFd, SOL_SOCKET, SO_REUSEADDR, &loop, sizeof(loop)) < 0)
|
if (setsockopt(_multicastSocketFd, SOL_SOCKET, SO_REUSEADDR, &loop, sizeof(loop)) < 0)
|
||||||
{
|
{
|
||||||
perror("setsockopt:SO_REUSEADDR");
|
perror("setsockopt:SO_REUSEADDR");
|
||||||
fatalError();
|
fatalError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind(_socketFd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
|
if (bind(_multicastSocketFd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
|
||||||
{
|
{
|
||||||
perror("bind");
|
perror("bind");
|
||||||
fatalError();
|
fatalError();
|
||||||
@ -109,7 +193,7 @@ void LinuxPlatform::setupMultiCast(uint32_t addr, uint16_t port)
|
|||||||
|
|
||||||
/* loopback */
|
/* loopback */
|
||||||
loop = 0;
|
loop = 0;
|
||||||
if (setsockopt(_socketFd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
|
if (setsockopt(_multicastSocketFd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0)
|
||||||
{
|
{
|
||||||
perror("setsockopt:IP_MULTICAST_LOOP");
|
perror("setsockopt:IP_MULTICAST_LOOP");
|
||||||
fatalError();
|
fatalError();
|
||||||
@ -119,15 +203,15 @@ void LinuxPlatform::setupMultiCast(uint32_t addr, uint16_t port)
|
|||||||
command.imr_multiaddr.s_addr = htonl(addr);
|
command.imr_multiaddr.s_addr = htonl(addr);
|
||||||
command.imr_interface.s_addr = htonl(INADDR_ANY);
|
command.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
||||||
if (setsockopt(_socketFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0)
|
if (setsockopt(_multicastSocketFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0)
|
||||||
{
|
{
|
||||||
perror("setsockopt:IP_ADD_MEMBERSHIP");
|
perror("setsockopt:IP_ADD_MEMBERSHIP");
|
||||||
fatalError();
|
fatalError();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flags = fcntl(_socketFd, F_GETFL);
|
uint32_t flags = fcntl(_multicastSocketFd, F_GETFL);
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
fcntl(_socketFd, F_SETFL, flags);
|
fcntl(_multicastSocketFd, F_SETFL, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinuxPlatform::closeMultiCast()
|
void LinuxPlatform::closeMultiCast()
|
||||||
@ -136,50 +220,52 @@ void LinuxPlatform::closeMultiCast()
|
|||||||
command.imr_multiaddr.s_addr = htonl(_multicastAddr);
|
command.imr_multiaddr.s_addr = htonl(_multicastAddr);
|
||||||
command.imr_interface.s_addr = htonl(INADDR_ANY);
|
command.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
||||||
if (setsockopt(_socketFd,
|
if (setsockopt(_multicastSocketFd,
|
||||||
IPPROTO_IP,
|
IPPROTO_IP,
|
||||||
IP_DROP_MEMBERSHIP,
|
IP_DROP_MEMBERSHIP,
|
||||||
&command, sizeof(command)) < 0) {
|
&command, sizeof(command)) < 0)
|
||||||
|
{
|
||||||
perror("setsockopt:IP_DROP_MEMBERSHIP");
|
perror("setsockopt:IP_DROP_MEMBERSHIP");
|
||||||
}
|
}
|
||||||
close(_socketFd);
|
close(_multicastSocketFd);
|
||||||
|
_multicastSocketFd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinuxPlatform::sendBytesMultiCast(uint8_t* buffer, uint16_t len)
|
bool LinuxPlatform::sendBytesMultiCast(uint8_t* buffer, uint16_t len)
|
||||||
{
|
{
|
||||||
struct sockaddr_in address = { 0 };
|
struct sockaddr_in address = {0};
|
||||||
address.sin_family = AF_INET;
|
address.sin_family = AF_INET;
|
||||||
address.sin_addr.s_addr = htonl(_multicastAddr);
|
address.sin_addr.s_addr = htonl(_multicastAddr);
|
||||||
address.sin_port = htons(_port);
|
address.sin_port = htons(_multicastPort);
|
||||||
|
|
||||||
ssize_t retVal = 0;
|
ssize_t retVal = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
retVal = sendto(_socketFd, buffer, len, 0, (struct sockaddr *) &address, sizeof(address));
|
retVal = sendto(_multicastSocketFd, buffer, len, 0, (struct sockaddr*)&address, sizeof(address));
|
||||||
if (retVal == -1)
|
if (retVal == -1)
|
||||||
{
|
{
|
||||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} while (retVal == -1);
|
} while (retVal == -1);
|
||||||
// printHex("<-", buffer, len);
|
// printHex("<-", buffer, len);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LinuxPlatform::readBytesMultiCast(uint8_t * buffer, uint16_t maxLen)
|
int LinuxPlatform::readBytesMultiCast(uint8_t* buffer, uint16_t maxLen)
|
||||||
{
|
{
|
||||||
uint32_t sin_len;
|
uint32_t sin_len;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
sin_len = sizeof(sin);
|
sin_len = sizeof(sin);
|
||||||
ssize_t len = recvfrom(_socketFd, buffer, maxLen, 0, (struct sockaddr *) &sin, &sin_len);
|
ssize_t len = recvfrom(_multicastSocketFd, buffer, maxLen, 0, (struct sockaddr*)&sin, &sin_len);
|
||||||
// if (len > 0)
|
// if (len > 0)
|
||||||
// printHex("->", buffer, len);
|
// printHex("->", buffer, len);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t * LinuxPlatform::getEepromBuffer(uint16_t size)
|
uint8_t* LinuxPlatform::getEepromBuffer(uint16_t size)
|
||||||
{
|
{
|
||||||
if (_fd < 0)
|
if (_fd < 0)
|
||||||
doMemoryMapping();
|
doMemoryMapping();
|
||||||
@ -242,69 +328,67 @@ void LinuxPlatform::doMemoryMapping()
|
|||||||
void LinuxPlatform::closeSpi()
|
void LinuxPlatform::closeSpi()
|
||||||
{
|
{
|
||||||
close(_spiFd);
|
close(_spiFd);
|
||||||
printf ("SPI device closed.\r\n");
|
printf("SPI device closed.\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int LinuxPlatform::readWriteSpi (uint8_t *data, size_t len)
|
int LinuxPlatform::readWriteSpi(uint8_t* data, size_t len)
|
||||||
{
|
{
|
||||||
uint16_t spiDelay = 0 ;
|
uint16_t spiDelay = 0;
|
||||||
uint32_t spiSpeed = 8000000; // 4 MHz SPI speed
|
uint32_t spiSpeed = 8000000; // 4 MHz SPI speed
|
||||||
uint8_t spiBPW = 8; // Bits per word
|
uint8_t spiBPW = 8; // Bits per word
|
||||||
|
|
||||||
struct spi_ioc_transfer spi ;
|
struct spi_ioc_transfer spi;
|
||||||
|
|
||||||
// Mentioned in spidev.h but not used in the original kernel documentation
|
// Mentioned in spidev.h but not used in the original kernel documentation
|
||||||
// test program )-:
|
// test program )-:
|
||||||
|
|
||||||
memset (&spi, 0, sizeof (spi)) ;
|
memset(&spi, 0, sizeof(spi));
|
||||||
|
|
||||||
spi.tx_buf = (uint64_t)data;
|
spi.tx_buf = (uint64_t)data;
|
||||||
spi.rx_buf = (uint64_t)data;
|
spi.rx_buf = (uint64_t)data;
|
||||||
spi.len = len;
|
spi.len = len;
|
||||||
spi.delay_usecs = spiDelay;
|
spi.delay_usecs = spiDelay;
|
||||||
spi.speed_hz = spiSpeed;
|
spi.speed_hz = spiSpeed;
|
||||||
spi.bits_per_word = spiBPW;
|
spi.bits_per_word = spiBPW;
|
||||||
|
|
||||||
return ioctl (_spiFd, SPI_IOC_MESSAGE(1), &spi) ;
|
return ioctl(_spiFd, SPI_IOC_MESSAGE(1), &spi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinuxPlatform::setupSpi()
|
void LinuxPlatform::setupSpi()
|
||||||
{
|
{
|
||||||
if ((_spiFd = open ("/dev/spidev0.0", O_RDWR)) < 0)
|
if ((_spiFd = open("/dev/spidev0.0", O_RDWR)) < 0)
|
||||||
{
|
{
|
||||||
printf ("ERROR: SPI setup failed! Could not open SPI device!\r\n");
|
printf("ERROR: SPI setup failed! Could not open SPI device!\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set SPI parameters.
|
// Set SPI parameters.
|
||||||
int mode = 0; // Mode 0
|
int mode = 0; // Mode 0
|
||||||
uint8_t spiBPW = 8; // Bits per word
|
uint8_t spiBPW = 8; // Bits per word
|
||||||
int speed = 8000000; // 4 MHz SPI speed
|
int speed = 8000000; // 4 MHz SPI speed
|
||||||
|
|
||||||
if (ioctl (_spiFd, SPI_IOC_WR_MODE, &mode) < 0)
|
if (ioctl(_spiFd, SPI_IOC_WR_MODE, &mode) < 0)
|
||||||
{
|
{
|
||||||
printf ("ERROR: SPI Mode Change failure: %s\n", strerror (errno)) ;
|
printf("ERROR: SPI Mode Change failure: %s\n", strerror(errno));
|
||||||
close(_spiFd);
|
close(_spiFd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl (_spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
|
if (ioctl(_spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
|
||||||
{
|
{
|
||||||
printf ("ERROR: SPI BPW Change failure: %s\n", strerror (errno)) ;
|
printf("ERROR: SPI BPW Change failure: %s\n", strerror(errno));
|
||||||
close(_spiFd);
|
close(_spiFd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl (_spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
|
if (ioctl(_spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
|
||||||
{
|
{
|
||||||
printf ("ERROR: SPI Speed Change failure: %s\n", strerror (errno)) ;
|
printf("ERROR: SPI Speed Change failure: %s\n", strerror(errno));
|
||||||
close(_spiFd);
|
close(_spiFd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("SPI device setup ok.\r\n");
|
printf("SPI device setup ok.\r\n");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinuxPlatform::flashFilePath(const std::string path)
|
void LinuxPlatform::flashFilePath(const std::string path)
|
||||||
@ -312,7 +396,6 @@ void LinuxPlatform::flashFilePath(const std::string path)
|
|||||||
_flashFilePath = path;
|
_flashFilePath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string LinuxPlatform::flashFilePath()
|
std::string LinuxPlatform::flashFilePath()
|
||||||
{
|
{
|
||||||
return _flashFilePath;
|
return _flashFilePath;
|
||||||
@ -521,13 +604,73 @@ void LinuxPlatform::cmdLineArgs(int argc, char** argv)
|
|||||||
#define MAX_STRBUF_SIZE 100
|
#define MAX_STRBUF_SIZE 100
|
||||||
#define MAX_NUM_GPIO 64
|
#define MAX_NUM_GPIO 64
|
||||||
|
|
||||||
static int gpioFds [MAX_NUM_GPIO] =
|
static int gpioFds[MAX_NUM_GPIO] =
|
||||||
{
|
{
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1,
|
||||||
} ;
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
};
|
||||||
|
|
||||||
/* Activate GPIO-Pin
|
/* Activate GPIO-Pin
|
||||||
* Write GPIO pin number to /sys/class/gpio/export
|
* Write GPIO pin number to /sys/class/gpio/export
|
||||||
@ -535,10 +678,10 @@ static int gpioFds [MAX_NUM_GPIO] =
|
|||||||
*/
|
*/
|
||||||
int gpio_export(int pin)
|
int gpio_export(int pin)
|
||||||
{
|
{
|
||||||
char buffer[MAX_STRBUF_SIZE]; /* Output Buffer */
|
char buffer[MAX_STRBUF_SIZE]; /* Output Buffer */
|
||||||
ssize_t bytes; /* Used Buffer length */
|
ssize_t bytes; /* Used Buffer length */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
int res; /* Result from write() */
|
int res; /* Result from write() */
|
||||||
|
|
||||||
fprintf(stderr, "Export GPIO pin %d\n", pin);
|
fprintf(stderr, "Export GPIO pin %d\n", pin);
|
||||||
|
|
||||||
@ -546,7 +689,7 @@ int gpio_export(int pin)
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
perror("Could not export GPIO pin(open)!\n");
|
perror("Could not export GPIO pin(open)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = snprintf(buffer, MAX_STRBUF_SIZE, "%d", pin);
|
bytes = snprintf(buffer, MAX_STRBUF_SIZE, "%d", pin);
|
||||||
@ -555,13 +698,13 @@ int gpio_export(int pin)
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
perror("Could not export GPIO pin(write)!\n");
|
perror("Could not export GPIO pin(write)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deactivate GPIO pin
|
/* Deactivate GPIO pin
|
||||||
@ -570,10 +713,10 @@ int gpio_export(int pin)
|
|||||||
*/
|
*/
|
||||||
int gpio_unexport(int pin)
|
int gpio_unexport(int pin)
|
||||||
{
|
{
|
||||||
char buffer[MAX_STRBUF_SIZE]; /* Output Buffer */
|
char buffer[MAX_STRBUF_SIZE]; /* Output Buffer */
|
||||||
ssize_t bytes; /* Used Buffer length */
|
ssize_t bytes; /* Used Buffer length */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
int res; /* Result from write() */
|
int res; /* Result from write() */
|
||||||
|
|
||||||
fprintf(stderr, "Unexport GPIO pin %d\n", pin);
|
fprintf(stderr, "Unexport GPIO pin %d\n", pin);
|
||||||
|
|
||||||
@ -583,7 +726,7 @@ int gpio_unexport(int pin)
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
perror("Could not unexport GPIO pin(open)!\n");
|
perror("Could not unexport GPIO pin(open)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = snprintf(buffer, MAX_STRBUF_SIZE, "%d", pin);
|
bytes = snprintf(buffer, MAX_STRBUF_SIZE, "%d", pin);
|
||||||
@ -592,11 +735,11 @@ int gpio_unexport(int pin)
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
perror("Could not unexport GPIO pin(write)!\n");
|
perror("Could not unexport GPIO pin(write)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set GPIO pin mode (input/output)
|
/* Set GPIO pin mode (input/output)
|
||||||
@ -606,35 +749,41 @@ int gpio_unexport(int pin)
|
|||||||
*/
|
*/
|
||||||
int gpio_direction(int pin, int dir)
|
int gpio_direction(int pin, int dir)
|
||||||
{
|
{
|
||||||
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
int res; /* Result from write() */
|
int res; /* Result from write() */
|
||||||
|
|
||||||
fprintf(stderr, "Set GPIO direction for pin %d to %s\n", pin, (dir==INPUT) ? "INPUT":"OUTPUT");
|
fprintf(stderr, "Set GPIO direction for pin %d to %s\n", pin, (dir == INPUT) ? "INPUT" : "OUTPUT");
|
||||||
|
|
||||||
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/direction", pin);
|
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/direction", pin);
|
||||||
fd = open(path, O_WRONLY);
|
fd = open(path, O_WRONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
perror("Could not set mode for GPIO pin(open)!\n");
|
perror("Could not set mode for GPIO pin(open)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (dir)
|
switch (dir)
|
||||||
{
|
{
|
||||||
case INPUT : res = write(fd,"in",2); break;
|
case INPUT:
|
||||||
case OUTPUT: res = write(fd,"out",3); break;
|
res = write(fd, "in", 2);
|
||||||
default: res = -1; break;
|
break;
|
||||||
|
case OUTPUT:
|
||||||
|
res = write(fd, "out", 3);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
perror("Could not set mode for GPIO pin(write)!\n");
|
perror("Could not set mode for GPIO pin(write)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read from GPIO pin
|
/* Read from GPIO pin
|
||||||
@ -642,7 +791,7 @@ int gpio_direction(int pin, int dir)
|
|||||||
*/
|
*/
|
||||||
int gpio_read(int pin)
|
int gpio_read(int pin)
|
||||||
{
|
{
|
||||||
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
|
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
|
||||||
@ -651,14 +800,14 @@ int gpio_read(int pin)
|
|||||||
if (gpioFds[pin] < 0)
|
if (gpioFds[pin] < 0)
|
||||||
{
|
{
|
||||||
perror("Could not read from GPIO(open)!\n");
|
perror("Could not read from GPIO(open)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
lseek(gpioFds [pin], 0L, SEEK_SET) ;
|
lseek(gpioFds[pin], 0L, SEEK_SET);
|
||||||
if (read(gpioFds[pin], &c, 1) < 0)
|
if (read(gpioFds[pin], &c, 1) < 0)
|
||||||
{
|
{
|
||||||
perror("Could not read from GPIO(read)!\n");
|
perror("Could not read from GPIO(read)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (c == '0') ? LOW : HIGH;
|
return (c == '0') ? LOW : HIGH;
|
||||||
@ -669,8 +818,8 @@ int gpio_read(int pin)
|
|||||||
*/
|
*/
|
||||||
int gpio_write(int pin, int value)
|
int gpio_write(int pin, int value)
|
||||||
{
|
{
|
||||||
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int res; /* Result from write()*/
|
int res; /* Result from write()*/
|
||||||
|
|
||||||
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
|
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
|
||||||
if (gpioFds[pin] < 0)
|
if (gpioFds[pin] < 0)
|
||||||
@ -679,23 +828,29 @@ int gpio_write(int pin, int value)
|
|||||||
if (gpioFds[pin] < 0)
|
if (gpioFds[pin] < 0)
|
||||||
{
|
{
|
||||||
perror("Could not write to GPIO(open)!\n");
|
perror("Could not write to GPIO(open)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (value)
|
switch (value)
|
||||||
{
|
{
|
||||||
case LOW : res = write(gpioFds[pin], "0\n", 2); break;
|
case LOW:
|
||||||
case HIGH: res = write(gpioFds[pin], "1\n", 2); break;
|
res = write(gpioFds[pin], "0\n", 2);
|
||||||
default: res = -1; break;
|
break;
|
||||||
|
case HIGH:
|
||||||
|
res = write(gpioFds[pin], "1\n", 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
perror("Could not write to GPIO(write)!\n");
|
perror("Could not write to GPIO(write)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set GPIO pin edge detection
|
/* Set GPIO pin edge detection
|
||||||
@ -705,25 +860,35 @@ int gpio_write(int pin, int value)
|
|||||||
*/
|
*/
|
||||||
int gpio_edge(unsigned int pin, char edge)
|
int gpio_edge(unsigned int pin, char edge)
|
||||||
{
|
{
|
||||||
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
|
|
||||||
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/edge", pin);
|
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/edge", pin);
|
||||||
|
|
||||||
fd = open(path, O_WRONLY | O_NONBLOCK );
|
fd = open(path, O_WRONLY | O_NONBLOCK);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
perror("Could not set GPIO edge detection(open)!\n");
|
perror("Could not set GPIO edge detection(open)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (edge)
|
switch (edge)
|
||||||
{
|
{
|
||||||
case 'r': strncpy(path,"rising",8); break;
|
case 'r':
|
||||||
case 'f': strncpy(path,"falling",8); break;
|
strncpy(path, "rising", 8);
|
||||||
case 'b': strncpy(path,"both",8); break;
|
break;
|
||||||
case 'n': strncpy(path,"none",8); break;
|
case 'f':
|
||||||
default: close(fd);return(-2);
|
strncpy(path, "falling", 8);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
strncpy(path, "both", 8);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
strncpy(path, "none", 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
close(fd);
|
||||||
|
return (-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
write(fd, path, strlen(path) + 1);
|
write(fd, path, strlen(path) + 1);
|
||||||
@ -740,19 +905,19 @@ int gpio_edge(unsigned int pin, char edge)
|
|||||||
*/
|
*/
|
||||||
int gpio_wait(unsigned int pin, int timeout)
|
int gpio_wait(unsigned int pin, int timeout)
|
||||||
{
|
{
|
||||||
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
struct pollfd polldat[1]; /* Variable for poll() */
|
struct pollfd polldat[1]; /* Variable for poll() */
|
||||||
char buf[MAX_STRBUF_SIZE]; /* Read buffer */
|
char buf[MAX_STRBUF_SIZE]; /* Read buffer */
|
||||||
int rc; /* Result */
|
int rc; /* Result */
|
||||||
|
|
||||||
/* Open GPIO pin */
|
/* Open GPIO pin */
|
||||||
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
|
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
|
||||||
fd = open(path, O_RDONLY | O_NONBLOCK );
|
fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
perror("Could not wait for GPIO edge(open)!\n");
|
perror("Could not wait for GPIO edge(open)!\n");
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare poll() */
|
/* prepare poll() */
|
||||||
@ -770,13 +935,13 @@ int gpio_wait(unsigned int pin, int timeout)
|
|||||||
{ /* poll() failed! */
|
{ /* poll() failed! */
|
||||||
perror("Could not wait for GPIO edge(poll)!\n");
|
perror("Could not wait for GPIO edge(poll)!\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
{ /* poll() timeout! */
|
{ /* poll() timeout! */
|
||||||
close(fd);
|
close(fd);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (polldat[0].revents & POLLPRI)
|
if (polldat[0].revents & POLLPRI)
|
||||||
@ -785,46 +950,159 @@ int gpio_wait(unsigned int pin, int timeout)
|
|||||||
{ /* read() failed! */
|
{ /* read() failed! */
|
||||||
perror("Could not wait for GPIO edge(read)!\n");
|
perror("Could not wait for GPIO edge(read)!\n");
|
||||||
close(fd);
|
close(fd);
|
||||||
return(-2);
|
return (-2);
|
||||||
}
|
}
|
||||||
/* printf("poll() GPIO %d interrupt occurred: %s\n", pin, buf); */
|
/* printf("poll() GPIO %d interrupt occurred: %s\n", pin, buf); */
|
||||||
close(fd);
|
close(fd);
|
||||||
return(1 + atoi(buf));
|
return (1 + atoi(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return(-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delayMicrosecondsHard (unsigned int howLong)
|
void delayMicrosecondsHard(unsigned int howLong)
|
||||||
{
|
{
|
||||||
struct timeval tNow, tLong, tEnd ;
|
struct timeval tNow, tLong, tEnd;
|
||||||
|
|
||||||
gettimeofday (&tNow, NULL) ;
|
gettimeofday(&tNow, NULL);
|
||||||
tLong.tv_sec = howLong / 1000000 ;
|
tLong.tv_sec = howLong / 1000000;
|
||||||
tLong.tv_usec = howLong % 1000000 ;
|
tLong.tv_usec = howLong % 1000000;
|
||||||
timeradd (&tNow, &tLong, &tEnd) ;
|
timeradd(&tNow, &tLong, &tEnd);
|
||||||
|
|
||||||
while (timercmp (&tNow, &tEnd, <))
|
while (timercmp(&tNow, &tEnd, <))
|
||||||
gettimeofday (&tNow, NULL) ;
|
gettimeofday(&tNow, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delayMicroseconds (unsigned int howLong)
|
void delayMicroseconds(unsigned int howLong)
|
||||||
{
|
{
|
||||||
struct timespec sleeper ;
|
struct timespec sleeper;
|
||||||
unsigned int uSecs = howLong % 1000000 ;
|
unsigned int uSecs = howLong % 1000000;
|
||||||
unsigned int wSecs = howLong / 1000000 ;
|
unsigned int wSecs = howLong / 1000000;
|
||||||
|
|
||||||
/**/ if (howLong == 0)
|
/**/ if (howLong == 0)
|
||||||
return ;
|
return;
|
||||||
else if (howLong < 100)
|
else if (howLong < 100)
|
||||||
delayMicrosecondsHard (howLong) ;
|
delayMicrosecondsHard(howLong);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sleeper.tv_sec = wSecs ;
|
sleeper.tv_sec = wSecs;
|
||||||
sleeper.tv_nsec = (long)(uSecs * 1000L) ;
|
sleeper.tv_nsec = (long)(uSecs * 1000L);
|
||||||
nanosleep (&sleeper, NULL) ;
|
nanosleep(&sleeper, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void LinuxPlatform::setupUniCast(uint32_t addr, uint16_t port, uint8_t type)
|
||||||
|
{
|
||||||
|
if (_unicastSocketFd >= 0)
|
||||||
|
closeUniCast();
|
||||||
|
|
||||||
|
_unicastAddr = addr;
|
||||||
|
_unicastPort = port;
|
||||||
|
_unicastType = type;
|
||||||
|
|
||||||
|
uint32_t loop = 1;
|
||||||
|
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
memset(&sin, 0, sizeof(sin));
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
sin.sin_port = htons(port);
|
||||||
|
|
||||||
|
int socketType = 0;
|
||||||
|
if (type == IPV4_UDP)
|
||||||
|
socketType = SOCK_DGRAM;
|
||||||
|
else
|
||||||
|
socketType = SOCK_STREAM;
|
||||||
|
|
||||||
|
_unicastSocketFd = socket(AF_INET, socketType, 0);
|
||||||
|
if (_unicastSocketFd == -1)
|
||||||
|
{
|
||||||
|
perror("socket()");
|
||||||
|
fatalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mehr Prozessen erlauben, denselben Port zu nutzen */
|
||||||
|
loop = 1;
|
||||||
|
if (setsockopt(_unicastSocketFd, SOL_SOCKET, SO_REUSEADDR, &loop, sizeof(loop)) < 0)
|
||||||
|
{
|
||||||
|
perror("setsockopt:SO_REUSEADDR");
|
||||||
|
fatalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(_unicastSocketFd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
|
||||||
|
{
|
||||||
|
perror("bind");
|
||||||
|
fatalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t flags = fcntl(_unicastSocketFd, F_GETFL);
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
fcntl(_unicastSocketFd, F_SETFL, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxPlatform::closeUniCast()
|
||||||
|
{
|
||||||
|
close(_unicastSocketFd);
|
||||||
|
_unicastSocketFd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinuxPlatform::sendBytesUniCast(uint8_t* buffer, uint16_t len)
|
||||||
|
{
|
||||||
|
struct sockaddr_in address = {0};
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
address.sin_addr.s_addr = htonl(_unicastAddr);
|
||||||
|
address.sin_port = htons(_unicastPort);
|
||||||
|
|
||||||
|
ssize_t retVal = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
retVal = sendto(_unicastSocketFd, buffer, len, 0, (struct sockaddr*)&address, sizeof(address));
|
||||||
|
if (retVal == -1)
|
||||||
|
{
|
||||||
|
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} while (retVal == -1);
|
||||||
|
// printHex("<-", buffer, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LinuxPlatform::readBytesUniCast(uint8_t* buffer,
|
||||||
|
uint16_t maxLen)
|
||||||
|
{
|
||||||
|
uint32_t sin_len;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
|
||||||
|
sin_len = sizeof(sin);
|
||||||
|
ssize_t len = recvfrom(_unicastSocketFd, buffer, maxLen, 0, (struct sockaddr*)&sin, &sin_len);
|
||||||
|
// if (len > 0)
|
||||||
|
// printHex("->", buffer, len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinuxPlatform::macAddress(uint8_t* mac_address)
|
||||||
|
{
|
||||||
|
memcpy(mac_address, _macAddress, IFHWADDRLEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t LinuxPlatform::currentIpAddress()
|
||||||
|
{
|
||||||
|
return _ipAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t LinuxPlatform::currentSubnetMask()
|
||||||
|
{
|
||||||
|
return _netmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t LinuxPlatform::currentDefaultGateway()
|
||||||
|
{
|
||||||
|
return _defaultGateway;
|
||||||
|
}
|
||||||
|
@ -26,12 +26,24 @@ public:
|
|||||||
void restart() override;
|
void restart() override;
|
||||||
void fatalError() override;
|
void fatalError() override;
|
||||||
|
|
||||||
|
// ip config
|
||||||
|
uint32_t currentIpAddress() override;
|
||||||
|
uint32_t currentSubnetMask() override;
|
||||||
|
uint32_t currentDefaultGateway() override;
|
||||||
|
void macAddress(uint8_t* data) override;
|
||||||
|
|
||||||
|
|
||||||
//multicast
|
//multicast
|
||||||
void setupMultiCast(uint32_t addr, uint16_t port) override;
|
void setupMultiCast(uint32_t addr, uint16_t port) override;
|
||||||
void closeMultiCast() override;
|
void closeMultiCast() override;
|
||||||
bool sendBytesMultiCast(uint8_t* buffer, uint16_t len) override;
|
bool sendBytesMultiCast(uint8_t* buffer, uint16_t len) override;
|
||||||
int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) override;
|
int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) override;
|
||||||
|
|
||||||
|
void setupUniCast(uint32_t addr, uint16_t port, uint8_t type);
|
||||||
|
void closeUniCast();
|
||||||
|
bool sendBytesUniCast(uint8_t* buffer, uint16_t len);
|
||||||
|
int readBytesUniCast(uint8_t* buffer, uint16_t maxLen);
|
||||||
|
|
||||||
//spi
|
//spi
|
||||||
void setupSpi() override;
|
void setupSpi() override;
|
||||||
void closeSpi() override;
|
void closeSpi() override;
|
||||||
@ -44,15 +56,25 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t _multicastAddr = -1;
|
uint32_t _multicastAddr = -1;
|
||||||
uint16_t _port = -1;
|
uint16_t _multicastPort = -1;
|
||||||
int _socketFd = -1;
|
int _multicastSocketFd = -1;
|
||||||
|
|
||||||
|
uint32_t _unicastAddr = -1;
|
||||||
|
uint16_t _unicastPort = -1;
|
||||||
|
int _unicastSocketFd = -1;
|
||||||
|
uint8_t _unicastType = -1;
|
||||||
|
|
||||||
void doMemoryMapping();
|
void doMemoryMapping();
|
||||||
uint8_t* _mappedFile = 0;
|
uint8_t* _mappedFile = 0;
|
||||||
int _fd = -1;
|
int _fd = -1;
|
||||||
int _spiFd = -1;
|
int _spiFd = -1;
|
||||||
uint8_t* _currentMaxMem = 0;
|
|
||||||
std::string _flashFilePath = "flash.bin";
|
std::string _flashFilePath = "flash.bin";
|
||||||
char** _args = 0;
|
char** _args = 0;
|
||||||
|
|
||||||
|
uint8_t _macAddress[6] = {0, 0, 0, 0, 0, 0};
|
||||||
|
uint32_t _ipAddress = 0;
|
||||||
|
uint32_t _netmask = 0;
|
||||||
|
uint32_t _defaultGateway = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user