mesh: move model utility functions to mesh_node from access

This commit is contained in:
Matthias Ringwald 2019-07-15 15:11:09 +02:00
parent 812ef2e382
commit 0d42a0592d
6 changed files with 235 additions and 235 deletions

View File

@ -484,13 +484,6 @@ void mesh_delete_appkey_lists(void){
}
}
void mesh_model_reset_appkeys(mesh_model_t * mesh_model){
uint16_t i;
for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
mesh_model->appkey_indices[i] = MESH_APPKEY_INVALID;
}
}
uint8_t mesh_model_bind_appkey(mesh_model_t * mesh_model, uint16_t appkey_index){
uint16_t i;
for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
@ -552,15 +545,6 @@ void mesh_access_key_refresh_revoke_keys(mesh_subnet_t * subnet){
}
}
// Mesh Model Subscription
int mesh_model_contains_subscription(mesh_model_t * mesh_model, uint16_t address){
uint16_t i;
for (i=0;i<MAX_NR_MESH_SUBSCRIPTION_PER_MODEL;i++){
if (mesh_model->subscriptions[i] == address) return 1;
}
return 0;
}
// Mesh IV Index
static uint32_t mesh_tag_for_iv_index_and_seq_number(void){
return ((uint32_t) 'M' << 24) | ((uint32_t) 'F' << 16) | ((uint32_t) 'I' << 9) | ((uint32_t) 'S');

View File

@ -87,9 +87,6 @@ uint8_t mesh_model_bind_appkey(mesh_model_t * mesh_model, uint16_t appkey_index)
void mesh_model_unbind_appkey(mesh_model_t * mesh_model, uint16_t appkey_index);
int mesh_model_contains_appkey(mesh_model_t * mesh_model, uint16_t appkey_index);
// Mesh Model Subscriptions
int mesh_model_contains_subscription(mesh_model_t * mesh_model, uint16_t address);
// temp
void mesh_access_setup_from_provisioning_data(const mesh_provisioning_data_t * provisioning_data);
void mesh_access_setup_without_provisiong_data(void);

View File

@ -66,8 +66,6 @@ static const mesh_operation_t * mesh_model_lookup_operation_by_opcode(mesh_model
static btstack_linked_list_t mesh_access_acknowledged_messages;
static btstack_timer_source_t mesh_access_acknowledged_timer;
static uint16_t mid_counter;
// Transitions
static btstack_linked_list_t transitions;
static btstack_timer_source_t transitions_timer;
@ -384,93 +382,6 @@ uint8_t mesh_access_transactions_get_next_transaction_id(void){
return mesh_transaction_id_counter;
}
// Mesh Node Element functions
uint8_t mesh_access_get_element_index(mesh_model_t * mesh_model){
return mesh_model->element->element_index;
}
uint16_t mesh_access_get_element_address(mesh_model_t * mesh_model){
return mesh_node_get_primary_element_address() + mesh_model->element->element_index;
}
// Model Identifier utilities
uint32_t mesh_model_get_model_identifier(uint16_t vendor_id, uint16_t model_id){
return (vendor_id << 16) | model_id;
}
uint32_t mesh_model_get_model_identifier_bluetooth_sig(uint16_t model_id){
return (BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC << 16) | model_id;
}
uint16_t mesh_model_get_model_id(uint32_t model_identifier){
return model_identifier & 0xFFFFu;
}
uint16_t mesh_model_get_vendor_id(uint32_t model_identifier){
return model_identifier >> 16;
}
int mesh_model_is_bluetooth_sig(uint32_t model_identifier){
return mesh_model_get_vendor_id(model_identifier) == BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC;
}
mesh_model_t * mesh_model_get_configuration_server(void){
return mesh_model_get_by_identifier(mesh_node_get_primary_element(), mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_CONFIGURATION_SERVER));
}
void mesh_element_add_model(mesh_element_t * element, mesh_model_t * mesh_model){
// reset app keys
mesh_model_reset_appkeys(mesh_model);
if (mesh_model_is_bluetooth_sig(mesh_model->model_identifier)){
element->models_count_sig++;
} else {
element->models_count_vendor++;
}
mesh_model->mid = mid_counter++;
mesh_model->element = element;
btstack_linked_list_add_tail(&element->models, (btstack_linked_item_t *) mesh_model);
}
void mesh_model_iterator_init(mesh_model_iterator_t * iterator, mesh_element_t * element){
btstack_linked_list_iterator_init(&iterator->it, &element->models);
}
int mesh_model_iterator_has_next(mesh_model_iterator_t * iterator){
return btstack_linked_list_iterator_has_next(&iterator->it);
}
mesh_model_t * mesh_model_iterator_next(mesh_model_iterator_t * iterator){
return (mesh_model_t *) btstack_linked_list_iterator_next(&iterator->it);
}
mesh_model_t * mesh_model_get_by_identifier(mesh_element_t * element, uint32_t model_identifier){
mesh_model_iterator_t it;
mesh_model_iterator_init(&it, element);
while (mesh_model_iterator_has_next(&it)){
mesh_model_t * model = mesh_model_iterator_next(&it);
if (model->model_identifier != model_identifier) continue;
return model;
}
return NULL;
}
mesh_model_t * mesh_access_model_for_address_and_model_identifier(uint16_t element_address, uint32_t model_identifier, uint8_t * status){
mesh_element_t * element = mesh_node_element_for_unicast_address(element_address);
if (element == NULL){
*status = MESH_FOUNDATION_STATUS_INVALID_ADDRESS;
return NULL;
}
mesh_model_t * model = mesh_model_get_by_identifier(element, model_identifier);
if (model == NULL) {
*status = MESH_FOUNDATION_STATUS_INVALID_MODEL;
} else {
*status = MESH_FOUNDATION_STATUS_SUCCESS;
}
return model;
}
uint16_t mesh_pdu_src(mesh_pdu_t * pdu){
switch (pdu->pdu_type){
case MESH_PDU_TYPE_TRANSPORT:

View File

@ -53,24 +53,8 @@ extern "C"
{
#endif
#define MAX_NR_MESH_APPKEYS_PER_MODEL 3u
#define MAX_NR_MESH_SUBSCRIPTION_PER_MODEL 3u
#define MESH_APPKEY_INVALID 0xffffu
#define MESH_SEQUENCE_NUMBER_STORAGE_INTERVAL 1000
struct mesh_model;
struct mesh_element;
// function to handle model operation message
typedef void (*mesh_operation_handler)(struct mesh_model * mesh_model, mesh_pdu_t * pdu);
// function to publish the current state of a model
// @param mesh_model to publish
// @returns mesh_pdu with status message
typedef mesh_pdu_t * (*mesh_publish_state_t)(struct mesh_model * mesh_model);
typedef enum {
MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_100ms = 0x00u,
MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_1s,
@ -104,71 +88,6 @@ typedef enum {
MODEL_STATE_ID_GENERIC_LEVEL = (BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC << 16) | 1u,
} model_state_id_t;
typedef enum {
MESH_MODEL_PUBLICATION_STATE_IDLE,
MESH_MODEL_PUBLICATION_STATE_W4_PUBLICATION_MS,
MESH_MODEL_PUBLICATION_STATE_W4_RETRANSMIT_MS,
} mesh_model_publication_state_t;
typedef struct {
mesh_publish_state_t publish_state_fn;
mesh_model_publication_state_t state;
uint32_t next_publication_ms;
uint32_t next_retransmit_ms;
uint8_t retransmit_count;
uint8_t publish_now;
uint16_t address;
uint16_t appkey_index;
uint8_t friendship_credential_flag;
uint8_t period;
uint8_t ttl;
uint8_t retransmit;
} mesh_publication_model_t;
typedef struct {
uint32_t opcode;
uint16_t minimum_length;
mesh_operation_handler handler;
} mesh_operation_t;
typedef struct mesh_model {
// linked list item
btstack_linked_item_t item;
// element
struct mesh_element * element;
// internal model enumeration
uint16_t mid;
// vendor_id << 16 | model id, use BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC for SIG models
uint32_t model_identifier;
// model operations
const mesh_operation_t * operations;
// publication model if supported
mesh_publication_model_t * publication_model;
// data
void * model_data;
// bound appkeys
uint16_t appkey_indices[MAX_NR_MESH_APPKEYS_PER_MODEL];
// subscription list
uint16_t subscriptions[MAX_NR_MESH_SUBSCRIPTION_PER_MODEL];
// packet handler for transition events in server, event callback handler in client
btstack_packet_handler_t model_packet_handler;
} mesh_model_t;
typedef struct {
btstack_linked_list_iterator_t it;
} mesh_model_iterator_t;
#define MESH_MAX_NUM_FAULTS 3
typedef struct {
@ -253,51 +172,6 @@ void mesh_access_send_unacknowledged_pdu(mesh_pdu_t * pdu);
*/
void mesh_access_send_acknowledged_pdu(mesh_pdu_t * pdu, uint8_t retransmissions, uint32_t ack_opcode);
/**
* @brief Get element index for give model
* @param mesh_model
*/
uint8_t mesh_access_get_element_index(mesh_model_t * mesh_model);
/**
* @brief Get unicast address for give model
* @param mesh_model
*/
uint16_t mesh_access_get_element_address(mesh_model_t * mesh_model);
/**
* @brief Add model to element
* @param element
* @param mesh_model
*/
void mesh_element_add_model(mesh_element_t * element, mesh_model_t * mesh_model);
// Mesh Model Iterator
void mesh_model_iterator_init(mesh_model_iterator_t * iterator, mesh_element_t * element);
int mesh_model_iterator_has_next(mesh_model_iterator_t * iterator);
mesh_model_t * mesh_model_iterator_next(mesh_model_iterator_t * iterator);
// Mesh Model Utility
mesh_model_t * mesh_model_get_by_identifier(mesh_element_t * element, uint32_t model_identifier);
uint32_t mesh_model_get_model_identifier_bluetooth_sig(uint16_t model_id);
int mesh_model_is_bluetooth_sig(uint32_t model_identifier);
uint16_t mesh_model_get_model_id(uint32_t model_identifier);
uint32_t mesh_model_get_model_identifier(uint16_t vendor_id, uint16_t model_id);
uint16_t mesh_model_get_vendor_id(uint32_t model_identifier);
mesh_model_t * mesh_model_get_configuration_server(void);
mesh_model_t * mesh_access_model_for_address_and_model_identifier(uint16_t element_address, uint32_t model_identifier, uint8_t * status);
uint8_t mesh_access_transitions_num_steps_from_gdtt(uint8_t time_gdtt);
uint32_t mesh_access_time_gdtt2ms(uint8_t time_gdtt);

View File

@ -37,6 +37,9 @@
#define __BTSTACK_FILE__ "mesh_node.c"
#include "bluetooth_company_id.h"
#include "mesh/mesh_foundation.h"
#include "mesh/mesh_node.h"
#include <stddef.h>
@ -50,6 +53,8 @@ static uint16_t mesh_element_index_next;
static btstack_linked_list_t mesh_elements;
static uint16_t mid_counter;
static uint8_t mesh_node_device_uuid[16];
static int mesh_node_have_device_uuid;
@ -116,6 +121,108 @@ mesh_element_t * mesh_element_iterator_next(mesh_element_iterator_t * iterator){
return (mesh_element_t *) btstack_linked_list_iterator_next(&iterator->it);
}
// Mesh Node Element functions
uint8_t mesh_access_get_element_index(mesh_model_t * mesh_model){
return mesh_model->element->element_index;
}
uint16_t mesh_access_get_element_address(mesh_model_t * mesh_model){
return mesh_node_get_primary_element_address() + mesh_model->element->element_index;
}
// Model Identifier utilities
uint32_t mesh_model_get_model_identifier(uint16_t vendor_id, uint16_t model_id){
return (vendor_id << 16) | model_id;
}
uint32_t mesh_model_get_model_identifier_bluetooth_sig(uint16_t model_id){
return (BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC << 16) | model_id;
}
uint16_t mesh_model_get_model_id(uint32_t model_identifier){
return model_identifier & 0xFFFFu;
}
uint16_t mesh_model_get_vendor_id(uint32_t model_identifier){
return model_identifier >> 16;
}
int mesh_model_is_bluetooth_sig(uint32_t model_identifier){
return mesh_model_get_vendor_id(model_identifier) == BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC;
}
mesh_model_t * mesh_model_get_configuration_server(void){
return mesh_model_get_by_identifier(mesh_node_get_primary_element(), mesh_model_get_model_identifier_bluetooth_sig(MESH_SIG_MODEL_ID_CONFIGURATION_SERVER));
}
void mesh_model_reset_appkeys(mesh_model_t * mesh_model){
uint16_t i;
for (i=0;i<MAX_NR_MESH_APPKEYS_PER_MODEL;i++){
mesh_model->appkey_indices[i] = MESH_APPKEY_INVALID;
}
}
void mesh_element_add_model(mesh_element_t * element, mesh_model_t * mesh_model){
// reset app keys
mesh_model_reset_appkeys(mesh_model);
if (mesh_model_is_bluetooth_sig(mesh_model->model_identifier)){
element->models_count_sig++;
} else {
element->models_count_vendor++;
}
mesh_model->mid = mid_counter++;
mesh_model->element = element;
btstack_linked_list_add_tail(&element->models, (btstack_linked_item_t *) mesh_model);
}
void mesh_model_iterator_init(mesh_model_iterator_t * iterator, mesh_element_t * element){
btstack_linked_list_iterator_init(&iterator->it, &element->models);
}
int mesh_model_iterator_has_next(mesh_model_iterator_t * iterator){
return btstack_linked_list_iterator_has_next(&iterator->it);
}
mesh_model_t * mesh_model_iterator_next(mesh_model_iterator_t * iterator){
return (mesh_model_t *) btstack_linked_list_iterator_next(&iterator->it);
}
mesh_model_t * mesh_model_get_by_identifier(mesh_element_t * element, uint32_t model_identifier){
mesh_model_iterator_t it;
mesh_model_iterator_init(&it, element);
while (mesh_model_iterator_has_next(&it)){
mesh_model_t * model = mesh_model_iterator_next(&it);
if (model->model_identifier != model_identifier) continue;
return model;
}
return NULL;
}
mesh_model_t * mesh_access_model_for_address_and_model_identifier(uint16_t element_address, uint32_t model_identifier, uint8_t * status){
mesh_element_t * element = mesh_node_element_for_unicast_address(element_address);
if (element == NULL){
*status = MESH_FOUNDATION_STATUS_INVALID_ADDRESS;
return NULL;
}
mesh_model_t * model = mesh_model_get_by_identifier(element, model_identifier);
if (model == NULL) {
*status = MESH_FOUNDATION_STATUS_INVALID_MODEL;
} else {
*status = MESH_FOUNDATION_STATUS_SUCCESS;
}
return model;
}
// Mesh Model Subscription
int mesh_model_contains_subscription(mesh_model_t * mesh_model, uint16_t address){
uint16_t i;
for (i=0;i<MAX_NR_MESH_SUBSCRIPTION_PER_MODEL;i++){
if (mesh_model->subscriptions[i] == address) return 1;
}
return 0;
}
void mesh_node_set_device_uuid(const uint8_t * device_uuid){
memcpy(mesh_node_device_uuid, device_uuid, 16);
mesh_node_have_device_uuid = 1;

View File

@ -41,11 +41,92 @@
#include <stdint.h>
#include "btstack_linked_list.h"
#include "mesh/mesh_network.h"
#if defined __cplusplus
extern "C" {
#endif
#define MESH_APPKEY_INVALID 0xffffu
#define MAX_NR_MESH_APPKEYS_PER_MODEL 3u
#define MAX_NR_MESH_SUBSCRIPTION_PER_MODEL 3u
struct mesh_model;
struct mesh_element;
// function to handle model operation message
typedef void (*mesh_operation_handler)(struct mesh_model * mesh_model, mesh_pdu_t * pdu);
// function to publish the current state of a model
// @param mesh_model to publish
// @returns mesh_pdu with status message
typedef mesh_pdu_t * (*mesh_publish_state_t)(struct mesh_model * mesh_model);
typedef enum {
MESH_MODEL_PUBLICATION_STATE_IDLE,
MESH_MODEL_PUBLICATION_STATE_W4_PUBLICATION_MS,
MESH_MODEL_PUBLICATION_STATE_W4_RETRANSMIT_MS,
} mesh_model_publication_state_t;
typedef struct {
mesh_publish_state_t publish_state_fn;
mesh_model_publication_state_t state;
uint32_t next_publication_ms;
uint32_t next_retransmit_ms;
uint8_t retransmit_count;
uint8_t publish_now;
uint16_t address;
uint16_t appkey_index;
uint8_t friendship_credential_flag;
uint8_t period;
uint8_t ttl;
uint8_t retransmit;
} mesh_publication_model_t;
typedef struct {
uint32_t opcode;
uint16_t minimum_length;
mesh_operation_handler handler;
} mesh_operation_t;
typedef struct mesh_model {
// linked list item
btstack_linked_item_t item;
// element
struct mesh_element * element;
// internal model enumeration
uint16_t mid;
// vendor_id << 16 | model id, use BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC for SIG models
uint32_t model_identifier;
// model operations
const mesh_operation_t * operations;
// publication model if supported
mesh_publication_model_t * publication_model;
// data
void * model_data;
// bound appkeys
uint16_t appkey_indices[MAX_NR_MESH_APPKEYS_PER_MODEL];
// subscription list
uint16_t subscriptions[MAX_NR_MESH_SUBSCRIPTION_PER_MODEL];
// packet handler for transition events in server, event callback handler in client
btstack_packet_handler_t model_packet_handler;
} mesh_model_t;
typedef struct {
btstack_linked_list_iterator_t it;
} mesh_model_iterator_t;
typedef struct mesh_element {
// linked list item
btstack_linked_item_t item;
@ -124,15 +205,61 @@ mesh_element_t * mesh_node_element_for_unicast_address(uint16_t unicast_address)
*/
mesh_element_t * mesh_node_element_for_index(uint16_t element_index);
/**
* @brief Get element index for give model
* @param mesh_model
*/
uint8_t mesh_access_get_element_index(mesh_model_t * mesh_model);
/**
* @brief Get unicast address for give model
* @param mesh_model
*/
uint16_t mesh_access_get_element_address(mesh_model_t * mesh_model);
/**
* @brief Add model to element
* @param element
* @param mesh_model
*/
void mesh_element_add_model(mesh_element_t * element, mesh_model_t * mesh_model);
// Mesh Element Iterator
void mesh_element_iterator_init(mesh_element_iterator_t * iterator);
int mesh_element_iterator_has_next(mesh_element_iterator_t * iterator);
mesh_element_t * mesh_element_iterator_next(mesh_element_iterator_t * iterator);
// Mesh Model Iterator
void mesh_model_iterator_init(mesh_model_iterator_t * iterator, mesh_element_t * element);
int mesh_model_iterator_has_next(mesh_model_iterator_t * iterator);
mesh_model_t * mesh_model_iterator_next(mesh_model_iterator_t * iterator);
// Mesh Model Utility
mesh_model_t * mesh_model_get_by_identifier(mesh_element_t * element, uint32_t model_identifier);
uint32_t mesh_model_get_model_identifier_bluetooth_sig(uint16_t model_id);
int mesh_model_is_bluetooth_sig(uint32_t model_identifier);
uint16_t mesh_model_get_model_id(uint32_t model_identifier);
uint32_t mesh_model_get_model_identifier(uint16_t vendor_id, uint16_t model_id);
uint16_t mesh_model_get_vendor_id(uint32_t model_identifier);
mesh_model_t * mesh_model_get_configuration_server(void);
mesh_model_t * mesh_access_model_for_address_and_model_identifier(uint16_t element_address, uint32_t model_identifier, uint8_t * status);
// Mesh Model Subscriptions
int mesh_model_contains_subscription(mesh_model_t * mesh_model, uint16_t address);
/**
* @brief Set Device UUID
* @param device_uuid