mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-29 21:32:38 +00:00
mesh: introduce transaction status
This commit is contained in:
parent
4963ec13ad
commit
f649fbc8b3
@ -47,6 +47,8 @@
|
|||||||
#include "mesh_foundation.h"
|
#include "mesh_foundation.h"
|
||||||
#include "btstack_tlv.h"
|
#include "btstack_tlv.h"
|
||||||
|
|
||||||
|
#define MEST_TRANSACTION_TIMEOUT_MS 6000
|
||||||
|
|
||||||
static void mesh_access_message_process_handler(mesh_pdu_t * pdu);
|
static void mesh_access_message_process_handler(mesh_pdu_t * pdu);
|
||||||
|
|
||||||
static uint16_t primary_element_address;
|
static uint16_t primary_element_address;
|
||||||
@ -111,6 +113,31 @@ void mesh_access_emit_state_update_int16(btstack_packet_handler_t * event_handle
|
|||||||
|
|
||||||
// Mesh Model Transitions
|
// Mesh Model Transitions
|
||||||
|
|
||||||
|
void mesh_access_transitions_setup_transaction(mesh_transition_t * transition, uint8_t transaction_identifier, uint16_t src_address, uint16_t dst_address){
|
||||||
|
transition->transaction_timestamp_ms = btstack_run_loop_get_time_ms();
|
||||||
|
transition->transaction_identifier = transaction_identifier;
|
||||||
|
transition->src_address = src_address;
|
||||||
|
transition->dst_address = dst_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mesh_access_transitions_abort_transaction(mesh_transition_t * transition){
|
||||||
|
mesh_access_transitions_remove(transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int mesh_access_transitions_transaction_is_expired(mesh_transition_t * transition){
|
||||||
|
return (btstack_run_loop_get_time_ms() - transition->transaction_timestamp_ms) > MEST_TRANSACTION_TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh_transaction_status_t mesh_access_transitions_transaction_status(mesh_transition_t * transition, uint8_t transaction_identifier, uint16_t src_address, uint16_t dst_address){
|
||||||
|
if (transition->src_address != src_address || transition->dst_address != dst_address) return MESH_TRANSACTION_STATUS_DIFFERENT_DST_OR_SRC;
|
||||||
|
|
||||||
|
if (transition->transaction_identifier == transaction_identifier && !mesh_access_transitions_transaction_is_expired(transition)){
|
||||||
|
return MESH_TRANSACTION_STATUS_RETRANSMISSION;
|
||||||
|
}
|
||||||
|
return MESH_TRANSACTION_STATUS_NEW;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t mesh_access_transitions_num_steps_from_gdtt(uint8_t transition_time_gdtt){
|
uint8_t mesh_access_transitions_num_steps_from_gdtt(uint8_t transition_time_gdtt){
|
||||||
return transition_time_gdtt >> 2;
|
return transition_time_gdtt >> 2;
|
||||||
}
|
}
|
||||||
|
@ -173,16 +173,26 @@ typedef struct {
|
|||||||
const char * format;
|
const char * format;
|
||||||
} mesh_access_message_t;
|
} mesh_access_message_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MESH_TRANSACTION_STATUS_NEW = 0,
|
||||||
|
MESH_TRANSACTION_STATUS_RETRANSMISSION,
|
||||||
|
MESH_TRANSACTION_STATUS_DIFFERENT_DST_OR_SRC
|
||||||
|
} mesh_transaction_status_t;
|
||||||
|
|
||||||
typedef struct mesh_transition {
|
typedef struct mesh_transition {
|
||||||
btstack_linked_item_t item;
|
btstack_linked_item_t item;
|
||||||
|
|
||||||
mesh_transition_state_t state;
|
mesh_transition_state_t state;
|
||||||
|
|
||||||
|
uint8_t transaction_identifier;
|
||||||
|
uint32_t transaction_timestamp_ms;
|
||||||
|
uint16_t src_address;
|
||||||
|
uint16_t dst_address;
|
||||||
|
|
||||||
mesh_default_transition_step_resolution_t step_duration_ms;
|
mesh_default_transition_step_resolution_t step_duration_ms;
|
||||||
uint32_t phase_start_ms;
|
uint32_t phase_start_ms;
|
||||||
uint32_t remaining_delay_time_ms;
|
uint32_t remaining_delay_time_ms;
|
||||||
uint32_t remaining_transition_time_ms;
|
uint32_t remaining_transition_time_ms;
|
||||||
|
|
||||||
// to send events and/or publish changes
|
// to send events and/or publish changes
|
||||||
mesh_model_t * mesh_model;
|
mesh_model_t * mesh_model;
|
||||||
|
|
||||||
@ -257,6 +267,10 @@ void mesh_access_emit_state_update_int16(btstack_packet_handler_t * event_handle
|
|||||||
model_state_id_t state_identifier, model_state_update_reason_t reason, int16_t value);
|
model_state_id_t state_identifier, model_state_update_reason_t reason, int16_t value);
|
||||||
|
|
||||||
// Mesh Model Transitions
|
// Mesh Model Transitions
|
||||||
|
void mesh_access_transitions_setup_transaction(mesh_transition_t * transition, uint8_t transaction_identifier, uint16_t src_address, uint16_t dst_address);
|
||||||
|
void mesh_access_transitions_abort_transaction(mesh_transition_t * transition);
|
||||||
|
mesh_transaction_status_t mesh_access_transitions_transaction_status(mesh_transition_t * transition, uint8_t transaction_identifier, uint16_t src_address, uint16_t dst_address);
|
||||||
|
|
||||||
void mesh_access_transitions_setup(mesh_transition_t * transition, mesh_model_t * mesh_model,
|
void mesh_access_transitions_setup(mesh_transition_t * transition, mesh_model_t * mesh_model,
|
||||||
uint8_t transition_time_gdtt, uint8_t delay_gdtt,
|
uint8_t transition_time_gdtt, uint8_t delay_gdtt,
|
||||||
void (* transition_callback)(struct mesh_transition * transition, transition_event_t event, uint32_t current_timestamp));
|
void (* transition_callback)(struct mesh_transition * transition, transition_event_t event, uint32_t current_timestamp));
|
||||||
|
@ -68,7 +68,12 @@ static int16_t add_and_clip_int16(int16_t current_value, int16_t increment){
|
|||||||
return (int16_t) value;
|
return (int16_t) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mesh_server_transition_state_update_stepwise_value(mesh_transition_uint16_t * transition){
|
static mesh_transition_t * generic_level_server_get_base_transition(mesh_model_t * mesh_model) {
|
||||||
|
mesh_generic_level_state_t * generic_level_server_state = (mesh_generic_level_state_t *)mesh_model->model_data;
|
||||||
|
return &generic_level_server_state->transition_data.base_transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mesh_server_transition_state_update_stepwise_value(mesh_transition_int16_t * transition){
|
||||||
mesh_model_t * generic_level_server_model = transition->base_transition.mesh_model;
|
mesh_model_t * generic_level_server_model = transition->base_transition.mesh_model;
|
||||||
|
|
||||||
transition->current_value = add_and_clip_int16(transition->current_value, transition->stepwise_value_increment);
|
transition->current_value = add_and_clip_int16(transition->current_value, transition->stepwise_value_increment);
|
||||||
@ -81,7 +86,7 @@ static void mesh_server_transition_state_update_stepwise_value(mesh_transition_u
|
|||||||
transition->current_value);
|
transition->current_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mesh_server_transition_state_update(mesh_transition_uint16_t * transition, uint32_t current_timestamp_ms){
|
static void mesh_server_transition_state_update(mesh_transition_int16_t * transition, uint32_t current_timestamp_ms){
|
||||||
if (transition->base_transition.remaining_delay_time_ms != 0){
|
if (transition->base_transition.remaining_delay_time_ms != 0){
|
||||||
transition->base_transition.state = MESH_TRANSITION_STATE_DELAYED;
|
transition->base_transition.state = MESH_TRANSITION_STATE_DELAYED;
|
||||||
transition->base_transition.remaining_delay_time_ms = 0;
|
transition->base_transition.remaining_delay_time_ms = 0;
|
||||||
@ -115,7 +120,7 @@ static void mesh_server_transition_state_update(mesh_transition_uint16_t * trans
|
|||||||
static void mesh_server_transition_step(mesh_transition_t * base_transition, transition_event_t event, uint32_t current_timestamp){
|
static void mesh_server_transition_step(mesh_transition_t * base_transition, transition_event_t event, uint32_t current_timestamp){
|
||||||
uint32_t time_step_ms;
|
uint32_t time_step_ms;
|
||||||
|
|
||||||
mesh_transition_uint16_t * transition = (mesh_transition_uint16_t*) base_transition;
|
mesh_transition_int16_t * transition = (mesh_transition_int16_t*) base_transition;
|
||||||
|
|
||||||
switch (transition->base_transition.state){
|
switch (transition->base_transition.state){
|
||||||
case MESH_TRANSITION_STATE_IDLE:
|
case MESH_TRANSITION_STATE_IDLE:
|
||||||
@ -219,11 +224,11 @@ static void mesh_generic_level_status_message(mesh_model_t *generic_level_server
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void generic_level_handle_set_target_level_message(mesh_model_t *generic_level_server_model, mesh_pdu_t * pdu){
|
static void generic_level_handle_set_target_level_message(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
|
||||||
if (generic_level_server_model == NULL){
|
if (mesh_model == NULL){
|
||||||
log_error("generic_level_server_model == NULL");
|
log_error("mesh_model == NULL");
|
||||||
}
|
}
|
||||||
mesh_generic_level_state_t * generic_level_server_state = (mesh_generic_level_state_t *)generic_level_server_model->model_data;
|
mesh_generic_level_state_t * generic_level_server_state = (mesh_generic_level_state_t *)mesh_model->model_data;
|
||||||
|
|
||||||
if (generic_level_server_state == NULL){
|
if (generic_level_server_state == NULL){
|
||||||
log_error("generic_level_server_state == NULL");
|
log_error("generic_level_server_state == NULL");
|
||||||
@ -236,17 +241,20 @@ static void generic_level_handle_set_target_level_message(mesh_model_t *generic_
|
|||||||
// a new message or a retransmission of a previously sent message
|
// a new message or a retransmission of a previously sent message
|
||||||
uint8_t tid = mesh_access_parser_get_u8(&parser);
|
uint8_t tid = mesh_access_parser_get_u8(&parser);
|
||||||
|
|
||||||
if (tid == generic_level_server_state->transaction_identifier){
|
uint8_t transition_time_gdtt = 0;
|
||||||
printf("retransmission\n");
|
uint8_t delay_time_gdtt = 0;
|
||||||
return;
|
mesh_transition_t * base_transition = generic_level_server_get_base_transition(mesh_model);
|
||||||
}
|
|
||||||
|
switch (mesh_access_transitions_transaction_status(base_transition, tid, mesh_pdu_src(pdu), mesh_pdu_dst(pdu))){
|
||||||
|
case MESH_TRANSACTION_STATUS_RETRANSMISSION:
|
||||||
|
// ignore
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mesh_access_transitions_setup_transaction(base_transition, tid, mesh_pdu_src(pdu), mesh_pdu_dst(pdu));
|
||||||
|
|
||||||
generic_level_server_state->transition_data.target_value = level_value;
|
generic_level_server_state->transition_data.target_value = level_value;
|
||||||
generic_level_server_state->transition_data.stepwise_value_increment = 0;
|
generic_level_server_state->transition_data.stepwise_value_increment = 0;
|
||||||
generic_level_server_state->transaction_identifier = tid;
|
|
||||||
|
|
||||||
uint8_t transition_time_gdtt = 0;
|
|
||||||
uint8_t delay_time_gdtt = 0;
|
|
||||||
if (mesh_access_parser_available(&parser) == 2){
|
if (mesh_access_parser_available(&parser) == 2){
|
||||||
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
|
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
|
||||||
transition_time_gdtt = mesh_access_parser_get_u8(&parser);
|
transition_time_gdtt = mesh_access_parser_get_u8(&parser);
|
||||||
@ -257,16 +265,17 @@ static void generic_level_handle_set_target_level_message(mesh_model_t *generic_
|
|||||||
generic_level_server_state->transition_data.stepwise_value_increment = (level_value - generic_level_server_state->transition_data.current_value)/num_steps;
|
generic_level_server_state->transition_data.stepwise_value_increment = (level_value - generic_level_server_state->transition_data.current_value)/num_steps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mesh_server_transition_setup_transition_or_instantaneous_update_int16(mesh_model, transition_time_gdtt, delay_time_gdtt, MODEL_STATE_UPDATE_REASON_SET);
|
||||||
mesh_server_transition_setup_transition_or_instantaneous_update_int16(generic_level_server_model, transition_time_gdtt, delay_time_gdtt, MODEL_STATE_UPDATE_REASON_SET);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void generic_level_handle_set_move_message(mesh_model_t *generic_level_server_model, mesh_pdu_t * pdu){
|
|
||||||
if (generic_level_server_model == NULL){
|
|
||||||
log_error("generic_level_server_model == NULL");
|
|
||||||
}
|
}
|
||||||
mesh_generic_level_state_t * generic_level_server_state = (mesh_generic_level_state_t *)generic_level_server_model->model_data;
|
|
||||||
|
static void generic_level_handle_set_move_message(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
|
||||||
|
if (mesh_model == NULL){
|
||||||
|
log_error("mesh_model == NULL");
|
||||||
|
}
|
||||||
|
mesh_generic_level_state_t * generic_level_server_state = (mesh_generic_level_state_t *)mesh_model->model_data;
|
||||||
|
|
||||||
if (generic_level_server_state == NULL){
|
if (generic_level_server_state == NULL){
|
||||||
log_error("generic_level_server_state == NULL");
|
log_error("generic_level_server_state == NULL");
|
||||||
@ -275,23 +284,25 @@ static void generic_level_handle_set_move_message(mesh_model_t *generic_level_se
|
|||||||
mesh_access_parser_state_t parser;
|
mesh_access_parser_state_t parser;
|
||||||
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
|
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
|
||||||
int16_t increment_value = (int16_t)mesh_access_parser_get_u16(&parser);
|
int16_t increment_value = (int16_t)mesh_access_parser_get_u16(&parser);
|
||||||
|
|
||||||
// The TID field is a transaction identifier indicating whether the message is
|
// The TID field is a transaction identifier indicating whether the message is
|
||||||
// a new message or a retransmission of a previously sent message
|
// a new message or a retransmission of a previously sent message
|
||||||
uint8_t tid = mesh_access_parser_get_u8(&parser);
|
uint8_t tid = mesh_access_parser_get_u8(&parser);
|
||||||
// uint16_t src = mesh_pdu_src(pdu);
|
|
||||||
// uint16_t dst = mesh_pdu_dst(pdu);
|
|
||||||
|
|
||||||
if (tid == generic_level_server_state->transaction_identifier){
|
|
||||||
printf("retransmission\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
generic_level_server_state->transition_data.target_value = add_and_clip_int16(generic_level_server_state->transition_data.current_value, increment_value);
|
|
||||||
generic_level_server_state->transition_data.stepwise_value_increment = increment_value;
|
|
||||||
generic_level_server_state->transaction_identifier = tid;
|
|
||||||
|
|
||||||
uint8_t transition_time_gdtt = 0;
|
uint8_t transition_time_gdtt = 0;
|
||||||
uint8_t delay_time_gdtt = 0;
|
uint8_t delay_time_gdtt = 0;
|
||||||
|
mesh_transition_t * base_transition = generic_level_server_get_base_transition(mesh_model);
|
||||||
|
|
||||||
|
switch (mesh_access_transitions_transaction_status(base_transition, tid, mesh_pdu_src(pdu), mesh_pdu_dst(pdu))){
|
||||||
|
case MESH_TRANSACTION_STATUS_RETRANSMISSION:
|
||||||
|
// ignore retransmission
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mesh_access_transitions_setup_transaction(base_transition, tid, mesh_pdu_src(pdu), mesh_pdu_dst(pdu));
|
||||||
|
|
||||||
|
generic_level_server_state->transition_data.target_value = add_and_clip_int16(generic_level_server_state->transition_data.current_value, increment_value);
|
||||||
|
generic_level_server_state->transition_data.stepwise_value_increment = increment_value;
|
||||||
|
|
||||||
if (mesh_access_parser_available(&parser) == 2){
|
if (mesh_access_parser_available(&parser) == 2){
|
||||||
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
|
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
|
||||||
transition_time_gdtt = mesh_access_parser_get_u8(&parser);
|
transition_time_gdtt = mesh_access_parser_get_u8(&parser);
|
||||||
@ -302,15 +313,17 @@ static void generic_level_handle_set_move_message(mesh_model_t *generic_level_se
|
|||||||
generic_level_server_state->transition_data.target_value = add_and_clip_int16(generic_level_server_state->transition_data.current_value, increment_value * num_steps);
|
generic_level_server_state->transition_data.target_value = add_and_clip_int16(generic_level_server_state->transition_data.current_value, increment_value * num_steps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mesh_server_transition_setup_transition_or_instantaneous_update_int16(generic_level_server_model, transition_time_gdtt, delay_time_gdtt, MODEL_STATE_UPDATE_REASON_SET);
|
mesh_server_transition_setup_transition_or_instantaneous_update_int16(mesh_model, transition_time_gdtt, delay_time_gdtt, MODEL_STATE_UPDATE_REASON_SET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void generic_level_handle_set_delta_message(mesh_model_t *generic_level_server_model, mesh_pdu_t * pdu){
|
static void generic_level_handle_set_delta_message(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
|
||||||
if (generic_level_server_model == NULL){
|
if (mesh_model == NULL){
|
||||||
log_error("generic_level_server_model == NULL");
|
log_error("mesh_model == NULL");
|
||||||
}
|
}
|
||||||
mesh_generic_level_state_t * generic_level_server_state = (mesh_generic_level_state_t *)generic_level_server_model->model_data;
|
mesh_generic_level_state_t * generic_level_server_state = (mesh_generic_level_state_t *)mesh_model->model_data;
|
||||||
|
|
||||||
if (generic_level_server_state == NULL){
|
if (generic_level_server_state == NULL){
|
||||||
log_error("generic_level_server_state == NULL");
|
log_error("generic_level_server_state == NULL");
|
||||||
@ -319,27 +332,39 @@ static void generic_level_handle_set_delta_message(mesh_model_t *generic_level_s
|
|||||||
mesh_access_parser_state_t parser;
|
mesh_access_parser_state_t parser;
|
||||||
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
|
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
|
||||||
int16_t delta_value = (int16_t) mesh_access_parser_get_u16(&parser);
|
int16_t delta_value = (int16_t) mesh_access_parser_get_u16(&parser);
|
||||||
|
|
||||||
// The TID field is a transaction identifier indicating whether the message is
|
// The TID field is a transaction identifier indicating whether the message is
|
||||||
// a new message or a retransmission of a previously sent message
|
// a new message or a retransmission of a previously sent message
|
||||||
uint8_t tid = mesh_access_parser_get_u8(&parser);
|
uint8_t tid = mesh_access_parser_get_u8(&parser);
|
||||||
|
uint8_t transition_time_gdtt = 0;
|
||||||
|
uint8_t delay_time_gdtt = 0;
|
||||||
|
|
||||||
if (tid != generic_level_server_state->transaction_identifier){
|
mesh_transition_t * base_transition = generic_level_server_get_base_transition(mesh_model);
|
||||||
printf("retransmission\n");
|
|
||||||
return;
|
switch (mesh_access_transitions_transaction_status(base_transition, tid, mesh_pdu_src(pdu), mesh_pdu_dst(pdu))){
|
||||||
}
|
case MESH_TRANSACTION_STATUS_DIFFERENT_DST_OR_SRC:
|
||||||
|
// abort transaction
|
||||||
|
mesh_access_transitions_abort_transaction(base_transition);
|
||||||
|
break;
|
||||||
|
case MESH_TRANSACTION_STATUS_RETRANSMISSION:
|
||||||
|
// ignore
|
||||||
|
break;
|
||||||
|
case MESH_TRANSACTION_STATUS_NEW:
|
||||||
|
mesh_access_transitions_setup_transaction(base_transition, tid, mesh_pdu_src(pdu), mesh_pdu_dst(pdu));
|
||||||
|
|
||||||
generic_level_server_state->transition_data.target_value = add_and_clip_int16(generic_level_server_state->transition_data.current_value, delta_value);
|
generic_level_server_state->transition_data.target_value = add_and_clip_int16(generic_level_server_state->transition_data.current_value, delta_value);
|
||||||
generic_level_server_state->transition_data.stepwise_value_increment = delta_value;
|
generic_level_server_state->transition_data.stepwise_value_increment = delta_value;
|
||||||
generic_level_server_state->transaction_identifier = tid;
|
|
||||||
|
|
||||||
uint8_t transition_time_gdtt = 0;
|
|
||||||
uint8_t delay_time_gdtt = 0;
|
|
||||||
if (mesh_access_parser_available(&parser) == 2){
|
if (mesh_access_parser_available(&parser) == 2){
|
||||||
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
|
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
|
||||||
transition_time_gdtt = mesh_access_parser_get_u8(&parser);
|
transition_time_gdtt = mesh_access_parser_get_u8(&parser);
|
||||||
delay_time_gdtt = mesh_access_parser_get_u8(&parser);
|
delay_time_gdtt = mesh_access_parser_get_u8(&parser);
|
||||||
}
|
}
|
||||||
mesh_server_transition_setup_transition_or_instantaneous_update_int16(generic_level_server_model, transition_time_gdtt, delay_time_gdtt, MODEL_STATE_UPDATE_REASON_SET);
|
mesh_server_transition_setup_transition_or_instantaneous_update_int16(mesh_model, transition_time_gdtt, delay_time_gdtt, MODEL_STATE_UPDATE_REASON_SET);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,19 +59,16 @@ extern "C"
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
mesh_transition_t base_transition;
|
mesh_transition_t base_transition;
|
||||||
|
|
||||||
|
int16_t initial_value;
|
||||||
int16_t current_value;
|
int16_t current_value;
|
||||||
int16_t target_value;
|
int16_t target_value;
|
||||||
int16_t stepwise_value_increment;
|
int16_t stepwise_value_increment;
|
||||||
|
|
||||||
int16_t delta_from_initial_value;
|
int16_t delta_from_initial_value;
|
||||||
int16_t transition_speed;
|
int16_t transition_speed;
|
||||||
} mesh_transition_uint16_t;
|
} mesh_transition_int16_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mesh_transition_uint16_t transition_data;
|
mesh_transition_int16_t transition_data;
|
||||||
uint8_t transaction_identifier;
|
|
||||||
uint16_t src_address;
|
|
||||||
uint16_t dst_address;
|
|
||||||
} mesh_generic_level_state_t;
|
} mesh_generic_level_state_t;
|
||||||
|
|
||||||
const mesh_operation_t * mesh_generic_level_server_get_operations(void);
|
const mesh_operation_t * mesh_generic_level_server_get_operations(void);
|
||||||
|
@ -58,51 +58,11 @@ static void generic_server_send_message(uint16_t src, uint16_t dest, uint16_t ne
|
|||||||
mesh_upper_transport_send_access_pdu(pdu);
|
mesh_upper_transport_send_access_pdu(pdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic On Off State
|
// Transaction management
|
||||||
|
|
||||||
void mesh_generic_on_off_server_register_packet_handler(mesh_model_t *generic_on_off_server_model, btstack_packet_handler_t transition_events_packet_handler){
|
static mesh_transition_t * generic_on_off_server_get_base_transition(mesh_model_t * mesh_model) {
|
||||||
if (transition_events_packet_handler == NULL){
|
mesh_generic_on_off_state_t * generic_on_off_server_state = (mesh_generic_on_off_state_t *)mesh_model->model_data;
|
||||||
log_error("mesh_generic_on_off_server_register_packet_handler called with NULL callback");
|
return &generic_on_off_server_state->transition_data.base_transition;
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (generic_on_off_server_model == NULL){
|
|
||||||
log_error("mesh_generic_on_off_server_register_packet_handler called with NULL generic_on_off_server_model");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
generic_on_off_server_model->transition_events_packet_handler = &transition_events_packet_handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mesh_access_message_t mesh_generic_on_off_status_transition = {
|
|
||||||
MESH_GENERIC_ON_OFF_STATUS, "111"
|
|
||||||
};
|
|
||||||
|
|
||||||
const mesh_access_message_t mesh_generic_on_off_status_instantaneous = {
|
|
||||||
MESH_GENERIC_ON_OFF_STATUS, "1"
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mesh_generic_on_off_status_message(mesh_model_t *generic_on_off_server_model, uint16_t netkey_index, uint16_t dest, uint16_t appkey_index){
|
|
||||||
if (generic_on_off_server_model->element == NULL){
|
|
||||||
log_error("generic_on_off_server_model->element == NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh_generic_on_off_state_t * state = (mesh_generic_on_off_state_t *) generic_on_off_server_model->model_data;
|
|
||||||
if (state == NULL){
|
|
||||||
log_error("generic_on_off_status == NULL");
|
|
||||||
}
|
|
||||||
// setup message
|
|
||||||
mesh_transport_pdu_t * transport_pdu = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
if (state->transition_data.base_transition.remaining_transition_time_ms != 0) {
|
|
||||||
transport_pdu = mesh_access_setup_segmented_message(&mesh_generic_on_off_status_transition, state->transition_data.current_value,
|
|
||||||
state->transition_data.target_value, state->transition_data.base_transition.remaining_transition_time_ms);
|
|
||||||
} else {
|
|
||||||
transport_pdu = mesh_access_setup_segmented_message(&mesh_generic_on_off_status_instantaneous, state->transition_data.current_value);
|
|
||||||
}
|
|
||||||
if (!transport_pdu) return;
|
|
||||||
|
|
||||||
// send as segmented access pdu
|
|
||||||
generic_server_send_message(mesh_access_get_element_address(generic_on_off_server_model), dest, netkey_index, appkey_index, (mesh_pdu_t *) transport_pdu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mesh_server_transition_state_update(mesh_transition_bool_t * transition, uint32_t current_timestamp_ms){
|
static void mesh_server_transition_state_update(mesh_transition_bool_t * transition, uint32_t current_timestamp_ms){
|
||||||
@ -204,16 +164,63 @@ static void mesh_server_transition_setup_transition_or_instantaneous_update(mesh
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generic On Off State
|
||||||
|
|
||||||
|
void mesh_generic_on_off_server_register_packet_handler(mesh_model_t *generic_on_off_server_model, btstack_packet_handler_t transition_events_packet_handler){
|
||||||
|
if (transition_events_packet_handler == NULL){
|
||||||
|
log_error("mesh_generic_on_off_server_register_packet_handler called with NULL callback");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (generic_on_off_server_model == NULL){
|
||||||
|
log_error("mesh_generic_on_off_server_register_packet_handler called with NULL generic_on_off_server_model");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
generic_on_off_server_model->transition_events_packet_handler = &transition_events_packet_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mesh_access_message_t mesh_generic_on_off_status_transition = {
|
||||||
|
MESH_GENERIC_ON_OFF_STATUS, "111"
|
||||||
|
};
|
||||||
|
|
||||||
|
const mesh_access_message_t mesh_generic_on_off_status_instantaneous = {
|
||||||
|
MESH_GENERIC_ON_OFF_STATUS, "1"
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mesh_generic_on_off_status_message(mesh_model_t *generic_on_off_server_model, uint16_t netkey_index, uint16_t dest, uint16_t appkey_index){
|
||||||
|
if (generic_on_off_server_model->element == NULL){
|
||||||
|
log_error("generic_on_off_server_model->element == NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh_generic_on_off_state_t * state = (mesh_generic_on_off_state_t *) generic_on_off_server_model->model_data;
|
||||||
|
if (state == NULL){
|
||||||
|
log_error("generic_on_off_status == NULL");
|
||||||
|
}
|
||||||
|
// setup message
|
||||||
|
mesh_transport_pdu_t * transport_pdu = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if (state->transition_data.base_transition.remaining_transition_time_ms != 0) {
|
||||||
|
transport_pdu = mesh_access_setup_segmented_message(&mesh_generic_on_off_status_transition, state->transition_data.current_value,
|
||||||
|
state->transition_data.target_value, state->transition_data.base_transition.remaining_transition_time_ms);
|
||||||
|
} else {
|
||||||
|
transport_pdu = mesh_access_setup_segmented_message(&mesh_generic_on_off_status_instantaneous, state->transition_data.current_value);
|
||||||
|
}
|
||||||
|
if (!transport_pdu) return;
|
||||||
|
|
||||||
|
// send as segmented access pdu
|
||||||
|
generic_server_send_message(mesh_access_get_element_address(generic_on_off_server_model), dest, netkey_index, appkey_index, (mesh_pdu_t *) transport_pdu);
|
||||||
|
}
|
||||||
|
|
||||||
static void generic_on_off_get_handler(mesh_model_t *generic_on_off_server_model, mesh_pdu_t * pdu){
|
static void generic_on_off_get_handler(mesh_model_t *generic_on_off_server_model, mesh_pdu_t * pdu){
|
||||||
mesh_generic_on_off_status_message(generic_on_off_server_model, mesh_pdu_netkey_index(pdu), mesh_pdu_src(pdu), mesh_pdu_appkey_index(pdu));
|
mesh_generic_on_off_status_message(generic_on_off_server_model, mesh_pdu_netkey_index(pdu), mesh_pdu_src(pdu), mesh_pdu_appkey_index(pdu));
|
||||||
mesh_access_message_processed(pdu);
|
mesh_access_message_processed(pdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generic_on_off_handle_set_message(mesh_model_t *generic_on_off_server_model, mesh_pdu_t * pdu){
|
static void generic_on_off_handle_set_message(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
|
||||||
if (generic_on_off_server_model == NULL){
|
if (mesh_model == NULL){
|
||||||
log_error("generic_on_off_server_model == NULL");
|
log_error("mesh_model == NULL");
|
||||||
}
|
}
|
||||||
mesh_generic_on_off_state_t * generic_on_off_server_state = (mesh_generic_on_off_state_t *)generic_on_off_server_model->model_data;
|
mesh_generic_on_off_state_t * generic_on_off_server_state = (mesh_generic_on_off_state_t *)mesh_model->model_data;
|
||||||
|
|
||||||
if (generic_on_off_server_state == NULL){
|
if (generic_on_off_server_state == NULL){
|
||||||
log_error("generic_on_off_server_state == NULL");
|
log_error("generic_on_off_server_state == NULL");
|
||||||
@ -222,27 +229,31 @@ static void generic_on_off_handle_set_message(mesh_model_t *generic_on_off_serve
|
|||||||
mesh_access_parser_state_t parser;
|
mesh_access_parser_state_t parser;
|
||||||
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
|
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
|
||||||
uint8_t on_off_value = mesh_access_parser_get_u8(&parser);
|
uint8_t on_off_value = mesh_access_parser_get_u8(&parser);
|
||||||
|
|
||||||
// The TID field is a transaction identifier indicating whether the message is
|
// The TID field is a transaction identifier indicating whether the message is
|
||||||
// a new message or a retransmission of a previously sent message
|
// a new message or a retransmission of a previously sent message
|
||||||
uint8_t tid = mesh_access_parser_get_u8(&parser);
|
uint8_t tid = mesh_access_parser_get_u8(&parser);
|
||||||
|
|
||||||
if (tid == generic_on_off_server_state->transaction_identifier){
|
|
||||||
printf("retransmission\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
generic_on_off_server_state->transition_data.target_value = on_off_value;
|
|
||||||
generic_on_off_server_state->transaction_identifier = tid;
|
|
||||||
|
|
||||||
uint8_t transition_time_gdtt = 0;
|
uint8_t transition_time_gdtt = 0;
|
||||||
uint8_t delay_time_gdtt = 0;
|
uint8_t delay_time_gdtt = 0;
|
||||||
|
|
||||||
|
mesh_transition_t * base_transition = generic_on_off_server_get_base_transition(mesh_model);
|
||||||
|
|
||||||
|
switch (mesh_access_transitions_transaction_status(base_transition, tid, mesh_pdu_src(pdu), mesh_pdu_dst(pdu))){
|
||||||
|
case MESH_TRANSACTION_STATUS_RETRANSMISSION:
|
||||||
|
// ignore on retransmission
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mesh_access_transitions_setup_transaction(base_transition, tid, mesh_pdu_src(pdu), mesh_pdu_dst(pdu));
|
||||||
|
generic_on_off_server_state->transition_data.target_value = on_off_value;
|
||||||
|
|
||||||
if (mesh_access_parser_available(&parser) == 2){
|
if (mesh_access_parser_available(&parser) == 2){
|
||||||
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
|
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
|
||||||
transition_time_gdtt = mesh_access_parser_get_u8(&parser);
|
transition_time_gdtt = mesh_access_parser_get_u8(&parser);
|
||||||
delay_time_gdtt = mesh_access_parser_get_u8(&parser);
|
delay_time_gdtt = mesh_access_parser_get_u8(&parser);
|
||||||
}
|
}
|
||||||
|
mesh_server_transition_setup_transition_or_instantaneous_update(mesh_model, transition_time_gdtt, delay_time_gdtt, MODEL_STATE_UPDATE_REASON_SET);
|
||||||
mesh_server_transition_setup_transition_or_instantaneous_update(generic_on_off_server_model, transition_time_gdtt, delay_time_gdtt, MODEL_STATE_UPDATE_REASON_SET);
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generic_on_off_set_handler(mesh_model_t *generic_on_off_server_model, mesh_pdu_t * pdu){
|
static void generic_on_off_set_handler(mesh_model_t *generic_on_off_server_model, mesh_pdu_t * pdu){
|
||||||
|
@ -60,7 +60,6 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mesh_transition_bool_t transition_data;
|
mesh_transition_bool_t transition_data;
|
||||||
uint8_t transaction_identifier;
|
|
||||||
} mesh_generic_on_off_state_t;
|
} mesh_generic_on_off_state_t;
|
||||||
|
|
||||||
const mesh_operation_t * mesh_generic_on_off_server_get_operations(void);
|
const mesh_operation_t * mesh_generic_on_off_server_get_operations(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user