diff --git a/src/NimBLEEddystoneTLM.cpp b/src/NimBLEEddystoneTLM.cpp index d6a7657..e7c699b 100644 --- a/src/NimBLEEddystoneTLM.cpp +++ b/src/NimBLEEddystoneTLM.cpp @@ -13,42 +13,26 @@ */ #include "nimconfig.h" -#if defined(CONFIG_BT_ENABLED) +#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) -#include "NimBLEEddystoneTLM.h" -#include "NimBLELog.h" +# include "NimBLEEddystoneTLM.h" +# include "NimBLEUUID.h" +# include "NimBLELog.h" -#include -#include - -#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8)) -#define ENDIAN_CHANGE_U32(x) ((((x)&0xFF000000)>>24) + (((x)&0x00FF0000)>>8)) + ((((x)&0xFF00)<<8) + (((x)&0xFF)<<24)) - -static const char LOG_TAG[] = "NimBLEEddystoneTLM"; - -/** - * @brief Construct a default EddystoneTLM beacon object. - */ -NimBLEEddystoneTLM::NimBLEEddystoneTLM() { - beaconUUID = 0xFEAA; - m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE; - m_eddystoneData.version = 0; - m_eddystoneData.volt = 3300; // 3300mV = 3.3V - m_eddystoneData.temp = (uint16_t) ((float) 23.00 * 256); // 8.8 fixed format - m_eddystoneData.advCount = 0; - m_eddystoneData.tmil = 0; -} // NimBLEEddystoneTLM +# define ENDIAN_CHANGE_U16(x) ((((x) & 0xFF00) >> 8) + (((x) & 0xFF) << 8)) +# define ENDIAN_CHANGE_U32(x) \ + ((((x) & 0xFF000000) >> 24) + (((x) & 0x00FF0000) >> 8)) + ((((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24)) +static const char* LOG_TAG = "NimBLEEddystoneTLM"; /** * @brief Retrieve the data that is being advertised. * @return The advertised data. */ -std::string NimBLEEddystoneTLM::getData() { - return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); +const NimBLEEddystoneTLM::BeaconData NimBLEEddystoneTLM::getData() { + return m_eddystoneData; } // getData - /** * @brief Get the UUID being advertised. * @return The UUID advertised. @@ -57,7 +41,6 @@ NimBLEUUID NimBLEEddystoneTLM::getUUID() { return NimBLEUUID(beaconUUID); } // getUUID - /** * @brief Get the version being advertised. * @return The version number. @@ -66,7 +49,6 @@ uint8_t NimBLEEddystoneTLM::getVersion() { return m_eddystoneData.version; } // getVersion - /** * @brief Get the battery voltage. * @return The battery voltage. @@ -75,13 +57,12 @@ uint16_t NimBLEEddystoneTLM::getVolt() { return ENDIAN_CHANGE_U16(m_eddystoneData.volt); } // getVolt - /** * @brief Get the temperature being advertised. * @return The temperature value. */ -float NimBLEEddystoneTLM::getTemp() { - return (int16_t)ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f; +int16_t NimBLEEddystoneTLM::getTemp() { + return ENDIAN_CHANGE_U16(m_eddystoneData.temp); } // getTemp /** @@ -92,7 +73,6 @@ uint32_t NimBLEEddystoneTLM::getCount() { return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); } // getCount - /** * @brief Get the advertisement time. * @return The advertisement time. @@ -101,89 +81,98 @@ uint32_t NimBLEEddystoneTLM::getTime() { return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; } // getTime - /** * @brief Get a string representation of the beacon. * @return The string representation. */ std::string NimBLEEddystoneTLM::toString() { - std::string out = ""; - uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil); - char val[12]; + std::string out = ""; + uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil); + char val[12]; - out += "Version "; // + std::string(m_eddystoneData.version); - snprintf(val, sizeof(val), "%d", m_eddystoneData.version); - out += val; - out += "\n"; - out += "Battery Voltage "; // + ENDIAN_CHANGE_U16(m_eddystoneData.volt); - snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U16(m_eddystoneData.volt)); - out += val; - out += " mV\n"; + out += "Version "; + snprintf(val, sizeof(val), "%d", m_eddystoneData.version); + out += val; + out += "\n"; + out += "Battery Voltage "; + snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U16(m_eddystoneData.volt)); + out += val; + out += " mV\n"; - out += "Temperature "; - snprintf(val, sizeof(val), "%.2f", ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f); - out += val; - out += " C\n"; + out += "Temperature "; + uint8_t intTemp = m_eddystoneData.temp / 256; + uint8_t frac = m_eddystoneData.temp % 256 * 100 / 256; + snprintf(val, sizeof(val), "%d.%d", intTemp, frac); + out += val; + out += " C\n"; - out += "Adv. Count "; - snprintf(val, sizeof(val), "%" PRIu32, ENDIAN_CHANGE_U32(m_eddystoneData.advCount)); - out += val; - out += "\n"; + out += "Adv. Count "; + snprintf(val, sizeof(val), "%" PRIu32, ENDIAN_CHANGE_U32(m_eddystoneData.advCount)); + out += val; + out += "\n"; - out += "Time in seconds "; - snprintf(val, sizeof(val), "%" PRIu32, rawsec/10); - out += val; - out += "\n"; + out += "Time in seconds "; + snprintf(val, sizeof(val), "%" PRIu32, rawsec / 10); + out += val; + out += "\n"; - out += "Time "; + out += "Time "; - snprintf(val, sizeof(val), "%04" PRIu32, rawsec / 864000); - out += val; - out += "."; + snprintf(val, sizeof(val), "%04" PRIu32, rawsec / 864000); + out += val; + out += "."; - snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 36000) % 24); - out += val; - out += ":"; + snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 36000) % 24); + out += val; + out += ":"; - snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 600) % 60); - out += val; - out += ":"; + snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 600) % 60); + out += val; + out += ":"; - snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 10) % 60); - out += val; - out += "\n"; + snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 10) % 60); + out += val; + out += "\n"; - return out; + return out; } // toString +/** + * @brief Set the raw data for the beacon advertisement. + * @param [in] data A pointer to the data to advertise. + * @param [in] length The length of the data. + */ +void NimBLEEddystoneTLM::setData(const uint8_t* data, uint8_t length) { + if (length != sizeof(m_eddystoneData)) { + NIMBLE_LOGE(LOG_TAG, + "Unable to set the data ... length passed in was %d and expected %d", + length, + sizeof(m_eddystoneData)); + return; + } + memcpy(&m_eddystoneData, data, length); +} // setData /** * @brief Set the raw data for the beacon advertisement. * @param [in] data The raw data to advertise. */ -void NimBLEEddystoneTLM::setData(const std::string &data) { - if (data.length() != sizeof(m_eddystoneData)) { - NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", - data.length(), sizeof(m_eddystoneData)); - return; - } - memcpy(&m_eddystoneData, data.data(), data.length()); +void NimBLEEddystoneTLM::setData(const NimBLEEddystoneTLM::BeaconData& data) { + m_eddystoneData = data; } // setData - /** * @brief Set the UUID to advertise. - * @param [in] l_uuid The UUID. + * @param [in] uuid The UUID. */ -void NimBLEEddystoneTLM::setUUID(const NimBLEUUID &l_uuid) { - if (l_uuid.bitSize() != 16) { +void NimBLEEddystoneTLM::setUUID(const NimBLEUUID& uuid) { + if (uuid.bitSize() != 16) { NIMBLE_LOGE(LOG_TAG, "UUID must be 16 bits"); return; } - beaconUUID = *reinterpret_cast(l_uuid.getValue()); + beaconUUID = *reinterpret_cast(uuid.getValue()); } // setUUID - /** * @brief Set the version to advertise. * @param [in] version The version number. @@ -192,7 +181,6 @@ void NimBLEEddystoneTLM::setVersion(uint8_t version) { m_eddystoneData.version = version; } // setVersion - /** * @brief Set the battery voltage to advertise. * @param [in] volt The voltage in millivolts. @@ -201,16 +189,14 @@ void NimBLEEddystoneTLM::setVolt(uint16_t volt) { m_eddystoneData.volt = volt; } // setVolt - /** * @brief Set the temperature to advertise. - * @param [in] temp The temperature value. + * @param [in] temp The temperature value in 8.8 fixed point format. */ -void NimBLEEddystoneTLM::setTemp(float temp) { - m_eddystoneData.temp = ENDIAN_CHANGE_U16((int16_t)(temp * 256.0f)); +void NimBLEEddystoneTLM::setTemp(int16_t temp) { + m_eddystoneData.temp = temp; } // setTemp - /** * @brief Set the advertisement count. * @param [in] advCount The advertisement number. @@ -219,7 +205,6 @@ void NimBLEEddystoneTLM::setCount(uint32_t advCount) { m_eddystoneData.advCount = advCount; } // setCount - /** * @brief Set the advertisement time. * @param [in] tmil The advertisement time in milliseconds. @@ -228,4 +213,4 @@ void NimBLEEddystoneTLM::setTime(uint32_t tmil) { m_eddystoneData.tmil = tmil; } // setTime -#endif +#endif // CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER diff --git a/src/NimBLEEddystoneTLM.h b/src/NimBLEEddystoneTLM.h index 265c81b..7bcee34 100644 --- a/src/NimBLEEddystoneTLM.h +++ b/src/NimBLEEddystoneTLM.h @@ -12,14 +12,17 @@ * Author: pcbreflux */ -#ifndef _NimBLEEddystoneTLM_H_ -#define _NimBLEEddystoneTLM_H_ +#ifndef NIMBLE_CPP_EDDYSTONETLM_H_ +#define NIMBLE_CPP_EDDYSTONETLM_H_ -#include "NimBLEUUID.h" +#include "nimconfig.h" +#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) -#include +class NimBLEUUID; -#define EDDYSTONE_TLM_FRAME_TYPE 0x20 +# include + +# define EDDYSTONE_TLM_FRAME_TYPE 0x20 /** * @brief Representation of a beacon. @@ -27,35 +30,38 @@ * * https://github.com/google/eddystone */ class NimBLEEddystoneTLM { -public: - NimBLEEddystoneTLM(); - std::string getData(); - NimBLEUUID getUUID(); - uint8_t getVersion(); - uint16_t getVolt(); - float getTemp(); - uint32_t getCount(); - uint32_t getTime(); - std::string toString(); - void setData(const std::string &data); - void setUUID(const NimBLEUUID &l_uuid); - void setVersion(uint8_t version); - void setVolt(uint16_t volt); - void setTemp(float temp); - void setCount(uint32_t advCount); - void setTime(uint32_t tmil); + public: + struct BeaconData { + uint8_t frameType{EDDYSTONE_TLM_FRAME_TYPE}; + uint8_t version{0}; + uint16_t volt{3300}; + uint16_t temp{23 * 256}; + uint32_t advCount{0}; + uint32_t tmil{0}; + } __attribute__((packed)); -private: - uint16_t beaconUUID; - struct { - uint8_t frameType; - uint8_t version; - uint16_t volt; - uint16_t temp; - uint32_t advCount; - uint32_t tmil; - } __attribute__((packed)) m_eddystoneData; + const BeaconData getData(); + NimBLEUUID getUUID(); + uint8_t getVersion(); + uint16_t getVolt(); + int16_t getTemp(); + uint32_t getCount(); + uint32_t getTime(); + std::string toString(); + void setData(const uint8_t* data, uint8_t length); + void setData(const BeaconData& data); + void setUUID(const NimBLEUUID& l_uuid); + void setVersion(uint8_t version); + void setVolt(uint16_t volt); + void setTemp(int16_t temp); + void setCount(uint32_t advCount); + void setTime(uint32_t tmil); + + private: + uint16_t beaconUUID{0xFEAA}; + BeaconData m_eddystoneData; }; // NimBLEEddystoneTLM -#endif /* _NimBLEEddystoneTLM_H_ */ +#endif // CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER +#endif // NIMBLE_CPP_EDDYSTONETLM_H_