Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 86 additions & 101 deletions src/NimBLEEddystoneTLM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <stdio.h>
#include <cstring>

#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.
Expand All @@ -57,7 +41,6 @@ NimBLEUUID NimBLEEddystoneTLM::getUUID() {
return NimBLEUUID(beaconUUID);
} // getUUID


/**
* @brief Get the version being advertised.
* @return The version number.
Expand All @@ -66,7 +49,6 @@ uint8_t NimBLEEddystoneTLM::getVersion() {
return m_eddystoneData.version;
} // getVersion


/**
* @brief Get the battery voltage.
* @return The battery voltage.
Expand All @@ -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

/**
Expand All @@ -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.
Expand All @@ -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];

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 += "Temperature ";
snprintf(val, sizeof(val), "%.2f", ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f);
out += val;
out += " C\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 ";

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 / 600) % 60);
out += val;
out += ":";

snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 10) % 60);
out += val;
out += "\n";

return out;
std::string out = "";
uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil);
char val[12];

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 ";
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 += "Time in seconds ";
snprintf(val, sizeof(val), "%" PRIu32, rawsec / 10);
out += val;
out += "\n";

out += "Time ";

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 / 600) % 60);
out += val;
out += ":";

snprintf(val, sizeof(val), "%02" PRIu32, (rawsec / 10) % 60);
out += val;
out += "\n";

return out;
} // toString


/**
* @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));
* @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.data(), data.length());
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 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<const uint16_t*>(l_uuid.getValue());
beaconUUID = *reinterpret_cast<const uint16_t*>(uuid.getValue());
} // setUUID


/**
* @brief Set the version to advertise.
* @param [in] version The version number.
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand All @@ -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
74 changes: 40 additions & 34 deletions src/NimBLEEddystoneTLM.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,50 +12,56 @@
* 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 <string>
class NimBLEUUID;

#define EDDYSTONE_TLM_FRAME_TYPE 0x20
# include <string>

# define EDDYSTONE_TLM_FRAME_TYPE 0x20

/**
* @brief Representation of a beacon.
* See:
* * 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);

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;
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));

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_