Make mifare_application_alloc() accept size in bytes.
Fixes issue 31.
This commit is contained in:
parent
92ae6036d2
commit
541292505a
4 changed files with 56 additions and 23 deletions
2
NEWS
2
NEWS
|
@ -2,4 +2,6 @@ Changes between 0.1.0 and x.x.x [xx XXX xxxx]
|
|||
|
||||
*) New function freefare_free_tag() to free individual tags from a MifareTag
|
||||
list.
|
||||
*) The mifare_application_alloc() size parameter is now expressed in bytes
|
||||
and not in sectors.
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ The
|
|||
.Fn mifare_application_alloc
|
||||
function allocates enought sectors to store
|
||||
.Vt size
|
||||
sectors for the Application Identifier
|
||||
bytes for the Application Identifier
|
||||
.Vt aid
|
||||
and returns the list of allocated sectors.
|
||||
.Pp
|
||||
|
|
|
@ -76,6 +76,12 @@ aidcmp (const MadAid left, const MadAid right)
|
|||
MifareSectorNumber *
|
||||
mifare_application_alloc (Mad mad, MadAid aid, size_t size)
|
||||
{
|
||||
uint8_t sector_map[40];
|
||||
MifareSectorNumber sector;
|
||||
MadAid sector_aid;
|
||||
MifareSectorNumber *res = NULL;
|
||||
ssize_t s = size;
|
||||
|
||||
/*
|
||||
* Ensure the card does not already have the application registered.
|
||||
*/
|
||||
|
@ -85,35 +91,60 @@ mifare_application_alloc (Mad mad, MadAid aid, size_t size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
MifareSectorNumber *res = malloc (sizeof (*res) * (size+1));
|
||||
res[size] = 0;
|
||||
for (size_t i = 0; i < sizeof (sector_map); i++)
|
||||
sector_map[i] = 0;
|
||||
|
||||
/*
|
||||
* Try to minimize lost space and allocate as many large pages as possible
|
||||
* when the target is a Mifare Classic 4k.
|
||||
*/
|
||||
MadAid free_aid = { 0x00, 0x00 };
|
||||
if (mad_get_version (mad) == 2) {
|
||||
sector = 32;
|
||||
while ((s >= 12*16) && sector < 40) {
|
||||
mad_get_aid (mad, sector, §or_aid);
|
||||
if (0 == aidcmp (sector_aid, free_aid)) {
|
||||
sector_map[sector] = 1;
|
||||
s -= 15*16;
|
||||
}
|
||||
sector++;
|
||||
}
|
||||
}
|
||||
|
||||
sector = FIRST_SECTOR;
|
||||
MifareSectorNumber s_max = (mad_get_version (mad) == 1) ? 15 : 31;
|
||||
while ((s > 0) && (sector <= s_max)) {
|
||||
mad_get_aid (mad, sector, §or_aid);
|
||||
if (0 == aidcmp (sector_aid, free_aid)) {
|
||||
sector_map[sector] = 1;
|
||||
s -= 3*16;
|
||||
}
|
||||
sector++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the remaining free space is suficient before destroying the MAD.
|
||||
*/
|
||||
MadAid free_aid = { 0x00, 0x00 };
|
||||
MifareSectorNumber *free_aids = mifare_application_find (mad, free_aid);
|
||||
if (!free_aids)
|
||||
if (s > 0)
|
||||
return NULL;
|
||||
|
||||
int n = 0;
|
||||
for (size_t i = FIRST_SECTOR; i < sizeof (sector_map); i++)
|
||||
if (sector_map[i])
|
||||
n++;
|
||||
|
||||
for (size_t c = 0; c < size; c++) {
|
||||
if (free_aids[c]) {
|
||||
res[c] = free_aids[c];
|
||||
} else {
|
||||
free (res);
|
||||
res = NULL;
|
||||
break;
|
||||
if (!(res = malloc (n+1)))
|
||||
return NULL;
|
||||
|
||||
n = 0;
|
||||
for (size_t i = FIRST_SECTOR; i < sizeof (sector_map); i++)
|
||||
if (sector_map[i]) {
|
||||
res[n] = i;
|
||||
mad_set_aid (mad, i, aid);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
free (free_aids);
|
||||
|
||||
if (res) {
|
||||
/* Update the MAD */
|
||||
for (size_t c = 0; c < size; c++)
|
||||
mad_set_aid (mad, res[c], aid);
|
||||
}
|
||||
res[n] = 0;
|
||||
|
||||
/* Return the list of allocated sectors */
|
||||
return res;
|
||||
|
|
|
@ -29,14 +29,14 @@ test_mifare_classic_application (void)
|
|||
Mad mad = mad_new (2);
|
||||
cut_assert_not_null (mad, cut_message ("mad_new() failed"));
|
||||
|
||||
MifareSectorNumber *s_alloc = mifare_application_alloc (mad, aid, 3);
|
||||
MifareSectorNumber *s_alloc = mifare_application_alloc (mad, aid, 3*3*16);
|
||||
cut_assert_not_null (s_alloc, cut_message ("mifare_application_alloc() failed"));
|
||||
|
||||
MifareSectorNumber *s_found = mifare_application_find (mad, aid);
|
||||
cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed"));
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
cut_assert_equal_int (s_alloc[i], s_found[i], cut_message ("Allocated and foudn blocks don't match"));
|
||||
cut_assert_equal_int (s_alloc[i], s_found[i], cut_message ("Allocated and found blocks don't match"));
|
||||
}
|
||||
|
||||
cut_assert_equal_int (0, s_alloc[3], cut_message ("Invalid size"));
|
||||
|
|
Loading…
Reference in a new issue