2017-12-13 22:53:20 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2017 Nordic Semiconductor ASA
|
|
|
|
* Copyright (c) 2015 Runtime Inc
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
2019-06-26 00:25:56 +08:00
|
|
|
#include <sys/crc.h>
|
2017-12-13 22:53:20 +08:00
|
|
|
|
2019-06-26 00:09:24 +08:00
|
|
|
#include <fs/fcb.h>
|
2017-12-13 22:53:20 +08:00
|
|
|
#include "fcb_priv.h"
|
|
|
|
|
|
|
|
/*
|
2018-01-27 06:07:10 +08:00
|
|
|
* Given offset in flash sector, fill in rest of the fcb_entry, and crc8 over
|
2017-12-13 22:53:20 +08:00
|
|
|
* the data.
|
|
|
|
*/
|
|
|
|
int
|
2020-05-28 00:26:57 +08:00
|
|
|
fcb_elem_crc8(struct fcb *fcb, struct fcb_entry *loc, uint8_t *c8p)
|
2017-12-13 22:53:20 +08:00
|
|
|
{
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t tmp_str[FCB_TMP_BUF_SZ];
|
2017-12-13 22:53:20 +08:00
|
|
|
int cnt;
|
|
|
|
int blk_sz;
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t crc8;
|
|
|
|
uint16_t len;
|
|
|
|
uint32_t off;
|
|
|
|
uint32_t end;
|
2017-12-13 22:53:20 +08:00
|
|
|
int rc;
|
|
|
|
|
2018-01-27 06:07:10 +08:00
|
|
|
if (loc->fe_elem_off + 2 > loc->fe_sector->fs_size) {
|
2019-07-11 17:21:35 +08:00
|
|
|
return -ENOTSUP;
|
2017-12-13 22:53:20 +08:00
|
|
|
}
|
2018-01-27 06:07:10 +08:00
|
|
|
rc = fcb_flash_read(fcb, loc->fe_sector, loc->fe_elem_off, tmp_str, 2);
|
2017-12-13 22:53:20 +08:00
|
|
|
if (rc) {
|
2019-07-11 17:21:35 +08:00
|
|
|
return -EIO;
|
2017-12-13 22:53:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
cnt = fcb_get_len(tmp_str, &len);
|
|
|
|
if (cnt < 0) {
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
loc->fe_data_off = loc->fe_elem_off + fcb_len_in_flash(fcb, cnt);
|
|
|
|
loc->fe_data_len = len;
|
|
|
|
|
|
|
|
crc8 = CRC8_CCITT_INITIAL_VALUE;
|
|
|
|
crc8 = crc8_ccitt(crc8, tmp_str, cnt);
|
|
|
|
|
|
|
|
off = loc->fe_data_off;
|
|
|
|
end = loc->fe_data_off + len;
|
|
|
|
for (; off < end; off += blk_sz) {
|
|
|
|
blk_sz = end - off;
|
|
|
|
if (blk_sz > sizeof(tmp_str)) {
|
|
|
|
blk_sz = sizeof(tmp_str);
|
|
|
|
}
|
|
|
|
|
2018-01-27 06:07:10 +08:00
|
|
|
rc = fcb_flash_read(fcb, loc->fe_sector, off, tmp_str, blk_sz);
|
2017-12-13 22:53:20 +08:00
|
|
|
if (rc) {
|
2019-07-11 17:21:35 +08:00
|
|
|
return -EIO;
|
2017-12-13 22:53:20 +08:00
|
|
|
}
|
|
|
|
crc8 = crc8_ccitt(crc8, tmp_str, blk_sz);
|
|
|
|
}
|
|
|
|
*c8p = crc8;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int fcb_elem_info(struct fcb *fcb, struct fcb_entry *loc)
|
|
|
|
{
|
|
|
|
int rc;
|
2020-05-28 00:26:57 +08:00
|
|
|
uint8_t crc8;
|
|
|
|
uint8_t fl_crc8;
|
2017-12-13 22:53:20 +08:00
|
|
|
off_t off;
|
|
|
|
|
|
|
|
rc = fcb_elem_crc8(fcb, loc, &crc8);
|
|
|
|
if (rc) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
off = loc->fe_data_off + fcb_len_in_flash(fcb, loc->fe_data_len);
|
|
|
|
|
2018-01-27 06:07:10 +08:00
|
|
|
rc = fcb_flash_read(fcb, loc->fe_sector, off, &fl_crc8, sizeof(fl_crc8));
|
2017-12-13 22:53:20 +08:00
|
|
|
if (rc) {
|
2019-07-11 17:21:35 +08:00
|
|
|
return -EIO;
|
2017-12-13 22:53:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fl_crc8 != crc8) {
|
2019-07-11 17:21:35 +08:00
|
|
|
return -EBADMSG;
|
2017-12-13 22:53:20 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|