From 99154786459d788501204989d1bfe2f7519460b9 Mon Sep 17 00:00:00 2001 From: Kimmo Vaisanen Date: Fri, 11 May 2018 09:50:24 +0300 Subject: [PATCH] Lora: Fix battery_level callback Application can give battery_level callback method what Lora stack uses to query battery level for DevStatusReq MAC command response. The problem was that this callback was never called. This commit fixes this problem and if application does not set battery_level callback at all, value 255 (= The end-device was not able to measure the battery level.) will be returned to lora gateway. --- features/lorawan/LoRaWANStack.cpp | 1 + features/lorawan/lorastack/mac/LoRaMac.cpp | 5 +++++ features/lorawan/lorastack/mac/LoRaMac.h | 5 +++++ features/lorawan/lorastack/mac/LoRaMacCommand.cpp | 14 ++++++++++---- features/lorawan/lorastack/mac/LoRaMacCommand.h | 8 ++++++++ features/lorawan/lorawan_types.h | 11 ++++++++++- 6 files changed, 39 insertions(+), 5 deletions(-) diff --git a/features/lorawan/LoRaWANStack.cpp b/features/lorawan/LoRaWANStack.cpp index eddb60373b..a2f8011403 100644 --- a/features/lorawan/LoRaWANStack.cpp +++ b/features/lorawan/LoRaWANStack.cpp @@ -134,6 +134,7 @@ lorawan_status_t LoRaWANStack::set_lora_callbacks(const lorawan_app_callbacks_t if (callbacks->battery_level) { _callbacks.battery_level = callbacks->battery_level; + _loramac.set_batterylevel_callback(callbacks->battery_level); } return LORAWAN_STATUS_OK; diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index f37f63bb0c..65a978a288 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -661,6 +661,11 @@ void LoRaMac::handle_data_frame(const uint8_t* const payload, _params.ack_timeout_retry_counter, _params.max_ack_timeout_retries ); } +void LoRaMac::set_batterylevel_callback(mbed::Callback battery_level) +{ + _mac_commands.set_batterylevel_callback(battery_level); +} + void LoRaMac::on_radio_rx_done(const uint8_t* const payload, uint16_t size, int16_t rssi, int8_t snr) { diff --git a/features/lorawan/lorastack/mac/LoRaMac.h b/features/lorawan/lorastack/mac/LoRaMac.h index 19cd83aa43..e4805b5920 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.h +++ b/features/lorawan/lorastack/mac/LoRaMac.h @@ -437,6 +437,11 @@ public: void post_process_mlme_request(void); void post_process_mlme_ind(void); + /** + * Set battery level query callback + */ + void set_batterylevel_callback(mbed::Callback battery_level); + /** * These locks trample through to the upper layers and make * the stack thread safe. diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp index 0c618fef53..24a519c204 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.cpp @@ -233,10 +233,11 @@ lorawan_status_t LoRaMacCommand::process_mac_commands(const uint8_t *payload, ui } break; case SRV_MAC_DEV_STATUS_REQ: { - uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE; - // we don't have a mechanism at the moment to measure - // battery levels - ret_value = add_dev_status_ans(batteryLevel, snr & 0x3F); + uint8_t battery_level = BAT_LEVEL_NO_MEASURE; + if (_battery_level_cb) { + battery_level = _battery_level_cb(); + } + ret_value = add_dev_status_ans(battery_level, snr & 0x3F); break; } case SRV_MAC_NEW_CHANNEL_REQ: { @@ -329,6 +330,11 @@ int32_t LoRaMacCommand::cmd_buffer_remaining() const return sizeof(mac_cmd_buffer) - mac_cmd_buf_idx_to_repeat - mac_cmd_buf_idx; } +void LoRaMacCommand::set_batterylevel_callback(mbed::Callback battery_level) +{ + _battery_level_cb = battery_level; +} + lorawan_status_t LoRaMacCommand::add_link_check_req() { lorawan_status_t ret = LORAWAN_STATUS_LENGTH_ERROR; diff --git a/features/lorawan/lorastack/mac/LoRaMacCommand.h b/features/lorawan/lorastack/mac/LoRaMacCommand.h index ba5528206f..dfbcd29608 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCommand.h +++ b/features/lorawan/lorastack/mac/LoRaMacCommand.h @@ -147,6 +147,12 @@ public: */ lorawan_status_t add_link_check_req(); + /** + * @brief Set battery level query callback method + * If callback is not set, BAT_LEVEL_NO_MEASURE is returned. + */ + void set_batterylevel_callback(mbed::Callback battery_level); + private: /** * @brief Get the remaining size of the MAC command buffer @@ -261,6 +267,8 @@ private: * Buffer containing the MAC layer commands which must be repeated */ uint8_t mac_cmd_buffer_to_repeat[LORA_MAC_COMMAND_MAX_LENGTH]; + + mbed::Callback _battery_level_cb; }; #endif //__LORAMACCOMMAND_H__ diff --git a/features/lorawan/lorawan_types.h b/features/lorawan/lorawan_types.h index d4c12c1d47..98f294ebf0 100644 --- a/features/lorawan/lorawan_types.h +++ b/features/lorawan/lorawan_types.h @@ -274,8 +274,17 @@ typedef struct { * Optional */ mbed::Callback link_check_resp; + + /** + * Battery level return value must follow the specification + * for DevStatusAns MAC command: + * + * 0 The end-device is connected to an external power source + * 1 - 254 The battery level, 1 being at minimum and 254 being at maximum + * 255 The end-device was not able to measure the battery level. + */ mbed::Callback battery_level; - } lorawan_app_callbacks_t; +} lorawan_app_callbacks_t; /** * DO NOT MODIFY, WILL BREAK THE API!