diff --git a/api/MacAddress.cpp b/api/MacAddress.cpp new file mode 100644 index 00000000..16fc3625 --- /dev/null +++ b/api/MacAddress.cpp @@ -0,0 +1,146 @@ +#include <MacAddress.h> +#include <stdio.h> +#include <Print.h> + +//Default constructor, blank mac address. +MacAddress::MacAddress() { + _mac.val = 0; +} + +MacAddress::MacAddress(uint64_t mac) { + _mac.val = mac; +} + +MacAddress::MacAddress(const uint8_t *macbytearray) { + memcpy(_mac.bytes, macbytearray, sizeof(_mac.bytes)); +} + +MacAddress::MacAddress(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6) { + _mac.bytes[0] = b1; + _mac.bytes[1] = b2; + _mac.bytes[2] = b3; + _mac.bytes[3] = b4; + _mac.bytes[4] = b5; + _mac.bytes[5] = b6; +} + +//Parse user entered string into MAC address +bool MacAddress::fromCStr(const char *buf) { + char cs[18]; + char *token; + char *next; //Unused but required + int i; + + strncpy(cs, buf, sizeof(cs)); //strtok modifies the buffer: copy to working buffer. + + for(i=0; i<sizeof(_mac.bytes); i++) { + token = strtok((i==0) ? cs : NULL, ":"); //Find first or next token + if(!token) { //No more tokens found + return false; + } + _mac.bytes[i] = strtol(token, &next, 16); + } + return true; +} + +//Parse user entered string into MAC address +bool MacAddress::fromString(const String &macstr) { + return fromCStr(macstr.c_str()); +} + +//Copy MAC into 6 byte array +void MacAddress::toBytes(uint8_t *buf) { + memcpy(buf, _mac.bytes, sizeof(_mac.bytes)); +} + +//Print MAC address into a C string. +//MAC: Buffer must be at least 18 chars +int MacAddress::toCStr(char *buf) { + return sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", + _mac.bytes[0], _mac.bytes[1], _mac.bytes[2], + _mac.bytes[3], _mac.bytes[4], _mac.bytes[5]); +} + +String MacAddress::toString() const { + char buf[18]; + sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", + _mac.bytes[0], _mac.bytes[1], _mac.bytes[2], + _mac.bytes[3], _mac.bytes[4], _mac.bytes[5]); + return String(buf); +} + +uint64_t MacAddress::Value() { + return _mac.val; +} + +//Allow getting individual octets of the address. e.g. uint8_t b0 = ma[0]; +uint8_t MacAddress::operator[](int index) const { + index = EnforceIndexBounds(index); + return _mac.bytes[index]; +} + +//Allow setting individual octets of the address. e.g. ma[2] = 255; +uint8_t& MacAddress::operator[](int index) { + index = EnforceIndexBounds(index); + return _mac.bytes[index]; +} + +//Overloaded copy operator: init MacAddress object from byte array +MacAddress& MacAddress::operator=(const uint8_t *macbytearray) { + memcpy(_mac.bytes, macbytearray, sizeof(_mac.bytes)); + return *this; +} + +//Overloaded copy operator: init MacAddress object from uint64_t +MacAddress& MacAddress::operator=(uint64_t macval) { + _mac.val = macval; + return *this; +} + +//Compare class to byte array +bool MacAddress::operator==(const uint8_t *macbytearray) const { + return !memcmp(_mac.bytes, macbytearray, sizeof(_mac.bytes)); +} + +//Allow comparing value of two classes +bool MacAddress::operator==(const MacAddress& mac2) const { + return _mac.val == mac2._mac.val; +} + +//Type converter object to uint64_t [same as .Value()] +MacAddress::operator uint64_t() const { + return _mac.val; +} + +//Type converter object to read only pointer to mac bytes. e.g. const uint8_t *ip_8 = ma; +MacAddress::operator const uint8_t*() const { + return _mac.bytes; +} + +//Type converter object to read only pointer to mac value. e.g. const uint32_t *ip_64 = ma; +MacAddress::operator const uint64_t*() const { + return &_mac.val; +} + +size_t MacAddress::printTo(Print& p) const +{ + size_t n = 0; + for(int i = 0; i < 6; i++) { + if(i){ + n += p.print(':'); + } + n += p.printf("%02X", _mac.bytes[i]); + } + return n; +} + +//Bounds checking +int MacAddress::EnforceIndexBounds(int i) const { + if(i < 0) { + return 0; + } + if(i >= sizeof(_mac.bytes)) { + return sizeof(_mac.bytes)-1; + } + return i; +} diff --git a/api/MacAddress.h b/api/MacAddress.h new file mode 100644 index 00000000..1356ab70 --- /dev/null +++ b/api/MacAddress.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// MacAddress.h - class to make it easier to handle BSSID and MAC addresses. +// +// Copyright 2022 David McCurley +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//----------------------------------------------------------------------------- + +#ifndef MacAddress_h +#define MacAddress_h + +#include <stdint.h> +#include <WString.h> +#include <Printable.h> + +// A class to make it easier to handle and pass around 6-byte BSSID and MAC addresses. +class MacAddress : public Printable { +private: + union { + struct { + uint8_t align[2]; + uint8_t bytes[6]; + }; + uint64_t val; + } _mac; + +public: + MacAddress(); + MacAddress(uint64_t mac); + MacAddress(const uint8_t *macbytearray); + MacAddress(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6); + virtual ~MacAddress() {} + bool fromCStr(const char *buf); + bool fromString(const String &macstr); + void toBytes(uint8_t *buf); + int toCStr(char *buf); + String toString() const; + uint64_t Value(); + + uint8_t operator[](int index) const; + uint8_t& operator[](int index); + MacAddress& operator=(const uint8_t *macbytearray); + MacAddress& operator=(uint64_t macval); + bool operator==(const uint8_t *macbytearray) const; + bool operator==(const MacAddress& mac2) const; + operator uint64_t() const; + operator const uint8_t*() const; + operator const uint64_t*() const; + + virtual size_t printTo(Print& p) const; + + // future use in Arduino Networking + friend class EthernetClass; + friend class UDP; + friend class Client; + friend class Server; + friend class DhcpClass; + friend class DNSClient; + +private: + int EnforceIndexBounds(int i) const; +}; + +#endif diff --git a/api/MacAddress8.cpp b/api/MacAddress8.cpp new file mode 100644 index 00000000..7406bee8 --- /dev/null +++ b/api/MacAddress8.cpp @@ -0,0 +1,147 @@ +#include <MacAddress8.h> +#include <stdio.h> +#include <Print.h> + +//Default constructor, blank mac address. +MacAddress8::MacAddress8() { + _mac.val = 0; +} + +MacAddress8::MacAddress8(uint64_t mac) { + _mac.val = mac; +} + +MacAddress8::MacAddress8(const uint8_t *macbytearray) { + memcpy(_mac.bytes, macbytearray, sizeof(_mac.bytes)); +} + +MacAddress8::MacAddress8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7, uint8_t b8) { + _mac.bytes[0] = b1; + _mac.bytes[1] = b2; + _mac.bytes[2] = b3; + _mac.bytes[3] = b4; + _mac.bytes[4] = b5; + _mac.bytes[5] = b6; + _mac.bytes[6] = b7; + _mac.bytes[7] = b8; +} + +//Parse user entered string into MAC address +bool MacAddress8::fromCStr(const char *buf) { + char cs[24]; + char *token; + char *next; //Unused but required + int i; + + strncpy(cs, buf, sizeof(cs)); //strtok modifies the buffer: copy to working buffer. + + for(i=0; i<sizeof(_mac.bytes); i++) { + token = strtok((i==0) ? cs : NULL, ":"); //Find first or next token + if(!token) { //No more tokens found + return false; + } + _mac.bytes[i] = strtol(token, &next, 16); + } + return true; +} + +//Parse user entered string into MAC address +bool MacAddress8::fromString(const String &macstr) { + return fromCStr(macstr.c_str()); +} + +//Copy MAC into 8 byte array +void MacAddress8::toBytes(uint8_t *buf) { + memcpy(buf, _mac.bytes, sizeof(_mac.bytes)); +} + +//Print MAC address into a C string. +//EUI-64: Buffer must be at least 24 chars +int MacAddress8::toCStr(char *buf) { + return sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", + _mac.bytes[0], _mac.bytes[1], _mac.bytes[2], _mac.bytes[3], + _mac.bytes[4], _mac.bytes[5], _mac.bytes[6], _mac.bytes[7]); +} + +String MacAddress8::toString() const { + char buf[24]; + sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", + _mac.bytes[0], _mac.bytes[1], _mac.bytes[2], _mac.bytes[3], + _mac.bytes[4], _mac.bytes[5], _mac.bytes[6], _mac.bytes[7]); + return String(buf); +} + +uint64_t MacAddress8::Value() { + return _mac.val; +} + +uint8_t MacAddress8::operator[](int index) const { + index = EnforceIndexBounds(index); + return _mac.bytes[index]; +} + +//Allow setting individual octets of the address. e.g. ma[2] = 255; +uint8_t& MacAddress8::operator[](int index) { + index = EnforceIndexBounds(index); + return _mac.bytes[index]; +} + +//Overloaded copy operator: init MacAddress object from byte array +MacAddress8& MacAddress8::operator=(const uint8_t *macbytearray) { + memcpy(_mac.bytes, macbytearray, sizeof(_mac.bytes)); + return *this; +} + +//Overloaded copy operator: init MacAddress object from uint64_t +MacAddress8& MacAddress8::operator=(uint64_t macval) { + _mac.val = macval; + return *this; +} + +//Compare class to byte array +bool MacAddress8::operator==(const uint8_t *macbytearray) const { + return !memcmp(_mac.bytes, macbytearray, sizeof(_mac.bytes)); +} + +//Allow comparing value of two classes +bool MacAddress8::operator==(const MacAddress8& mac2) const { + return _mac.val == mac2._mac.val; +} + +//Type converter object to uint64_t [same as .Value()] +MacAddress8::operator uint64_t() const { + return _mac.val; +} + +//Type converter object to read only pointer to mac bytes. e.g. const uint8_t *ip_8 = ma; +MacAddress8::operator const uint8_t*() const { + return _mac.bytes; +} + +//Type converter object to read only pointer to mac value. e.g. const uint32_t *ip_64 = ma; +MacAddress8::operator const uint64_t*() const { + return &_mac.val; +} + +size_t MacAddress8::printTo(Print& p) const +{ + size_t n = 0; + for(int i = 0; i < 8; i++) { + if(i){ + n += p.print(':'); + } + n += p.printf("%02X", _mac.bytes[i]); + } + return n; +} + +//Bounds checking +int MacAddress8::EnforceIndexBounds(int i) const { + if(i < 0) { + return 0; + } + if(i >= sizeof(_mac.bytes)) { + return sizeof(_mac.bytes)-1; + } + return i; +} diff --git a/api/MacAddress8.h b/api/MacAddress8.h new file mode 100644 index 00000000..360ce8c9 --- /dev/null +++ b/api/MacAddress8.h @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------- +// MacAddress8.h - class to make it easier to handle 8-byte EUI-64 addresses. +// +// Copyright 2022 David McCurley +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +//----------------------------------------------------------------------------- + +#ifndef MacAddress8_h +#define MacAddress8_h + +#include <stdint.h> +#include <WString.h> +#include <Printable.h> + +// A class to make it easier to handle and pass around 8-byte EUI-64(used for IEEE 802.15.4) addresses. See <esp_mac.h>. +class MacAddress8 : public Printable { +private: + union { + uint8_t bytes[8]; + uint64_t val; + } _mac; + +public: + MacAddress8(); + MacAddress8(uint64_t mac); + MacAddress8(const uint8_t *macbytearray); + MacAddress8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7, uint8_t b8); + virtual ~MacAddress8() {} + bool fromCStr(const char *buf); + bool fromString(const String &macstr); + void toBytes(uint8_t *buf); + int toCStr(char *buf); + String toString() const; + uint64_t Value(); + + uint8_t operator[](int index) const; + uint8_t& operator[](int index); + MacAddress8& operator=(const uint8_t *macbytearray); + MacAddress8& operator=(uint64_t macval); + bool operator==(const uint8_t *macbytearray) const; + bool operator==(const MacAddress8& mac2) const; + operator uint64_t() const; + operator const uint8_t*() const; + operator const uint64_t*() const; + + virtual size_t printTo(Print& p) const; + + // future use in Arduino Networking + friend class EthernetClass; + friend class UDP; + friend class Client; + friend class Server; + friend class DhcpClass; + friend class DNSClient; + +private: + int EnforceIndexBounds(int i) const; +}; + +#endif