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
|
*) New function freefare_free_tag() to free individual tags from a MifareTag
|
||||||
list.
|
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
|
.Fn mifare_application_alloc
|
||||||
function allocates enought sectors to store
|
function allocates enought sectors to store
|
||||||
.Vt size
|
.Vt size
|
||||||
sectors for the Application Identifier
|
bytes for the Application Identifier
|
||||||
.Vt aid
|
.Vt aid
|
||||||
and returns the list of allocated sectors.
|
and returns the list of allocated sectors.
|
||||||
.Pp
|
.Pp
|
||||||
|
|
|
@ -76,6 +76,12 @@ aidcmp (const MadAid left, const MadAid right)
|
||||||
MifareSectorNumber *
|
MifareSectorNumber *
|
||||||
mifare_application_alloc (Mad mad, MadAid aid, size_t size)
|
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.
|
* 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
MifareSectorNumber *res = malloc (sizeof (*res) * (size+1));
|
for (size_t i = 0; i < sizeof (sector_map); i++)
|
||||||
res[size] = 0;
|
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.
|
* Ensure the remaining free space is suficient before destroying the MAD.
|
||||||
*/
|
*/
|
||||||
MadAid free_aid = { 0x00, 0x00 };
|
if (s > 0)
|
||||||
MifareSectorNumber *free_aids = mifare_application_find (mad, free_aid);
|
|
||||||
if (!free_aids)
|
|
||||||
return NULL;
|
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 (!(res = malloc (n+1)))
|
||||||
if (free_aids[c]) {
|
return NULL;
|
||||||
res[c] = free_aids[c];
|
|
||||||
} else {
|
n = 0;
|
||||||
free (res);
|
for (size_t i = FIRST_SECTOR; i < sizeof (sector_map); i++)
|
||||||
res = NULL;
|
if (sector_map[i]) {
|
||||||
break;
|
res[n] = i;
|
||||||
|
mad_set_aid (mad, i, aid);
|
||||||
|
n++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free (free_aids);
|
res[n] = 0;
|
||||||
|
|
||||||
if (res) {
|
|
||||||
/* Update the MAD */
|
|
||||||
for (size_t c = 0; c < size; c++)
|
|
||||||
mad_set_aid (mad, res[c], aid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the list of allocated sectors */
|
/* Return the list of allocated sectors */
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -29,14 +29,14 @@ test_mifare_classic_application (void)
|
||||||
Mad mad = mad_new (2);
|
Mad mad = mad_new (2);
|
||||||
cut_assert_not_null (mad, cut_message ("mad_new() failed"));
|
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"));
|
cut_assert_not_null (s_alloc, cut_message ("mifare_application_alloc() failed"));
|
||||||
|
|
||||||
MifareSectorNumber *s_found = mifare_application_find (mad, aid);
|
MifareSectorNumber *s_found = mifare_application_find (mad, aid);
|
||||||
cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed"));
|
cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed"));
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
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"));
|
cut_assert_equal_int (0, s_alloc[3], cut_message ("Invalid size"));
|
||||||
|
|
Loading…
Reference in a new issue