mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-22 15:46:14 +01:00
Automatic MAC Address handling for Ethernet/WiFi
This commit is contained in:
parent
dda7bc7277
commit
8fa6ded079
121
ArduinoUniqueID.cpp
Normal file
121
ArduinoUniqueID.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* © 2020 Gregor Baues, Luiz Henrique Cassettari. All rights reserved.
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* See the GNU General Public License for more details <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#include "ArduinoUniqueID.h"
|
||||
|
||||
ArduinoUniqueID::ArduinoUniqueID()
|
||||
{
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
for (size_t i = 0; i < UniqueIDsize; i++)
|
||||
{
|
||||
id[i] = boot_signature_byte_get(0x0E + i + (UniqueIDsize == 9 && i > 5 ? 1 : 0));
|
||||
}
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
uint32_t chipid = ESP.getChipId();
|
||||
id[0] = 0;
|
||||
id[1] = 0;
|
||||
id[2] = 0;
|
||||
id[3] = 0;
|
||||
id[4] = chipid >> 24;
|
||||
id[5] = chipid >> 16;
|
||||
id[6] = chipid >> 8;
|
||||
id[7] = chipid;
|
||||
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
uint64_t chipid = ESP.getEfuseMac();
|
||||
id[0] = 0;
|
||||
id[1] = 0;
|
||||
id[2] = chipid;
|
||||
id[3] = chipid >> 8;
|
||||
id[4] = chipid >> 16;
|
||||
id[5] = chipid >> 24;
|
||||
id[6] = chipid >> 32;
|
||||
id[7] = chipid >> 40;
|
||||
|
||||
#elif defined(ARDUINO_ARCH_SAM)
|
||||
unsigned int status ;
|
||||
/* Send the Start Read unique Identifier command (STUI) by writing the Flash Command Register with the STUI command.*/
|
||||
EFC1->EEFC_FCR = (0x5A << 24) | EFC_FCMD_STUI;
|
||||
do
|
||||
{
|
||||
status = EFC1->EEFC_FSR ;
|
||||
} while ( (status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY ) ;
|
||||
|
||||
/* The Unique Identifier is located in the first 128 bits of the Flash memory mapping. So, at the address 0x400000-0x400003. */
|
||||
uint32_t pdwUniqueID[4];
|
||||
pdwUniqueID[0] = *(uint32_t *)IFLASH1_ADDR;
|
||||
pdwUniqueID[1] = *(uint32_t *)(IFLASH1_ADDR + 4);
|
||||
pdwUniqueID[2] = *(uint32_t *)(IFLASH1_ADDR + 8);
|
||||
pdwUniqueID[3] = *(uint32_t *)(IFLASH1_ADDR + 12);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
id[i*4+0] = (uint8_t)(pdwUniqueID[i] >> 24);
|
||||
id[i*4+1] = (uint8_t)(pdwUniqueID[i] >> 16);
|
||||
id[i*4+2] = (uint8_t)(pdwUniqueID[i] >> 8);
|
||||
id[i*4+3] = (uint8_t)(pdwUniqueID[i] >> 0);
|
||||
}
|
||||
|
||||
/* To stop the Unique Identifier mode, the user needs to send the Stop Read unique Identifier
|
||||
command (SPUI) by writing the Flash Command Register with the SPUI command. */
|
||||
EFC1->EEFC_FCR = (0x5A << 24) | EFC_FCMD_SPUI ;
|
||||
|
||||
/* When the Stop read Unique Unique Identifier command (SPUI) has been performed, the
|
||||
FRDY bit in the Flash Programming Status Register (EEFC_FSR) rises. */
|
||||
do
|
||||
{
|
||||
status = EFC1->EEFC_FSR ;
|
||||
} while ( (status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY );
|
||||
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
|
||||
// from section 9.3.3 of the datasheet
|
||||
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x0080A00C)
|
||||
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x0080A040)
|
||||
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x0080A044)
|
||||
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x0080A048)
|
||||
|
||||
uint32_t pdwUniqueID[4];
|
||||
pdwUniqueID[0] = SERIAL_NUMBER_WORD_0;
|
||||
pdwUniqueID[1] = SERIAL_NUMBER_WORD_1;
|
||||
pdwUniqueID[2] = SERIAL_NUMBER_WORD_2;
|
||||
pdwUniqueID[3] = SERIAL_NUMBER_WORD_3;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
id[i*4+0] = (uint8_t)(pdwUniqueID[i] >> 24);
|
||||
id[i*4+1] = (uint8_t)(pdwUniqueID[i] >> 16);
|
||||
id[i*4+2] = (uint8_t)(pdwUniqueID[i] >> 8);
|
||||
id[i*4+3] = (uint8_t)(pdwUniqueID[i] >> 0);
|
||||
}
|
||||
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
uint32_t pdwUniqueID[3];
|
||||
pdwUniqueID[0] = HAL_GetUIDw0();
|
||||
pdwUniqueID[1] = HAL_GetUIDw1();
|
||||
pdwUniqueID[2] = HAL_GetUIDw2();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
id[i*4+0] = (uint8_t)(pdwUniqueID[i] >> 24);
|
||||
id[i*4+1] = (uint8_t)(pdwUniqueID[i] >> 16);
|
||||
id[i*4+2] = (uint8_t)(pdwUniqueID[i] >> 8);
|
||||
id[i*4+3] = (uint8_t)(pdwUniqueID[i] >> 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ArduinoUniqueID _UniqueID;
|
104
ArduinoUniqueID.h
Normal file
104
ArduinoUniqueID.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* © 2020 Gregor Baues, Luiz Henrique Cassettari. All rights reserved.
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* See the GNU General Public License for more details <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef _ARDUINO_UNIQUE_ID_H_
|
||||
#define _ARDUINO_UNIQUE_ID_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
#include <avr/boot.h>
|
||||
#ifndef SIGRD
|
||||
#define SIGRD 5
|
||||
#endif
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
#elif defined(ARDUINO_ARCH_SAM)
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
#else
|
||||
#error "ArduinoUniqueID only works on AVR, SAM, SAMD, STM32 and ESP Architecture"
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
|
||||
#if defined(__AVR_ATmega328PB__)
|
||||
#define UniqueIDsize 10
|
||||
#else
|
||||
#define UniqueIDsize 9
|
||||
#endif
|
||||
|
||||
#define UniqueIDbuffer UniqueIDsize
|
||||
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
#define UniqueIDsize 4
|
||||
#define UniqueIDbuffer 8
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
#define UniqueIDsize 6
|
||||
#define UniqueIDbuffer 8
|
||||
#elif defined(ARDUINO_ARCH_SAM)
|
||||
#define UniqueIDsize 16
|
||||
#define UniqueIDbuffer 16
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#define UniqueIDsize 16
|
||||
#define UniqueIDbuffer 16
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
#define UniqueIDsize 12
|
||||
#define UniqueIDbuffer 12
|
||||
#endif
|
||||
|
||||
#define UniqueID8 (_UniqueID.id + UniqueIDbuffer - 8)
|
||||
#define UniqueID (_UniqueID.id + UniqueIDbuffer - UniqueIDsize)
|
||||
|
||||
#define UniqueIDdump(stream) \
|
||||
{ \
|
||||
stream.print("UniqueID: "); \
|
||||
for (size_t i = 0; i < UniqueIDsize; i++) \
|
||||
{ \
|
||||
if (UniqueID[i] < 0x10) \
|
||||
stream.print("0"); \
|
||||
stream.print(UniqueID[i], HEX); \
|
||||
stream.print(" "); \
|
||||
} \
|
||||
stream.println(); \
|
||||
}
|
||||
|
||||
#define UniqueID8dump(stream) \
|
||||
{ \
|
||||
stream.print("UniqueID: "); \
|
||||
for (size_t i = 0; i < 8; i++) \
|
||||
{ \
|
||||
if (UniqueID8[i] < 0x10) \
|
||||
stream.print("0"); \
|
||||
stream.print(UniqueID8[i], HEX); \
|
||||
stream.print(" "); \
|
||||
} \
|
||||
stream.println(); \
|
||||
}
|
||||
|
||||
class ArduinoUniqueID
|
||||
{
|
||||
public:
|
||||
ArduinoUniqueID();
|
||||
uint8_t id[UniqueIDbuffer];
|
||||
};
|
||||
|
||||
extern ArduinoUniqueID _UniqueID;
|
||||
|
||||
#endif
|
|
@ -86,7 +86,7 @@ void setup()
|
|||
// nwi1.setup(ETHERNET, TCP); // ETHERNET/TCP on Port 2560
|
||||
nwi2.setup(ETHERNET, TCP, 23); // ETHERNET/TCP on Port 23 for the CLI
|
||||
// nwi1.setup(ETHERNET, TCP, 8888); // ETHERNET/TCP on Port 8888
|
||||
// nwi2.setup(WIFI, TCP); // WIFI/TCP on Port 2560
|
||||
nwi2.setup(WIFI, TCP); // WIFI/TCP on Port 2560
|
||||
// nwi1.setHttpCallback(httpRequestHandler); // HTTP callback
|
||||
|
||||
DIAG(F("\nNetwork Setup done ...\n"));
|
||||
|
|
|
@ -20,10 +20,13 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
#include "NetworkDiag.h"
|
||||
#include "NetworkSetup.h"
|
||||
#include "EthernetSetup.h"
|
||||
|
||||
byte EthernetSetup::setup()
|
||||
{
|
||||
INFO(F("Initialize MAC Address ..."));
|
||||
NetworkSetup::genMacAddress();
|
||||
|
||||
INFO(F("Initialize Ethernet with DHCP"));
|
||||
if (Ethernet.begin(mac) == 0)
|
||||
|
@ -61,7 +64,7 @@ byte EthernetSetup::setup()
|
|||
maxConnections = 8;
|
||||
}
|
||||
|
||||
INFO(F("Network Protocol: [%s]"), protocol ? "UDP" : "TCP");
|
||||
INFO(F("Network Protocol: [%s]"), protocol ? "UDP" : "TCP");
|
||||
switch (protocol)
|
||||
{
|
||||
case UDPR:
|
||||
|
@ -102,8 +105,9 @@ byte EthernetSetup::setup()
|
|||
if (connected)
|
||||
{
|
||||
ip = Ethernet.localIP();
|
||||
INFO(F("Local IP address: [%d.%d.%d.%d]"), ip[0], ip[1], ip[2], ip[3]);
|
||||
INFO(F("Listening on port: [%d]"), port);
|
||||
NetworkSetup::printMacAddress(NetworkSetup::mac);
|
||||
INFO(F("Local IP address: [%d.%d.%d.%d]"), ip[0], ip[1], ip[2], ip[3]);
|
||||
INFO(F("Listening on port: [%d]"), port);
|
||||
dnsip = Ethernet.dnsServerIP();
|
||||
INFO(F("DNS server IP address: [%d.%d.%d.%d] "), dnsip[0], dnsip[1], dnsip[2], dnsip[3]);
|
||||
INFO(F("Number of connections: [%d]"), maxConnections);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
#include "NetworkDiag.h"
|
||||
#include "NetworkSetup.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "Transport.h"
|
||||
#include "EthernetSetup.h"
|
||||
|
@ -76,6 +77,8 @@ void NetworkInterface::setup(transportType transport, protocolType protocol, uin
|
|||
bool ok = false;
|
||||
_nLogLevel = 4; // set the log level to ERROR during setup to get proper information
|
||||
|
||||
NetworkSetup::setDeviceId();
|
||||
|
||||
INFO(F("[%s] Transport Setup In Progress ..."), transport ? "Ethernet" : "Wifi");
|
||||
|
||||
// configure the Transport and get Ethernet/Wifi server up and running
|
||||
|
@ -130,7 +133,7 @@ void NetworkInterface::setup(transportType transport, protocolType protocol, uin
|
|||
}
|
||||
|
||||
INFO(F("[%s] Transport %s ..."), transport ? "Ethernet" : "Wifi", ok ? "OK" : "Failed");
|
||||
_nLogLevel = 0; // set loging back to silent;
|
||||
// _nLogLevel = 0; // set loging back to silent;
|
||||
}
|
||||
|
||||
void NetworkInterface::setup(transportType tt, protocolType pt)
|
||||
|
|
|
@ -18,7 +18,59 @@
|
|||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "ArduinoUniqueID.h"
|
||||
#include "NetworkSetup.h"
|
||||
#include "NetworkDiag.h"
|
||||
|
||||
bool NetworkSetup::deviceIdSet = false;
|
||||
bool NetworkSetup::macAddressSet = false;
|
||||
char NetworkSetup::_deviceId[MAXDEVICEID] = {0};
|
||||
uint8_t NetworkSetup::mac[6] = MAC_ADDRESS; // default MacAddress
|
||||
uint8_t NetworkSetup::apWifiMacAddress[6] = MAC_ADDRESS; // default MacAddress
|
||||
uint8_t NetworkSetup::stWifiMacAddress[6] = MAC_ADDRESS; // default MacAddress
|
||||
|
||||
static void array_to_string(byte array[], unsigned int len, char buffer[])
|
||||
{
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
byte nib1 = (array[i] >> 4) & 0x0F;
|
||||
byte nib2 = (array[i] >> 0) & 0x0F;
|
||||
buffer[i * 2 + 0] = nib1 < 0xA ? '0' + nib1 : 'A' + nib1 - 0xA;
|
||||
buffer[i * 2 + 1] = nib2 < 0xA ? '0' + nib2 : 'A' + nib2 - 0xA;
|
||||
}
|
||||
buffer[len * 2] = '\0';
|
||||
}
|
||||
|
||||
void NetworkSetup::setDeviceId()
|
||||
{
|
||||
array_to_string(UniqueID, UniqueIDsize, _deviceId);
|
||||
DBG(F("Unique device ID: %s\n"), _deviceId);
|
||||
deviceIdSet = true;
|
||||
}
|
||||
|
||||
void NetworkSetup::printMacAddress(uint8_t a[]) {
|
||||
INFO(F("MAC Address: [%x:%x:%x:%x:%x:%x]"),a[0],a[1],a[2],a[3],a[4],a[5]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief generates Mac Addresses for Ethernet and WiFi
|
||||
*
|
||||
*/
|
||||
void NetworkSetup::genMacAddress() {
|
||||
|
||||
if (!deviceIdSet) NetworkSetup::setDeviceId();
|
||||
if (!macAddressSet) {
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
mac[i] = UniqueID[i];
|
||||
};
|
||||
}
|
||||
macAddressSet = true;
|
||||
}
|
||||
|
||||
NetworkSetup::NetworkSetup() {}
|
||||
NetworkSetup::~NetworkSetup() {}
|
||||
NetworkSetup::~NetworkSetup() {}
|
||||
|
||||
|
||||
// WiFi.apMacAddress(apWifiMacAddress);
|
||||
// WiFi.macAddress(stWifiMacAddress);
|
|
@ -25,18 +25,36 @@
|
|||
#include "NetworkConfig.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
#define MAXDEVICEID 20
|
||||
|
||||
class NetworkSetup
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
static char _deviceId[MAXDEVICEID];
|
||||
static bool macAddressSet;
|
||||
static bool deviceIdSet;
|
||||
|
||||
public:
|
||||
IPAddress dnsip;
|
||||
IPAddress ip;
|
||||
uint8_t mac[6] = MAC_ADDRESS;
|
||||
static uint8_t mac[6]; // Default if not set automatically for EthernetShield
|
||||
static uint8_t apWifiMacAddress[6]; // for the WiFi AP
|
||||
static uint8_t stWifiMacAddress[6]; // for the normal WiFi connection
|
||||
|
||||
uint8_t maxConnections;
|
||||
bool connected; // semantics is that the server has successfullt started or not; client connections will be started in the Transport object
|
||||
protocolType protocol;
|
||||
uint16_t port = LISTEN_PORT; // Default port
|
||||
|
||||
static void setDeviceId();
|
||||
char *getDeviceId() {
|
||||
return _deviceId;
|
||||
}
|
||||
static void genMacAddress();
|
||||
static void printMacAddress(uint8_t a[]);
|
||||
|
||||
NetworkSetup();
|
||||
~NetworkSetup();
|
||||
};
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "NetworkSetup.h"
|
||||
#include "WifiSetup.h"
|
||||
|
||||
void reverseArray(uint8_t arr[], int start, int end);
|
||||
|
||||
bool WifiSetup::setup() {
|
||||
/**
|
||||
* @todo setup using SoftwareSerial or any other Hardware Serial port on the mega (i.e. 2 or 3);
|
||||
|
@ -47,6 +49,11 @@ bool WifiSetup::setup() {
|
|||
}
|
||||
|
||||
INFO(F("Network Protocol: [%s]"), protocol ? "UDP" : "TCP");
|
||||
INFO(F("Initialize MAC Addresses ... "));
|
||||
WiFi.apMacAddress(apWifiMacAddress);
|
||||
reverseArray(apWifiMacAddress, 0, 5); // the MAc is provided in reverse order ...
|
||||
WiFi.macAddress(stWifiMacAddress);
|
||||
reverseArray(stWifiMacAddress, 0, 5);
|
||||
|
||||
// Setup the protocol handler
|
||||
switch (protocol)
|
||||
|
@ -96,6 +103,9 @@ bool WifiSetup::setup() {
|
|||
if (connected)
|
||||
{
|
||||
ip = WiFi.localIP();
|
||||
NetworkSetup::printMacAddress(apWifiMacAddress);
|
||||
NetworkSetup::printMacAddress(stWifiMacAddress);
|
||||
|
||||
INFO(F("Local IP address: [%d.%d.%d.%d]"), ip[0], ip[1], ip[2], ip[3]);
|
||||
INFO(F("Listening on port: [%d]"), port);
|
||||
dnsip = WiFi.dnsServer1();
|
||||
|
@ -107,6 +117,18 @@ bool WifiSetup::setup() {
|
|||
|
||||
};
|
||||
|
||||
void reverseArray(uint8_t arr[], int start, int end)
|
||||
{
|
||||
while (start < end)
|
||||
{
|
||||
uint8_t temp = arr[start];
|
||||
arr[start] = arr[end];
|
||||
arr[end] = temp;
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
}
|
||||
|
||||
WifiSetup::WifiSetup() {}
|
||||
WifiSetup::WifiSetup(uint16_t p, protocolType pt ) { port = p; protocol = pt; }
|
||||
WifiSetup::~WifiSetup() {}
|
Loading…
Reference in New Issue
Block a user