From 20cc5dae5d8da524ee4ed3806be134682870aab8 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Fri, 4 Oct 2019 23:09:09 +0200 Subject: [PATCH] mesh: use timer_active flag in adv_bearer, mesh_access and mesh_configuration_server --- src/mesh/adv_bearer.c | 10 +++++++--- src/mesh/mesh_access.c | 4 ++++ src/mesh/mesh_configuration_server.c | 29 +++++++++++++++++++--------- src/mesh/mesh_configuration_server.h | 1 + 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/mesh/adv_bearer.c b/src/mesh/adv_bearer.c index 38901f72b..612370ec4 100644 --- a/src/mesh/adv_bearer.c +++ b/src/mesh/adv_bearer.c @@ -86,6 +86,7 @@ static void adv_bearer_run(void); static btstack_packet_callback_registration_t hci_event_callback_registration; static btstack_timer_source_t adv_timer; +static int adv_timer_active; static bd_addr_t null_addr; static btstack_packet_handler_t client_callbacks[NUM_TYPES]; @@ -199,6 +200,7 @@ static void adv_bearer_emit_can_send_now(void){ static void adv_bearer_timeout_handler(btstack_timer_source_t * ts){ UNUSED(ts); + adv_timer_active = 0; uint32_t now = btstack_run_loop_get_time_ms(); switch (adv_bearer_state){ case STATE_GAP: @@ -229,13 +231,15 @@ static void adv_bearer_set_timeout(uint32_t time_ms){ btstack_run_loop_set_timer_handler(&adv_timer, &adv_bearer_timeout_handler); btstack_run_loop_set_timer(&adv_timer, time_ms); // compile time constants btstack_run_loop_add_timer(&adv_timer); + adv_timer_active = 1; } // scheduler static void adv_bearer_run(void){ if (hci_get_state() != HCI_STATE_WORKING) return; - + if (adv_timer_active) return; + uint32_t now = btstack_run_loop_get_time_ms(); switch (adv_bearer_state){ case STATE_IDLE: @@ -250,8 +254,8 @@ static void adv_bearer_run(void){ gap_advertisements_set_params(ADVERTISING_INTERVAL_CONNECTABLE_MIN, ADVERTISING_INTERVAL_CONNECTABLE_MIN, gap_adv_type, gap_direct_address_typ, gap_direct_address, gap_channel_map, gap_filter_policy); gap_advertisements_set_data(item->adv_length, item->adv_data); gap_advertisements_enable(1); - adv_bearer_set_timeout(ADVERTISING_INTERVAL_CONNECTABLE_MIN_MS); adv_bearer_state = STATE_GAP; + adv_bearer_set_timeout(ADVERTISING_INTERVAL_CONNECTABLE_MIN_MS); } break; } @@ -264,8 +268,8 @@ static void adv_bearer_run(void){ gap_advertisements_set_params(ADVERTISING_INTERVAL_NONCONNECTABLE_MIN, ADVERTISING_INTERVAL_NONCONNECTABLE_MIN, 3, 0, null_addr, 0x07, 0); gap_advertisements_set_data(adv_bearer_buffer_length, adv_bearer_buffer); gap_advertisements_enable(1); - adv_bearer_set_timeout(ADVERTISING_INTERVAL_NONCONNECTABLE_MIN_MS); adv_bearer_state = STATE_BEARER; + adv_bearer_set_timeout(ADVERTISING_INTERVAL_NONCONNECTABLE_MIN_MS); break; // } } diff --git a/src/mesh/mesh_access.c b/src/mesh/mesh_access.c index ef223cb9f..718f917b2 100644 --- a/src/mesh/mesh_access.c +++ b/src/mesh/mesh_access.c @@ -64,6 +64,7 @@ static const mesh_operation_t * mesh_model_lookup_operation_by_opcode(mesh_model // acknowledged messages static btstack_linked_list_t mesh_access_acknowledged_messages; static btstack_timer_source_t mesh_access_acknowledged_timer; +static int mesh_access_acknowledged_timer_active; // Transitions static btstack_linked_list_t transitions; @@ -182,6 +183,8 @@ static void mesh_access_acknowledged_run(btstack_timer_source_t * ts){ } } + if (mesh_access_acknowledged_timer_active) return; + // find earliest timeout and set timer btstack_linked_list_iterator_init(&ack_it, &mesh_access_acknowledged_messages); int32_t next_timeout_ms = 0; @@ -199,6 +202,7 @@ static void mesh_access_acknowledged_run(btstack_timer_source_t * ts){ btstack_run_loop_set_timer(&mesh_access_acknowledged_timer, next_timeout_ms); btstack_run_loop_set_timer_handler(&mesh_access_acknowledged_timer, mesh_access_acknowledged_run); btstack_run_loop_add_timer(&mesh_access_acknowledged_timer); + mesh_access_acknowledged_timer_active = 1; } static void mesh_access_acknowledged_received(uint16_t rx_src, uint32_t opcode){ diff --git a/src/mesh/mesh_configuration_server.c b/src/mesh/mesh_configuration_server.c index 74289af53..6bbf43577 100644 --- a/src/mesh/mesh_configuration_server.c +++ b/src/mesh/mesh_configuration_server.c @@ -98,13 +98,15 @@ static uint8_t heartbeat_count_log(uint16_t value){ if (value == 0) return 0x00; if (value == 0xffff) return 0xff; // count leading zeros, supported by clang and gcc - return 32 - __builtin_clz(value); + // note: CountLog(8) == CountLog(7) = 3 + return 33 - __builtin_clz(value - 1); } static uint8_t heartbeat_period_log(uint16_t value){ if (value == 0) return 0x00; // count leading zeros, supported by clang and gcc - return 32 - __builtin_clz(value); + // note: PeriodLog(8) == PeriodLog(7) = 3 + return 33 - __builtin_clz(value - 1); } // TLV @@ -1778,6 +1780,7 @@ void mesh_configuration_server_feature_changed(void){ static void config_heartbeat_publication_timeout_handler(btstack_timer_source_t * ts){ mesh_heartbeat_publication_t * mesh_heartbeat_publication = (mesh_heartbeat_publication_t*) ts; + mesh_heartbeat_publication->timer_active = 0; // emit beat config_heartbeat_publication_emit(mesh_heartbeat_publication); @@ -1790,6 +1793,7 @@ static void config_heartbeat_publication_timeout_handler(btstack_timer_source_t btstack_run_loop_set_timer(ts, mesh_heartbeat_publication->period_ms); btstack_run_loop_add_timer(ts); + mesh_heartbeat_publication->timer_active = 1; } static void config_heartbeat_publication_status(mesh_model_t *mesh_model, uint16_t netkey_index, uint16_t dest, uint8_t status, mesh_heartbeat_publication_t * mesh_heartbeat_publication){ @@ -1817,7 +1821,8 @@ static void config_heartbeat_publication_status(mesh_model_t *mesh_model, uint16 static void config_heartbeat_publication_set_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu) { mesh_heartbeat_publication_t requested_publication; - + memset(&requested_publication, 0, sizeof(requested_publication)); + mesh_access_parser_state_t parser; mesh_access_parser_init(&parser, (mesh_pdu_t*) pdu); @@ -1851,6 +1856,13 @@ static void config_heartbeat_publication_set_handler(mesh_model_t *mesh_model, m printf("MESH config_heartbeat_publication_set, destination %x, count = %x, period = %u s\n", requested_publication.destination, requested_publication.count, requested_publication.period_ms); + // stop timer if active + // note: accept update below using memcpy overwwrite timer_active flag + if (mesh_heartbeat_publication->timer_active){ + btstack_run_loop_remove_timer(&mesh_heartbeat_publication->timer); + mesh_heartbeat_publication->timer_active = 0; + } + // accept update memcpy(mesh_heartbeat_publication, &requested_publication, sizeof(mesh_heartbeat_publication_t)); } @@ -1860,19 +1872,18 @@ static void config_heartbeat_publication_set_handler(mesh_model_t *mesh_model, m mesh_access_message_processed(pdu); if (status != MESH_FOUNDATION_STATUS_SUCCESS) return; - + // check if heartbeats should be disabled if (mesh_heartbeat_publication->destination == MESH_ADDRESS_UNSASSIGNED || mesh_heartbeat_publication->period_log == 0) { - btstack_run_loop_remove_timer(&mesh_heartbeat_publication->timer); - printf("MESH config_heartbeat_publication_set, disable periodic sending\n"); return; } - - // NOTE: defer first heartbeat to allow config status getting sent first + + // initial heartbeat in 100 ms btstack_run_loop_set_timer_handler(&mesh_heartbeat_publication->timer, config_heartbeat_publication_timeout_handler); btstack_run_loop_set_timer_context(&mesh_heartbeat_publication->timer, mesh_heartbeat_publication); - btstack_run_loop_set_timer(&mesh_heartbeat_publication->timer, 2000); + btstack_run_loop_set_timer(&mesh_heartbeat_publication->timer, 100); btstack_run_loop_add_timer(&mesh_heartbeat_publication->timer); + mesh_heartbeat_publication->timer_active = 1; } static void config_heartbeat_publication_get_handler(mesh_model_t *mesh_model, mesh_pdu_t * pdu) { diff --git a/src/mesh/mesh_configuration_server.h b/src/mesh/mesh_configuration_server.h index 6e15471f9..02dd9966e 100644 --- a/src/mesh/mesh_configuration_server.h +++ b/src/mesh/mesh_configuration_server.h @@ -51,6 +51,7 @@ extern "C" typedef struct { btstack_timer_source_t timer; + uint8_t timer_active; uint16_t active_features; uint32_t period_ms; uint16_t count;