mirror of git://git.sysmocom.de/ofono
Add support for long sub-block header
This commit is contained in:
parent
6c08fc8e50
commit
3cec9ac67b
65
gisi/iter.c
65
gisi/iter.c
|
@ -47,30 +47,53 @@ static inline void bcd_to_mccmnc(const uint8_t *bcd, char *mcc, char *mnc)
|
|||
mnc[3] = '\0';
|
||||
}
|
||||
|
||||
bool g_isi_sb_iter_is_valid(GIsiSubBlockIter *iter)
|
||||
bool g_isi_sb_iter_init(const void restrict *data, size_t len,
|
||||
GIsiSubBlockIter *iter, bool longhdr)
|
||||
{
|
||||
if (!iter || iter->end - iter->start < 2)
|
||||
if (!iter || !data || len == 0)
|
||||
return false;
|
||||
|
||||
if (iter->start + iter->start[1] > iter->end)
|
||||
iter->start = (uint8_t *)data;
|
||||
iter->end = iter->start + len;
|
||||
iter->longhdr = longhdr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool g_isi_sb_iter_is_valid(GIsiSubBlockIter *iter)
|
||||
{
|
||||
if (!iter || iter->end - iter->start < (iter->longhdr ? 4 : 2))
|
||||
return false;
|
||||
|
||||
if (iter->start + g_isi_sb_iter_get_len(iter) > iter->end)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t g_isi_sb_iter_get_id(GIsiSubBlockIter *iter)
|
||||
int g_isi_sb_iter_get_id(GIsiSubBlockIter *iter)
|
||||
{
|
||||
if (iter->longhdr) {
|
||||
uint16_t *hdr = (uint16_t *)iter->start;
|
||||
return (int)ntohs(hdr[0]);
|
||||
}
|
||||
|
||||
return iter->start[0];
|
||||
}
|
||||
|
||||
uint8_t g_isi_sb_iter_get_len(GIsiSubBlockIter *iter)
|
||||
size_t g_isi_sb_iter_get_len(GIsiSubBlockIter *iter)
|
||||
{
|
||||
if (iter->longhdr) {
|
||||
uint16_t *hdr = (uint16_t *)iter->start;
|
||||
return (size_t)ntohs(hdr[1]);
|
||||
}
|
||||
|
||||
return iter->start[1];
|
||||
}
|
||||
|
||||
bool g_isi_sb_iter_get_byte(GIsiSubBlockIter *iter, uint8_t *byte, int pos)
|
||||
{
|
||||
if (pos > iter->start[1] || iter->start + pos > iter->end)
|
||||
if (pos > (int)g_isi_sb_iter_get_len(iter) || iter->start + pos > iter->end)
|
||||
return false;
|
||||
|
||||
*byte = iter->start[pos];
|
||||
|
@ -81,7 +104,7 @@ bool g_isi_sb_iter_get_word(GIsiSubBlockIter *iter, uint16_t *word, int pos)
|
|||
{
|
||||
uint16_t val;
|
||||
|
||||
if (pos + 1 > iter->start[1])
|
||||
if (pos + 1 > (int)g_isi_sb_iter_get_len(iter))
|
||||
return false;
|
||||
|
||||
memcpy(&val, iter->start + pos, sizeof(uint16_t));
|
||||
|
@ -94,7 +117,7 @@ bool g_isi_sb_iter_get_dword(GIsiSubBlockIter *iter, uint32_t *dword,
|
|||
{
|
||||
uint32_t val;
|
||||
|
||||
if (pos + 3 > iter->start[1])
|
||||
if (pos + 3 > (int)g_isi_sb_iter_get_len(iter))
|
||||
return false;
|
||||
|
||||
memcpy(&val, iter->start + pos, sizeof(uint32_t));
|
||||
|
@ -105,7 +128,7 @@ bool g_isi_sb_iter_get_dword(GIsiSubBlockIter *iter, uint32_t *dword,
|
|||
bool g_isi_sb_iter_get_oper_code(GIsiSubBlockIter *iter, char *mcc,
|
||||
char *mnc, int pos)
|
||||
{
|
||||
if (pos + 2 > iter->start[1])
|
||||
if (pos + 2 > (int)g_isi_sb_iter_get_len(iter))
|
||||
return false;
|
||||
|
||||
bcd_to_mccmnc(iter->start + pos, mcc, mnc);
|
||||
|
@ -117,10 +140,10 @@ bool g_isi_sb_iter_get_alpha_tag(GIsiSubBlockIter *iter, char **utf8,
|
|||
{
|
||||
uint8_t *ucs2 = NULL;
|
||||
|
||||
if (pos > iter->start[1])
|
||||
if (pos > (int)g_isi_sb_iter_get_len(iter))
|
||||
return false;
|
||||
|
||||
if (!utf8 || len == 0 || pos + len > iter->start[1])
|
||||
if (!utf8 || len == 0 || pos + len > g_isi_sb_iter_get_len(iter))
|
||||
return false;
|
||||
|
||||
ucs2 = iter->start + pos;
|
||||
|
@ -137,10 +160,10 @@ bool g_isi_sb_iter_get_latin_tag(GIsiSubBlockIter *iter, char **latin,
|
|||
{
|
||||
uint8_t *str = NULL;
|
||||
|
||||
if (pos > iter->start[1])
|
||||
if (pos > (int)g_isi_sb_iter_get_len(iter))
|
||||
return false;
|
||||
|
||||
if (!latin || len == 0 || pos + len > iter->start[1])
|
||||
if (!latin || len == 0 || pos + len > g_isi_sb_iter_get_len(iter))
|
||||
return false;
|
||||
|
||||
str = iter->start + pos;
|
||||
|
@ -152,20 +175,12 @@ bool g_isi_sb_iter_get_latin_tag(GIsiSubBlockIter *iter, char **latin,
|
|||
return latin != NULL;
|
||||
}
|
||||
|
||||
bool g_isi_sb_iter_init(const void restrict *data, size_t len, GIsiSubBlockIter *iter)
|
||||
{
|
||||
if (!iter || !data || len == 0)
|
||||
return false;
|
||||
|
||||
iter->start = (uint8_t *)data;
|
||||
iter->end = iter->start + len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool g_isi_sb_iter_next(GIsiSubBlockIter *iter)
|
||||
{
|
||||
uint8_t len = iter->start[1] == 0 ? 2 : iter->start[1];
|
||||
uint8_t len = g_isi_sb_iter_get_len(iter);
|
||||
|
||||
if (len == 0)
|
||||
len = iter->longhdr ? 4 : 2;
|
||||
|
||||
if (iter->start + len > iter->end)
|
||||
return false;
|
||||
|
|
10
gisi/iter.h
10
gisi/iter.h
|
@ -34,14 +34,17 @@ extern "C" {
|
|||
struct _GIsiSubBlockIter {
|
||||
uint8_t *start;
|
||||
uint8_t *end;
|
||||
bool longhdr;
|
||||
};
|
||||
typedef struct _GIsiSubBlockIter GIsiSubBlockIter;
|
||||
|
||||
bool g_isi_sb_iter_init(const void restrict *data, size_t len,
|
||||
GIsiSubBlockIter *iter, bool longhdr);
|
||||
bool g_isi_sb_iter_is_valid(GIsiSubBlockIter *iter);
|
||||
bool g_isi_sb_iter_next(GIsiSubBlockIter *iter);
|
||||
|
||||
uint8_t g_isi_sb_iter_get_id(GIsiSubBlockIter *iter);
|
||||
uint8_t g_isi_sb_iter_get_len(GIsiSubBlockIter *iter);
|
||||
int g_isi_sb_iter_get_id(GIsiSubBlockIter *iter);
|
||||
size_t g_isi_sb_iter_get_len(GIsiSubBlockIter *iter);
|
||||
|
||||
bool g_isi_sb_iter_get_byte(GIsiSubBlockIter *iter, uint8_t *byte, int pos);
|
||||
bool g_isi_sb_iter_get_word(GIsiSubBlockIter *iter, uint16_t *word, int pos);
|
||||
|
@ -53,9 +56,6 @@ bool g_isi_sb_iter_get_alpha_tag(GIsiSubBlockIter *iter, char **utf8,
|
|||
bool g_isi_sb_iter_get_latin_tag(GIsiSubBlockIter *iter, char **ascii,
|
||||
size_t len, int pos);
|
||||
|
||||
bool g_isi_sb_iter_init(const void restrict *data, size_t len,
|
||||
GIsiSubBlockIter *iter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue