diff options
author | Aki Niemi <aki.niemi@nokia.com> | 2009-09-14 14:34:00 +0300 |
---|---|---|
committer | Aki Niemi <aki.niemi@nokia.com> | 2009-09-14 14:34:00 +0300 |
commit | dec66954b6e4569f644f3e1f4a0a5a02f30662d4 (patch) | |
tree | 9723ab205d37726635afd8f04c8a1354ae5f4604 | |
parent | ffaba2b637f403af238551d5ec87d9955ce5a23a (diff) | |
download | ofono-dec66954b6e4569f644f3e1f4a0a5a02f30662d4.tar.bz2 |
gisi: Add ISI sub-block iterator
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | gisi/iter.c | 155 | ||||
-rw-r--r-- | gisi/iter.h | 59 |
3 files changed, 216 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index f441e53a..fcf6771b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,8 @@ gdbus_sources = gdbus/gdbus.h gdbus/mainloop.c gdbus/object.c gdbus/watch.c gisi_sources = gisi/phonet.h gisi/modem.h gisi/netlink.h gisi/netlink.c \ gisi/socket.h gisi/socket.c gisi/client.h gisi/client.c \ - gisi/pep.h gisi/pep.c gisi/pipe.h gisi/pipe.c + gisi/pep.h gisi/pep.c gisi/pipe.h gisi/pipe.c gisi/iter.h \ + gisi/iter.c gatchat_sources = gatchat/gatchat.h gatchat/gatchat.c \ gatchat/gatresult.h gatchat/gatresult.c \ diff --git a/gisi/iter.c b/gisi/iter.c new file mode 100644 index 00000000..dfc6dfa8 --- /dev/null +++ b/gisi/iter.c @@ -0,0 +1,155 @@ +/* + * This file is part of oFono - Open Source Telephony + * + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <glib.h> +#include <arpa/inet.h> + +#include "iter.h" + +static inline void bcd_to_mccmnc(const uint8_t *bcd, char *mcc, char *mnc) +{ + mcc[0] = '0' + (bcd[0] & 0x0F); + mcc[1] = '0' + ((bcd[0] & 0xF0) >> 4); + mcc[2] = '0' + (bcd[1] & 0x0F); + mcc[3] = '\0'; + + mnc[0] = '0' + (bcd[2] & 0x0F); + mnc[1] = '0' + ((bcd[2] & 0xF0) >> 4); + mnc[2] = (bcd[1] & 0xF0) == 0xF0 ? '\0' : '0' + + (bcd[1] & 0xF0); + mnc[3] = '\0'; +} + +bool g_isi_sb_iter_is_valid(GIsiSubBlockIter *iter) +{ + if (!iter || iter->end - iter->start < 2) + return false; + + if (iter->start + iter->start[1] > iter->end) + return false; + + return true; +} + +uint8_t g_isi_sb_iter_get_id(GIsiSubBlockIter *iter) +{ + return iter->start[0]; +} + +uint8_t g_isi_sb_iter_get_len(GIsiSubBlockIter *iter) +{ + 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) + return false; + + *byte = iter->start[pos]; + return true; +} + +bool g_isi_sb_iter_get_word(GIsiSubBlockIter *iter, uint16_t *word, int pos) +{ + uint16_t val; + + if (pos + 1 > iter->start[1]) + return false; + + memcpy(&val, iter->start + pos, sizeof(uint16_t)); + *word = ntohs(val); + return true; +} + +bool g_isi_sb_iter_get_dword(GIsiSubBlockIter *iter, uint32_t *dword, + int pos) +{ + uint32_t val; + + if (pos + 3 > iter->start[1]) + return false; + + memcpy(&val, iter->start + pos, sizeof(uint32_t)); + *dword = ntohl(val); + return true; +} + +bool g_isi_sb_iter_get_oper_code(GIsiSubBlockIter *iter, char *mcc, + char *mnc, int pos) +{ + if (pos + 2 > iter->start[1]) + return false; + + bcd_to_mccmnc(iter->start + pos, mcc, mnc); + return true; +} + +bool g_isi_sb_iter_get_alpha_tag(GIsiSubBlockIter *iter, char **utf8, + int pos) +{ + uint8_t *ucs2 = NULL; + int len = 0; + + if (pos > iter->start[1]) + return false; + + len = iter->start[pos] * 2; /* Alpha tags are UCS-2 */ + + if (!utf8 || len == 0 || pos + 1 + len > iter->start[1]) + return false; + + ucs2 = iter->start + pos + 1; + *utf8 = g_convert((const char *)ucs2, len, "UTF-8//TRANSLIT", "UCS-2BE", + NULL, NULL, NULL); + return utf8 != 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]; + + if (iter->start + len > iter->end) + return false; + + iter->start += len; + return true; +} diff --git a/gisi/iter.h b/gisi/iter.h new file mode 100644 index 00000000..87ebfdba --- /dev/null +++ b/gisi/iter.h @@ -0,0 +1,59 @@ +/* + * This file is part of oFono - Open Source Telephony + * + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __GISI_ITER_H +#define __GISI_ITER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <stdbool.h> + +struct _GIsiSubBlockIter { + uint8_t *start; + uint8_t *end; +}; +typedef struct _GIsiSubBlockIter GIsiSubBlockIter; + +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); + +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); +bool g_isi_sb_iter_get_dword(GIsiSubBlockIter *iter, uint32_t *dword, int pos); +bool g_isi_sb_iter_get_oper_code(GIsiSubBlockIter *iter, char *mcc, + char *mnc, int pos); +bool g_isi_sb_iter_get_alpha_tag(GIsiSubBlockIter *iter, char **utf8, int pos); +bool g_isi_sb_iter_init(const void restrict *data, size_t len, + GIsiSubBlockIter *iter); + +#ifdef __cplusplus +} +#endif + +#endif /* __GISI_ITER_H */ |