This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/sensors/MACAddress.h
2018-10-25 11:50:12 +02:00

177 lines
4.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © Copyright 2014 Urheberrechtshinweis
* Alle Rechte vorbehalten / All Rights Reserved
*
* Programmcode ist urheberrechtlich geschuetzt.
* Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner.
* Keine Verwendung ohne explizite Genehmigung.
* (vgl. § 106 ff UrhG / § 97 UrhG)
*/
#ifndef MACADDRESS_H
#define MACADDRESS_H
#include <cstdint>
#include <string>
#include "../Exception.h"
/**
* describes a MAC-Address as 64-bit integer.
* provides 8-bit access to all 6 values
*/
union MACAddress {
private:
/** fieldwise access */
struct {
uint8_t h5;
uint8_t h4;
uint8_t h3;
uint8_t h2;
uint8_t h1;
uint8_t h0;
} fields;
/** store as 64-bit integer */
uint64_t mac = 0;
public:
/** empty ctor */
MACAddress() {
;
}
/** copy ctor */
MACAddress(const MACAddress& o) : mac(o.mac) {
;
}
/** ctor form long */
MACAddress(const uint64_t mac) : mac(mac) {
;
}
/** ctor form string (e.g. "xx:xx:xx:xx:xx:xx") */
MACAddress(const std::string& str) {
// sanity check
if (str.size() == 17 ){
mac = 0; // all zeros
fields.h5 = hexWordToInt(str[ 0], str[ 1]);
fields.h4 = hexWordToInt(str[ 3], str[ 4]);
fields.h3 = hexWordToInt(str[ 6], str[ 7]);
fields.h2 = hexWordToInt(str[ 9], str[10]);
fields.h1 = hexWordToInt(str[12], str[13]);
fields.h0 = hexWordToInt(str[15], str[16]);
}
else if (str.size() == 12){
mac = 0; // all zeros
fields.h5 = hexWordToInt(str[ 0], str[ 1]);
fields.h4 = hexWordToInt(str[ 2], str[ 3]);
fields.h3 = hexWordToInt(str[ 4], str[ 5]);
fields.h2 = hexWordToInt(str[ 6], str[ 7]);
fields.h1 = hexWordToInt(str[ 8], str[ 9]);
fields.h0 = hexWordToInt(str[10], str[11]);
}
else{
throw Exception("invalid hex string length. must be 17 or 12 (without :)");
}
}
uint8_t getField(const int idx) const {
switch(idx) {
case 0: return fields.h0;
case 1: return fields.h1;
case 2: return fields.h2;
case 3: return fields.h3;
case 4: return fields.h4;
case 5: return fields.h5;
}
throw Exception("field-idx out of bounds");
}
/** convert to lower-case hex-string ("xx:xx:xx:xx:xx:xx") */
std::string asString() const {
std::string str = ":::::::::::::::::";
intToHexStr(fields.h5, &str[ 0]);
intToHexStr(fields.h4, &str[ 3]);
intToHexStr(fields.h3, &str[ 6]);
intToHexStr(fields.h2, &str[ 9]);
intToHexStr(fields.h1, &str[12]);
intToHexStr(fields.h0, &str[15]);
return str;
}
/** get the mac address as a long-int value */
uint64_t asLong() const {
// even if we initialized all 8 bytes with zero
// we mask the 2 unsued bytes to be absolutely safe
return mac & 0x0000FFFFFFFFFFFF;
}
/** equal? */
bool operator == (const MACAddress& o) const {
return o.asLong() == asLong();
}
/** not equal? */
bool operator != (const MACAddress& o) const {
return o.asLong() != asLong();
}
private:
/** convert the given hex char [0-F] to an integer [0-15] */
static uint8_t hexCharToInt(const char hex) {
// convert
if (hex >= '0' && hex <= '9') { // digits
return (hex - '0');
} else if (hex >= 'a' && hex <= 'f') { // lower case
return (hex - 'a' + 10);
} else if (hex >= 'A' && hex <= 'F') { // upper case
return (hex - 'A' + 10);
}
// found an invalid character
throw Exception("invalid character within MAC address");
}
/** convert the given hex-word to an integer */
static uint8_t hexWordToInt(const char hi, const char lo) {
return hexCharToInt(hi) << 4 | hexCharToInt(lo);
}
/** conver the given integer [0-15] to a hex char [0-F] */
static char intToHexChar(const uint8_t val) {
return (val < 10) ? ('0' + val) : ('A' - 10 + val);
}
/** insert two hex chars into the provided string buffer */
static void intToHexStr(const uint8_t val, char* dst) {
dst[0] = intToHexChar((val >> 4) & 0xF);
dst[1] = intToHexChar((val >> 0) & 0xF);
}
};
/** hash-method for MAC-Addresses */
namespace std {
template <> struct hash<MACAddress> {
std::size_t operator() (const MACAddress& mac) const {
return std::hash<uint64_t>()(mac.asLong());
}
};
}
#endif // MACADDRESS_H