mesh: register packet handler with generic on off server, draft implementation of generic_on_off_set_handler message

This commit is contained in:
Milanka Ringwald 2019-06-13 15:16:02 +02:00 committed by Matthias Ringwald
parent acb226f8c0
commit e874e56d99
3 changed files with 134 additions and 10 deletions

View File

@ -543,6 +543,25 @@ static void mesh_provisioning_message_handler (uint8_t packet_type, uint16_t cha
}
}
static void mesh_state_update_message_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
if (packet_type != HCI_EVENT_PACKET) return;
switch(packet[0]){
case HCI_EVENT_MESH_META:
switch(packet[2]){
case MESH_SUBEVENT_STATE_UPDATE_BOOL:
printf("state update\n");
break;
default:
break;
}
break;
default:
break;
}
}
static void mesh_unprovisioned_beacon_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
if (packet_type != MESH_BEACON_PACKET) return;
uint8_t device_uuid[16];
@ -1162,6 +1181,7 @@ int btstack_main(void)
mesh_generic_on_off_server_model.operations = mesh_generic_on_off_server_get_operations();
mesh_element_add_model(mesh_primary_element(), &mesh_generic_on_off_server_model);
mesh_generic_on_off_server_model.model_data = (void *) &mesh_generic_on_off_state;
mesh_generic_on_off_server_register_packet_handler(&mesh_state_update_message_handler);
mesh_vendor_model.model_identifier = mesh_model_get_model_identifier(BLUETOOTH_COMPANY_ID_BLUEKITCHEN_GMBH, MESH_BLUEKITCHEN_MODEL_ID_TEST_SERVER);
mesh_model_reset_appkeys(&mesh_vendor_model);

View File

@ -50,6 +50,8 @@
#include "btstack_memory.h"
#include "btstack_debug.h"
// TODO handler in model?
static btstack_packet_handler_t mesh_packet_handler;
static void generic_server_send_message(mesh_model_t *mesh_model, uint16_t netkey_index, uint16_t dest, mesh_pdu_t *pdu){
if (mesh_model == NULL){
@ -66,6 +68,11 @@ static void generic_server_send_message(mesh_model_t *mesh_model, uint16_t netke
}
// Generic On Off State
void mesh_generic_on_off_server_register_packet_handler(btstack_packet_handler_t packet_handler){
mesh_packet_handler = packet_handler;
}
const mesh_access_message_t mesh_generic_on_off_status = {
MESH_GENERIC_ON_OFF_STATUS, "111"
};
@ -81,9 +88,9 @@ static void mesh_generic_on_off_status_message(mesh_model_t *generic_on_off_serv
// setup message
mesh_transport_pdu_t * transport_pdu = NULL;
if (state->remaining_time != 0) {
if (state->remaining_time_ms != 0) {
transport_pdu = mesh_access_setup_segmented_message(&mesh_generic_on_off_status, state->current_on_off_value,
state->target_on_off_value, state->remaining_time);
state->target_on_off_value, state->remaining_time_ms);
} else {
transport_pdu = mesh_access_setup_segmented_message(&mesh_generic_on_off_status, state->current_on_off_value);
}
@ -93,20 +100,102 @@ static void mesh_generic_on_off_status_message(mesh_model_t *generic_on_off_serv
generic_server_send_message(generic_on_off_server_model, netkey_index, dest, (mesh_pdu_t *) transport_pdu);
}
static void generic_on_off_get_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
mesh_generic_on_off_status_message(mesh_model, mesh_pdu_netkey_index(pdu), mesh_pdu_src(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_access_message_processed(pdu);
}
// static void generic_on_off_set_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
// }
static uint8_t mesh_get_num_steps_from_gdtt(uint8_t transition_time_gdtt){
return transition_time_gdtt >> 2;
}
static uint32_t mesh_get_time_ms_from_gdtt(uint8_t transition_time_gdtt){
uint32_t step_resolution_ms = 0;
uint8_t num_steps = mesh_get_num_steps_from_gdtt(transition_time_gdtt);
mesh_default_transition_step_resolution_t step_resolution = (mesh_default_transition_step_resolution_t) (transition_time_gdtt & 0x03u);
switch (step_resolution){
case MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_100ms:
step_resolution_ms = 100;
break;
case MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_1s:
step_resolution_ms = 1000;
break;
case MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_10s:
step_resolution_ms = 10000;
break;
case MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_10min:
step_resolution_ms = 600000;
break;
default:
break;
}
return num_steps * step_resolution_ms;
}
static void generic_on_off_set_handler(mesh_model_t *generic_on_off_server_model, mesh_pdu_t * pdu){
if (generic_on_off_server_model == NULL){
log_error("generic_on_off_server_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;
if (generic_on_off_server_state == NULL){
log_error("generic_on_off_server_state == NULL");
}
uint8_t status = MESH_FOUNDATION_STATUS_SUCCESS;
mesh_access_parser_state_t parser;
mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu);
uint8_t on_off_value = mesh_access_parser_get_u8(&parser);
// The TID field is a transaction identifier indicating whether the message is
// a new message or a retransmission of a previously sent message
uint8_t tid = mesh_access_parser_get_u8(&parser);
if (tid == generic_on_off_server_state->transaction_identifier){
printf("retransmission\n");
return;
}
if (mesh_access_parser_available(&parser) == 4){
// Generic Default Transition Time format - num_steps (higher 6 bits), step_resolution (lower 2 bits)
uint8_t transition_time_gdtt = mesh_access_parser_get_u8(&parser);
// Only values of 0x00 through 0x3E shall be used to specify the value of the Transition Number of Steps field
uint8_t num_steps = mesh_get_num_steps_from_gdtt(transition_time_gdtt);
if (num_steps > 0x3E){
}
uint32_t transition_time_ms = mesh_get_time_ms_from_gdtt(transition_time_gdtt);
// Delay is given in 5 millisecond steps
uint16_t delay_ms = mesh_access_parser_get_u8(&parser) * 5;
printf("todo check/set transition timer transition_time %d ms, delay %d ms", transition_time_ms, delay_ms);
//TODO: return;
}
// Instantanious update
generic_on_off_server_state->current_on_off_value = on_off_value;
generic_on_off_server_state->transaction_identifier = tid;
generic_on_off_server_state->transition_time_ms = 0;
generic_on_off_server_state->delay_ms = 0;
mesh_generic_on_off_status_message(generic_on_off_server_model, mesh_pdu_netkey_index(pdu), mesh_pdu_src(pdu));
mesh_access_message_processed(pdu);
// TODO
uint8_t reason = 0;
uint8_t value = on_off_value;
uint8_t element_index = 0; // TODO generic_on_off_server_model->element_index?
uint32_t state_identifier = 0; // TODO
mesh_access_emit_state_update_bool(&mesh_packet_handler, element_index, generic_on_off_server_model->model_identifier, state_identifier, reason, value);
}
// static void generic_on_off_set_unacknowledged_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu){
// }
// Generic On Off Message
const static mesh_operation_t mesh_generic_on_off_model_operations[] = {
{ MESH_GENERIC_ON_OFF_GET, 0, generic_on_off_get_handler },
// { MESH_GENERIC_ON_OFF_SET, 4, generic_on_off_set_handler },
{ MESH_GENERIC_ON_OFF_SET, 2, generic_on_off_set_handler },
// { MESH_GENERIC_ON_OFF_SET_UNACKNOWLEDGED, 4, generic_on_off_set_unacknowledged_handler },
{ 0, 0, NULL }
};

View File

@ -51,15 +51,30 @@ extern "C"
#define MESH_GENERIC_ON_OFF_SET_UNACKNOWLEDGED 0x8203u
#define MESH_GENERIC_ON_OFF_STATUS 0x8204u
typedef enum {
MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_100ms = 0x00u,
MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_1s,
MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_10s,
MESH_DEFAULT_TRANSITION_STEP_RESOLUTION_10min
} mesh_default_transition_step_resolution_t;
typedef struct {
uint8_t current_on_off_value;
uint8_t current_on_off_value;
uint8_t transaction_identifier;
uint32_t transition_time_ms;
uint16_t delay_ms;
// transition data
uint8_t target_on_off_value;
uint8_t remaining_time;
uint8_t target_on_off_value;
uint32_t remaining_time_ms;
} mesh_generic_on_off_state_t;
const mesh_operation_t * mesh_generic_on_off_server_get_operations(void);
/**
* @brief Register packet handler
* @param packet_handler
*/
void mesh_generic_on_off_server_register_packet_handler(btstack_packet_handler_t packet_handler);
#ifdef __cplusplus
} /* end of extern "C" */