From 56c68d7eea8492800242f4d0c94993c79efcdd6f Mon Sep 17 00:00:00 2001 From: h2zero Date: Tue, 15 Sep 2020 22:11:42 -0600 Subject: [PATCH] Add support for app created health server models. --- src/NimBLEMeshElement.cpp | 26 +++++++++--- src/NimBLEMeshElement.h | 4 +- src/NimBLEMeshModel.cpp | 85 +++++++++++++++++++++++++++++++++++++-- src/NimBLEMeshModel.h | 43 ++++++++++++++++++-- src/NimBLEMeshNode.cpp | 73 ++------------------------------- src/NimBLEMeshNode.h | 22 ---------- 6 files changed, 148 insertions(+), 105 deletions(-) diff --git a/src/NimBLEMeshElement.cpp b/src/NimBLEMeshElement.cpp index ef40f67..43b2e65 100644 --- a/src/NimBLEMeshElement.cpp +++ b/src/NimBLEMeshElement.cpp @@ -12,15 +12,19 @@ static const char* LOG_TAG = "NimBLEMeshElement"; NimBLEMeshElement::NimBLEMeshElement() { - m_pElem = nullptr; + m_pElem_t = nullptr; } NimBLEMeshElement::~NimBLEMeshElement() { - if(m_pElem != nullptr) { - delete m_pElem; + if(m_pElem_t != nullptr) { + delete m_pElem_t; } + delete m_pHealthModel; + for(auto &it : m_modelsVec) { - delete (NimBLEMeshModel*)it.user_data; + if(it.id != BT_MESH_MODEL_ID_HEALTH_SRV) { + delete (NimBLEMeshModel*)it.user_data; + } } m_modelsVec.clear(); @@ -51,6 +55,12 @@ NimBLEMeshModel* NimBLEMeshElement::createModel(uint16_t type, NimBLEMeshModelCa pModel = new NimBLEGenLevelSrvModel(pCallbacks); break; + case BT_MESH_MODEL_ID_HEALTH_SRV: + m_pHealthModel = new NimBLEHealthSrvModel(pCallbacks); + 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()}); + return pModel; + default: NIMBLE_LOGE(LOG_TAG, "Error: model type %04x not supported", type); return nullptr; @@ -70,6 +80,10 @@ void NimBLEMeshElement::addModel(bt_mesh_model* model) { NimBLEMeshModel* NimBLEMeshElement::getModel(uint16_t type) { + if(type == BT_MESH_MODEL_ID_HEALTH_SRV) { + return m_pHealthModel; + } + for(auto &it : m_modelsVec) { if(it.id == type) { return (NimBLEMeshModel*)it.user_data; @@ -86,8 +100,8 @@ NimBLEMeshModel* NimBLEMeshElement::getModel(uint16_t type) { * @details Must not be called until all models have been added. */ bt_mesh_elem* NimBLEMeshElement::start() { - m_pElem = new bt_mesh_elem{0, 0, uint8_t(m_modelsVec.size()), 0, &m_modelsVec[0], NULL}; - return m_pElem; + m_pElem_t = new bt_mesh_elem{0, 0, uint8_t(m_modelsVec.size()), 0, &m_modelsVec[0], NULL}; + return m_pElem_t; } diff --git a/src/NimBLEMeshElement.h b/src/NimBLEMeshElement.h index d276d76..257c9ad 100644 --- a/src/NimBLEMeshElement.h +++ b/src/NimBLEMeshElement.h @@ -20,6 +20,7 @@ class NimBLEMeshModelCallbacks; class NimBLEMeshModel; +class NimBLEHealthSrvModel; class NimBLEMeshElement { public: @@ -34,7 +35,8 @@ private: void addModel(bt_mesh_model* model); bt_mesh_elem* start(); - bt_mesh_elem *m_pElem; + bt_mesh_elem *m_pElem_t; + NimBLEHealthSrvModel* m_pHealthModel; std::vector m_modelsVec; }; diff --git a/src/NimBLEMeshModel.cpp b/src/NimBLEMeshModel.cpp index 7ec762f..8bddc5b 100644 --- a/src/NimBLEMeshModel.cpp +++ b/src/NimBLEMeshModel.cpp @@ -16,6 +16,15 @@ static const char* LOG_TAG = "NimBLEMeshModel"; static NimBLEMeshModelCallbacks defaultCallbacks; +static const struct bt_mesh_health_srv_cb health_srv_cb = { + NimBLEHealthSrvCallbacks::faultGetCurrent, + NimBLEHealthSrvCallbacks::faultGetRegistered, + NimBLEHealthSrvCallbacks::faultClear, + NimBLEHealthSrvCallbacks::faultTest, + NimBLEHealthSrvCallbacks::attentionOn, + NimBLEHealthSrvCallbacks::attentionOff +}; + /** * @brief base model constructor * @param [in] pCallbacks, a pointer to a callback instance for model operations @@ -113,15 +122,21 @@ void NimBLEMeshModel::publish() { ble_npl_callout_reset(&m_pubTimer, 1); } + uint32_t NimBLEMeshModel::getTransTime() { return (m_transTime & 0x3F) * NimBLEUtils::meshTransTimeMs(m_transTime); } + uint16_t NimBLEMeshModel::getDelayTime() { return m_delayTime * 5; } +bt_mesh_health_srv* NimBLEMeshModel::getHealth_t() { + return nullptr; +} + /** * @brief Generic on/off server model constructor * @param [in] pCallbacks, a pointer to a callback instance for model operations @@ -142,7 +157,7 @@ NimBLEGenOnOffSrvModel::NimBLEGenOnOffSrvModel(NimBLEMeshModelCallbacks *pCallba NimBLEGenOnOffSrvModel::pubTimerCb, this); m_opPub.msg = NET_BUF_SIMPLE(2 + 3); - + m_value.push_back(0); m_targetValue.push_back(0); } @@ -310,7 +325,7 @@ NimBLEGenLevelSrvModel::NimBLEGenLevelSrvModel(NimBLEMeshModelCallbacks *pCallba ble_npl_callout_init(&m_pubTimer, nimble_port_get_dflt_eventq(), NimBLEGenLevelSrvModel::pubTimerCb, this); m_opPub.msg = NET_BUF_SIMPLE(2 + 5); - + m_value.assign(2, 0); m_targetValue.assign(2, 0); } @@ -371,9 +386,9 @@ void NimBLEGenLevelSrvModel::setLevelUnack(bt_mesh_model *model, ble_npl_callout_stop(&pModel->m_tdTimer); ble_npl_time_t timerMs = 0; - + int16_t curval = *(int16_t*)&pModel->m_value[0]; - + if(newval != curval) { pModel->m_targetValue.assign({(uint8_t)newval, (uint8_t)(newval >> 8)}); @@ -488,6 +503,7 @@ void NimBLEGenLevelSrvModel::pubTimerCb(ble_npl_event *event) { } } + void NimBLEGenLevelSrvModel::setPubMsg() { bt_mesh_model_msg_init(m_opPub.msg, BT_MESH_MODEL_OP_2(0x82, 0x08)); net_buf_simple_add_le16(m_opPub.msg, *(int16_t*)&m_value[0]); @@ -499,6 +515,7 @@ void NimBLEGenLevelSrvModel::setPubMsg() { } } + void NimBLEGenLevelSrvModel::setValue(uint8_t *val, size_t len) { if(len != sizeof(int16_t)) { NIMBLE_LOGE(LOG_TAG, "NimBLEGenLevelSrvModel: Incorrect value length"); @@ -507,6 +524,7 @@ void NimBLEGenLevelSrvModel::setValue(uint8_t *val, size_t len) { m_value.assign({*val, val[1]}); } + void NimBLEGenLevelSrvModel::setTargetValue(uint8_t *val, size_t len) { if(len != sizeof(int16_t)) { NIMBLE_LOGE(LOG_TAG, "NimBLEGenLevelSrvModel: Incorrect target value length"); @@ -515,6 +533,24 @@ void NimBLEGenLevelSrvModel::setTargetValue(uint8_t *val, size_t len) { m_targetValue.assign({*val, val[1]}); } + +/** + * @brief Health server model constructor + * @param [in] pCallbacks, a pointer to a callback instance for model operations + */ +NimBLEHealthSrvModel::NimBLEHealthSrvModel(NimBLEMeshModelCallbacks *pCallbacks) +:NimBLEMeshModel(pCallbacks) +{ + memset(&m_healthSrv, 0, sizeof(m_healthSrv)); + m_healthSrv.cb = &health_srv_cb; +} + + +bt_mesh_health_srv* NimBLEHealthSrvModel::getHealth_t() { + return &m_healthSrv; +} + + /** * Default model callbacks */ @@ -537,3 +573,44 @@ int16_t NimBLEMeshModelCallbacks::getLevel(NimBLEMeshModel *pModel) { NIMBLE_LOGD(LOG_TAG, "Gen Level get"); return 0; } + +/** + * @brief Health server callbacks + */ +int NimBLEHealthSrvCallbacks::faultGetCurrent(bt_mesh_model *model, uint8_t *test_id, + uint16_t *company_id, uint8_t *faults, + uint8_t *fault_count) +{ + NIMBLE_LOGD(LOG_TAG, "faultGetCurrent - default"); + return 0; +} + +int NimBLEHealthSrvCallbacks::faultGetRegistered(bt_mesh_model *model, uint16_t company_id, + uint8_t *test_id, uint8_t *faults, + uint8_t *fault_count) +{ + NIMBLE_LOGD(LOG_TAG, "faultGetRegistered - default"); + return 0; +} + +int NimBLEHealthSrvCallbacks::faultClear(bt_mesh_model *model, uint16_t company_id) +{ + NIMBLE_LOGD(LOG_TAG, "faultClear - default"); + return 0; +} + +int NimBLEHealthSrvCallbacks::faultTest(bt_mesh_model *model, uint8_t test_id, uint16_t company_id) +{ + NIMBLE_LOGD(LOG_TAG, "faultTest - default"); + return 0; +} + +void NimBLEHealthSrvCallbacks::attentionOn(bt_mesh_model *model) +{ + NIMBLE_LOGD(LOG_TAG, "attentionOn - default"); +} + +void NimBLEHealthSrvCallbacks::attentionOff(bt_mesh_model *model) +{ + NIMBLE_LOGD(LOG_TAG, "attentionOff - default"); +} diff --git a/src/NimBLEMeshModel.h b/src/NimBLEMeshModel.h index b8ec725..98b8c96 100644 --- a/src/NimBLEMeshModel.h +++ b/src/NimBLEMeshModel.h @@ -33,22 +33,23 @@ public: virtual void setPubMsg(){}; virtual void setValue(uint8_t *val, size_t len){}; virtual void setTargetValue(uint8_t *val, size_t len){}; + virtual bt_mesh_health_srv* getHealth_t(); template void setValue(const T &s) { setValue((uint8_t*)&s, sizeof(T)); } - + template void setTargetValue(const T &s) { setTargetValue((uint8_t*)&s, sizeof(T)); } - + template void getValue(T &s) { s = (T)m_value[0]; } - + template void getTargetValue(T &s) { s = (T)m_targetValue[0]; @@ -71,6 +72,7 @@ public: ble_npl_callout m_pubTimer; }; + class NimBLEGenOnOffSrvModel : NimBLEMeshModel { friend class NimBLEMeshElement; friend class NimBLEMeshNode; @@ -95,6 +97,7 @@ class NimBLEGenOnOffSrvModel : NimBLEMeshModel { void setTargetValue(uint8_t *val, size_t len) override; }; + class NimBLEGenLevelSrvModel : NimBLEMeshModel { friend class NimBLEMeshElement; friend class NimBLEMeshNode; @@ -131,6 +134,20 @@ class NimBLEGenLevelSrvModel : NimBLEMeshModel { void setTargetValue(uint8_t *val, size_t len) override; }; + +class NimBLEHealthSrvModel : NimBLEMeshModel { + friend class NimBLEMeshElement; + friend class NimBLEMeshNode; + + NimBLEHealthSrvModel(NimBLEMeshModelCallbacks *pCallbacks); + ~NimBLEHealthSrvModel(){}; + + bt_mesh_health_srv* getHealth_t() override; + + bt_mesh_health_srv m_healthSrv; +}; + + class NimBLEMeshModelCallbacks { public: virtual ~NimBLEMeshModelCallbacks(); @@ -140,5 +157,25 @@ public: virtual int16_t getLevel(NimBLEMeshModel *pModel); }; + +class NimBLEHealthSrvCallbacks { +public: + static int faultGetCurrent(bt_mesh_model *model, uint8_t *test_id, + uint16_t *company_id, uint8_t *faults, + uint8_t *fault_count); + + static int faultGetRegistered(bt_mesh_model *model, uint16_t company_id, + uint8_t *test_id, uint8_t *faults, + uint8_t *fault_count); + + static int faultClear(bt_mesh_model *model, uint16_t company_id); + + static int faultTest(bt_mesh_model *model, uint8_t test_id, uint16_t company_id); + + static void attentionOn(bt_mesh_model *model); + + static void attentionOff(bt_mesh_model *model); +}; + #endif // CONFIG_BT_ENABLED #endif // MAIN_NIMBLE_MESH_MODEL_H_ \ No newline at end of file diff --git a/src/NimBLEMeshNode.cpp b/src/NimBLEMeshNode.cpp index 2dc64a0..6a332d8 100644 --- a/src/NimBLEMeshNode.cpp +++ b/src/NimBLEMeshNode.cpp @@ -20,17 +20,6 @@ static const char* LOG_TAG = "NimBLEMeshNode"; -/** - * Health server callback struct - */ -static const struct bt_mesh_health_srv_cb health_srv_cb = { - NimBLEHealthSrvCallbacks::faultGetCurrent, - NimBLEHealthSrvCallbacks::faultGetRegistered, - NimBLEHealthSrvCallbacks::faultClear, - NimBLEHealthSrvCallbacks::faultTest, - NimBLEHealthSrvCallbacks::attentionOn, - NimBLEHealthSrvCallbacks::attentionOff -}; /** * @brief Construct a mesh node. @@ -43,8 +32,6 @@ NimBLEMeshNode::NimBLEMeshNode(const NimBLEUUID &uuid, uint8_t type) { memset(&m_serverConfig, 0, sizeof(m_serverConfig)); memset(&m_prov, 0, sizeof(m_prov)); memset(&m_comp, 0, sizeof(m_comp)); - memset(&m_healthPub, 0, sizeof(m_healthPub)); - memset(&m_healthSrv, 0, sizeof(m_healthSrv)); // Default server config m_serverConfig.relay = BT_MESH_RELAY_DISABLED;/*(type & NIMBLE_MESH::RELAY) ? @@ -66,12 +53,6 @@ NimBLEMeshNode::NimBLEMeshNode(const NimBLEUUID &uuid, uint8_t type) { m_serverConfig.net_transmit = BT_MESH_TRANSMIT(2, 20); m_serverConfig.relay_retransmit = BT_MESH_TRANSMIT(2, 20); - // Default health server config - m_healthSrv.cb = &health_srv_cb; - - // Default health pub config - m_healthPub.msg = BT_MESH_HEALTH_FAULT_MSG(0); - // Provisioning config m_uuid = uuid; m_prov.uuid = m_uuid.getNative()->u128.value; @@ -79,7 +60,6 @@ NimBLEMeshNode::NimBLEMeshNode(const NimBLEUUID &uuid, uint8_t type) { m_prov.reset = NimBLEMeshNode::provReset; m_configSrvModel = nullptr; - m_configHthModel = nullptr; // Create the primary element m_elemVec.push_back(new NimBLEMeshElement()); @@ -94,10 +74,6 @@ NimBLEMeshNode::~NimBLEMeshNode() { delete m_configSrvModel; } - if(m_configHthModel != nullptr) { - delete m_configHthModel; - } - if(m_comp.elem != nullptr) { free (m_comp.elem); } @@ -175,10 +151,11 @@ bool NimBLEMeshNode::start() { m_configSrvModel->groups[i] = BT_MESH_ADDR_UNASSIGNED; } - m_configHthModel = new bt_mesh_model{{BT_MESH_MODEL_ID_HEALTH_SRV},0,0,0,&m_healthPub,{0},{0},bt_mesh_health_srv_op,&m_healthSrv}; - m_elemVec[0]->addModel(m_configSrvModel); - m_elemVec[0]->addModel(m_configHthModel); + + if(m_elemVec[0]->getModel(BT_MESH_MODEL_ID_HEALTH_SRV) == nullptr) { + m_elemVec[0]->createModel(BT_MESH_MODEL_ID_HEALTH_SRV); + } // setup node composition m_comp.cid = CID_VENDOR; @@ -218,46 +195,4 @@ bool NimBLEMeshNode::start() { } -/** - * @brief Health server callbacks - */ -int NimBLEHealthSrvCallbacks::faultGetCurrent(bt_mesh_model *model, uint8_t *test_id, - uint16_t *company_id, uint8_t *faults, - uint8_t *fault_count) -{ - NIMBLE_LOGD(LOG_TAG, "faultGetCurrent - default"); - return 0; -} - -int NimBLEHealthSrvCallbacks::faultGetRegistered(bt_mesh_model *model, uint16_t company_id, - uint8_t *test_id, uint8_t *faults, - uint8_t *fault_count) -{ - NIMBLE_LOGD(LOG_TAG, "faultGetRegistered - default"); - return 0; -} - -int NimBLEHealthSrvCallbacks::faultClear(bt_mesh_model *model, uint16_t company_id) -{ - NIMBLE_LOGD(LOG_TAG, "faultClear - default"); - return 0; -} - -int NimBLEHealthSrvCallbacks::faultTest(bt_mesh_model *model, uint8_t test_id, uint16_t company_id) -{ - NIMBLE_LOGD(LOG_TAG, "faultTest - default"); - return 0; -} - -void NimBLEHealthSrvCallbacks::attentionOn(bt_mesh_model *model) -{ - NIMBLE_LOGD(LOG_TAG, "attentionOn - default"); -} - -void NimBLEHealthSrvCallbacks::attentionOff(bt_mesh_model *model) -{ - NIMBLE_LOGD(LOG_TAG, "attentionOff - default"); -} - - #endif // CONFIG_BT_ENABLED \ No newline at end of file diff --git a/src/NimBLEMeshNode.h b/src/NimBLEMeshNode.h index 6862ca5..8ce35dc 100644 --- a/src/NimBLEMeshNode.h +++ b/src/NimBLEMeshNode.h @@ -60,33 +60,11 @@ private: uint16_t m_primAddr; uint16_t m_primNetIdx; bt_mesh_model* m_configSrvModel; - bt_mesh_model* m_configHthModel; - bt_mesh_health_srv m_healthSrv; - bt_mesh_model_pub m_healthPub; NimBLEUUID m_uuid; std::vector m_elemVec; }; -class NimBLEHealthSrvCallbacks { -public: - static int faultGetCurrent(bt_mesh_model *model, uint8_t *test_id, - uint16_t *company_id, uint8_t *faults, - uint8_t *fault_count); - - static int faultGetRegistered(bt_mesh_model *model, uint16_t company_id, - uint8_t *test_id, uint8_t *faults, - uint8_t *fault_count); - - static int faultClear(bt_mesh_model *model, uint16_t company_id); - - static int faultTest(bt_mesh_model *model, uint8_t test_id, uint16_t company_id); - - static void attentionOn(bt_mesh_model *model); - - static void attentionOff(bt_mesh_model *model); -}; - #endif // CONFIG_BT_ENABLED #endif // MAIN_NIMBLE_MESH_NODE_H_ \ No newline at end of file