[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
12 years, 11 months
[PATCH] fix test compile
by Shane Bryan
unit/test-sms.c: g_print format errors on x86_64 compiles, using %zd
and %ld as appropriate.
Shane...
13 years
[PATCH] Read EF-SPDI and use it for SPN display.
by Andrzej Zaborowski
When the operator is one of those listed in EF-SPDI then we need to
treat it like a HPLMN in deciding whether the SPN or PLMN name should
be displayed.
---
I was also going to try implementing the semantics described in EF-PNN /
EF-OPL but I have not found evidence that it's not already handled by the
modem in the responses to +COPN (i.e. it may already be taking care to
substitute the network names? is this specified somewhere or would this
be very unlikely?)
Regards
---
src/network.c | 7 ++-
src/sim.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/sim.h | 3 +
3 files changed, 176 insertions(+), 1 deletions(-)
diff --git a/src/network.c b/src/network.c
index a437f0d..43fa2ab 100644
--- a/src/network.c
+++ b/src/network.c
@@ -328,6 +328,7 @@ static char *get_operator_display_name(struct ofono_modem *modem)
const char *plmn;
char *name = netreg->display_name;
int len = sizeof(netreg->display_name);
+ int home_or_spdi;
/* The name displayed to user depends on whether we're in a home
* PLMN or roaming and on configuration bits from the SIM, all
@@ -345,7 +346,11 @@ static char *get_operator_display_name(struct ofono_modem *modem)
plmn = netreg->current_operator->name;
- if (netreg->status == NETWORK_REGISTRATION_STATUS_REGISTERED)
+ home_or_spdi =
+ (netreg->status == NETWORK_REGISTRATION_STATUS_REGISTERED) ||
+ ofono_operator_in_spdi(modem, netreg->current_operator);
+
+ if (home_or_spdi)
if (netreg->flags & NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN)
/* Case 1 */
snprintf(name, len, "%s (%s)", netreg->spname, plmn);
diff --git a/src/sim.c b/src/sim.c
index a8b7d5f..572f6a8 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -53,6 +53,8 @@ struct sim_manager_data {
GSList *update_spn_notify;
+ GSList *spdi;
+
int own_numbers_num;
int own_numbers_size;
int own_numbers_current;
@@ -80,6 +82,44 @@ static char **get_own_numbers(GSList *own_numbers)
return ret;
}
+/* Parse ASN.1 Basic Encoding Rules TLVs per ISO/IEC 7816 */
+static const guint8 *ber_tlv_find_by_tag(const guint8 *pdu, guint8 in_tag,
+ int in_len, int *out_len)
+{
+ guint8 tag;
+ int len;
+ const guint8 *end = pdu + in_len;
+
+ do {
+ while (pdu < end && (*pdu == 0x00 || *pdu == 0xff))
+ pdu ++;
+ if (pdu == end)
+ break;
+
+ tag = *pdu ++;
+ if (!(0x1f & ~tag))
+ while (pdu < end && (*pdu ++ & 0x80));
+ if (pdu == end)
+ break;
+
+ for (len = 0; pdu + 1 < end && (*pdu & 0x80);
+ len = (len | (*pdu ++ & 0x7f)) << 7);
+ if (*pdu & 0x80)
+ break;
+ len |= *pdu ++;
+
+ if (tag == in_tag && pdu + len <= end) {
+ if (out_len)
+ *out_len = len;
+ return pdu;
+ }
+
+ pdu += len;
+ } while (pdu < end);
+
+ return NULL;
+}
+
static struct sim_manager_data *sim_manager_create()
{
return g_try_new0(struct sim_manager_data, 1);
@@ -105,6 +145,12 @@ static void sim_manager_destroy(gpointer userdata)
g_free(data->spn);
data->spn = NULL;
}
+
+ if (data->spdi) {
+ g_slist_foreach(data->spdi, (GFunc)g_free, NULL);
+ g_slist_free(data->spdi);
+ data->spdi = NULL;
+ }
}
static DBusMessage *sim_get_properties(DBusConnection *conn,
@@ -156,6 +202,7 @@ static GDBusSignalTable sim_manager_signals[] = { { } };
enum sim_fileids {
SIM_EFMSISDN_FILEID = 0x6f40,
SIM_EFSPN_FILEID = 0x6f46,
+ SIM_EFSPDI_FILEID = 0x6fcd,
};
#define SIM_EFSPN_DC_HOME_PLMN_BIT 0x1
@@ -338,6 +385,123 @@ static gboolean sim_retrieve_own_number(void *user_data)
return FALSE;
}
+struct spdi_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)
+{
+ struct spdi_operator *spdi = g_new0(struct spdi_operator, 1);
+ char *mcc = spdi->mcc;
+ char *mnc = spdi->mnc;
+ guint8 digit;
+
+ digit = (bcd[0] >> 0) & 0xf;
+ if (digit != 0xf)
+ *mcc ++ = '0' + digit;
+ digit = (bcd[0] >> 4) & 0xf;
+ if (digit != 0xf)
+ *mcc ++ = '0' + digit;
+ digit = (bcd[1] >> 0) & 0xf;
+ if (digit != 0xf)
+ *mcc ++ = '0' + digit;
+ digit = (bcd[2] >> 0) & 0xf;
+ if (digit != 0xf)
+ *mnc ++ = '0' + digit;
+ digit = (bcd[2] >> 4) & 0xf;
+ if (digit != 0xf)
+ *mnc ++ = '0' + digit;
+ digit = (bcd[1] >> 4) & 0xf;
+ if (digit != 0xf)
+ *mnc ++ = '0' + digit;
+
+ return spdi;
+}
+
+static gint spdi_operator_compare(gconstpointer a, gconstpointer b)
+{
+ const struct spdi_operator *opa = a;
+ const struct spdi_operator *opb = b;
+
+ return strcmp(opa->mcc, opb->mcc) ?: strcmp(opa->mnc, opb->mnc);
+}
+
+int 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;
+
+ if (!sim)
+ return FALSE;
+
+ g_strlcpy(spdi_op.mcc, op->mcc, sizeof(spdi_op.mcc));
+ g_strlcpy(spdi_op.mnc, op->mnc, sizeof(spdi_op.mnc));
+
+ return !!g_slist_find_custom(sim->spdi,
+ &spdi_op, spdi_operator_compare);
+}
+
+static void sim_spdi_read_cb(const struct ofono_error *error,
+ const unsigned char *spdidata,
+ int length, void *data)
+{
+ struct ofono_modem *modem = data;
+ struct sim_manager_data *sim = modem->sim_manager;
+ const guint8 *plmn_list;
+ struct spdi_operator *spdi;
+ GSList *l;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length <= 5)
+ return;
+
+ plmn_list = ber_tlv_find_by_tag(spdidata, 0x80, length, &length);
+ if (!plmn_list) {
+ ofono_debug("Couldn't parse the EF-SPDI contents as a TLV");
+ return;
+ }
+
+ for (length /= 3; length --; plmn_list += 3) {
+ if ((plmn_list[0] & plmn_list[1] & plmn_list[2]) == 0xff)
+ continue;
+
+ sim->spdi = g_slist_insert_sorted(sim->spdi,
+ spdi_operator_alloc(plmn_list),
+ spdi_operator_compare);
+ }
+
+ if (sim->spdi)
+ for (l = sim->update_spn_notify; l; l = l->next)
+ sim_spn_notify(modem, l->data);
+}
+
+static void sim_spdi_info_cb(const struct ofono_error *error, int length,
+ enum ofono_sim_file_structure structure,
+ int dummy, void *data)
+{
+ struct ofono_modem *modem = data;
+ struct sim_manager_data *sim = modem->sim_manager;
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length <= 5 ||
+ structure != OFONO_SIM_FILE_STRUCTURE_TRANSPARENT)
+ return;
+
+ sim->ops->read_file_transparent(modem, SIM_EFSPDI_FILEID, 0, length,
+ sim_spdi_read_cb, modem);
+}
+
+static gboolean sim_retrieve_spdi(void *user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct sim_manager_data *sim = modem->sim_manager;
+
+ sim->ops->read_file_info(modem, SIM_EFSPDI_FILEID,
+ sim_spdi_info_cb, modem);
+
+ return FALSE;
+}
+
static void initialize_sim_manager(struct ofono_modem *modem)
{
DBusConnection *conn = dbus_gsm_connection();
@@ -367,6 +531,9 @@ static void initialize_sim_manager(struct ofono_modem *modem)
if (modem->sim_manager->ops->read_file_linear)
g_timeout_add(0, sim_retrieve_own_number, modem);
+
+ if (modem->sim_manager->ops->read_file_transparent)
+ g_timeout_add(0, sim_retrieve_spdi, modem);
}
int ofono_sim_manager_register(struct ofono_modem *modem,
diff --git a/src/sim.h b/src/sim.h
index e0b471d..9456934 100644
--- a/src/sim.h
+++ b/src/sim.h
@@ -28,3 +28,6 @@ int ofono_spn_update_notify_register(struct ofono_modem *modem,
update_spn_cb cb);
int ofono_spn_update_notify_unregister(struct ofono_modem *modem,
update_spn_cb cb);
+
+int ofono_operator_in_spdi(struct ofono_modem *modem,
+ const struct ofono_network_operator *op);
--
1.6.0
13 years
[PATCH] Change sim_ops plugin interface to allow acces to linear fixed files
by Andrzej Zaborowski
(iow record based files), both read and update access.
Implement writing sim files through AT.
Depends on "[PATCH] Use GET RESPONSE sim command to retrieve EF length."
---
drivers/atmodem/sim.c | 199 +++++++++++++++++++++++++++++++++++++++++++------
src/driver.h | 31 ++++++--
src/sim.c | 16 ++--
3 files changed, 210 insertions(+), 36 deletions(-)
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index a2aebb8..66e951e 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -41,20 +41,22 @@
static const char *crsm_prefix[] = { "+CRSM:", NULL };
static const char *cnum_prefix[] = { "+CNUM:", NULL };
-static void at_crsm_len_cb(gboolean ok, GAtResult *result, gpointer user_data)
+static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct cb_data *cbd = user_data;
GAtResultIter iter;
- ofono_sim_file_len_cb_t cb = cbd->cb;
+ ofono_sim_file_info_cb_t cb = cbd->cb;
struct ofono_error error;
const guint8 *response;
gint sw1, sw2, len;
+ int flen, rlen;
+ enum ofono_simfile_struct str;
- dump_response("at_crsm_len_cb", ok, result);
+ dump_response("at_crsm_info_cb", ok, result);
decode_at_error(&error, g_at_result_final_response(result));
if (!ok) {
- cb(&error, -1, cbd->data);
+ cb(&error, -1, -1, -1, cbd->data);
return;
}
@@ -63,29 +65,38 @@ static void at_crsm_len_cb(gboolean ok, GAtResult *result, gpointer user_data)
if (!g_at_result_iter_next(&iter, "+CRSM:")) {
DECLARE_FAILURE(e);
- cb(&e, -1, cbd->data);
+ cb(&e, -1, -1, -1, cbd->data);
return;
}
g_at_result_iter_next_number(&iter, &sw1);
- g_at_result_iter_next_number(&iter, &len);
+ g_at_result_iter_next_number(&iter, &sw2);
if (!g_at_result_iter_next_hexstring(&iter, &response, &len) ||
(sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92) ||
- (sw1 == 0x90 && sw2 != 0x00) || len < 14) {
+ (sw1 == 0x90 && sw2 != 0x00) ||
+ len < 14 || response[6] != 0x04 ||
+ (response[13] == 0x01 && len < 15)) {
DECLARE_FAILURE(e);
- cb(&e, -1, cbd->data);
+ cb(&e, -1, -1, -1, cbd->data);
return;
}
- ofono_debug("crsm_len_cb: %02x, %02x, %i", sw1, sw2, len);
+ ofono_debug("crsm_info_cb: %02x, %02x, %i", sw1, sw2, len);
+
+ flen = (response[2] << 8) | response[3];
+ str = response[13];
+ if (str == 0x01)
+ rlen = response[14];
+ else
+ rlen = 0;
- cb(&error, (response[2] << 8) | response[3], cbd->data);
+ cb(&error, flen, str, rlen, cbd->data);
}
-static void at_sim_read_file_len(struct ofono_modem *modem, int fileid,
- ofono_sim_file_len_cb_t cb,
+static void at_sim_read_info(struct ofono_modem *modem, int fileid,
+ ofono_sim_file_info_cb_t cb,
void *data)
{
struct at_data *at = ofono_modem_userdata(modem);
@@ -97,7 +108,7 @@ static void at_sim_read_file_len(struct ofono_modem *modem, int fileid,
snprintf(buf, sizeof(buf), "AT+CRSM=192,%i,0,0,15", fileid);
if (g_at_chat_send(at->parser, buf, crsm_prefix,
- at_crsm_len_cb, cbd, g_free) > 0)
+ at_crsm_info_cb, cbd, g_free) > 0)
return;
error:
@@ -106,11 +117,12 @@ error:
{
DECLARE_FAILURE(error);
- cb(&error, -1, data);
+ cb(&error, -1, -1, -1, data);
}
}
-static void at_crsm_cb(gboolean ok, GAtResult *result, gpointer user_data)
+static void at_crsm_read_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
{
struct cb_data *cbd = user_data;
GAtResultIter iter;
@@ -119,7 +131,7 @@ static void at_crsm_cb(gboolean ok, GAtResult *result, gpointer user_data)
const guint8 *response;
gint sw1, sw2, len;
- dump_response("at_crsm_cb", ok, result);
+ dump_response("at_crsm_read_cb", ok, result);
decode_at_error(&error, g_at_result_final_response(result));
if (!ok) {
@@ -147,14 +159,14 @@ static void at_crsm_cb(gboolean ok, GAtResult *result, gpointer user_data)
return;
}
- ofono_debug("crsm_cb: %02x, %02x, %d", sw1, sw2, len);
+ ofono_debug("crsm_read_cb: %02x, %02x, %d", sw1, sw2, len);
cb(&error, response, len, cbd->data);
}
-static void at_sim_read_file(struct ofono_modem *modem, int fileid, int start,
- int length, ofono_sim_read_cb_t cb,
- void *data)
+static void at_sim_read_binary(struct ofono_modem *modem, int fileid,
+ int start, int length,
+ ofono_sim_read_cb_t cb, void *data)
{
struct at_data *at = ofono_modem_userdata(modem);
struct cb_data *cbd = cb_data_new(modem, cb, data);
@@ -166,7 +178,34 @@ static void at_sim_read_file(struct ofono_modem *modem, int fileid, int start,
snprintf(buf, sizeof(buf), "AT+CRSM=176,%i,%i,%i,%i", fileid,
start >> 8, start & 0xff, length);
if (g_at_chat_send(at->parser, buf, crsm_prefix,
- at_crsm_cb, cbd, g_free) > 0)
+ at_crsm_read_cb, cbd, g_free) > 0)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ {
+ DECLARE_FAILURE(error);
+ cb(&error, NULL, 0, data);
+ }
+}
+
+static void at_sim_read_record(struct ofono_modem *modem, int fileid,
+ int record, int length,
+ ofono_sim_read_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];
+
+ if (!cbd)
+ goto error;
+
+ snprintf(buf, sizeof(buf), "AT+CRSM=178,%i,%i,4,%i", fileid,
+ record + 1, length);
+ if (g_at_chat_send(at->parser, buf, crsm_prefix,
+ at_crsm_read_cb, cbd, g_free) > 0)
return;
error:
@@ -179,6 +218,117 @@ error:
}
}
+static void at_crsm_update_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ GAtResultIter iter;
+ ofono_generic_cb_t cb = cbd->cb;
+ struct ofono_error error;
+ gint sw1, sw2;
+
+ dump_response("at_crsm_update_cb", ok, result);
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CRSM:")) {
+ DECLARE_FAILURE(e);
+
+ cb(&e, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_next_number(&iter, &sw1);
+ g_at_result_iter_next_number(&iter, &sw2);
+ if ((sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92 && sw1 != 0x9f) ||
+ (sw1 == 0x90 && sw2 != 0x00)) {
+ DECLARE_FAILURE(e);
+
+ cb(&e, cbd->data);
+ return;
+ }
+
+ ofono_debug("crsm_update_cb: %02x, %02x", sw1, sw2);
+
+ cb(&error, cbd->data);
+}
+
+static void at_sim_update_binary(struct ofono_modem *modem, int fileid,
+ int start, int length,
+ const unsigned char *value,
+ 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 = g_try_new(char, 36 + length * 2);
+ int len, ret;
+
+ if (!cbd || !buf)
+ goto error;
+
+ len = sprintf(buf, "AT+CRSM=214,%i,%i,%i,%i,", fileid,
+ start >> 8, start & 0xff, length);
+ for (; length; length--)
+ len += sprintf(buf + len, "%02hhx", *value++);
+ ret = g_at_chat_send(at->parser, buf, crsm_prefix,
+ at_crsm_update_cb, cbd, g_free);
+
+ g_free(buf);
+
+ if (ret > 0)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ {
+ DECLARE_FAILURE(error);
+ cb(&error, data);
+ }
+}
+
+static void at_sim_update_record(struct ofono_modem *modem, int fileid,
+ int record, int length,
+ const unsigned char *value,
+ 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 = g_try_new(char, 36 + length * 2);
+ int len, ret;
+
+ if (!cbd || !buf)
+ goto error;
+
+ len = sprintf(buf, "AT+CRSM=220,%i,%i,4,%i,", fileid,
+ record + 1, length);
+ for (; length; length--)
+ len += sprintf(buf + len, "%02hhx", *value++);
+ ret = g_at_chat_send(at->parser, buf, crsm_prefix,
+ at_crsm_update_cb, cbd, g_free);
+
+ g_free(buf);
+
+ if (ret > 0)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ {
+ DECLARE_FAILURE(error);
+ cb(&error, data);
+ }
+}
+
static void at_cimi_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct cb_data *cbd = user_data;
@@ -317,8 +467,11 @@ error:
}
static struct ofono_sim_ops ops = {
- .read_file_len = at_sim_read_file_len,
- .read_file = at_sim_read_file,
+ .read_file_info = at_sim_read_info,
+ .read_file_transparent = at_sim_read_binary,
+ .read_file_linear = at_sim_read_record,
+ .write_file_transparent = at_sim_update_binary,
+ .write_file_linear = at_sim_update_record,
.read_imsi = at_read_imsi,
.read_own_numbers = at_read_msisdn,
};
diff --git a/src/driver.h b/src/driver.h
index 61504dd..36b9a08 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -98,6 +98,13 @@ struct ofono_own_number {
int itc;
};
+/* 51.011 Section 9.3 */
+enum ofono_simfile_struct {
+ OFONO_SIM_FILE_TRANSPARENT = 0,
+ OFONO_SIM_FILE_FIXED = 1,
+ OFONO_SIM_FILE_CYCLIC = 3
+};
+
/* 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
@@ -156,8 +163,10 @@ typedef void (*ofono_call_meter_puct_query_cb_t)(const struct ofono_error *error
typedef void (*ofono_call_barring_cb_t)(const struct ofono_error *error,
int status, void *data);
-typedef void (*ofono_sim_file_len_cb_t)(const struct ofono_error *error,
- int length, void *data);
+typedef void (*ofono_sim_file_info_cb_t)(const struct ofono_error *error,
+ int filelength,
+ enum ofono_simfile_struct structure,
+ int recordlength, void *data);
typedef void (*ofono_sim_read_cb_t)(const struct ofono_error *error,
const unsigned char *sdata, int length,
@@ -363,10 +372,20 @@ int ofono_call_barring_register(struct ofono_modem *modem,
void ofono_call_barring_unregister(struct ofono_modem *modem);
struct ofono_sim_ops {
- void (*read_file_len)(struct ofono_modem *modem, int fileid,
- ofono_sim_file_len_cb_t cb, void *data);
- void (*read_file)(struct ofono_modem *modem, int fileid, int start,
- int length, ofono_sim_read_cb_t cb, void *data);
+ void (*read_file_info)(struct ofono_modem *modem, int fileid,
+ ofono_sim_file_info_cb_t cb, void *data);
+ void (*read_file_transparent)(struct ofono_modem *modem, int fileid,
+ int start, int length,
+ ofono_sim_read_cb_t cb, void *data);
+ void (*read_file_linear)(struct ofono_modem *modem, int fileid,
+ int record, int length,
+ ofono_sim_read_cb_t cb, void *data);
+ void (*write_file_transparent)(struct ofono_modem *modem, int fileid,
+ int start, int length, const unsigned char *value,
+ ofono_generic_cb_t cb, void *data);
+ void (*write_file_linear)(struct ofono_modem *modem, int fileid,
+ int record, int length, const unsigned char *value,
+ ofono_generic_cb_t cb, void *data);
void (*read_imsi)(struct ofono_modem *modem,
ofono_imsi_cb_t cb, void *data);
void (*read_own_numbers)(struct ofono_modem *modem,
diff --git a/src/sim.c b/src/sim.c
index acec7bb..9c85292 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -237,16 +237,18 @@ static void sim_spn_read_cb(const struct ofono_error *error,
sim_spn_notify(modem, l->data);
}
-static void sim_spn_len_cb(const struct ofono_error *error,
- int length, void *data)
+static void sim_spn_info_cb(const struct ofono_error *error,
+ int length, enum ofono_simfile_struct structure, int dummy,
+ void *data)
{
struct ofono_modem *modem = data;
struct sim_manager_data *sim = modem->sim_manager;
- if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length <= 1)
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR || length <= 1 ||
+ structure != OFONO_SIM_FILE_TRANSPARENT)
return;
- sim->ops->read_file(modem, SIM_EFSPN_FILEID, 0, length,
+ sim->ops->read_file_transparent(modem, SIM_EFSPN_FILEID, 0, length,
sim_spn_read_cb, modem);
}
@@ -255,8 +257,8 @@ static gboolean sim_retrieve_spn(void *user_data)
struct ofono_modem *modem = user_data;
struct sim_manager_data *sim = modem->sim_manager;
- sim->ops->read_file_len(modem, SIM_EFSPN_FILEID,
- sim_spn_len_cb, modem);
+ sim->ops->read_file_info(modem, SIM_EFSPN_FILEID,
+ sim_spn_info_cb, modem);
return FALSE;
}
@@ -341,7 +343,7 @@ static void initialize_sim_manager(struct ofono_modem *modem)
modem_add_interface(modem, SIM_MANAGER_INTERFACE);
- if (modem->sim_manager->ops->read_file)
+ if (modem->sim_manager->ops->read_file_transparent)
g_timeout_add(0, sim_retrieve_spn, modem);
if (modem->sim_manager->ops->read_imsi)
--
1.6.0
13 years
[PATCH] Use GET RESPONSE sim command to retrieve EF length.
by Andrzej Zaborowski
Also accept 0x9f as a success status word 1 for READ BINARY (GSM specific).
Note that GET RESPONSE doesn't seem to work on on the TI Calypso modems
in OpenMoko phones. They return the 0x9f status which ETSI says is what
the SIM shall return if GET RESPONSE is not issued immediately after
the command generating the response, which would be the case if the
modem sends some command between SELECT and the GET RESPONSE. These
modems don't support AT+CSIM either in case we wanted to manually send
the SELECT and the GET RESPONSE.
---
drivers/atmodem/sim.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 7b41c76..a2aebb8 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -46,8 +46,9 @@ static void at_crsm_len_cb(gboolean ok, GAtResult *result, gpointer user_data)
struct cb_data *cbd = user_data;
GAtResultIter iter;
ofono_sim_file_len_cb_t cb = cbd->cb;
- gint sw1, len;
struct ofono_error error;
+ const guint8 *response;
+ gint sw1, sw2, len;
dump_response("at_crsm_len_cb", ok, result);
decode_at_error(&error, g_at_result_final_response(result));
@@ -69,16 +70,18 @@ static void at_crsm_len_cb(gboolean ok, GAtResult *result, gpointer user_data)
g_at_result_iter_next_number(&iter, &sw1);
g_at_result_iter_next_number(&iter, &len);
- ofono_debug("crsm_len_cb: %i, %i", sw1, len);
-
- if (sw1 != 0x67) {
+ if (!g_at_result_iter_next_hexstring(&iter, &response, &len) ||
+ (sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92) ||
+ (sw1 == 0x90 && sw2 != 0x00) || len < 14) {
DECLARE_FAILURE(e);
cb(&e, -1, cbd->data);
return;
}
- cb(&error, len, cbd->data);
+ ofono_debug("crsm_len_cb: %02x, %02x, %i", sw1, sw2, len);
+
+ cb(&error, (response[2] << 8) | response[3], cbd->data);
}
static void at_sim_read_file_len(struct ofono_modem *modem, int fileid,
@@ -92,7 +95,7 @@ static void at_sim_read_file_len(struct ofono_modem *modem, int fileid,
if (!cbd)
goto error;
- snprintf(buf, sizeof(buf), "AT+CRSM=176,%i,0,0,0", fileid);
+ snprintf(buf, sizeof(buf), "AT+CRSM=192,%i,0,0,15", fileid);
if (g_at_chat_send(at->parser, buf, crsm_prefix,
at_crsm_len_cb, cbd, g_free) > 0)
return;
@@ -136,7 +139,7 @@ static void at_crsm_cb(gboolean ok, GAtResult *result, gpointer user_data)
g_at_result_iter_next_number(&iter, &sw1);
g_at_result_iter_next_number(&iter, &sw2);
if (!g_at_result_iter_next_hexstring(&iter, &response, &len) ||
- (sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92) ||
+ (sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92 && sw1 != 0x9f) ||
(sw1 == 0x90 && sw2 != 0x00)) {
DECLARE_FAILURE(e);
--
1.6.0
13 years
[PATCH] Teach USSD to recognise password change strings.
by Andrzej Zaborowski
This is slightly hacky, part of ussd.c responsible for registering services
is duplicated and parse_ss_control_string is modified to accept a fourth
SI fragment in the input string.
---
src/common.c | 3 +-
src/common.h | 2 +-
src/modem.h | 1 +
src/ussd.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++---
src/ussd.h | 10 ++++
unit/test-common.c | 10 +++-
6 files changed, 159 insertions(+), 11 deletions(-)
diff --git a/src/common.c b/src/common.c
index 8653432..a9166bf 100644
--- a/src/common.c
+++ b/src/common.c
@@ -465,7 +465,7 @@ const char *ss_control_type_to_string(enum ss_control_type type)
gboolean parse_ss_control_string(char *str, int *ss_type,
char **sc, char **sia,
char **sib, char **sic,
- char **dn)
+ char **sid, char **dn)
{
int len = strlen(str);
int cur = 0;
@@ -533,6 +533,7 @@ gboolean parse_ss_control_string(char *str, int *ss_type,
NEXT_FIELD(c, *sia);
NEXT_FIELD(c, *sib);
NEXT_FIELD(c, *sic);
+ NEXT_FIELD(c, *sid);
if (*c == '\0')
ret = TRUE;
diff --git a/src/common.h b/src/common.h
index 1c0a776..0f7684e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -192,7 +192,7 @@ gboolean valid_ussd_string(const char *str);
gboolean parse_ss_control_string(char *str, int *ss_type,
char **sc, char **sia,
char **sib, char **sic,
- char **dn);
+ char **sid, char **dn);
const char *ss_control_type_to_string(enum ss_control_type type);
diff --git a/src/modem.h b/src/modem.h
index 22655f7..bbe7f99 100644
--- a/src/modem.h
+++ b/src/modem.h
@@ -28,6 +28,7 @@ struct ofono_modem {
void *userdata;
GSList *ss_control_list;
+ GSList *ss_passwd_list;
struct ofono_modem_data *modem_info;
struct network_registration_data *network_registration;
diff --git a/src/ussd.c b/src/ussd.c
index 7225398..d2251c8 100644
--- a/src/ussd.c
+++ b/src/ussd.c
@@ -165,22 +165,148 @@ void ss_control_unregister(struct ofono_modem *modem, const char *str,
l->data);
}
+struct ss_passwd_entry {
+ char *service;
+ ss_passwd_cb_t cb;
+};
+
+static struct ss_passwd_entry *ss_passwd_entry_create(const char *service,
+ ss_passwd_cb_t cb)
+{
+ struct ss_passwd_entry *r;
+
+ r = g_try_new0(struct ss_passwd_entry, 1);
+
+ if (!r)
+ return r;
+
+ r->service = g_strdup(service);
+ r->cb = cb;
+
+ return r;
+}
+
+static void ss_passwd_entry_destroy(struct ss_passwd_entry *ca)
+{
+ g_free(ca->service);
+ g_free(ca);
+}
+
+static gint ss_passwd_entry_compare(gconstpointer a, gconstpointer b)
+{
+ const struct ss_passwd_entry *ca = a;
+ const struct ss_passwd_entry *cb = b;
+ int ret;
+
+ ret = strcmp(ca->service, cb->service);
+
+ if (ret)
+ return ret;
+
+ if (ca->cb < cb->cb)
+ return -1;
+
+ if (ca->cb > cb->cb)
+ return 1;
+
+ return 0;
+}
+
+static gint ss_passwd_entry_find_by_service(gconstpointer a, gconstpointer b)
+{
+ const struct ss_passwd_entry *ca = a;
+
+ return strcmp(ca->service, b);
+}
+
+gboolean ss_passwd_register(struct ofono_modem *modem, const char *str,
+ ss_passwd_cb_t cb)
+{
+ struct ss_passwd_entry *entry;
+
+ if (!modem)
+ return FALSE;
+
+ entry = ss_passwd_entry_create(str, cb);
+
+ if (!entry)
+ return FALSE;
+
+ modem->ss_passwd_list = g_slist_append(modem->ss_passwd_list, entry);
+
+ return TRUE;
+}
+
+void ss_passwd_unregister(struct ofono_modem *modem, const char *str,
+ ss_passwd_cb_t cb)
+{
+ const struct ss_passwd_entry entry = { (char *)str, cb };
+ GSList *l;
+
+ if (!modem)
+ return;
+
+ l = g_slist_find_custom(modem->ss_passwd_list, &entry,
+ ss_passwd_entry_compare);
+
+ if (!l)
+ return;
+
+ ss_passwd_entry_destroy(l->data);
+ modem->ss_passwd_list = g_slist_remove(modem->ss_passwd_list,
+ l->data);
+}
+
+static gboolean recognized_passwd_change_string(struct ofono_modem *modem,
+ int type, char *sc,
+ char *sia, char *sib,
+ char *sic, char *sid,
+ char *dn, DBusMessage *msg)
+{
+ GSList *l = modem->ss_passwd_list;
+
+ switch (type) {
+ case SS_CONTROL_TYPE_ACTIVATION:
+ case SS_CONTROL_TYPE_REGISTRATION:
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (strcmp(sc, "03") || strlen(dn) || strcmp(sic, sid))
+ return FALSE;
+
+ while ((l = g_slist_find_custom(l, sia,
+ ss_passwd_entry_find_by_service)) != NULL) {
+ struct ss_passwd_entry *entry = l->data;
+
+ if (entry->cb(modem, sia, sib, sic, msg))
+ return TRUE;
+
+ l = l->next;
+ }
+
+ return FALSE;
+}
+
static gboolean recognized_control_string(struct ofono_modem *modem,
const char *ss_str,
DBusMessage *msg)
{
char *str = g_strdup(ss_str);
- char *sc, *sia, *sib, *sic, *dn;
+ char *sc, *sia, *sib, *sic, *sid, *dn;
int type;
gboolean ret = FALSE;
ofono_debug("parsing control string");
- if (parse_ss_control_string(str, &type, &sc, &sia, &sib, &sic, &dn)) {
+ if (parse_ss_control_string(str, &type, &sc,
+ &sia, &sib, &sic, &sid, &dn)) {
GSList *l = modem->ss_control_list;
- ofono_debug("Got parse result: %d, %s, %s, %s, %s, %s",
- type, sc, sia, sib, sic, dn);
+ ofono_debug("Got parse result: %d, %s, %s, %s, %s, %s, %s",
+ type, sc, sia, sib, sic, sid, dn);
while ((l = g_slist_find_custom(l, sc,
ss_control_entry_find_by_service)) != NULL) {
@@ -193,6 +319,13 @@ static gboolean recognized_control_string(struct ofono_modem *modem,
l = l->next;
}
+
+ /* A password change string needs to be treated separately
+ * because it uses a fourth SI and is thus not a valid
+ * control string. */
+ if (recognized_passwd_change_string(modem, type, sc,
+ sia, sib, sic, sid, dn, msg))
+ goto out;
}
/* TODO: Handle all strings that control voice calls */
@@ -205,9 +338,6 @@ static gboolean recognized_control_string(struct ofono_modem *modem,
* by SEND and are not valid USSD requests.
*/
- /* TODO: Handle Password registration according to 22.030 Section 6.5.4
- */
-
out:
g_free(str);
diff --git a/src/ussd.h b/src/ussd.h
index 5b956e5..5f40f61 100644
--- a/src/ussd.h
+++ b/src/ussd.h
@@ -26,8 +26,18 @@ typedef gboolean (*ss_control_cb_t)(struct ofono_modem *modem,
const char *sic, const char *dn,
DBusMessage *msg);
+typedef gboolean (*ss_passwd_cb_t)(struct ofono_modem *modem, const char *sc,
+ const char *old, const char *new,
+ DBusMessage *msg);
+
gboolean ss_control_register(struct ofono_modem *modem, const char *str,
ss_control_cb_t cb);
void ss_control_unregister(struct ofono_modem *modem, const char *str,
ss_control_cb_t cb);
+
+gboolean ss_passwd_register(struct ofono_modem *modem, const char *str,
+ ss_passwd_cb_t cb);
+
+void ss_passwd_unregister(struct ofono_modem *modem, const char *str,
+ ss_passwd_cb_t cb);
diff --git a/unit/test-common.c b/unit/test-common.c
index 5c753d3..96509bd 100644
--- a/unit/test-common.c
+++ b/unit/test-common.c
@@ -57,6 +57,7 @@ static void test_invalid()
char *sia;
char *sib;
char *sic;
+ char *sid;
char *dn;
int type;
@@ -71,7 +72,9 @@ static void test_invalid()
str = strdup(invalid_strings[i]);
ret = parse_ss_control_string(str, &type, &sc,
- &sia, &sib, &sic, &dn);
+ &sia, &sib, &sic, &sid, &dn);
+ if (strlen(sid))
+ ret = FALSE;
g_assert(ret == FALSE);
@@ -105,6 +108,7 @@ static void test_valid()
char *sia;
char *sib;
char *sic;
+ char *sid;
char *dn;
int type;
gboolean ret;
@@ -119,7 +123,9 @@ static void test_valid()
str = strdup(valid_strings[i]);
ret = parse_ss_control_string(str, &type, &sc,
- &sia, &sib, &sic, &dn);
+ &sia, &sib, &sic, &sid, &dn);
+ if (strlen(sid))
+ ret = FALSE;
g_assert(ret == TRUE);
--
1.6.0
13 years
[PATCH] Move struct ussd_data definition out of the header.
by Andrzej Zaborowski
No fuctional change.
---
src/ussd.c | 7 +++++++
src/ussd.h | 7 -------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/ussd.c b/src/ussd.c
index c9796e5..7225398 100644
--- a/src/ussd.c
+++ b/src/ussd.c
@@ -49,6 +49,13 @@ enum ussd_state {
USSD_STATE_USER_ACTION = 2
};
+struct ussd_data {
+ struct ofono_ussd_ops *ops;
+ int state;
+ DBusMessage *pending;
+ int flags;
+};
+
static struct ussd_data *ussd_create()
{
struct ussd_data *r;
diff --git a/src/ussd.h b/src/ussd.h
index bfd707f..5b956e5 100644
--- a/src/ussd.h
+++ b/src/ussd.h
@@ -19,13 +19,6 @@
*
*/
-struct ussd_data {
- struct ofono_ussd_ops *ops;
- int state;
- DBusMessage *pending;
- int flags;
-};
-
typedef gboolean (*ss_control_cb_t)(struct ofono_modem *modem,
enum ss_control_type type,
const char *sc,
--
1.6.0
13 years
[PATCH] Read own numbers from EFmsisdn instead of AT+CNUM.
by Andrzej Zaborowski
This was found to be more portable. On the other hand this doesn't give
the service type or speed information per number.
Depends on "[PATCH] Change sim_ops plugin interface to allow acces to linear fixed files."
---
drivers/atmodem/sim.c | 1 +
src/driver.h | 22 +++++++++++
src/sim.c | 99 +++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 107 insertions(+), 15 deletions(-)
diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 66e951e..165bb65 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -430,6 +430,7 @@ static void at_cnum_cb(gboolean ok, GAtResult *result, gpointer user_data)
numbers[count].speed = -1;
numbers[count].service = -1;
numbers[count].itc = -1;
+ numbers[count].npi = -1;
g_at_result_iter_skip_next(&iter);
g_at_result_iter_next_number(&iter, &numbers[count].service);
diff --git a/src/driver.h b/src/driver.h
index 36b9a08..793414e 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -96,6 +96,28 @@ struct ofono_own_number {
int speed;
int service;
int itc;
+ int npi;
+};
+
+/* 24.008 Section 10.5.4.7 */
+enum ofono_number_type {
+ OFONO_NUMBER_TYPE_UNKNOWN = 0,
+ OFONO_NUMBER_TYPE_INTERNATIONAL = 1,
+ OFONO_NUMBER_TYPE_NATIONAL = 2,
+ OFONO_NUMBER_TYPE_NETWORK_SPECIFIC = 3,
+ OFONO_NUMBER_TYPE_DEDICATED_ACCESS = 4,
+ OFONO_NUMBER_TYPE_RESERVED = 7
+};
+
+enum ofono_numbering_plan {
+ OFONO_NUMBERING_PLAN_UNKNOWN = 0,
+ OFONO_NUMBERING_PLAN_ISDN = 1,
+ OFONO_NUMBERING_PLAN_DATA = 3,
+ OFONO_NUMBERING_PLAN_TELEX = 4,
+ OFONO_NUMBERING_PLAN_NATIONAL = 8,
+ OFONO_NUMBERING_PLAN_PRIVATE = 9,
+ OFONO_NUMBERING_PLAN_RESERVED_CTS = 11,
+ OFONO_NUMBERING_PLAN_RESERVED = 15
};
/* 51.011 Section 9.3 */
diff --git a/src/sim.c b/src/sim.c
index 9c85292..e25b210 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -51,6 +51,10 @@ struct sim_manager_data {
int dcbyte;
GSList *update_spn_notify;
+
+ int own_numbers_num;
+ int own_numbers_size;
+ int own_numbers_current;
};
static char **own_numbers_by_type(GSList *own_numbers, int type)
@@ -181,6 +185,7 @@ static GDBusMethodTable sim_manager_methods[] = {
static GDBusSignalTable sim_manager_signals[] = { { } };
enum sim_fileids {
+ SIM_EFMSISDN_FILEID = 0x6f40,
SIM_EFSPN_FILEID = 0x6f46,
};
@@ -285,31 +290,94 @@ static gboolean sim_retrieve_imsi(void *user_data)
return FALSE;
}
-static void sim_own_number_cb(const struct ofono_error *error, int num,
- const struct ofono_own_number *own, void *data)
+static void sim_msisdn_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;
- int i;
+ struct ofono_own_number *ph;
+ int number_len;
+ int ton_npi;
+ int i, digit;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
- return;
+ goto skip;
- for (i = 0; i < num; i++) {
- struct ofono_own_number *ph;
+ if (length < sim->own_numbers_size)
+ goto skip;
- if (own[i].phone_number.number[0] == '\0')
- continue;
+ /* Skip Alpha-Identifier field */
+ sdata += sim->own_numbers_size - 14;
+
+ number_len = *sdata++;
+ ton_npi = *sdata++;
+
+ if (number_len > 11 || ton_npi == 0xff)
+ goto skip;
+
+ ph = g_new(struct ofono_own_number, 1);
+
+ ph->speed = -1;
+ ph->service = -1;
+ ph->itc = -1;
+ ph->npi = (ton_npi >> 0) & 15;
+ ph->phone_number.type = (ton_npi >> 4) & 7;
- ph = g_new(struct ofono_own_number, 1);
+ if (number_len > 10)
+ number_len = 10;
+ number_len *= 2;
+ if (number_len > OFONO_MAX_PHONE_NUMBER_LENGTH)
+ number_len = OFONO_MAX_PHONE_NUMBER_LENGTH;
- memcpy(ph, &own[i], sizeof(struct ofono_own_number));
+ for (i = 0; i < number_len; i ++) {
+ digit = *sdata;
+ /* BCD coded */
+ if (i & 1) {
+ sdata ++;
+ digit >>= 4;
+ }
+ digit &= 0xf;
- sim->own_numbers = g_slist_prepend(sim->own_numbers, ph);
+ if (digit > 9)
+ break;
+
+ ph->phone_number.number[i] = '0' + digit;
}
+ memset(&ph->phone_number.number[i], 0,
+ OFONO_MAX_PHONE_NUMBER_LENGTH - i);
+
+ sim->own_numbers = g_slist_prepend(sim->own_numbers, ph);
+
+skip:
+ sim->own_numbers_current ++;
+ if (sim->own_numbers_current < sim->own_numbers_num)
+ sim->ops->read_file_linear(modem, SIM_EFMSISDN_FILEID,
+ sim->own_numbers_current,
+ sim->own_numbers_size,
+ sim_msisdn_read_cb, modem);
+ else
+ /* All records retrieved */
+ if (sim->own_numbers)
+ sim->own_numbers = g_slist_reverse(sim->own_numbers);
+}
+
+static void sim_msisdn_info_cb(const struct ofono_error *error,
+ int length, enum ofono_simfile_struct 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 < 14 ||
+ record_length < 14 ||
+ structure != OFONO_SIM_FILE_FIXED)
+ return;
- if (sim->own_numbers)
- sim->own_numbers = g_slist_reverse(sim->own_numbers);
+ sim->own_numbers_current = 0;
+ sim->own_numbers_size = record_length;
+ sim->own_numbers_num = length / record_length;
+ sim->ops->read_file_linear(modem, SIM_EFMSISDN_FILEID, 0,
+ record_length, sim_msisdn_read_cb, modem);
}
static gboolean sim_retrieve_own_number(void *user_data)
@@ -317,7 +385,8 @@ static gboolean sim_retrieve_own_number(void *user_data)
struct ofono_modem *modem = user_data;
struct sim_manager_data *sim = modem->sim_manager;
- sim->ops->read_own_numbers(modem, sim_own_number_cb, modem);
+ sim->ops->read_file_info(modem, SIM_EFMSISDN_FILEID,
+ sim_msisdn_info_cb, modem);
return FALSE;
}
@@ -349,7 +418,7 @@ static void initialize_sim_manager(struct ofono_modem *modem)
if (modem->sim_manager->ops->read_imsi)
g_timeout_add(0, sim_retrieve_imsi, modem);
- if (modem->sim_manager->ops->read_own_numbers)
+ if (modem->sim_manager->ops->read_file_linear)
g_timeout_add(0, sim_retrieve_own_number, modem);
}
--
1.6.0
13 years
[PATCH] Fix NetworkRegistration test by fixing indentation.
by Andrzej Zaborowski
[Sorry if you get this mail or some of the other mails a second time,
I sent a copy from an unsubscribed address yesterday].
---
test/test-network-registration | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/test-network-registration b/test/test-network-registration
index 8d2176b..b21d06a 100755
--- a/test/test-network-registration
+++ b/test/test-network-registration
@@ -78,7 +78,7 @@ if __name__ == "__main__":
else:
obj = bus.get_object('org.ofono', sys.argv[1]);
op = dbus.Interface(obj, 'org.ofono.NetworkOperator')
- op.Register()
+ op.Register()
except dbus.DBusException, e:
print "Unable to register/deregister: ", e
sys.exit(1)
--
1.6.0
13 years
[PATCH] Implement CallBarring::ChangePassword in AT backend.
by Andrzej Zaborowski
Depends on "[PATCH] Add CallBarring::ChangePassword for setting a new service password."
---
drivers/atmodem/call-barring.c | 45 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/atmodem/call-barring.c b/drivers/atmodem/call-barring.c
index 5d2af58..f0ba18e 100644
--- a/drivers/atmodem/call-barring.c
+++ b/drivers/atmodem/call-barring.c
@@ -152,9 +152,50 @@ error:
}
}
+static void cpwd_set_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_generic_cb_t cb = cbd->cb;
+ struct ofono_error error;
+
+ dump_response("cpwd_set_cb", ok, result);
+ decode_at_error(&error, g_at_result_final_response(result));
+ cb(&error, cbd->data);
+}
+
+static void at_call_barring_set_passwd(struct ofono_modem *modem,
+ const char *lock,
+ const char *old_passwd, const char *new_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];
+
+ if (!cbd || strlen(lock) != 2)
+ goto error;
+
+ 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)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ {
+ DECLARE_FAILURE(error);
+ cb(&error, data);
+ }
+}
+
static struct ofono_call_barring_ops ops = {
- .set = at_call_barring_set,
- .query = at_call_barring_query,
+ .set = at_call_barring_set,
+ .query = at_call_barring_query,
+ .set_passwd = at_call_barring_set_passwd,
};
void at_call_barring_init(struct ofono_modem *modem)
--
1.6.0
13 years