timeout when read phonebook
by Li, Zhigang
Hi,
There was one issue in 0.2 version for reading phonebook: it can't read phonebook records. It's ok in latest version.
Another problem is timeout during read records in first time
It's mean I have to read more than once again.
In fact I had only one record in modem so it's strange behavior.
Thanks
11 years, 5 months
[PATCH] add manpage for ofonod
by Andres Salomon
Hi,
I created this manpage for Debian; feel free to use it. The license
is the same as oFono's.
---
doc/Makefile.am | 2 ++
doc/ofonod.8 | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 0 deletions(-)
create mode 100644 doc/ofonod.8
diff --git a/doc/Makefile.am b/doc/Makefile.am
index dae164a..85f6023 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -2,3 +2,5 @@
EXTRA_DIST = overview.txt
MAINTAINERCLEANFILES = Makefile.in
+
+man_MANS = ofonod.8
diff --git a/doc/ofonod.8 b/doc/ofonod.8
new file mode 100644
index 0000000..474d7fb
--- /dev/null
+++ b/doc/ofonod.8
@@ -0,0 +1,35 @@
+.\"
+.\" ofonod(8)
+.\"
+.\" Copyright (C) 2009 Collabora Ltd.
+.TH ofonod 8 "Jul 2009"
+.SH NAME
+ofonod \- oFono mobile telephony daemon
+.SH SYNOPSIS
+.B "ofonod [options]"
+.SH DESCRIPTION
+.B ofonod
+is a daemon which provides an oFono stack for interfacing mobile telephony devices.
+oFono is controlled through \fID-Bus\fP; for example, one can tell
+.B ofonod
+to send AT commands over /dev/rfcomm0 by calling the \fID-Bus\fP method org.ofono.at.Manager.Create.
+.I "/etc/dbus-1/system.d/ofono.conf"
+is used to manage \fID-Bus\fP permissions for oFono.
+.SH OPTIONS
+.TP
+.B --debug, -d
+Enable debug information output.
+.TP
+.B --nodetach, -n
+Don't run as daemon in background.
+.TP
+.SH SEE ALSO
+.PP
+\&\fIdbus-send\fR\|(1)
+
+.SH FILES
+.BR /etc/dbus-1/system.d/ofono.conf
+.SH AUTHOR
+.br
+This man page was written by Andres Salomon <dilinger(a)collabora.co.uk>.
+
--
1.6.3.3
11 years, 5 months
[PATCH] Return SIM file access conditions from read_file_info.
by Andrzej Zaborowski
---
drivers/atmodem/sim.c | 28 +++++++++++++++++++++++-----
src/driver.h | 23 ++++++++++++++++++++++-
src/sim.c | 3 ++-
3 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 01b5719..81b566a 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -40,6 +40,13 @@
static const char *crsm_prefix[] = { "+CRSM:", NULL };
+static inline enum ofono_sim_file_access file_access_condition_decode(int bcd)
+{
+ if (bcd >= 4 && bcd <= 14)
+ return OFONO_SIM_FILE_ACCESS_ADM;
+ return bcd;
+}
+
static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct cb_data *cbd = user_data;
@@ -50,12 +57,13 @@ static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
gint sw1, sw2, len;
int flen, rlen;
enum ofono_sim_file_structure str;
+ enum ofono_sim_file_access access[__OFONO_SIM_FILE_CONDITION_NUM];
dump_response("at_crsm_info_cb", ok, result);
decode_at_error(&error, g_at_result_final_response(result));
if (!ok) {
- cb(&error, -1, -1, -1, cbd->data);
+ cb(&error, -1, -1, -1, NULL, cbd->data);
return;
}
@@ -64,7 +72,7 @@ static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
if (!g_at_result_iter_next(&iter, "+CRSM:")) {
DECLARE_FAILURE(e);
- cb(&e, -1, -1, -1, cbd->data);
+ cb(&e, -1, -1, -1, NULL, cbd->data);
return;
}
@@ -78,7 +86,7 @@ static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
(response[13] == 0x01 && len < 15)) {
DECLARE_FAILURE(e);
- cb(&e, -1, -1, -1, cbd->data);
+ cb(&e, -1, -1, -1, NULL, cbd->data);
return;
}
@@ -86,13 +94,23 @@ static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
flen = (response[2] << 8) | response[3];
str = response[13];
+ access[OFONO_SIM_FILE_CONDITION_UPDATE] =
+ file_access_condition_decode((response[9] >> 4) & 0xf);
+ access[OFONO_SIM_FILE_CONDITION_READ] =
+ file_access_condition_decode((response[9] >> 0) & 0xf);
+ access[OFONO_SIM_FILE_CONDITION_INCREASE] =
+ file_access_condition_decode((response[10] >> 0) & 0xf);
+ access[OFONO_SIM_FILE_CONDITION_INVALIDATE] =
+ file_access_condition_decode((response[11] >> 4) & 0xf);
+ access[OFONO_SIM_FILE_CONDITION_REHABILITATE] =
+ file_access_condition_decode((response[11] >> 0) & 0xf);
if (str == 0x01)
rlen = response[14];
else
rlen = 0;
- cb(&error, flen, str, rlen, cbd->data);
+ cb(&error, flen, str, rlen, access, cbd->data);
}
static void at_sim_read_info(struct ofono_modem *modem, int fileid,
@@ -118,7 +136,7 @@ error:
{
DECLARE_FAILURE(error);
- cb(&error, -1, -1, -1, data);
+ cb(&error, -1, -1, -1, NULL, data);
}
}
diff --git a/src/driver.h b/src/driver.h
index f324c1c..c730eea 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -101,6 +101,25 @@ enum ofono_sim_file_structure {
OFONO_SIM_FILE_STRUCTURE_CYCLIC = 3
};
+/* 51.011 Section 9.3 */
+enum ofono_sim_file_access {
+ OFONO_SIM_FILE_ACCESS_ALWAYS = 0,
+ OFONO_SIM_FILE_ACCESS_CHV1 = 1,
+ OFONO_SIM_FILE_ACCESS_CHV2 = 2,
+ OFONO_SIM_FILE_ACCESS_RESERVED = 3,
+ OFONO_SIM_FILE_ACCESS_ADM = 4,
+ OFONO_SIM_FILE_ACCESS_NEVER = 15,
+};
+
+enum ofono_sim_file_condition {
+ OFONO_SIM_FILE_CONDITION_READ = 0,
+ OFONO_SIM_FILE_CONDITION_UPDATE,
+ OFONO_SIM_FILE_CONDITION_INCREASE,
+ OFONO_SIM_FILE_CONDITION_INVALIDATE,
+ OFONO_SIM_FILE_CONDITION_REHABILITATE,
+ __OFONO_SIM_FILE_CONDITION_NUM,
+};
+
/* Notification functions, the integer values here should map to
* values obtained from the modem. The enumerations are the same
* as the values for the fields found in 3GPP TS 27.007
@@ -162,7 +181,9 @@ typedef void (*ofono_call_barring_cb_t)(const struct ofono_error *error,
typedef void (*ofono_sim_file_info_cb_t)(const struct ofono_error *error,
int filelength,
enum ofono_sim_file_structure structure,
- int recordlength, void *data);
+ int recordlength,
+ enum ofono_sim_file_access *access,
+ void *data);
typedef void (*ofono_sim_read_cb_t)(const struct ofono_error *error,
const unsigned char *sdata, int length,
diff --git a/src/sim.c b/src/sim.c
index 86f2e98..787ebc7 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -356,7 +356,8 @@ static gboolean sim_op_retrieve_next(gpointer user)
static void sim_op_info_cb(const struct ofono_error *error, int length,
enum ofono_sim_file_structure structure,
- int record_length, void *data)
+ int record_length,
+ enum ofono_sim_file_access *access, void *data)
{
struct ofono_modem *modem = data;
struct sim_manager_data *sim = modem->sim_manager;
--
1.6.0
11 years, 5 months
[PATCH] Read EF-PNN, EF-OPL and override network names accordingly.
by Andrzej Zaborowski
---
src/driver.h | 2 +
src/network.c | 54 ++++++----
src/sim.c | 315 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/sim.h | 4 +
4 files changed, 345 insertions(+), 30 deletions(-)
diff --git a/src/driver.h b/src/driver.h
index f324c1c..595c980 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -84,6 +84,8 @@ struct ofono_network_operator {
char mnc[OFONO_MAX_MNC_LENGTH + 1];
int status;
int tech;
+
+ const char *override_name;
};
/* 27.007 Section 7.11 Call Forwarding */
diff --git a/src/network.c b/src/network.c
index 5419a97..eab3cde 100644
--- a/src/network.c
+++ b/src/network.c
@@ -339,13 +339,15 @@ static char *get_operator_display_name(struct ofono_modem *modem)
return name;
}
+ plmn = netreg->current_operator->name;
+ if (netreg->current_operator->override_name)
+ plmn = netreg->current_operator->override_name;
+
if (!netreg->spname || strlen(netreg->spname) == 0) {
- g_strlcpy(name, netreg->current_operator->name, len);
+ g_strlcpy(name, plmn, len);
return name;
}
- plmn = netreg->current_operator->name;
-
home_or_spdi =
(netreg->status == NETWORK_REGISTRATION_STATUS_REGISTERED) ||
ofono_operator_in_spdi(modem, netreg->current_operator);
@@ -383,20 +385,22 @@ static void set_network_operator_name(struct ofono_modem *modem,
strncpy(op->name, name, OFONO_MAX_OPERATOR_NAME_LENGTH);
op->name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
- path = network_operator_build_path(modem, op);
+ if (!op->override_name) {
+ path = network_operator_build_path(modem, op);
- dbus_gsm_signal_property_changed(conn, path,
- NETWORK_OPERATOR_INTERFACE,
- "Name", DBUS_TYPE_STRING,
- &name);
+ dbus_gsm_signal_property_changed(conn, path,
+ NETWORK_OPERATOR_INTERFACE,
+ "Name", DBUS_TYPE_STRING,
+ &name);
- if (op == netreg->current_operator) {
- operator = get_operator_display_name(modem);
+ if (op == netreg->current_operator) {
+ operator = get_operator_display_name(modem);
- dbus_gsm_signal_property_changed(conn, modem->path,
- NETWORK_REGISTRATION_INTERFACE,
- "Operator", DBUS_TYPE_STRING,
- &operator);
+ dbus_gsm_signal_property_changed(conn, modem->path,
+ NETWORK_REGISTRATION_INTERFACE,
+ "Operator", DBUS_TYPE_STRING,
+ &operator);
+ }
}
}
@@ -413,6 +417,9 @@ static DBusMessage *network_operator_get_properties(DBusConnection *conn,
const char *status =
network_operator_status_to_string(op->operator->status);
+ if (op->operator->override_name)
+ name = op->operator->override_name;
+
reply = dbus_message_new_method_return(msg);
if (!reply)
return NULL;
@@ -852,6 +859,13 @@ void ofono_network_registration_notify(struct ofono_modem *modem, int status,
}
}
+static void network_operator_name_override(struct ofono_modem *modem,
+ struct ofono_network_operator *op)
+{
+ op->override_name =
+ ofono_operator_name_sim_override(modem, op->mcc, op->mnc);
+}
+
static void operator_list_callback(const struct ofono_error *error, int total,
const struct ofono_network_operator *list,
void *data)
@@ -890,11 +904,12 @@ static void operator_list_callback(const struct ofono_error *error, int total,
} else {
/* New operator */
struct ofono_network_operator *op =
- g_try_new0(struct ofono_network_operator, 1);
+ g_memdup(&list[i],
+ sizeof(struct ofono_network_operator));
if (!op)
continue;
- memcpy(op, &list[i], sizeof(struct ofono_network_operator));
+ network_operator_name_override(modem, op);
if (network_operator_dbus_register(modem, op)) {
n = g_slist_prepend(n, op);
@@ -968,15 +983,14 @@ static void current_operator_callback(const struct ofono_error *error,
if (current) {
netreg->current_operator =
- g_try_new0(struct ofono_network_operator, 1);
-
+ g_memdup(current,
+ sizeof(struct ofono_network_operator));
if (!netreg->current_operator) {
ofono_error("Unable to allocate current operator");
return;
}
- memcpy(netreg->current_operator, current,
- sizeof(struct ofono_network_operator));
+ network_operator_name_override(modem, netreg->current_operator);
netreg->operator_list = g_slist_append(netreg->operator_list,
netreg->current_operator);
diff --git a/src/sim.c b/src/sim.c
index a5d2164..13557bf 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -58,6 +58,16 @@ struct sim_manager_data {
int own_numbers_num;
int own_numbers_size;
int own_numbers_current;
+
+ GSList *opl;
+ int opl_num;
+ int opl_size;
+ int opl_current;
+
+ struct pnn_operator *pnn;
+ int pnn_num;
+ int pnn_size;
+ int pnn_current;
};
static char **get_own_numbers(GSList *own_numbers)
@@ -120,6 +130,11 @@ static const guint8 *ber_tlv_find_by_tag(const guint8 *pdu, guint8 in_tag,
return NULL;
}
+struct pnn_operator {
+ char *longname;
+ char *shortname;
+};
+
static struct sim_manager_data *sim_manager_create()
{
return g_try_new0(struct sim_manager_data, 1);
@@ -129,6 +144,7 @@ static void sim_manager_destroy(gpointer userdata)
{
struct ofono_modem *modem = userdata;
struct sim_manager_data *data = modem->sim_manager;
+ int i;
if (data->imsi) {
g_free(data->imsi);
@@ -151,6 +167,24 @@ static void sim_manager_destroy(gpointer userdata)
g_slist_free(data->spdi);
data->spdi = NULL;
}
+
+ if (data->opl) {
+ g_slist_foreach(data->opl, (GFunc)g_free, NULL);
+ g_slist_free(data->opl);
+ data->opl = NULL;
+ }
+
+ if (data->pnn) {
+ for (i = 0; i < data->pnn_num; i ++) {
+ if (data->pnn[i].longname)
+ g_free(data->pnn[i].longname);
+ if (data->pnn[i].shortname)
+ g_free(data->pnn[i].shortname);
+ }
+ g_free(data->pnn);
+ data->pnn = NULL;
+ data->pnn_num = 0;
+ }
}
static DBusMessage *sim_get_properties(DBusConnection *conn,
@@ -199,6 +233,37 @@ static GDBusMethodTable sim_manager_methods[] = {
static GDBusSignalTable sim_manager_signals[] = { { } };
+static char *network_name_parse(const unsigned char *buffer, int length)
+{
+ unsigned char *endp;
+ unsigned int dcs;
+
+ if (length < 1)
+ return NULL;
+
+ dcs = *buffer ++;
+ length --;
+
+ if (dcs & (1 << 3)) {
+ /* TODO: "The MS should add the letters for the Country's
+ * Initials and a separator (e.g. a space)" */
+ }
+
+ switch (dcs & (7 << 4)) {
+ case 0x00:
+ endp = memchr(buffer, 0xff, length);
+ if (endp)
+ length = endp - buffer;
+ return convert_gsm_to_utf8(buffer, length,
+ NULL, NULL, 0xff);
+ case 0x10:
+ return convert_ucs2_to_utf8(buffer, length,
+ NULL, NULL, 0xffff);
+ }
+
+ return NULL;
+}
+
static char *sim_alpha_field_parse(const unsigned char *buffer, int length)
{
long utf_len, char_len;
@@ -311,6 +376,8 @@ static char *sim_alpha_field_parse(const unsigned char *buffer, int length)
enum sim_fileids {
SIM_EFMSISDN_FILEID = 0x6f40,
SIM_EFSPN_FILEID = 0x6f46,
+ SIM_EFPNN_FILEID = 0x6fc5,
+ SIM_EFOPL_FILEID = 0x6fc6,
SIM_EFSPDI_FILEID = 0x6fcd,
};
@@ -494,16 +561,15 @@ static gboolean sim_retrieve_own_number(void *user_data)
return FALSE;
}
-struct spdi_operator {
+struct sim_operator {
char mcc[OFONO_MAX_MCC_LENGTH + 1];
char mnc[OFONO_MAX_MNC_LENGTH + 1];
};
-static struct spdi_operator *spdi_operator_alloc(const guint8 *bcd)
+static void parse_mcc_mnc(struct sim_operator *oper, const guint8 *bcd)
{
- struct spdi_operator *spdi = g_new0(struct spdi_operator, 1);
- char *mcc = spdi->mcc;
- char *mnc = spdi->mnc;
+ char *mcc = oper->mcc;
+ char *mnc = oper->mnc;
guint8 digit;
digit = (bcd[0] >> 0) & 0xf;
@@ -524,14 +590,21 @@ static struct spdi_operator *spdi_operator_alloc(const guint8 *bcd)
digit = (bcd[1] >> 4) & 0xf;
if (digit != 0xf)
*mnc ++ = '0' + digit;
+}
+
+static struct sim_operator *sim_operator_alloc(const guint8 *bcd)
+{
+ struct sim_operator *spdi = g_new0(struct sim_operator, 1);
+
+ parse_mcc_mnc(spdi, bcd);
return spdi;
}
static gint spdi_operator_compare(gconstpointer a, gconstpointer b)
{
- const struct spdi_operator *opa = a;
- const struct spdi_operator *opb = b;
+ const struct sim_operator *opa = a;
+ const struct sim_operator *opb = b;
gint r;
if (r = strcmp(opa->mcc, opb->mcc))
@@ -544,7 +617,7 @@ gboolean ofono_operator_in_spdi(struct ofono_modem *modem,
const struct ofono_network_operator *op)
{
struct sim_manager_data *sim = modem->sim_manager;
- struct spdi_operator spdi_op;
+ struct sim_operator spdi_op;
if (!sim)
return FALSE;
@@ -563,7 +636,7 @@ static void sim_spdi_read_cb(const struct ofono_error *error,
struct ofono_modem *modem = data;
struct sim_manager_data *sim = modem->sim_manager;
const guint8 *plmn_list;
- struct spdi_operator *spdi;
+ struct sim_operator *spdi;
GSList *l;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length <= 5)
@@ -580,7 +653,7 @@ static void sim_spdi_read_cb(const struct ofono_error *error,
continue;
sim->spdi = g_slist_insert_sorted(sim->spdi,
- spdi_operator_alloc(plmn_list),
+ sim_operator_alloc(plmn_list),
spdi_operator_compare);
}
@@ -615,6 +688,225 @@ static gboolean sim_retrieve_spdi(void *user_data)
return FALSE;
}
+struct opl_operator {
+ struct sim_operator mcc_mnc;
+ guint16 lac_tac_low;
+ guint16 lac_tac_high;
+ guint8 id;
+};
+
+static struct opl_operator *opl_operator_alloc(const guint8 *record)
+{
+ struct opl_operator *oper = g_new0(struct opl_operator, 1);
+
+ parse_mcc_mnc(&oper->mcc_mnc, record);
+ record += 3;
+
+ oper->lac_tac_low = (record[0] << 8) | record[1];
+ record += 2;
+ oper->lac_tac_high = (record[0] << 8) | record[1];
+ record += 2;
+
+ oper->id = record[0];
+ if (!oper->id) {
+ /* TODO: name to be taken from other sources, see TS 22.101 */
+ }
+
+ return oper;
+}
+
+static gint opl_operator_compare(gconstpointer a, gconstpointer b)
+{
+ const struct opl_operator *opa = a;
+ const struct sim_operator *opb = b;
+ int i;
+
+ for (i = 0; opb->mcc[i] | opa->mcc_mnc.mcc[i]; i ++)
+ if (opb->mcc[i] != opa->mcc_mnc.mcc[i] &&
+ !(opa->mcc_mnc.mcc[i] == '0' + 0xd &&
+ opb->mcc[i]))
+ return opa->mcc_mnc.mcc[i] - opb->mcc[i];
+ for (i = 0; opb->mnc[i] | opa->mcc_mnc.mnc[i]; i ++)
+ if (opb->mnc[i] != opa->mcc_mnc.mnc[i] &&
+ !(opa->mcc_mnc.mnc[i] == '0' + 0xd &&
+ opb->mnc[i]))
+ return opa->mcc_mnc.mnc[i] - opb->mnc[i];
+
+ if (opa->lac_tac_low > 0x0000 || opa->lac_tac_high < 0xfffe)
+ return 1;
+
+ return 0;
+}
+
+static void sim_opl_read_cb(const struct ofono_error *error,
+ const unsigned char *sdata, int length, void *data)
+{
+ struct ofono_modem *modem = data;
+ struct sim_manager_data *sim = modem->sim_manager;
+ struct opl_operator *oper;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
+ goto skip;
+
+ if (length < sim->opl_size)
+ goto skip;
+
+ oper = opl_operator_alloc(sdata);
+ if (oper->id > sim->pnn_num) {
+ g_free(oper);
+ goto skip;
+ }
+
+ sim->opl = g_slist_prepend(sim->opl, oper);
+
+skip:
+ sim->opl_current ++;
+ if (sim->opl_current < sim->opl_num)
+ sim->ops->read_file_linear(modem, SIM_EFOPL_FILEID,
+ sim->opl_current,
+ sim->opl_size,
+ sim_opl_read_cb, modem);
+ else
+ /* All records retrieved */
+ if (sim->opl)
+ sim->opl = g_slist_reverse(sim->opl);
+}
+
+static void sim_opl_info_cb(const struct ofono_error *error, int length,
+ enum ofono_sim_file_structure structure,
+ int record_length, void *data)
+{
+ struct ofono_modem *modem = data;
+ struct sim_manager_data *sim = modem->sim_manager;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length < 8 ||
+ record_length < 8 ||
+ structure != OFONO_SIM_FILE_STRUCTURE_FIXED)
+ return;
+
+ sim->opl_current = 0;
+ sim->opl_size = record_length;
+ sim->opl_num = length / record_length;
+ sim->ops->read_file_linear(modem, SIM_EFOPL_FILEID, 0,
+ record_length, sim_opl_read_cb, modem);
+}
+
+static gboolean sim_retrieve_opl(void *user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct sim_manager_data *sim = modem->sim_manager;
+
+ sim->ops->read_file_info(modem, SIM_EFOPL_FILEID,
+ sim_opl_info_cb, modem);
+
+ return FALSE;
+}
+
+const char *ofono_operator_name_sim_override(struct ofono_modem *modem,
+ const char *mcc, const char *mnc)
+{
+ struct sim_manager_data *sim = modem->sim_manager;
+ struct sim_operator op;
+ GSList *l;
+ const struct opl_operator *opl_op;
+
+ g_strlcpy(op.mcc, mcc, sizeof(op.mcc));
+ g_strlcpy(op.mnc, mnc, sizeof(op.mnc));
+
+ l = g_slist_find_custom(sim->opl, &op, opl_operator_compare);
+ if (!l)
+ return NULL;
+ opl_op = l->data;
+
+ return sim->pnn[opl_op->id - 1].longname;
+}
+
+static gboolean pnn_operator_parse(struct pnn_operator *oper,
+ const guint8 *tlv, int length)
+{
+ const char *name;
+ int namelength;
+
+ name = ber_tlv_find_by_tag(tlv, 0x43, length, &namelength);
+ if (!name || !namelength)
+ return FALSE;
+ oper->longname = network_name_parse(name, namelength);
+
+ name = ber_tlv_find_by_tag(tlv, 0x45, length, &namelength);
+ if (name && namelength)
+ oper->shortname = network_name_parse(name, namelength);
+
+ if (ber_tlv_find_by_tag(tlv, 0x80, length, &namelength))
+ ofono_debug("%i octets of addition PLMN information "
+ "present in EF-PNN");
+
+ return TRUE;
+}
+
+static void sim_pnn_read_cb(const struct ofono_error *error,
+ const unsigned char *pnndata, int length, void *data)
+{
+ struct ofono_modem *modem = data;
+ struct sim_manager_data *sim = modem->sim_manager;
+ struct opl_operator *oper;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
+ goto skip;
+
+ if (length < sim->pnn_size)
+ goto skip;
+
+ pnn_operator_parse(&sim->pnn[sim->pnn_current], pnndata, length);
+
+skip:
+ sim->pnn_current ++;
+ if (sim->pnn_current < sim->pnn_num)
+ sim->ops->read_file_linear(modem, SIM_EFPNN_FILEID,
+ sim->pnn_current,
+ sim->pnn_size,
+ sim_pnn_read_cb, modem);
+ else
+ /* All records retrieved */
+ /* We now need EF-OPL if it's there for PNN to be
+ * useful. */
+ sim_retrieve_opl(modem);
+}
+
+static void sim_pnn_info_cb(const struct ofono_error *error, int length,
+ enum ofono_sim_file_structure structure,
+ int record_length, void *data)
+{
+ struct ofono_modem *modem = data;
+ struct sim_manager_data *sim = modem->sim_manager;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length < 3 ||
+ record_length < 3 ||
+ structure != OFONO_SIM_FILE_STRUCTURE_FIXED)
+ /* If PNN is not present then OPL is not useful, don't
+ * retrieve it. If OPL is not there then PNN[1] will
+ * still be used for the HPLMN and/or EHPLMN, if PNN
+ * is present. */
+ return;
+
+ sim->pnn_current = 0;
+ sim->pnn_size = record_length;
+ sim->pnn_num = length / record_length;
+ sim->pnn = g_new0(struct pnn_operator, sim->pnn_num);
+ sim->ops->read_file_linear(modem, SIM_EFPNN_FILEID, 0,
+ record_length, sim_pnn_read_cb, modem);
+}
+
+static gboolean sim_retrieve_pnn(void *user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct sim_manager_data *sim = modem->sim_manager;
+
+ sim->ops->read_file_info(modem, SIM_EFPNN_FILEID,
+ sim_pnn_info_cb, modem);
+
+ return FALSE;
+}
+
static void initialize_sim_manager(struct ofono_modem *modem)
{
DBusConnection *conn = dbus_gsm_connection();
@@ -647,6 +939,9 @@ static void initialize_sim_manager(struct ofono_modem *modem)
if (modem->sim_manager->ops->read_file_transparent)
g_timeout_add(0, sim_retrieve_spdi, modem);
+
+ if (modem->sim_manager->ops->read_file_linear)
+ g_timeout_add(0, sim_retrieve_pnn, modem);
}
int ofono_sim_manager_register(struct ofono_modem *modem,
diff --git a/src/sim.h b/src/sim.h
index 251a339..ecb809a 100644
--- a/src/sim.h
+++ b/src/sim.h
@@ -31,3 +31,7 @@ int ofono_spn_update_notify_unregister(struct ofono_modem *modem,
gboolean ofono_operator_in_spdi(struct ofono_modem *modem,
const struct ofono_network_operator *op);
+
+const char *ofono_operator_name_sim_override(struct ofono_modem *modem,
+ const char *mcc,
+ const char *mnc);
--
1.6.0
11 years, 6 months
Problems with voice call.
by Marko Saukko
Hi,
I'm trying to make a voice call with oFono. I'm using Option GlobeSurfer
ICON 225 HSDPA/UMTS USB as the modem. If I understood correctly voice
call should be possible with the dbus-messages used below. However, I
end up with an error "Operation failed".
$ dbus-send --system --print-reply --dest=org.ofono /
org.ofono.at.Manager.Create string:"dev:/dev/ttyHS0" string:"at"
method return sender=:1.540 -> dest=:1.544 reply_serial=2
object path "/modem1"
$ dbus-send --system --print-reply --dest=org.ofono /modem1
org.ofono.VoiceCallManager.Dial string:"+000000000000" string:"default"
Error org.ofono.Error.Failed: Operation failed
When the second dbus-message is sent the following messages are printed
by the ofonod:
ofonod[19113]: atd_cb got result: 0
ofonod[19113]: Final response: ERROR
ofonod[19113]: Dial callback returned error: (null)
Are the messages I sent to the ofonod correct?
Regards,
Marko
11 years, 6 months
Problems of CF setting and GSM string
by Li, Zhigang
HI,
Test against the 0.1 version,
Tow problem were detected,
1, only set CF no reply timer can't successful, and I have to set no reply number or disable it first.
Cf.setproperties("VoiceNoReply",dbusInt16(30))
2, *SC***SIC# don't support in GSM string
*61***30#
Are they known issue? or anything I did wrong
Also only CF need update DATA,FAX,SMS in the future, right?
Thanks
Zhigang
11 years, 6 months
Compiler errors.
by Marko Saukko
Hi,
with the latest oFono git version I'm getting the following compiler
errors when using gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3.
----
gcc -DHAVE_CONFIG_H -I. -I.. -I../include -I../src
-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -Werror
-Wextra -Wno-unused-parameter -Wno-missing-field-initializers
-Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls
-Wcast-align -MT smsutil.o -MD -MP -MF .deps/smsutil.Tpo -c -o smsutil.o
`test -f '../src/smsutil.c' || echo './'`../src/smsutil.c
cc1: warnings being treated as errors
../src/smsutil.c: In function ‘sms_extract_common’:
../src/smsutil.c:1442: error: ‘dcs’ may be used uninitialized in this
function
../src/smsutil.c:1441: error: ‘udhi’ may be used uninitialized in this
function
../src/smsutil.c:1440: error: ‘max’ may be used uninitialized in this
function
../src/smsutil.c:1439: error: ‘udl’ may be used uninitialized in this
function
../src/smsutil.c: In function ‘extract_app_port_common’:
../src/smsutil.c:1756: error: ‘is_addr_8bit’ may be used uninitialized
in this function
../src/smsutil.c: In function ‘sms_extract_concatenation’:
../src/smsutil.c:1843: error: ‘seq’ may be used uninitialized in this
function
../src/smsutil.c:1843: error: ‘max’ may be used uninitialized in this
function
../src/smsutil.c:1842: error: ‘rn’ may be used uninitialized in this
function
../src/smsutil.c: In function ‘cbs_decode_text’:
../src/smsutil.c:2706: error: ‘iso639’ may be used uninitialized in this
function
../src/smsutil.c:2704: error: ‘charset’ may be used uninitialized in
this function
make[2]: *** [smsutil.o] Error 1
make[2]: Leaving directory `/home/muk/software/ofono/ofono/unit'
----
Regards,
Marko
11 years, 6 months
The very first oFono release
by Marcel Holtmann
Hello everyone,
I just went ahead and tagged version 0.1 of oFono. We have announced
this project about 3 month ago, but the actual code base is a little bit
older of course. And at some point we have to start making releases :)
http://www.kernel.org/pub/linux/network/ofono/
Not everything is fully functional at this point of time, but simple
voice call handling with an AT based modem (or phone simulator) should
be working fine. If anything fails, please send bug reports to the
mailing list and we will fix it.
Basic SMS support is available and within the next releases we will make
sure it works properly. After that the work on GPRS/HSPA with smooth
integration into ConnMan will start. Just to give everybody a heads up.
I also think it is a good time for package maintainers to look into
making oFono available in their distributions. And give feedback on
things that don't integrate well.
Regards
Marcel
11 years, 6 months
[PATCH] Fix g_isi_client_destroy segfault
by Marko Saukko
If null pointer is given to g_isi_client_destroy it segfaults. Currently
this is happening when signal 15 is sent to ofonod.
---
diff --git a/gisi/client.c b/gisi/client.c
index b12dc85..a12640d 100644
--- a/gisi/client.c
+++ b/gisi/client.c
@@ -143,6 +143,8 @@ void g_isi_client_destroy(GIsiClient *client)
{
unsigned id;
+ if (!client)
+ return;
g_source_remove(client->source);
for (id = 0; id < 256; id++)
if (client->timeout[id] > 0)
11 years, 6 months
3GPP and EVDO
by Daniel Barden
Hi,
We're thinking about using Moblin Connection Manager in a project, and
in the connman list, they said that for 3G support, the long term goal is to
use oFono to handle these connection.
However, one statement in the oFono home page called my attention:
The plug-in API functionality is modeled on public standards, in
particular 3GPP TS 27.007 "AT command set for User Equipment (UE)."
Sorry for the beginner question, but will oFono provide support to
EV-DO (that as far as I could find is a 3GPP2 standard) or is usable only
with 3GPP protocols (UMTS)?
Best Regards,
Daniel Barden
11 years, 6 months