/*************************************************************************** * * Copyright 2015-2019 BES. * All rights reserved. All unpublished rights reserved. * * No part of this work may be used or reproduced in any form or by any * means, or stored in a database or retrieval system, without prior written * permission of BES. * * Use of this work is governed by a license granted by BES. * This work contains confidential and proprietary information of * BES. which is protected by copyright, trade secret, * trademark and other intellectual property rights. * ****************************************************************************/ /** **************************************************************************************** * @addtogroup APP * @{ **************************************************************************************** */ #include "rwip_config.h" // SW configuration #if (BLE_APP_TOTA) /* * INCLUDE FILES **************************************************************************************** */ #include "app.h" // Application Definitions #include "app_ble_rx_handler.h" #include "app_task.h" // application task definitions #include "app_tota.h" #include "app_tota_ble.h" // TOTA Application Definitions #include "app_tota_cmd_handler.h" #include "app_tota_data_handler.h" #include "arch.h" // Platform Definitions #include "co_bt.h" #include "prf.h" #include "prf_types.h" #include "prf_utils.h" #include "string.h" #include "tota_task.h" /* * GLOBAL VARIABLE DEFINITIONS **************************************************************************************** */ struct app_tota_env_tag app_tota_env; static app_tota_tx_done_t tota_data_tx_done_callback = NULL; /* * GLOBAL FUNCTION DEFINITIONS **************************************************************************************** */ void app_tota_connected_evt_handler(uint8_t conidx) { TOTA_LOG_DBG(1, "[%s]TOTA", __func__); app_tota_env.connectionIndex = conidx; app_tota_update_datapath(APP_TOTA_VIA_NOTIFICATION); // tota_register_transmitter(app_tota_send_notification); } void app_tota_disconnected_evt_handler(uint8_t conidx) { TOTA_LOG_DBG(3, "[%s], condix = %d Index = %d", __func__, conidx, app_tota_env.connectionIndex); if (conidx == app_tota_env.connectionIndex) { app_tota_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; app_tota_env.isNotificationEnabled = false; app_tota_env.mtu[conidx] = 0; app_tota_update_datapath(APP_TOTA_PATH_IDLE); // tota_disconnection_handler(); } } void app_tota_ble_init(void) { app_tota_env.connectionIndex = BLE_INVALID_CONNECTION_INDEX; app_tota_env.isNotificationEnabled = false; memset((uint8_t *)&(app_tota_env.mtu), 0, sizeof(app_tota_env.mtu)); } void app_tota_add_tota(void) { struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, TASK_GAPM, TASK_APP, gapm_profile_task_add_cmd, 0); // Fill message req->operation = GAPM_PROFILE_TASK_ADD; #if BLE_CONNECTION_MAX > 1 req->sec_lvl = PERM(SVC_AUTH, ENABLE) | PERM(SVC_MI, ENABLE); #else req->sec_lvl = PERM(SVC_AUTH, ENABLE); #endif req->prf_task_id = TASK_ID_TOTA; req->app_task = TASK_APP; req->start_hdl = 0; // Send the message ke_msg_send(req); } void app_tota_send_notification(uint8_t *ptrData, uint32_t length) { TOTA_LOG_DBG(1, "[%s]TOTA", __func__); struct ble_tota_send_data_req_t *req = KE_MSG_ALLOC_DYN(TOTA_SEND_NOTIFICATION, KE_BUILD_ID(prf_get_task_from_id(TASK_ID_TOTA), app_tota_env.connectionIndex), TASK_APP, ble_tota_send_data_req_t, length); req->connecionIndex = app_tota_env.connectionIndex; req->length = length; memcpy(req->value, ptrData, length); ke_msg_send(req); } void app_tota_send_indication(uint8_t *ptrData, uint32_t length) { TOTA_LOG_DBG(1, "[%s]TOTA", __func__); struct ble_tota_send_data_req_t *req = KE_MSG_ALLOC_DYN(TOTA_SEND_INDICATION, KE_BUILD_ID(prf_get_task_from_id(TASK_ID_TOTA), app_tota_env.connectionIndex), TASK_APP, ble_tota_send_data_req_t, length); req->connecionIndex = app_tota_env.connectionIndex; req->length = length; memcpy(req->value, ptrData, length); ke_msg_send(req); } static int app_tota_msg_handler(ke_msg_id_t const msgid, void const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Do nothing TOTA_LOG_DBG(1, "[%s]TOTA", __func__); return (KE_MSG_CONSUMED); } void tota_update_MTU(uint16_t mtu) { // remove the 3 bytes of overhead app_tota_env.mtu[app_tota_env.connectionIndex] = mtu; TRACE(1, "updated data packet size is %d", app_tota_env.mtu[app_tota_env.connectionIndex]); } static int app_tota_ccc_changed_handler( ke_msg_id_t const msgid, struct ble_tota_tx_notif_config_t *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { TOTA_LOG_DBG(1, "tota data ccc changed to %d", param->isNotificationEnabled); app_tota_env.isNotificationEnabled = param->isNotificationEnabled; if (app_tota_env.isNotificationEnabled) { if (BLE_INVALID_CONNECTION_INDEX == app_tota_env.connectionIndex) { uint8_t conidx = KE_IDX_GET(src_id); app_tota_connected_evt_handler(conidx); if (app_tota_env.mtu[conidx]) { // tota_update_MTU(app_tota_env.mtu[conidx]); } } } else { app_tota_update_datapath(APP_TOTA_VIA_INDICATION); } return (KE_MSG_CONSUMED); } static int app_tota_tx_data_sent_handler(ke_msg_id_t const msgid, struct ble_tota_tx_sent_ind_t *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { if (NULL != tota_data_tx_done_callback) { tota_data_tx_done_callback(); } // tota_data_transmission_done_callback(); return (KE_MSG_CONSUMED); } static int app_tota_data_received_handler(ke_msg_id_t const msgid, struct ble_tota_rx_data_ind_t *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { app_ble_push_rx_data(BLE_RX_DATA_SELF_TOTA, app_tota_env.connectionIndex, param->data, param->length); return (KE_MSG_CONSUMED); } void app_tota_register_tx_done(app_tota_tx_done_t callback) { tota_data_tx_done_callback = callback; } void app_tota_mtu_exchanged_handler(uint8_t conidx, uint16_t MTU) { TOTA_LOG_DBG(1, "[%s]TOTA", __func__); if (conidx == app_tota_env.connectionIndex) { tota_update_MTU(MTU); } else { app_tota_env.mtu[conidx] = MTU; } } /* * LOCAL VARIABLE DEFINITIONS **************************************************************************************** */ /// Default State handlers definition const struct ke_msg_handler app_tota_msg_handler_list[] = { // Note: first message is latest message checked by kernel so default is put // on top. {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_tota_msg_handler}, {TOTA_CCC_CHANGED, (ke_msg_func_t)app_tota_ccc_changed_handler}, {TOTA_TX_DATA_SENT, (ke_msg_func_t)app_tota_tx_data_sent_handler}, {TOTA_DATA_RECEIVED, (ke_msg_func_t)app_tota_data_received_handler}, }; const struct ke_state_handler app_tota_table_handler = { &app_tota_msg_handler_list[0], (sizeof(app_tota_msg_handler_list) / sizeof(struct ke_msg_handler))}; #endif // BLE_APP_TOTA /// @} APP