[BREAKING] - Refactor NimBLEEddystoneTLM

* `NimBLEEddystoneTLM::BeaconData` struct is now public and usable by the application.
* `NimBLEEddystoneTLM::setTemp` now takes an `int16_t` parameter instead of float to be friendly to devices without floating point support.
* `NimBLEEddystoneTLM::getTemp` now returns `int16_t` to work with devices that don't have floating point support.
* `NimBLEEddystoneTLM::setData` now takes a reference to * `NimBLEEddystoneTLM::BeaconData` instead of `std::string`.
* `NimBLEEddystoneTLM::getData` now returns a reference to * `NimBLEEddystoneTLM::BeaconData` instead of `std::string`.
This commit is contained in:
h2zero 2024-11-29 14:17:45 -07:00 committed by h2zero
parent 308b81e81a
commit e0fe1668de
2 changed files with 115 additions and 124 deletions

View file

@ -13,42 +13,26 @@
*/ */
#include "nimconfig.h" #include "nimconfig.h"
#if defined(CONFIG_BT_ENABLED) #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
#include "NimBLEEddystoneTLM.h" # include "NimBLEEddystoneTLM.h"
#include "NimBLELog.h" # include "NimBLEUUID.h"
# include "NimBLELog.h"
#include <stdio.h> # define ENDIAN_CHANGE_U16(x) ((((x) & 0xFF00) >> 8) + (((x) & 0xFF) << 8))
#include <cstring> # define ENDIAN_CHANGE_U32(x) \
((((x) & 0xFF000000) >> 24) + (((x) & 0x00FF0000) >> 8)) + ((((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24))
#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
static const char* LOG_TAG = "NimBLEEddystoneTLM";
/** /**
* @brief Retrieve the data that is being advertised. * @brief Retrieve the data that is being advertised.
* @return The advertised data. * @return The advertised data.
*/ */
std::string NimBLEEddystoneTLM::getData() { const NimBLEEddystoneTLM::BeaconData NimBLEEddystoneTLM::getData() {
return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); return m_eddystoneData;
} // getData } // getData
/** /**
* @brief Get the UUID being advertised. * @brief Get the UUID being advertised.
* @return The UUID advertised. * @return The UUID advertised.
@ -57,7 +41,6 @@ NimBLEUUID NimBLEEddystoneTLM::getUUID() {
return NimBLEUUID(beaconUUID); return NimBLEUUID(beaconUUID);
} // getUUID } // getUUID
/** /**
* @brief Get the version being advertised. * @brief Get the version being advertised.
* @return The version number. * @return The version number.
@ -66,7 +49,6 @@ uint8_t NimBLEEddystoneTLM::getVersion() {
return m_eddystoneData.version; return m_eddystoneData.version;
} // getVersion } // getVersion
/** /**
* @brief Get the battery voltage. * @brief Get the battery voltage.
* @return The battery voltage. * @return The battery voltage.
@ -75,13 +57,12 @@ uint16_t NimBLEEddystoneTLM::getVolt() {
return ENDIAN_CHANGE_U16(m_eddystoneData.volt); return ENDIAN_CHANGE_U16(m_eddystoneData.volt);
} // getVolt } // getVolt
/** /**
* @brief Get the temperature being advertised. * @brief Get the temperature being advertised.
* @return The temperature value. * @return The temperature value.
*/ */
float NimBLEEddystoneTLM::getTemp() { int16_t NimBLEEddystoneTLM::getTemp() {
return (int16_t)ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f; return ENDIAN_CHANGE_U16(m_eddystoneData.temp);
} // getTemp } // getTemp
/** /**
@ -92,7 +73,6 @@ uint32_t NimBLEEddystoneTLM::getCount() {
return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); return ENDIAN_CHANGE_U32(m_eddystoneData.advCount);
} // getCount } // getCount
/** /**
* @brief Get the advertisement time. * @brief Get the advertisement time.
* @return The advertisement time. * @return The advertisement time.
@ -101,7 +81,6 @@ uint32_t NimBLEEddystoneTLM::getTime() {
return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10;
} // getTime } // getTime
/** /**
* @brief Get a string representation of the beacon. * @brief Get a string representation of the beacon.
* @return The string representation. * @return The string representation.
@ -111,17 +90,19 @@ std::string NimBLEEddystoneTLM::toString() {
uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil); uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil);
char val[12]; char val[12];
out += "Version "; // + std::string(m_eddystoneData.version); out += "Version ";
snprintf(val, sizeof(val), "%d", m_eddystoneData.version); snprintf(val, sizeof(val), "%d", m_eddystoneData.version);
out += val; out += val;
out += "\n"; out += "\n";
out += "Battery Voltage "; // + ENDIAN_CHANGE_U16(m_eddystoneData.volt); out += "Battery Voltage ";
snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U16(m_eddystoneData.volt)); snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U16(m_eddystoneData.volt));
out += val; out += val;
out += " mV\n"; out += " mV\n";
out += "Temperature "; out += "Temperature ";
snprintf(val, sizeof(val), "%.2f", ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f); 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 += val;
out += " C\n"; out += " C\n";
@ -131,7 +112,7 @@ std::string NimBLEEddystoneTLM::toString() {
out += "\n"; out += "\n";
out += "Time in seconds "; out += "Time in seconds ";
snprintf(val, sizeof(val), "%" PRIu32, rawsec/10); snprintf(val, sizeof(val), "%" PRIu32, rawsec / 10);
out += val; out += val;
out += "\n"; out += "\n";
@ -156,34 +137,42 @@ std::string NimBLEEddystoneTLM::toString() {
return out; return out;
} // toString } // 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. * @brief Set the raw data for the beacon advertisement.
* @param [in] data The raw data to advertise. * @param [in] data The raw data to advertise.
*/ */
void NimBLEEddystoneTLM::setData(const std::string &data) { void NimBLEEddystoneTLM::setData(const NimBLEEddystoneTLM::BeaconData& data) {
if (data.length() != sizeof(m_eddystoneData)) { m_eddystoneData = data;
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());
} // setData } // setData
/** /**
* @brief Set the UUID to advertise. * @brief Set the UUID to advertise.
* @param [in] l_uuid The UUID. * @param [in] uuid The UUID.
*/ */
void NimBLEEddystoneTLM::setUUID(const NimBLEUUID &l_uuid) { void NimBLEEddystoneTLM::setUUID(const NimBLEUUID& uuid) {
if (l_uuid.bitSize() != 16) { if (uuid.bitSize() != 16) {
NIMBLE_LOGE(LOG_TAG, "UUID must be 16 bits"); NIMBLE_LOGE(LOG_TAG, "UUID must be 16 bits");
return; return;
} }
beaconUUID = *reinterpret_cast<const uint16_t*>(l_uuid.getValue()); beaconUUID = *reinterpret_cast<const uint16_t*>(uuid.getValue());
} // setUUID } // setUUID
/** /**
* @brief Set the version to advertise. * @brief Set the version to advertise.
* @param [in] version The version number. * @param [in] version The version number.
@ -192,7 +181,6 @@ void NimBLEEddystoneTLM::setVersion(uint8_t version) {
m_eddystoneData.version = version; m_eddystoneData.version = version;
} // setVersion } // setVersion
/** /**
* @brief Set the battery voltage to advertise. * @brief Set the battery voltage to advertise.
* @param [in] volt The voltage in millivolts. * @param [in] volt The voltage in millivolts.
@ -201,16 +189,14 @@ void NimBLEEddystoneTLM::setVolt(uint16_t volt) {
m_eddystoneData.volt = volt; m_eddystoneData.volt = volt;
} // setVolt } // setVolt
/** /**
* @brief Set the temperature to advertise. * @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) { void NimBLEEddystoneTLM::setTemp(int16_t temp) {
m_eddystoneData.temp = ENDIAN_CHANGE_U16((int16_t)(temp * 256.0f)); m_eddystoneData.temp = temp;
} // setTemp } // setTemp
/** /**
* @brief Set the advertisement count. * @brief Set the advertisement count.
* @param [in] advCount The advertisement number. * @param [in] advCount The advertisement number.
@ -219,7 +205,6 @@ void NimBLEEddystoneTLM::setCount(uint32_t advCount) {
m_eddystoneData.advCount = advCount; m_eddystoneData.advCount = advCount;
} // setCount } // setCount
/** /**
* @brief Set the advertisement time. * @brief Set the advertisement time.
* @param [in] tmil The advertisement time in milliseconds. * @param [in] tmil The advertisement time in milliseconds.
@ -228,4 +213,4 @@ void NimBLEEddystoneTLM::setTime(uint32_t tmil) {
m_eddystoneData.tmil = tmil; m_eddystoneData.tmil = tmil;
} // setTime } // setTime
#endif #endif // CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER

View file

@ -12,14 +12,17 @@
* Author: pcbreflux * Author: pcbreflux
*/ */
#ifndef _NimBLEEddystoneTLM_H_ #ifndef NIMBLE_CPP_EDDYSTONETLM_H_
#define _NimBLEEddystoneTLM_H_ #define NIMBLE_CPP_EDDYSTONETLM_H_
#include "NimBLEUUID.h" #include "nimconfig.h"
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER)
#include <string> class NimBLEUUID;
#define EDDYSTONE_TLM_FRAME_TYPE 0x20 # include <string>
# define EDDYSTONE_TLM_FRAME_TYPE 0x20
/** /**
* @brief Representation of a beacon. * @brief Representation of a beacon.
@ -27,35 +30,38 @@
* * https://github.com/google/eddystone * * https://github.com/google/eddystone
*/ */
class NimBLEEddystoneTLM { class NimBLEEddystoneTLM {
public: public:
NimBLEEddystoneTLM(); struct BeaconData {
std::string getData(); 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));
const BeaconData getData();
NimBLEUUID getUUID(); NimBLEUUID getUUID();
uint8_t getVersion(); uint8_t getVersion();
uint16_t getVolt(); uint16_t getVolt();
float getTemp(); int16_t getTemp();
uint32_t getCount(); uint32_t getCount();
uint32_t getTime(); uint32_t getTime();
std::string toString(); std::string toString();
void setData(const std::string &data); void setData(const uint8_t* data, uint8_t length);
void setUUID(const NimBLEUUID &l_uuid); void setData(const BeaconData& data);
void setUUID(const NimBLEUUID& l_uuid);
void setVersion(uint8_t version); void setVersion(uint8_t version);
void setVolt(uint16_t volt); void setVolt(uint16_t volt);
void setTemp(float temp); void setTemp(int16_t temp);
void setCount(uint32_t advCount); void setCount(uint32_t advCount);
void setTime(uint32_t tmil); void setTime(uint32_t tmil);
private: private:
uint16_t beaconUUID; uint16_t beaconUUID{0xFEAA};
struct { BeaconData m_eddystoneData;
uint8_t frameType;
uint8_t version;
uint16_t volt;
uint16_t temp;
uint32_t advCount;
uint32_t tmil;
} __attribute__((packed)) m_eddystoneData;
}; // NimBLEEddystoneTLM }; // NimBLEEddystoneTLM
#endif /* _NimBLEEddystoneTLM_H_ */ #endif // CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER
#endif // NIMBLE_CPP_EDDYSTONETLM_H_