daemon designed to read short data bursts from weather stations transmitting over the Iridium satellite network
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

79 lines
1.6 KiB

#include <stdlib.h>
#include <inttypes.h>
#include "imei.h"
imei_set* imei_set_new(size_t capacity)
{
imei_set* set = (imei_set*)malloc(
sizeof(imei_set) + (capacity * sizeof(uint64_t))
);
if(set == NULL) return NULL;
set->sz = 0;
set->cp = capacity;
return set;
}
// This is not efficient at all. It could be made vastly
// more efficient by having imei_set_add() insert in order
// and then implementing a binary search algorithm here
int imei_set_search(imei_set* set, uint64_t imei)
{
for(size_t i = 0; i < set->sz; i++){
if(set->imeis[i] == imei) return 1;
}
return 0;
}
void imei_set_free(imei_set *set){
if(set != NULL) free(set);
}
int imei_set_add(imei_set** set, uint64_t imei)
{
// Don't allow out-of-bounds imeis
if(imei == UINT64_MAX) return 1;
// Don't allow duplicate entries
if(imei_set_search(*set, imei)) return 2;
// If the set is full, expand it
if((*set)->sz == (*set)->cp){
imei_set* nset = realloc(
*set, sizeof(imei_set) + (((*set)->cp + 1000) * sizeof(uint64_t))
);
if(nset == NULL) return 1;
nset->cp += 1000;
(*set) = nset;
}
(*set)->imeis[(*set)->sz] = imei;
(*set)->sz++;
return 0;
}
uint64_t imei_uint64(unsigned char *imei, size_t sz)
{
// IMEI's are always 15 bytes in length
if(sz != 15) return UINT64_MAX;
uint64_t r = 0;
for(int i = 0; i < 15; i++){
// If any byte in the IMEI isn't a proper digit,
// return an error - UINT64_MAX is used because
// an imei will only use 60 bits, so the
// max for a 64-bit unsigned int is out of bounds.
if(imei[i] < '0' || imei[i] > '9') return UINT64_MAX;
r = (r<<4) + (imei[i] - '0');
}
return r;
}