Слияние кода завершено, страница обновится автоматически
/**
*!
* \file b_srv_transfile.c
* \version v0.0.1
* \date 2023/08/27
* \author Bean(notrynohigh@outlook.com)
*******************************************************************************
* @attention
*
* Copyright (c) 2023 Bean
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************
*/
/*Includes ----------------------------------------------*/
#include "services/inc/b_srv_transfile.h"
#if (defined(_TRANSFILE_SERVICE_ENABLE) && (_TRANSFILE_SERVICE_ENABLE == 1))
#include "algorithm/inc/algo_crc.h"
#include "core/inc/b_core.h"
#include "core/inc/b_sem.h"
#include "core/inc/b_task.h"
#include "drivers/inc/b_driver.h"
#include "hal/inc/b_hal.h"
/**
* \addtogroup BABYOS
* \{
*/
/**
* \addtogroup SERVICES
* \{
*/
/**
* \addtogroup TRANSFILE
* \{
*/
/**
* \defgroup TRANSFILE_Private_TypesDefinitions
* \{
*/
/**
* \}
*/
/**
* \defgroup TRANSFILE_Private_Defines
* \{
*/
#ifndef TRANSFILE_TIMEOUT_S
#define TRANSFILE_TIMEOUT_S (30)
#endif
#define TFL_KLV_FILENAME_ID (0xAA01)
#define TFL_KLV_FILEVALUE_ID (0xAA02)
/**
* \}
*/
/**
* \defgroup TRANSFILE_Private_Macros
* \{
*/
/**
* \}
*/
/**
* \defgroup TRANSFILE_Private_Variables
* \{
*/
static bProtSrvId_t bProtocolId = NULL;
static bTFLSrvSendData_t bProtocolSend = NULL;
static uint32_t bFileOffset = 0;
static bProtoFileInfo_t bCurrentFileInfo = {
.size = 0,
.fcrc32 = 0,
};
static bProtoFileLocation_t bCurrentLocation = {
.dev = 0,
};
B_TASK_CREATE_ATTR(bTFLTaskAttr);
B_SEM_CREATE_ATTR(bTFLSemAttr);
static bTaskId_t bTFLTaskId = NULL;
static bSemId_t bTFLSemId = NULL;
static bProtSrvSubscribe_t bSubInfo = {
.number = 0,
};
const static bProtoCmd_t bCmdTable[] = {B_PROTO_TRANS_FILE_INFO, B_PROTO_SET_FILE_LOCATION,
B_PROTO_FILE_DATA};
/**
* \}
*/
/**
* \defgroup TRANSFILE_Private_FunctionPrototypes
* \{
*/
/**
* \}
*/
/**
* \defgroup TRANSFILE_Private_Functions
* \{
*/
static int _bTFLSendResult(uint8_t result)
{
uint8_t buf[128];
uint16_t olen = 0;
buf[0] = result;
olen = bProtSrvPackage(bProtocolId, B_PROTO_TRANS_FILE_RESULT, buf, sizeof(buf));
if (olen > 0 && bProtocolSend != NULL)
{
bProtocolSend(buf, olen);
}
return 0;
}
static void _bTFLEnd()
{
bProtSrvUnsubscribe(bProtocolId, &bSubInfo);
bTaskRemove(bTFLTaskId);
bTFLTaskId = NULL;
memset(&bCurrentFileInfo, 0, sizeof(bCurrentFileInfo));
memset(&bCurrentLocation, 0, sizeof(bCurrentLocation));
bProtocolId = NULL;
}
static int _bTFLCheck()
{
uint32_t tmp_len = 0;
uint8_t tmp[64];
uint32_t r_len = 0;
CRC_REG_SBS_HANDLE(tmp_crc, ALGO_CRC32);
int fd = bOpen(bCurrentLocation.dev, BCORE_FLAG_RW);
if (fd == -1)
{
return -1;
}
bLseek(fd, bCurrentLocation.offset);
while (tmp_len < bCurrentFileInfo.size)
{
r_len = ((bCurrentFileInfo.size - tmp_len) > 64) ? 64 : (bCurrentFileInfo.size - tmp_len);
bRead(fd, tmp, r_len);
crc_calculate_sbs(&tmp_crc, tmp, r_len);
tmp_len += r_len;
}
bClose(fd);
if (tmp_crc.crc != bCurrentFileInfo.fcrc32)
{
return -1;
}
return 0;
}
PT_THREAD(bTFLTaskFunc)(struct pt *pt, void *arg)
{
uint8_t buf[128];
uint16_t len = 0;
bProtoReqFileData_t *p_req = (bProtoReqFileData_t *)buf;
static uint32_t timeout = 0;
B_TASK_INIT_BEGIN();
timeout = bHalGetSysTick();
B_TASK_INIT_END();
PT_BEGIN(pt);
while (1)
{
bTaskDelayMs(pt, 200);
if (bCurrentLocation.dev == 0 || bCurrentFileInfo.size == 0)
{
bTaskRestart(pt);
}
if (bFileOffset >= bCurrentFileInfo.size)
{
if (_bTFLCheck() == 0)
{
_bTFLSendResult(B_PROTO_TRANS_RESULT_OK);
}
else
{
_bTFLSendResult(B_PROTO_TRANS_RESULT_CHECKSUM_FAIL);
}
_bTFLEnd();
bTaskRestart(pt);
}
p_req->offset = bFileOffset;
p_req->size = 512;
len = bProtSrvPackage(bProtocolId, B_PROTO_REQ_FILE_DATA, buf, sizeof(buf));
bProtocolSend(buf, len);
bSemAcquireBlock(pt, bTFLSemId, 3000);
if (PT_WAIT_IS_TIMEOUT(pt))
{
if (TICK_DIFF_BIT32(timeout, bHalGetSysTick()) >=
(MS2TICKS(TRANSFILE_TIMEOUT_S * 1000)))
{
_bTFLSendResult(B_PROTO_TRANS_RESULT_TIMEOUT);
_bTFLEnd();
bTaskRestart(pt);
}
}
else
{
timeout = bHalGetSysTick();
}
}
PT_END(pt);
}
static int _TFLProtCallback(bProtoCmd_t cmd, void *param)
{
if (cmd == B_PROTO_TRANS_FILE_INFO)
{
bProtoFileInfo_t *pinfo = (bProtoFileInfo_t *)param;
if (pinfo->size == 0)
{
return -1;
}
memcpy(&bCurrentFileInfo, param, sizeof(bCurrentFileInfo));
bFileOffset = 0;
}
else if (cmd == B_PROTO_SET_FILE_LOCATION)
{
bProtoFileLocation_t *plocation = (bProtoFileLocation_t *)param;
if (plocation->dev == 0)
{
return -1;
}
memcpy(&bCurrentLocation, plocation, sizeof(bCurrentLocation));
bFileOffset = 0;
}
else if (cmd == B_PROTO_FILE_DATA)
{
if (bCurrentLocation.dev == 0 || bCurrentFileInfo.size == 0)
{
return -1;
}
bProtoFileData_t *pFileData = (bProtoFileData_t *)param;
if (pFileData->size > 0 && pFileData->offset == bFileOffset)
{
int fd = -1;
fd = bOpen(bCurrentLocation.dev, BCORE_FLAG_RW);
if (fd < 0)
{
return -1;
}
if (bFileOffset == 0)
{
uint32_t sector_size = 0;
bCtl(fd, bCMD_GET_SECTOR_SIZE, §or_size);
if (sector_size == 0)
{
bClose(fd);
return -1;
}
bFlashErase_t eparam;
eparam.addr = bCurrentLocation.offset;
eparam.num = (bCurrentFileInfo.size + sector_size - 1) / sector_size;
bCtl(fd, bCMD_ERASE_SECTOR, &eparam);
}
bLseek(fd, bCurrentLocation.offset + bFileOffset);
uint32_t w_len = ((bCurrentFileInfo.size - bFileOffset) > pFileData->size)
? pFileData->size
: (bCurrentFileInfo.size - bFileOffset);
bWrite(fd, pFileData->dat, w_len);
bFileOffset += w_len;
bClose(fd);
bSemRelease(bTFLSemId);
}
}
return 0;
}
/**
* \}
*/
/**
* \addtogroup TRANSFILE_Exported_Functions
* \{
*/
int bTFLSrvInit(bProtSrvId_t protocol_id, bTFLSrvSendData_t send)
{
int ret = 0;
if (protocol_id == NULL || send == NULL)
{
return -1;
}
bProtocolId = protocol_id;
bProtocolSend = send;
bFileOffset = 0;
bSubInfo.number = sizeof(bCmdTable) / sizeof(bProtoCmd_t);
bSubInfo.pcmd_table = &bCmdTable[0];
bSubInfo.callback = _TFLProtCallback;
bProtSrvSubscribe(protocol_id, &bSubInfo);
memset(&bCurrentFileInfo, 0, sizeof(bCurrentFileInfo));
memset(&bCurrentLocation, 0, sizeof(bCurrentLocation));
if (bTFLTaskId == NULL)
{
bTFLTaskId = bTaskCreate("transfile", bTFLTaskFunc, NULL, &bTFLTaskAttr);
}
if (bTFLSemId == NULL)
{
bTFLSemId = bSemCreate(1, 0, &bTFLSemAttr);
}
bSemAcquireNonblock(bTFLSemId);
return 0;
}
int bTFLSrvDeinit()
{
int ret = -1;
if (bProtocolId == NULL)
{
return -1;
}
_bTFLEnd();
return 0;
}
int bTFLSrvGetFileInfo(uint32_t dev_no, uint32_t base_addr, const char *filename,
bTFLSrvFileInfo_t *pinfo)
{
uint16_t key = 0;
uint32_t len = 0;
uint8_t tmp_buf[16];
uint8_t file_name_ok = 0;
uint8_t i = 0;
if (dev_no == 0 || filename == NULL || pinfo == NULL)
{
return -1;
}
int fd = -1;
int filename_len = strlen(filename);
fd = bOpen(dev_no, BCORE_FLAG_RW);
if (fd < 0)
{
return -1;
}
while (1)
{
bLseek(fd, base_addr);
bRead(fd, (uint8_t *)&key, sizeof(key));
base_addr += sizeof(key);
key = B_SWAP_16(key);
if (key != TFL_KLV_FILENAME_ID && key != TFL_KLV_FILEVALUE_ID)
{
bClose(fd);
return -1;
}
bRead(fd, (uint8_t *)&len, sizeof(len));
base_addr += sizeof(len);
len = B_SWAP_32(len);
if (key == TFL_KLV_FILENAME_ID && len == filename_len)
{
int tmp_i = 0;
while (tmp_i < len)
{
bRead(fd, tmp_buf, 16);
for (i = 0; i < 16; i++)
{
if (filename[tmp_i + i] == '\0')
{
file_name_ok = 1;
break;
}
if (filename[tmp_i + i] != tmp_buf[i])
{
break;
}
}
if (i < 16)
{
break;
}
tmp_i += 16;
}
}
else if (key == TFL_KLV_FILEVALUE_ID && file_name_ok == 1)
{
pinfo->addr = base_addr;
pinfo->len = len;
break;
}
base_addr += len;
}
bClose(fd);
return 0;
}
/**
* \}
*/
/**
* \}
*/
/**
* \}
*/
/**
* \}
*/
#endif
/************************ Copyright (c) 2023 Bean *****END OF FILE****/
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )