Skip to content

Commit

Permalink
Add version getter to api (#57)
Browse files Browse the repository at this point in the history
* Moving XNCP version storage into a dedicated class NSEZSP::EzspAdapterVersion
* Creating a getter API in libezsp to retrieve XNCP info (fw+hw versions)
* Adding EZSP version details to EzspAdapterVersion class
* Implementing EzspAdapterVersion::toString() and using it as example in mainEzspTest
  • Loading branch information
lionelains authored May 14, 2020
1 parent c34c534 commit 8571574
Show file tree
Hide file tree
Showing 18 changed files with 361 additions and 97 deletions.
1 change: 1 addition & 0 deletions example/mainEzspStateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class MainStateMachine {
* @brief Set internal state machine to run mode (waiting for asynchronous sensor reports)
*/
void ezspRun() {
clogI << "Adapter version: " << this->libEzsp.getAdapterVersion() << "\n";
clogI << "Preparation steps finished... switching to run state\n";
this->currentState = MainState::RUN;
}
Expand Down
103 changes: 103 additions & 0 deletions include/ezsp/ezsp-adapter-version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* @file ezsp-adapter-version.h
*
* @brief Handling EZSP adapter versions (firmware and hardware)
*/

#ifndef __EZSP_ADAPTER_VERSION_H__
#define __EZSP_ADAPTER_VERSION_H__

#include <string>
#include <cstdint>

#include <ezsp/export.h>

namespace NSEZSP {

/**
* @brief Class storing information about the EZSP adapter
*/
class LIBEXPORT EzspAdapterVersion {
public:
enum class Manufacturer {
UNKNOWN = 0,
LEGRAND = 0x1021
};

EzspAdapterVersion();
~EzspAdapterVersion() = default;

/**
* @brief Store the EZSP stack version present inside an EZSP version info packet
*
* @param ezspStackVersion The EZSP stack version
*/
void setEzspVersionInfo(uint16_t ezspStackVersion);

/**
* @brief Store EZSP version data present inside an EZSP version info packet
*
* @param ezspStackVersion The EZSP stack version
* @param ezspProtocolVersion The EZSP protocol version (EZSPv7, EZSPv8)
* @param ezspStackType The EZSP stack type
*/
void setEzspVersionInfo(uint16_t ezspStackVersion, uint8_t ezspProtocolVersion, uint8_t ezspStackType);

/**
* @brief Store EZSP XNCP data present inside an EZSP XNCP info packet
*
* @param xncpManufacturerId The manufacturer ID (16-bit ID)
* @param xncpVersionNumber The Legrand XNCP 16-bit encoded hardware+firmware version (encoding is proprietary from Legrand)
*/
void setXncpData(uint16_t xncpManufacturerId, uint16_t xncpVersionNumber);

/**
* @brief Get a string representation of the XNCP firmware version data
*
* @return The firmware version as a string
*/
std::string getFirmwareVersionAsString() const;

/**
* @brief Get a string representation of the embedded stack version data
*
* @return The stack version as a string
*/
std::string getStackVersionAsString() const;

/**
* @brief Represent the information stored by this instance as a string
*
* @result The resulting string
*/
std::string toString() const;

/**
* @brief Serialize to an iostream
*
* @param out The original output stream
* @param data The object to serialize
*
* @return The new output stream with serialized data appended
*/
friend std::ostream& operator<< (std::ostream& out, const EzspAdapterVersion& data){
out << data.toString();
return out;
}

unsigned int ezspProtocolVersion; /*<! The EZSP protocol version EZSPv7, EZSPv8 */
uint8_t ezspStackType; /*<! The EZSP stack type (2 being mesh stack) */
unsigned int ezspStackMajorVersion; /*<! The EZSP adapter embedded stack major version */
unsigned int ezspStackMinorVersion; /*<! The EZSP adapter embedded stack minor version */
unsigned int ezspStackRevisionVersion; /*<! The EZSP adapter embedded stack revision version */
unsigned int ezspStackBugfixVersion; /*<! The EZSP adapter embedded stack bugfix version */
uint16_t xncpManufacturerId; /*<! The manufacturer ID (16-bit ID). 0x1021 is the ID registered for Legrand at the Zigbee Alliance */
unsigned int xncpAdapterHardwareVersion; /*<! The Legrand XNCP EZSP adapter hardware version (valid only if manufacturer is Legrand) */
unsigned int xncpAdapterMajorVersion; /*<! The Legrand XNCP EZSP adapter firmware major version (valid only if manufacturer is Legrand) */
unsigned int xncpAdapterMinorVersion; /*<! The Legrand XNCP EZSP adapter firmware minor version (valid only if manufacturer is Legrand) */
unsigned int xncpAdapterRevisionVersion; /*<! The Legrand XNCP EZSP adapter firmware revision version (valid only if manufacturer is Legrand) */
};

} // namespace NSEZSP

#endif // __EZSP_ADAPTER_VERSION_H__
1 change: 1 addition & 0 deletions include/ezsp/ezsp-protocol/ezsp-enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,7 @@ typedef enum
DONGLE_READY,
DONGLE_REMOVE,
DONGLE_NOT_RESPONDING,
DONGLE_VERSION_RETRIEVED,
}EDongleState;

class CEzspEnum{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class LIBEXPORT CEmberGpSinkTableOption
*
* @return The resulting string
*/
std::string String() const;
std::string toString() const;

/**
* @brief Serialize to an iostream
Expand All @@ -122,8 +122,8 @@ class LIBEXPORT CEmberGpSinkTableOption
*
* @return The new output stream with serialized data appended
*/
friend std::ostream& operator<< (std::ostream& out, const CEmberGpSinkTableOption& data){
out << data.String();
friend std::ostream& operator<< (std::ostream& out, const CEmberGpSinkTableOption& data){
out << data.toString();
return out;
}

Expand Down
10 changes: 9 additions & 1 deletion include/ezsp/ezsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <ezsp/gpd.h>
#include <ezsp/zbmessage/green-power-device.h>
#include <ezsp/zbmessage/green-power-frame.h>
#include <ezsp/ezsp-adapter-version.h>
#include <spi/TimerBuilder.h>
#include <spi/IUartDriver.h>

Expand Down Expand Up @@ -48,7 +49,7 @@ typedef CLibEzspPublic::State CLibEzspState; /* Shortcut for access to public

class CLibEzspMain;

typedef std::function<void (CLibEzspPublic::State i_state)> FLibStateCallback; /*!< Callback type for method registerLibraryStateCallback() */
typedef std::function<void (CLibEzspState i_state)> FLibStateCallback; /*!< Callback type for method registerLibraryStateCallback() */
typedef std::function<void (uint32_t &i_gpd_id, bool i_gpd_known, CGpdKeyStatus i_gpd_key_status)> FGpSourceIdCallback; /*!< Callback type for method registerGPSourceIdCallback() */
typedef std::function<void (CGpFrame &i_gpf)> FGpFrameRecvCallback; /*!< Callback type for method registerGPFrameRecvCallback() */
typedef std::function<void (std::map<uint8_t, int8_t>)> FEnergyScanCallback; /*!< Callback type for method startEnergyScan() */
Expand All @@ -71,6 +72,13 @@ class LIBEXPORT CEzsp {
*/
void start();

/**
* @brief Get the EZSP adapter's version
*
* @return The EZSP adapter version (hardware and firmware) if already known
*/
NSEZSP::EzspAdapterVersion getAdapterVersion() const;

/**
* @brief Instruct the library to directly switch to firmware upgrade mode at init if we get an EZSP timeout
*
Expand Down
7 changes: 4 additions & 3 deletions src/ezsp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ list(APPEND ezsp_SOURCES
ash.cpp
bootloader-prompt.cpp
ezsp-dongle.cpp
ezsp-adapter-version.cpp
ezsp-protocol/ezsp-enum.cpp
ezsp-protocol/get-network-parameters-response.cpp
ezsp-protocol/struct/ember-child-data-struct.cpp
Expand Down Expand Up @@ -36,16 +37,16 @@ option(USE_BUILTIN_MIC_PROCESSING "Compute and check MIC on the host rather than

configure_file(${PROJECT_SOURCE_DIR}/src/ezsp/config.h.in ${PROJECT_SOURCE_DIR}/include/ezsp/config.h)

set(ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/gpd.h)
set(ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/ezsp.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/export.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/enum-generator.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/gpd.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/zbmessage/zcl.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/zbmessage/gpd-commissioning-command-payload.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/zbmessage/green-power-frame.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/zbmessage/green-power-device.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/byte-manip.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/ezsp.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/export.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/ezsp-adapter-version.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/ezsp-protocol/struct/ember-gp-sink-table-options-field.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/ezsp/ezsp-protocol/ezsp-enum.h)
list(APPEND ezsp_PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/include/config.h)
Expand Down
98 changes: 98 additions & 0 deletions src/ezsp/ezsp-adapter-version.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* @file ezsp-adapter-version.cpp
*
* @brief Handling EZSP adapter versions (firmware and hardware)
*/

#include <sstream>
#include <iomanip>

#include <ezsp/ezsp-adapter-version.h>

#include "ezsp/byte-manip.h"

using NSEZSP::EzspAdapterVersion;

EzspAdapterVersion::EzspAdapterVersion() :
ezspProtocolVersion(0),
ezspStackType(0),
ezspStackMajorVersion(0),
ezspStackMinorVersion(0),
ezspStackRevisionVersion(0),
ezspStackBugfixVersion(0),
xncpManufacturerId(static_cast<uint16_t>(Manufacturer::UNKNOWN)),
xncpAdapterHardwareVersion(0),
xncpAdapterMajorVersion(0),
xncpAdapterMinorVersion(0),
xncpAdapterRevisionVersion(0) {
}

void EzspAdapterVersion::setEzspVersionInfo(uint16_t ezspStackVersion) {
this->ezspStackMajorVersion = u8_get_hi_nibble(u16_get_hi_u8(ezspStackVersion));
this->ezspStackMinorVersion = u8_get_lo_nibble(u16_get_hi_u8(ezspStackVersion));
this->ezspStackRevisionVersion = u8_get_hi_nibble(u16_get_lo_u8(ezspStackVersion));
this->ezspStackBugfixVersion = u8_get_lo_nibble(u16_get_lo_u8(ezspStackVersion));
}

void EzspAdapterVersion::setEzspVersionInfo(uint16_t ezspStackVersion, uint8_t ezspProtocolVersion, uint8_t ezspStackType) {
this->setEzspVersionInfo(ezspStackVersion);
this->ezspProtocolVersion = ezspProtocolVersion;
this->ezspStackType = ezspStackType;
}

void EzspAdapterVersion::setXncpData(uint16_t xncpManufacturerId, uint16_t xncpVersionNumber) {
this->xncpManufacturerId = xncpManufacturerId;
this->xncpAdapterHardwareVersion = u8_get_hi_nibble(u16_get_hi_u8(xncpVersionNumber)); /* High nibble of MSB */
this->xncpAdapterMajorVersion = u8_get_lo_nibble(u16_get_hi_u8(xncpVersionNumber)); /* Low nibble of MSB */
this->xncpAdapterMinorVersion = u8_get_hi_nibble(u16_get_lo_u8(xncpVersionNumber)); /* High nibble of LSB */
this->xncpAdapterRevisionVersion = u8_get_lo_nibble(u16_get_lo_u8(xncpVersionNumber)); /* Low nibble of LSB */
}

std::string EzspAdapterVersion::getFirmwareVersionAsString() const {
std::stringstream result;
result << this->xncpAdapterMajorVersion << "." << this->xncpAdapterMinorVersion << "." << this->xncpAdapterRevisionVersion;
return result.str();
}

std::string EzspAdapterVersion::getStackVersionAsString() const {
std::stringstream result;
result << static_cast<unsigned int>(this->ezspStackMajorVersion) << ".";
result << static_cast<unsigned int>(this->ezspStackMinorVersion) << ".";
result << static_cast<unsigned int>(this->ezspStackRevisionVersion) << ".";
result << static_cast<unsigned int>(this->ezspStackBugfixVersion);
return result.str();
}

std::string EzspAdapterVersion::toString() const {
std::stringstream buf;

buf << "EzspAdapterVersion : { ";
if (this->xncpManufacturerId != static_cast<uint16_t>(Manufacturer::UNKNOWN)) {
buf << "[Manufacturer: 0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(this->xncpManufacturerId);
if (this->xncpManufacturerId == static_cast<uint16_t>(Manufacturer::LEGRAND)) {
buf << " (LEGRAND)";
}
buf << "]";
}
if (this->ezspProtocolVersion) {
buf << "[EZSPv" << std::dec << std::setw(0) << static_cast<unsigned int>(this->ezspProtocolVersion);
buf << " running stack type " << static_cast<unsigned int>(this->ezspStackType);
if (this->ezspStackType == 2) {
buf << " (mesh)";
}
buf << "]";
}
if (this->ezspStackMajorVersion || this->ezspStackMinorVersion || this->ezspStackRevisionVersion || this->ezspStackBugfixVersion) {
buf << "[stack v" << this->getStackVersionAsString() << "]";
}
/* XNCP can only be properly decoded if manufacturer is Legrand */
if (this->xncpManufacturerId == static_cast<uint16_t>(Manufacturer::LEGRAND)) {
if (this->xncpAdapterHardwareVersion || this->xncpAdapterMajorVersion || this->xncpAdapterMinorVersion || this->xncpAdapterRevisionVersion) {
buf << "[hw v" << this->xncpAdapterHardwareVersion;
buf << ", fw v" << this->getFirmwareVersionAsString() << "]";
}
}
buf << " }";

return buf.str();
}
20 changes: 20 additions & 0 deletions src/ezsp/ezsp-dongle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ using NSEZSP::CEzspDongle;

CEzspDongle::CEzspDongle(const NSSPI::TimerBuilder& i_timer_builder, CEzspDongleObserver* ip_observer) :
firstStartup(true),
version(),
lastKnownMode(CEzspDongle::Mode::UNKNOWN),
switchToFirmwareUpgradeOnInitTimeout(false),
timerBuilder(i_timer_builder),
Expand Down Expand Up @@ -64,6 +65,25 @@ bool CEzspDongle::reset() {
return true;
}

void CEzspDongle::setFetchedXncpData(uint16_t xncpManufacturerId, uint16_t xncpVersionNumber) {
this->version.setXncpData(xncpManufacturerId, xncpVersionNumber);
this->notifyObserversOfDongleState(DONGLE_VERSION_RETRIEVED); /* Notify observers that we now know the EZSP adapter's version */
}

void CEzspDongle::setFetchedEzspVersionData(uint16_t ezspStackVersion) {
this->version.setEzspVersionInfo(ezspStackVersion);
this->notifyObserversOfDongleState(DONGLE_VERSION_RETRIEVED); /* Notify observers that we now know the EZSP adapter's version */
}

void CEzspDongle::setFetchedEzspVersionData(uint16_t ezspStackVersion, uint8_t ezspProtocolVersion, uint8_t ezspStackType) {
this->version.setEzspVersionInfo(ezspStackVersion, ezspProtocolVersion, ezspStackType);
this->notifyObserversOfDongleState(DONGLE_VERSION_RETRIEVED); /* Notify observers that we now know the EZSP adapter's version */
}

NSEZSP::EzspAdapterVersion CEzspDongle::getVersion() const {
return this->version;
}

void CEzspDongle::ashCbInfo(CAsh::EAshInfo info) {
clogD << "ashCbInfo : " << CAsh::getEAshInfoAsString(info) << "\n";

Expand Down
Loading

0 comments on commit 8571574

Please sign in to comment.