Implement health server callbacks.

This commit is contained in:
h2zero 2020-10-25 08:29:54 -06:00
parent 56c68d7eea
commit afb76b8cb6
6 changed files with 159 additions and 14 deletions

View file

@ -13,13 +13,18 @@ static const char* LOG_TAG = "NimBLEMeshElement";
NimBLEMeshElement::NimBLEMeshElement() { NimBLEMeshElement::NimBLEMeshElement() {
m_pElem_t = nullptr; m_pElem_t = nullptr;
m_pHealthModel = nullptr;
} }
NimBLEMeshElement::~NimBLEMeshElement() { NimBLEMeshElement::~NimBLEMeshElement() {
if(m_pElem_t != nullptr) { if(m_pElem_t != nullptr) {
delete m_pElem_t; delete m_pElem_t;
} }
delete m_pHealthModel; if(m_pHealthModel != nullptr) {
delete m_pHealthModel;
}
for(auto &it : m_modelsVec) { for(auto &it : m_modelsVec) {
if(it.id != BT_MESH_MODEL_ID_HEALTH_SRV) { if(it.id != BT_MESH_MODEL_ID_HEALTH_SRV) {
@ -30,6 +35,7 @@ NimBLEMeshElement::~NimBLEMeshElement() {
m_modelsVec.clear(); m_modelsVec.clear();
} }
/** /**
* @brief Creates a model and adds it the the elements model vector. * @brief Creates a model and adds it the the elements model vector.
* @param [in] type The type of model to create. * @param [in] type The type of model to create.
@ -58,7 +64,7 @@ NimBLEMeshModel* NimBLEMeshElement::createModel(uint16_t type, NimBLEMeshModelCa
case BT_MESH_MODEL_ID_HEALTH_SRV: case BT_MESH_MODEL_ID_HEALTH_SRV:
m_pHealthModel = new NimBLEHealthSrvModel(pCallbacks); m_pHealthModel = new NimBLEHealthSrvModel(pCallbacks);
pModel = m_pHealthModel; pModel = m_pHealthModel;
m_modelsVec.push_back(bt_mesh_model{{BT_MESH_MODEL_ID_HEALTH_SRV},0,0,0,&pModel->m_opPub,{0},{0},bt_mesh_health_srv_op,pModel->getHealth_t()}); m_modelsVec.push_back(bt_mesh_model{{type},0,0,0,&pModel->m_opPub,{0},{0},bt_mesh_health_srv_op,&m_pHealthModel->m_healthSrv});
return pModel; return pModel;
default: default:
@ -70,15 +76,21 @@ NimBLEMeshModel* NimBLEMeshElement::createModel(uint16_t type, NimBLEMeshModelCa
return pModel; return pModel;
} }
/** /**
* @brief Adds a model created outside of element context to the elements model vector. * @brief Adds a model created outside of element context to the elements model vector.
* @param [in] model A pointer to the model instance to add. * @param [in] model A pointer to the model instance to add.
*/ */
void NimBLEMeshElement::addModel(bt_mesh_model* model) { void NimBLEMeshElement::addModel(bt_mesh_model *model) {
m_modelsVec.push_back(*model); m_modelsVec.push_back(*model);
} }
/**
* @brief Get a pointer to the model in the element with the type specified.
* @param [in] The model type requested.
* @returns A pointer to the model or nullptr if not found.
*/
NimBLEMeshModel* NimBLEMeshElement::getModel(uint16_t type) { NimBLEMeshModel* NimBLEMeshElement::getModel(uint16_t type) {
if(type == BT_MESH_MODEL_ID_HEALTH_SRV) { if(type == BT_MESH_MODEL_ID_HEALTH_SRV) {
return m_pHealthModel; return m_pHealthModel;
@ -94,6 +106,28 @@ NimBLEMeshModel* NimBLEMeshElement::getModel(uint16_t type) {
} }
/**
* @brief Get a pointer to a model with matching type and ID.
* @param [in] eidx The element ID to compare.
* @param [in] midx The model ID to compare.
* @param [in] The model type requested.
* @returns A pointer to the model or nullptr if not found.
*/
NimBLEMeshModel* NimBLEMeshElement::getModelByIdx(uint8_t eidx, uint8_t midx, uint16_t type) {
for(auto &it : m_modelsVec) {
if(it.elem_idx == eidx && it.mod_idx == midx) {
if(type == BT_MESH_MODEL_ID_HEALTH_SRV) {
return m_pHealthModel;
} else {
return (NimBLEMeshModel*)it.user_data;
}
}
}
return nullptr;
}
/** /**
* @brief Creates a bt_mesh_elem for registering with the nimble stack. * @brief Creates a bt_mesh_elem for registering with the nimble stack.
* @returns A pointer to the bt_mesh_elem created. * @returns A pointer to the bt_mesh_elem created.

View file

@ -26,6 +26,7 @@ class NimBLEMeshElement {
public: public:
NimBLEMeshModel* createModel(uint16_t type, NimBLEMeshModelCallbacks* pCallbacks=nullptr); NimBLEMeshModel* createModel(uint16_t type, NimBLEMeshModelCallbacks* pCallbacks=nullptr);
NimBLEMeshModel* getModel(uint16_t type); NimBLEMeshModel* getModel(uint16_t type);
NimBLEMeshModel* getModelByIdx(uint8_t eidx, uint8_t midx, uint16_t type);
private: private:
friend class NimBLEMeshNode; friend class NimBLEMeshNode;

View file

@ -12,6 +12,11 @@
#include "nimble/nimble_port.h" #include "nimble/nimble_port.h"
#include "NimBLEDevice.h"
#define CID_VENDOR 0x05C3
#define STANDARD_TEST_ID 0x00
static const char* LOG_TAG = "NimBLEMeshModel"; static const char* LOG_TAG = "NimBLEMeshModel";
static NimBLEMeshModelCallbacks defaultCallbacks; static NimBLEMeshModelCallbacks defaultCallbacks;
@ -133,10 +138,6 @@ uint16_t NimBLEMeshModel::getDelayTime() {
} }
bt_mesh_health_srv* NimBLEMeshModel::getHealth_t() {
return nullptr;
}
/** /**
* @brief Generic on/off server model constructor * @brief Generic on/off server model constructor
* @param [in] pCallbacks, a pointer to a callback instance for model operations * @param [in] pCallbacks, a pointer to a callback instance for model operations
@ -245,6 +246,7 @@ void NimBLEGenOnOffSrvModel::setOnOffUnack(bt_mesh_model *model,
} }
} }
void NimBLEGenOnOffSrvModel::tdTimerCb(ble_npl_event *event) { void NimBLEGenOnOffSrvModel::tdTimerCb(ble_npl_event *event) {
NimBLEMeshModel *pModel = (NimBLEMeshModel*)event->arg; NimBLEMeshModel *pModel = (NimBLEMeshModel*)event->arg;
if(pModel->m_delayTime > 0) { if(pModel->m_delayTime > 0) {
@ -286,6 +288,7 @@ void NimBLEGenOnOffSrvModel::setPubMsg() {
} }
} }
void NimBLEGenOnOffSrvModel::setValue(uint8_t *val, size_t len) { void NimBLEGenOnOffSrvModel::setValue(uint8_t *val, size_t len) {
if(len != sizeof(uint8_t)) { if(len != sizeof(uint8_t)) {
NIMBLE_LOGE(LOG_TAG, "NimBLEGenOnOffSrvModel: Incorrect value length"); NIMBLE_LOGE(LOG_TAG, "NimBLEGenOnOffSrvModel: Incorrect value length");
@ -294,6 +297,7 @@ void NimBLEGenOnOffSrvModel::setValue(uint8_t *val, size_t len) {
m_value[0] = *val; m_value[0] = *val;
} }
void NimBLEGenOnOffSrvModel::setTargetValue(uint8_t *val, size_t len) { void NimBLEGenOnOffSrvModel::setTargetValue(uint8_t *val, size_t len) {
if(len != sizeof(uint8_t)) { if(len != sizeof(uint8_t)) {
NIMBLE_LOGE(LOG_TAG, "NimBLEGenOnOffSrvModel: Incorrect target value length"); NIMBLE_LOGE(LOG_TAG, "NimBLEGenOnOffSrvModel: Incorrect target value length");
@ -302,6 +306,7 @@ void NimBLEGenOnOffSrvModel::setTargetValue(uint8_t *val, size_t len) {
m_targetValue[0] = *val; m_targetValue[0] = *val;
} }
/** /**
* @brief Generic level server model constructor * @brief Generic level server model constructor
* @param [in] pCallbacks, a pointer to a callback instance for model operations * @param [in] pCallbacks, a pointer to a callback instance for model operations
@ -543,11 +548,21 @@ NimBLEHealthSrvModel::NimBLEHealthSrvModel(NimBLEMeshModelCallbacks *pCallbacks)
{ {
memset(&m_healthSrv, 0, sizeof(m_healthSrv)); memset(&m_healthSrv, 0, sizeof(m_healthSrv));
m_healthSrv.cb = &health_srv_cb; m_healthSrv.cb = &health_srv_cb;
m_opPub.msg = NET_BUF_SIMPLE(1 + 3);
m_hasFault = false;
m_testId = 0;
} }
bt_mesh_health_srv* NimBLEHealthSrvModel::getHealth_t() { void NimBLEHealthSrvModel::setFault(uint8_t fault) {
return &m_healthSrv; m_faults.push_back(fault);
m_hasFault = true;
}
void NimBLEHealthSrvModel::clearFaults() {
m_faults.clear();
m_hasFault = false;
} }
@ -574,6 +589,23 @@ int16_t NimBLEMeshModelCallbacks::getLevel(NimBLEMeshModel *pModel) {
return 0; return 0;
} }
void NimBLEMeshModelCallbacks::attentionOn(NimBLEMeshModel *pModel) {
NIMBLE_LOGD(LOG_TAG, "Attention On Default");
}
void NimBLEMeshModelCallbacks::attentionOff(NimBLEMeshModel *pModel) {
NIMBLE_LOGD(LOG_TAG, "Attention Off Default");
}
void NimBLEMeshModelCallbacks::faultTest(NimBLEMeshModel *pModel) {
NIMBLE_LOGD(LOG_TAG, "Fault Test");
}
void NimBLEMeshModelCallbacks::faultClear(NimBLEMeshModel *pModel) {
NIMBLE_LOGD(LOG_TAG, "Fault Clear");
}
/** /**
* @brief Health server callbacks * @brief Health server callbacks
*/ */
@ -582,6 +614,12 @@ int NimBLEHealthSrvCallbacks::faultGetCurrent(bt_mesh_model *model, uint8_t *tes
uint8_t *fault_count) uint8_t *fault_count)
{ {
NIMBLE_LOGD(LOG_TAG, "faultGetCurrent - default"); NIMBLE_LOGD(LOG_TAG, "faultGetCurrent - default");
NimBLEHealthSrvModel* pModel = (NimBLEHealthSrvModel*)NimBLEDevice::getMeshNode()->getHealthModel(model);
*test_id = pModel->m_testId;
*company_id = CID_VENDOR;
faults = &pModel->m_faults[0];
*fault_count = pModel->m_faults.size();
return 0; return 0;
} }
@ -590,27 +628,64 @@ int NimBLEHealthSrvCallbacks::faultGetRegistered(bt_mesh_model *model, uint16_t
uint8_t *fault_count) uint8_t *fault_count)
{ {
NIMBLE_LOGD(LOG_TAG, "faultGetRegistered - default"); NIMBLE_LOGD(LOG_TAG, "faultGetRegistered - default");
if (company_id != CID_VENDOR) {
return -BLE_HS_EINVAL;
}
NimBLEHealthSrvModel* pModel = (NimBLEHealthSrvModel*)NimBLEDevice::getMeshNode()->getHealthModel(model);
*test_id = pModel->m_testId;
faults = &pModel->m_faults[0];
*fault_count = pModel->m_faults.size();
return 0; return 0;
} }
int NimBLEHealthSrvCallbacks::faultClear(bt_mesh_model *model, uint16_t company_id) int NimBLEHealthSrvCallbacks::faultClear(bt_mesh_model *model, uint16_t company_id)
{ {
NIMBLE_LOGD(LOG_TAG, "faultClear - default"); NIMBLE_LOGD(LOG_TAG, "faultClear - default");
if (company_id != CID_VENDOR) {
return -BLE_HS_EINVAL;
}
NimBLEHealthSrvModel* pModel = (NimBLEHealthSrvModel*)NimBLEDevice::getMeshNode()->getHealthModel(model);
pModel->m_callbacks->faultClear(pModel);
pModel->clearFaults();
return 0; return 0;
} }
int NimBLEHealthSrvCallbacks::faultTest(bt_mesh_model *model, uint8_t test_id, uint16_t company_id) int NimBLEHealthSrvCallbacks::faultTest(bt_mesh_model *model, uint8_t test_id, uint16_t company_id)
{ {
NIMBLE_LOGD(LOG_TAG, "faultTest - default"); NIMBLE_LOGD(LOG_TAG, "faultTest - default");
if (company_id != CID_VENDOR) {
return -BLE_HS_EINVAL;
}
if (test_id != STANDARD_TEST_ID) {
return -BLE_HS_EINVAL;
}
NimBLEHealthSrvModel* pModel = (NimBLEHealthSrvModel*)NimBLEDevice::getMeshNode()->getHealthModel(model);
pModel->setFault(0);
pModel->m_testId = test_id;
pModel->m_callbacks->faultTest(pModel);
return 0; return 0;
} }
void NimBLEHealthSrvCallbacks::attentionOn(bt_mesh_model *model) void NimBLEHealthSrvCallbacks::attentionOn(bt_mesh_model *model)
{ {
NIMBLE_LOGD(LOG_TAG, "attentionOn - default"); NIMBLE_LOGD(LOG_TAG, "attentionOn - default");
NimBLEMeshModel* pModel = NimBLEDevice::getMeshNode()->getHealthModel(model);
pModel->m_callbacks->attentionOn(pModel);
} }
void NimBLEHealthSrvCallbacks::attentionOff(bt_mesh_model *model) void NimBLEHealthSrvCallbacks::attentionOff(bt_mesh_model *model)
{ {
NIMBLE_LOGD(LOG_TAG, "attentionOff - default"); NIMBLE_LOGD(LOG_TAG, "attentionOff - default");
NimBLEMeshModel* pModel = NimBLEDevice::getMeshNode()->getHealthModel(model);
pModel->m_callbacks->attentionOff(pModel);
} }

View file

@ -33,7 +33,8 @@ public:
virtual void setPubMsg(){}; virtual void setPubMsg(){};
virtual void setValue(uint8_t *val, size_t len){}; virtual void setValue(uint8_t *val, size_t len){};
virtual void setTargetValue(uint8_t *val, size_t len){}; virtual void setTargetValue(uint8_t *val, size_t len){};
virtual bt_mesh_health_srv* getHealth_t(); virtual void setFault(uint8_t){};
virtual void clearFaults(){};
template<typename T> template<typename T>
void setValue(const T &s) { void setValue(const T &s) {
@ -138,13 +139,20 @@ class NimBLEGenLevelSrvModel : NimBLEMeshModel {
class NimBLEHealthSrvModel : NimBLEMeshModel { class NimBLEHealthSrvModel : NimBLEMeshModel {
friend class NimBLEMeshElement; friend class NimBLEMeshElement;
friend class NimBLEMeshNode; friend class NimBLEMeshNode;
friend class NimBLEHealthSrvCallbacks;
NimBLEHealthSrvModel(NimBLEMeshModelCallbacks *pCallbacks); NimBLEHealthSrvModel(NimBLEMeshModelCallbacks *pCallbacks);
~NimBLEHealthSrvModel(){}; ~NimBLEHealthSrvModel(){};
bt_mesh_health_srv* getHealth_t() override; public:
void setFault(uint8_t) override;
void clearFaults() override;
private:
bt_mesh_health_srv m_healthSrv; bt_mesh_health_srv m_healthSrv;
bool m_hasFault;
uint8_t m_testId;
std::vector<uint8_t> m_faults;
}; };
@ -155,6 +163,11 @@ public:
virtual uint8_t getOnOff(NimBLEMeshModel *pModel); virtual uint8_t getOnOff(NimBLEMeshModel *pModel);
virtual void setLevel(NimBLEMeshModel *pModel, int16_t val); virtual void setLevel(NimBLEMeshModel *pModel, int16_t val);
virtual int16_t getLevel(NimBLEMeshModel *pModel); virtual int16_t getLevel(NimBLEMeshModel *pModel);
virtual void attentionOn(NimBLEMeshModel *pModel);
virtual void attentionOff(NimBLEMeshModel *pModel);
virtual void faultTest(NimBLEMeshModel *pModel);
virtual void faultClear(NimBLEMeshModel *pModel);
}; };

View file

@ -128,6 +128,25 @@ NimBLEMeshElement* NimBLEMeshNode::createElement() {
} }
/**
* @brief Get a pointer to the health model instance that matches the ID's of the input model.
* @param [in] model A pointer to the NimBLE internal model instance.
* @returns A pointer to the model.
*/
NimBLEMeshModel* NimBLEMeshNode::getHealthModel(bt_mesh_model *model) {
NimBLEMeshModel* pModel;
for(auto &it : m_elemVec) {
pModel = it->getModelByIdx(model->elem_idx, model->mod_idx, BT_MESH_MODEL_ID_HEALTH_SRV);
if(pModel != nullptr) {
return pModel;
}
}
return nullptr;
}
/** /**
* @brief Start the Mesh mode. * @brief Start the Mesh mode.
* @returns true on success. * @returns true on success.

View file

@ -29,6 +29,8 @@
#include <vector> #include <vector>
class NimBLEMeshModel;
typedef enum { typedef enum {
RELAY = 0x01 << 0, RELAY = 0x01 << 0,
BEACON = 0x01 << 1, BEACON = 0x01 << 1,
@ -40,9 +42,10 @@ class NimBLEMeshElement;
class NimBLEMeshNode { class NimBLEMeshNode {
public: public:
bool start(); bool start();
NimBLEMeshElement* createElement(); NimBLEMeshElement* createElement();
NimBLEMeshElement* getElement(uint8_t index = 0); NimBLEMeshElement* getElement(uint8_t index = 0);
NimBLEMeshModel* getHealthModel(bt_mesh_model *model);
private: private:
friend class NimBLEDevice; friend class NimBLEDevice;