oFono Features
by Admin
Hello
I am interested to know which kind of feature range the ofono platform
is intended to have once. Specially are there plans to provide a
framework of ready-to-use gadgets, i.e. for user interfaces, graphics,
application components ?
Regards, Robert
11 years, 6 months
[PATCH] Parse SIM alpha fields (EF-SPN) according to TS 11.11.
by Andrzej Zaborowski
---
src/sim.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 114 insertions(+), 5 deletions(-)
diff --git a/src/sim.c b/src/sim.c
index 8485e1e..a5d2164 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -199,6 +199,115 @@ static GDBusMethodTable sim_manager_methods[] = {
static GDBusSignalTable sim_manager_signals[] = { { } };
+static char *sim_alpha_field_parse(const unsigned char *buffer, int length)
+{
+ long utf_len, char_len;
+ unsigned char str[2];
+ int i;
+ char *r, *ret;
+
+ if (length < 1)
+ return NULL;
+
+ if (buffer[0] < 0x80)
+ return convert_gsm_to_utf8(buffer, length, NULL, NULL, 0xff);
+ switch (buffer[0]) {
+ case 0x80:
+ if (length < 2)
+ return NULL;
+
+ return convert_ucs2_to_utf8(buffer + 1, length - 1,
+ NULL, NULL, 0xffff);
+
+ case 0x81:
+ if (length < 4 || buffer[1] == 0 || buffer[1] > length - 3)
+ return NULL;
+
+ length = buffer[1];
+ utf_len = 0;
+ for (i = 0; i < length; i ++) {
+ if (buffer[3 + i] & 0x80) {
+ str[0] = (buffer[2] >> 1);
+ str[1] = (buffer[2] << 7) |
+ (buffer[3 + i] & 0x7f);
+ r = convert_ucs2_to_utf8(str, 2,
+ NULL, &char_len, 0xffff);
+ } else
+ r = convert_gsm_to_utf8(&buffer[3 + i], 1,
+ NULL, &char_len, 0xff);
+
+ if (!r)
+ break;
+ g_free(r);
+ utf_len += char_len;
+ }
+
+ ret = g_malloc(utf_len + 1);
+
+ for (i = 0; i < length; i ++) {
+ if (buffer[3 + i] & 0x80) {
+ str[0] = (buffer[2] >> 1);
+ str[1] = (buffer[2] << 7) |
+ (buffer[3 + i] & 0x7f);
+ r = convert_ucs2_to_utf8(str, 2,
+ NULL, &char_len, 0xffff);
+ } else
+ r = convert_gsm_to_utf8(&buffer[3 + i], 1,
+ NULL, &char_len, 0xff);
+
+ memcpy(ret + utf_len, r, char_len);
+ g_free(r);
+ utf_len += char_len;
+ }
+ ret[utf_len] = 0;
+
+ return ret;
+
+ case 0x82:
+ if (length < 5 || buffer[1] == 0 || buffer[1] > length - 4)
+ return NULL;
+
+ length = buffer[1];
+ for (i = 0; i < length; i ++) {
+ if (buffer[4 + i] & 0x80) {
+ str[0] = buffer[2];
+ str[1] = buffer[3] + (buffer[4 + i] & 0x7f);
+ r = convert_ucs2_to_utf8(str, 2,
+ NULL, &char_len, 0xffff);
+ } else
+ r = convert_gsm_to_utf8(&buffer[4 + i], 1,
+ NULL, &char_len, 0xff);
+
+ if (!r)
+ break;
+ g_free(r);
+ utf_len += char_len;
+ }
+
+ ret = g_malloc(utf_len + 1);
+
+ for (i = 0; i < length; i ++) {
+ if (buffer[4 + i] & 0x80) {
+ str[0] = buffer[2];
+ str[1] = buffer[3] + (buffer[4 + i] & 0x7f);
+ r = convert_ucs2_to_utf8(str, 2,
+ NULL, &char_len, 0xffff);
+ } else
+ r = convert_gsm_to_utf8(&buffer[4 + i], 1,
+ NULL, &char_len, 0xff);
+
+ memcpy(ret + utf_len, r, char_len);
+ g_free(r);
+ utf_len += char_len;
+ }
+ ret[utf_len] = 0;
+
+ return ret;
+ }
+
+ return NULL;
+}
+
enum sim_fileids {
SIM_EFMSISDN_FILEID = 0x6f40,
SIM_EFSPN_FILEID = 0x6f46,
@@ -237,9 +346,7 @@ static void sim_spn_read_cb(const struct ofono_error *error,
if (endp)
length = endp - sdata;
- /*
- * The specification has this to say about the encoding of SPN:
- * Coding:
+ /* TS 31.102 says:
*
* the string shall use:
*
@@ -250,9 +357,11 @@ static void sim_spn_read_cb(const struct ofono_error *error,
* - or one of the UCS2 code options defined in the annex of TS
* 31.101 [11].
*
- * Assume the first option.
+ * 31.101 has no such annex though. 51.101 refers to Annex B of
+ * itself which is not there either. 11.11 contains the same
+ * paragraph as 51.101 and has an Annex B which we implement.
*/
- sim->spn = convert_gsm_to_utf8(sdata, length, NULL, NULL, 0xff);
+ sim->spn = sim_alpha_field_parse(sdata, length);
for (l = sim->update_spn_notify; l; l = l->next)
sim_spn_notify(modem, l->data);
--
1.6.0
11 years, 6 months
Potential Memory Leak in isimodem
by Gu, Yang
In isimodem_init() of file drivers/isimodem/isimodem.c, memory of size of "struct isi_data" is allocated, but I find no place to free it. Is this a real memory leak?
Regards,
-Yang
11 years, 6 months
Re: [PATCH] Add USC-2 to UTF-8 conversion utility function.
by Denis Kenzior
Hi,
The rest of the codebase uses g_convert which handles the necessary magic of
invoking iconv. So this function is really not necessary, use g_convert(buf,
bufsize, "UTF-8//TRANSLIT", "UCS-2BE",... instead.
Regards,
-Denis
11 years, 6 months
[PATCH] Add USC-2 to UTF-8 conversion utility function.
by Andrzej Zaborowski
---
src/util.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/util.h | 4 ++++
2 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/src/util.c b/src/util.c
index 84ce507..7a96afe 100644
--- a/src/util.c
+++ b/src/util.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <endian.h>
#include <glib.h>
@@ -692,3 +693,61 @@ unsigned char *pack_7bit(const unsigned char *in, long len, int byte_offset,
return pack_7bit_own_buf(in, len, byte_offset, ussd, items_written,
terminator, buf);
}
+
+/*!
+ * Converts text coded using ISO/IEC 10646 UCS-2 encoding into UTF8 encoded
+ * text. Input buffer length is given in bytes, not words.
+ *
+ * Returns newly-allocated UTF8 encoded string or NULL if the conversion
+ * could not be performed. Returns the number of bytes read from the
+ * UCS-2 encoded string in items_read (if not NULL), not including the
+ * terminator character. Returns the number of bytes written into the UTF8
+ * encoded string in items_written (if not NULL) not including the terminal
+ * '\0' character. The caller is reponsible for freeing the returned value.
+ */
+char *convert_ucs2_to_utf8(const unsigned char *buffer, long len,
+ long *items_read, long *items_written,
+ unsigned short terminator)
+{
+ int i;
+ unsigned short ucs2;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned char *swap_buf;
+#endif
+ unsigned char *ret;
+ GError *error;
+
+ /* All UCS-2 text is valid UTF-16 text but UTF-16 sequences of
+ * surrogate pairs are not valid in UCS-2 so first check that
+ * there are no surrogate pairs in the buffer and then use
+ * g_utf16_to_utf8() on it. */
+ for (i = 0; i < len - 1; i += 2) {
+ ucs2 = (buffer[i] << 8) + buffer[i + 1];
+
+ if (ucs2 == terminator)
+ break;
+
+ if ((ucs2 & 0xf800) == 0xd800)
+ return NULL;
+ }
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ swap_buf = g_malloc(i);
+ if (!swap_buf)
+ return NULL;
+
+ swab(buffer, swap_buf, i);
+ buffer = swap_buf;
+#endif
+
+ ret = g_utf16_to_utf8((const gunichar2 *) buffer, i / 2,
+ NULL, items_written, &error);
+ if (ret && items_read)
+ *items_read = i;
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ g_free(swap_buf);
+#endif
+
+ return ret;
+}
diff --git a/src/util.h b/src/util.h
index 6269630..8589f0c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -56,3 +56,7 @@ unsigned char *pack_7bit_own_buf(const unsigned char *in, long len,
unsigned char *pack_7bit(const unsigned char *in, long len, int byte_offset,
gboolean ussd,
long *items_written, unsigned char terminator);
+
+char *convert_ucs2_to_utf8(const unsigned char *buffer, long len,
+ long *items_read, long *items_written,
+ unsigned short terminator);
--
1.6.0
11 years, 6 months
[PATCH] Scrap PINs in memory when no longer needed.
by Andrzej Zaborowski
Zero memory holding PINs/passwords where trivially doable. Other
places can pontentially hold passwords but in this patch we don't
touch them if we're not sure, maybe we should.
---
drivers/atmodem/call-barring.c | 19 ++++++++++++++-----
drivers/atmodem/call-meter.c | 37 ++++++++++++++++++++++++++-----------
src/ussd.c | 3 +++
3 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/drivers/atmodem/call-barring.c b/drivers/atmodem/call-barring.c
index f0ba18e..c659371 100644
--- a/drivers/atmodem/call-barring.c
+++ b/drivers/atmodem/call-barring.c
@@ -124,6 +124,7 @@ static void at_call_barring_set(struct ofono_modem *modem, const char *lock,
struct cb_data *cbd = cb_data_new(modem, cb, data);
char buf[64];
int len;
+ guint id;
if (!cbd || strlen(lock) != 2 || (cls && !passwd))
goto error;
@@ -138,8 +139,11 @@ static void at_call_barring_set(struct ofono_modem *modem, const char *lock,
",%i", cls);
}
- if (g_at_chat_send(at->parser, buf, none_prefix,
- clck_set_cb, cbd, g_free) > 0)
+ id = g_at_chat_send(at->parser, buf, none_prefix,
+ clck_set_cb, cbd, g_free);
+ memset(buf, 0, len);
+
+ if (id > 0)
return;
error:
@@ -171,15 +175,20 @@ static void at_call_barring_set_passwd(struct ofono_modem *modem,
struct at_data *at = ofono_modem_userdata(modem);
struct cb_data *cbd = cb_data_new(modem, cb, data);
char buf[64];
+ guint id;
+ int len;
if (!cbd || strlen(lock) != 2)
goto error;
- snprintf(buf, sizeof(buf), "AT+CPWD=\"%s\",\"%s\",\"%s\"",
+ len = snprintf(buf, sizeof(buf), "AT+CPWD=\"%s\",\"%s\",\"%s\"",
lock, old_passwd, new_passwd);
- if (g_at_chat_send(at->parser, buf, none_prefix,
- cpwd_set_cb, cbd, g_free) > 0)
+ id = g_at_chat_send(at->parser, buf, none_prefix,
+ cpwd_set_cb, cbd, g_free);
+ memset(buf, 0, len);
+
+ if (id > 0)
return;
error:
diff --git a/drivers/atmodem/call-meter.c b/drivers/atmodem/call-meter.c
index e7c55c3..cff27a5 100644
--- a/drivers/atmodem/call-meter.c
+++ b/drivers/atmodem/call-meter.c
@@ -175,14 +175,19 @@ static void at_cacm_set(struct ofono_modem *modem, const char *passwd,
struct at_data *at = ofono_modem_userdata(modem);
struct cb_data *cbd = cb_data_new(modem, cb, data);
char buf[64];
+ guint id;
+ int len;
if (!cbd)
goto error;
- snprintf(buf, sizeof(buf), "AT+CACM=\"%s\"", passwd);
+ len = snprintf(buf, sizeof(buf), "AT+CACM=\"%s\"", passwd);
- if (g_at_chat_send(at->parser, buf, none_prefix,
- generic_set_cb, cbd, g_free) > 0)
+ id = g_at_chat_send(at->parser, buf, none_prefix,
+ generic_set_cb, cbd, g_free);
+ memset(buf, 0, len);
+
+ if (id > 0)
return;
error:
@@ -219,20 +224,25 @@ error:
}
}
-static void at_camm_set(struct ofono_modem *modem, int accmax, const char *passwd,
- ofono_generic_cb_t cb, void *data)
+static void at_camm_set(struct ofono_modem *modem, int accmax,
+ const char *passwd, ofono_generic_cb_t cb, void *data)
{
struct at_data *at = ofono_modem_userdata(modem);
struct cb_data *cbd = cb_data_new(modem, cb, data);
char buf[64];
+ guint id;
+ int len;
if (!cbd)
goto error;
- sprintf(buf, "AT+CAMM=\"%06X\",\"%s\"", accmax, passwd);
+ len = sprintf(buf, "AT+CAMM=\"%06X\",\"%s\"", accmax, passwd);
- if (g_at_chat_send(at->parser, buf, none_prefix,
- generic_set_cb, cbd, g_free) > 0)
+ id = g_at_chat_send(at->parser, buf, none_prefix,
+ generic_set_cb, cbd, g_free);
+ memset(buf, 0, len);
+
+ if (id > 0)
return;
error:
@@ -313,15 +323,20 @@ static void at_cpuc_set(struct ofono_modem *modem, const char *currency,
struct at_data *at = ofono_modem_userdata(modem);
struct cb_data *cbd = cb_data_new(modem, cb, data);
char buf[64];
+ guint id;
+ int len;
if (!cbd)
goto error;
- snprintf(buf, sizeof(buf), "AT+CPUC=\"%s\",\"%f\",\"%s\"",
+ len = snprintf(buf, sizeof(buf), "AT+CPUC=\"%s\",\"%f\",\"%s\"",
currency, ppu, passwd);
- if (g_at_chat_send(at->parser, buf, none_prefix,
- generic_set_cb, cbd, g_free) > 0)
+ id = g_at_chat_send(at->parser, buf, none_prefix,
+ generic_set_cb, cbd, g_free);
+ memset(buf, 0, len);
+
+ if (id > 0)
return;
error:
diff --git a/src/ussd.c b/src/ussd.c
index 97c3304..08b9b52 100644
--- a/src/ussd.c
+++ b/src/ussd.c
@@ -322,6 +322,9 @@ static gboolean recognized_control_string(struct ofono_modem *modem,
if (recognized_passwd_change_string(modem, type, sc,
sia, sib, sic, sid, dn, msg)) {
ret = TRUE;
+ memset(sib, 0, strlen(sib));
+ memset(sic, 0, strlen(sic));
+ memset(sid, 0, strlen(sid));
goto out;
}
--
1.6.0
11 years, 6 months
[0/5] Phonet build work-arounds
by Rémi Denis-Courmont
configure.ac | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/atmodem/at.h | 4 ----
drivers/isimodem/isi.h | 4 ----
gisi/client.c | 8 +++-----
gisi/netlink.c | 7 +++----
gisi/socket.c | 9 +++------
6 files changed, 49 insertions(+), 23 deletions(-)
--
Rémi Denis-Courmont
11 years, 6 months
[PATCH] Add support for tty on character device.
by Santtu Lakkala
Adds support for using ttys through a serial device directly.
Signed-off-by: Santtu Lakkala <inz(a)inz.fi>
---
drivers/atmodem/session.c | 36 ++++++++++++++++++++++++++++--------
1 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/drivers/atmodem/session.c b/drivers/atmodem/session.c
index 2301756..3a9e49b 100644
--- a/drivers/atmodem/session.c
+++ b/drivers/atmodem/session.c
@@ -77,7 +77,7 @@ static gboolean connect_cb(GIOChannel *io,
GIOCondition cond, gpointer user)
socklen_t len = sizeof(err);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
- err = errno;
+ err = errno == ENOTSOCK ? 0 : errno;
} else if (cond & (G_IO_HUP | G_IO_ERR))
err = ECONNRESET;
@@ -101,29 +101,47 @@ static gboolean connect_timeout(gpointer user)
return FALSE;
}
-#if 0
-static int tty_open(const char *tty, struct termios *ti)
+static GIOChannel *tty_connect(const char *tty)
{
+ GIOChannel *io;
int sk;
+ struct termios newtio;
sk = open(tty, O_RDWR | O_NOCTTY);
if (sk < 0) {
ofono_error("Can't open TTY %s: %s(%d)",
tty, strerror(errno), errno);
- return -1;
+ return NULL;
}
- if (ti && tcsetattr(sk, TCSANOW, ti) < 0) {
+ newtio.c_cflag = B115200 | CRTSCTS | CLOCAL | CREAD;
+ newtio.c_iflag = IGNPAR;
+ newtio.c_oflag = 0;
+ newtio.c_lflag = 0;
+
+ newtio.c_cc[VTIME] = 1;
+ newtio.c_cc[VMIN] = 5;
+
+ tcflush(sk, TCIFLUSH);
+ if (tcsetattr(sk, TCSANOW, &newtio) < 0) {
ofono_error("Can't change serial settings: %s(%d)",
strerror(errno), errno);
close(sk);
- return -1;
+ return NULL;
}
- return sk;
+ io = g_io_channel_unix_new(sk);
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ if (g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK,
+ NULL) != G_IO_STATUS_NORMAL) {
+ g_io_channel_unref(io);
+ return NULL;
+ }
+
+ return io;
}
-#endif
static GIOChannel *socket_common(int sk, struct sockaddr *addr,
socklen_t addrlen)
@@ -233,6 +251,8 @@ GIOChannel *modem_session_create(const char *target,
io = tcp_connect(target+4);
else if (!strncasecmp(target, "unix:", 5))
io = unix_connect(target+5);
+ else if (!strncasecmp(target, "dev:", 4))
+ io = tty_connect(target+4);
if (io == NULL)
return NULL;
--
debian.1.6.1.2.1
11 years, 6 months