Optimized special case when new meta data length is the same.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
21f70601b4
commit
3431293d43
1 changed files with 43 additions and 14 deletions
|
|
@ -355,20 +355,49 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
||||||
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
|
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
|
||||||
if (!ef)
|
if (!ef)
|
||||||
return CCID_ERR_FILE_NOT_FOUND;
|
return CCID_ERR_FILE_NOT_FOUND;
|
||||||
if ((r = meta_delete(fid)) != CCID_OK)
|
uint16_t ef_size = file_get_size(ef);
|
||||||
return r;
|
uint8_t *fdata = (uint8_t *)calloc(1, ef_size);
|
||||||
size_t fdata_len = 1+format_tlv_len(len+2, NULL)+len+2;
|
memcpy(fdata, file_get_data(ef), ef_size);
|
||||||
uint8_t *fdata = (uint8_t *)calloc(1, fdata_len), *f = fdata;
|
uint8_t tag = 0x0, *tag_data = NULL, *p = NULL;
|
||||||
*f++ = fid & 0xff;
|
size_t tag_len = 0;
|
||||||
f += format_tlv_len(len, f);
|
while (walk_tlv(fdata, ef_size, &p, &tag, &tag_len, &tag_data)) {
|
||||||
*f++ = fid >> 8;
|
if (tag_len < 2)
|
||||||
*f++ = fid & 0xff;
|
continue;
|
||||||
memcpy(f, data, len);
|
uint16_t cfid = (tag_data[0] << 8 | tag_data[1]);
|
||||||
r = flash_write_data_to_file(ef, fdata, fdata_len);
|
if (cfid == fid) {
|
||||||
|
if (tag_len-2 == len) { //an update
|
||||||
|
memcpy(p-tag_len+2, data, len);
|
||||||
|
r = flash_write_data_to_file(ef, fdata, ef_size);
|
||||||
|
free(fdata);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return CCID_EXEC_ERROR;
|
||||||
|
low_flash_available();
|
||||||
|
return CCID_OK;
|
||||||
|
}
|
||||||
|
else { //needs reallocation
|
||||||
|
uint8_t *tpos = p-tag_len-format_tlv_len(tag_len, NULL)-1;
|
||||||
|
memmove(tpos, p, fdata+ef_size-p);
|
||||||
|
tpos += fdata+ef_size-p;
|
||||||
|
uintptr_t meta_offset = tpos-fdata;
|
||||||
|
ef_size += len - (tag_len-2);
|
||||||
|
if (len > tag_len-2)
|
||||||
|
fdata = (uint8_t *)realloc(fdata, ef_size);
|
||||||
|
uint8_t *f = fdata+meta_offset;
|
||||||
|
*f++ = fid & 0xff;
|
||||||
|
f += format_tlv_len(len+2, f);
|
||||||
|
*f++ = fid >> 8;
|
||||||
|
*f++ = fid & 0xff;
|
||||||
|
memcpy(f, data, len);
|
||||||
|
r = flash_write_data_to_file(ef, fdata, ef_size);
|
||||||
|
free(fdata);
|
||||||
|
if (r != CCID_OK)
|
||||||
|
return CCID_EXEC_ERROR;
|
||||||
|
low_flash_available();
|
||||||
|
return CCID_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
free(fdata);
|
free(fdata);
|
||||||
if (r != CCID_OK)
|
return CCID_WRONG_DATA;
|
||||||
return CCID_EXEC_ERROR;
|
|
||||||
low_flash_available();
|
|
||||||
return CCID_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue