231 lines
5.9 KiB
C++
231 lines
5.9 KiB
C++
/***************************************************************************
|
|
*
|
|
* 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.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "string.h"
|
|
#include "cmsis_os.h"
|
|
#include "hal_trace.h"
|
|
#include "hal_timer.h"
|
|
#include "apps.h"
|
|
#include "stdbool.h"
|
|
#include "app_tota.h"
|
|
#include "app_tota_cmd_code.h"
|
|
#include "app_tota_cmd_handler.h"
|
|
#include "app_tota_data_handler.h"
|
|
#include "app_utils.h"
|
|
#include "crc32.h"
|
|
#include "app_spp_tota.h"
|
|
#include "app_spp_tota_general_service.h"
|
|
#include "tota_buffer_manager.h"
|
|
#include "tota_stream_data_transfer.h"
|
|
#include "app_tota_conn.h"
|
|
|
|
/*
|
|
** stream control strcut
|
|
** stream packet format:
|
|
** # header + body #
|
|
** > header: 2 bytes
|
|
** > body : 664 bytes
|
|
**
|
|
** note: stream will never be encrypted!
|
|
*/
|
|
typedef struct{
|
|
uint32_t flush_bytes;
|
|
bool is_streaming;
|
|
uint8_t module;
|
|
|
|
osMutexId mutex;
|
|
osSemaphoreId sem;
|
|
}stream_control_t;
|
|
|
|
stream_control_t stream_control;
|
|
|
|
osMutexDef (tota_tx_buf_mutex);
|
|
osMutexId tota_tx_buf_mutex_id;
|
|
|
|
#define SPP_BUFFER_NUM 5
|
|
|
|
static uint8_t spp_tx_buffer[MAX_SPP_PACKET_SIZE*SPP_BUFFER_NUM];
|
|
static uint8_t tx_buf_index = 0;
|
|
|
|
|
|
/* static function */
|
|
static bool _tota_send_stream_packet(uint8_t * pdata, uint32_t dataLen);
|
|
static void _tota_stream_data_init();
|
|
static void _update_tx_buf();
|
|
static uint8_t * _get_tx_buf_ptr();
|
|
|
|
// Semaphore
|
|
osSemaphoreDef(app_tota_send_data_sem);
|
|
|
|
// define stream data transfer thread
|
|
#define TOTA_STREAM_DATA_STACK_SIZE 2048
|
|
static void tota_stream_data_transfer_thread(void const *argument);
|
|
osThreadId tota_stream_thread_tid;
|
|
osThreadDef(tota_stream_data_transfer_thread, osPriorityHigh, 1, TOTA_STREAM_DATA_STACK_SIZE, "TOTA_STREAM_DATA_THREAD");
|
|
|
|
static void tota_stream_data_transfer_thread(void const *argument)
|
|
{
|
|
// TODO: max speed
|
|
uint8_t buf[MAX_SPP_PACKET_SIZE];
|
|
while ( true )
|
|
{
|
|
app_sysfreq_req(APP_SYSFREQ_USER_OTA, APP_SYSFREQ_32K);
|
|
osSignalWait(0x0001, osWaitForever);
|
|
app_sysfreq_req(APP_SYSFREQ_USER_OTA, APP_SYSFREQ_208M);
|
|
while ( tota_stream_buffer_read(buf + STREAM_HEADER_SIZE, MAX_SPP_PACKET_SIZE - STREAM_HEADER_SIZE) )
|
|
{
|
|
_tota_send_stream_packet(buf, MAX_SPP_PACKET_SIZE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void app_tota_stream_data_transfer_init()
|
|
{
|
|
stream_control.sem = osSemaphoreCreate(osSemaphore(app_tota_send_data_sem), SPP_BUFFER_NUM);
|
|
tota_stream_thread_tid = osThreadCreate(osThread(tota_stream_data_transfer_thread), NULL);
|
|
_tota_stream_data_init();
|
|
}
|
|
|
|
// stream start
|
|
void app_tota_stream_data_start(uint16_t set_module)
|
|
{
|
|
stream_control.module = set_module;
|
|
stream_control.is_streaming = true;
|
|
}
|
|
|
|
// stream end
|
|
void app_tota_stream_data_end()
|
|
{
|
|
stream_control.is_streaming = false;
|
|
}
|
|
|
|
// stream send data while stream is start
|
|
bool app_tota_send_stream_data(uint8_t * pdata, uint32_t dataLen)
|
|
{
|
|
if ( !stream_control.is_streaming )
|
|
{
|
|
TOTA_LOG_DBG(0, "error: data stream not start.");
|
|
return false;
|
|
}
|
|
if ( tota_stream_buffer_write(pdata, dataLen) )
|
|
{
|
|
TOTA_LOG_DBG(0, "send to stream buffer ok.");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
TOTA_LOG_DBG(0, "send to stream buffer error.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// stream flush
|
|
void app_tota_stream_data_flush()
|
|
{
|
|
tota_stream_buffer_flush();
|
|
}
|
|
|
|
// stream clean
|
|
void app_tota_stream_data_clean()
|
|
{
|
|
tota_stream_buffer_clean();
|
|
}
|
|
|
|
|
|
bool app_tota_send_data_via_spp(uint8_t * pdata, uint32_t dataLen)
|
|
{
|
|
osSemaphoreWait(stream_control.sem, osWaitForever);
|
|
osMutexRelease(tota_tx_buf_mutex_id);
|
|
uint8_t * pbuf = pdata;
|
|
uint32_t bufLen = dataLen;
|
|
#if TOTA_ENCODE
|
|
if ( ((uint16_t *)pdata)[0] == OP_TOTA_STRING )
|
|
{
|
|
TOTA_LOG_DBG(0, "yeah! This is a string. Do not encrypt");
|
|
}
|
|
else if ( is_tota_connected() )
|
|
{
|
|
pbuf = tota_encrypt_packet(pdata, dataLen, &bufLen);
|
|
}
|
|
#endif
|
|
memcpy(_get_tx_buf_ptr(), pbuf, bufLen);
|
|
|
|
if ( app_spp_tota_send_data(_get_tx_buf_ptr(), bufLen) )
|
|
{
|
|
_update_tx_buf();
|
|
osMutexRelease(tota_tx_buf_mutex_id);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
osMutexRelease(tota_tx_buf_mutex_id);
|
|
osSemaphoreRelease(stream_control.sem);
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
void app_tota_tx_done_callback()
|
|
{
|
|
osSemaphoreRelease(stream_control.sem);
|
|
}
|
|
|
|
bool is_stream_data_running()
|
|
{
|
|
return stream_control.is_streaming;
|
|
}
|
|
|
|
// send stream packet with header. packet size:666
|
|
static bool _tota_send_stream_packet(uint8_t * pdata, uint32_t dataLen)
|
|
{
|
|
osSemaphoreWait(stream_control.sem, osWaitForever);
|
|
osMutexRelease(tota_tx_buf_mutex_id);
|
|
((uint16_t *)pdata)[0] = (OP_TOTA_STREAM_DATA - stream_control.module);
|
|
memcpy(_get_tx_buf_ptr(), pdata, dataLen);
|
|
if ( app_spp_tota_send_data(_get_tx_buf_ptr(), dataLen) )
|
|
{
|
|
_update_tx_buf();
|
|
osMutexRelease(tota_tx_buf_mutex_id);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
osMutexRelease(tota_tx_buf_mutex_id);
|
|
osSemaphoreRelease(stream_control.sem);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static void _tota_stream_data_init()
|
|
{
|
|
tota_stream_buffer_init(tota_stream_thread_tid);
|
|
stream_control.module = 0;
|
|
stream_control.is_streaming = false;
|
|
}
|
|
|
|
static void _update_tx_buf()
|
|
{
|
|
tx_buf_index = (tx_buf_index + 1) % 5;
|
|
}
|
|
|
|
|
|
static uint8_t * _get_tx_buf_ptr()
|
|
{
|
|
return (spp_tx_buffer + tx_buf_index*MAX_SPP_PACKET_SIZE);
|
|
}
|
|
|
|
|