mirror of git://git.sysmocom.de/ofono
Evolve SIM driver
This commit is contained in:
parent
3b043e9b1a
commit
5e72405120
|
@ -4,7 +4,7 @@ includedir = @includedir@/ofono
|
|||
include_HEADERS = log.h plugin.h history.h dbus.h modem.h \
|
||||
types.h call-barring.h call-forwarding.h \
|
||||
call-meter.h call-settings.h phonebook.h \
|
||||
ssn.h ussd.h sms.h
|
||||
ssn.h ussd.h sms.h sim.h
|
||||
|
||||
nodist_include_HEADERS = version.h
|
||||
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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 __OFONO_SIM_H
|
||||
#define __OFONO_SIM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <ofono/types.h>
|
||||
|
||||
struct ofono_sim;
|
||||
|
||||
/* 51.011 Section 9.3 */
|
||||
enum ofono_sim_file_structure {
|
||||
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT = 0,
|
||||
OFONO_SIM_FILE_STRUCTURE_FIXED = 1,
|
||||
OFONO_SIM_FILE_STRUCTURE_CYCLIC = 3
|
||||
};
|
||||
|
||||
typedef void (*ofono_sim_file_info_cb_t)(const struct ofono_error *error,
|
||||
int filelength,
|
||||
enum ofono_sim_file_structure structure,
|
||||
int recordlength,
|
||||
const unsigned char access[3],
|
||||
void *data);
|
||||
|
||||
typedef void (*ofono_sim_read_cb_t)(const struct ofono_error *error,
|
||||
const unsigned char *sdata, int length,
|
||||
void *data);
|
||||
|
||||
typedef void (*ofono_sim_write_cb_t)(const struct ofono_error *error,
|
||||
void *data);
|
||||
|
||||
typedef void (*ofono_sim_imsi_cb_t)(const struct ofono_error *error,
|
||||
const char *imsi, void *data);
|
||||
|
||||
typedef void (*ofono_sim_ready_notify_cb_t)(void *data);
|
||||
|
||||
typedef void (*ofono_sim_file_read_cb_t)(int ok,
|
||||
enum ofono_sim_file_structure structure,
|
||||
int total_length, int record,
|
||||
const unsigned char *data,
|
||||
int record_length, void *userdata);
|
||||
|
||||
typedef void (*ofono_sim_file_write_cb_t)(int ok, void *userdata);
|
||||
|
||||
struct ofono_sim_driver {
|
||||
const char *name;
|
||||
int (*probe)(struct ofono_sim *sim);
|
||||
int (*remove)(struct ofono_sim *sim);
|
||||
void (*read_file_info)(struct ofono_sim *sim, int fileid,
|
||||
ofono_sim_file_info_cb_t cb, void *data);
|
||||
void (*read_file_transparent)(struct ofono_sim *sim, int fileid,
|
||||
int start, int length,
|
||||
ofono_sim_read_cb_t cb, void *data);
|
||||
void (*read_file_linear)(struct ofono_sim *sim, int fileid,
|
||||
int record, int length,
|
||||
ofono_sim_read_cb_t cb, void *data);
|
||||
void (*read_file_cyclic)(struct ofono_sim *sim, int fileid,
|
||||
int record, int length,
|
||||
ofono_sim_read_cb_t cb, void *data);
|
||||
void (*write_file_transparent)(struct ofono_sim *sim, int fileid,
|
||||
int start, int length, const unsigned char *value,
|
||||
ofono_sim_write_cb_t cb, void *data);
|
||||
void (*write_file_linear)(struct ofono_sim *sim, int fileid,
|
||||
int record, int length, const unsigned char *value,
|
||||
ofono_sim_write_cb_t cb, void *data);
|
||||
void (*write_file_cyclic)(struct ofono_sim *sim, int fileid,
|
||||
int length, const unsigned char *value,
|
||||
ofono_sim_write_cb_t cb, void *data);
|
||||
void (*read_imsi)(struct ofono_sim *sim,
|
||||
ofono_sim_imsi_cb_t cb, void *data);
|
||||
};
|
||||
|
||||
int ofono_sim_driver_register(const struct ofono_sim_driver *d);
|
||||
void ofono_sim_driver_unregister(const struct ofono_sim_driver *d);
|
||||
|
||||
struct ofono_sim *ofono_sim_create(struct ofono_modem *modem,
|
||||
const char *driver, void *data);
|
||||
|
||||
void ofono_sim_register(struct ofono_sim *sim);
|
||||
void ofono_sim_remove(struct ofono_sim *sim);
|
||||
|
||||
void ofono_sim_set_data(struct ofono_sim *sim, void *data);
|
||||
void *ofono_sim_get_data(struct ofono_sim *sim);
|
||||
|
||||
const char *ofono_sim_get_imsi(struct ofono_sim *sim);
|
||||
|
||||
unsigned int ofono_sim_add_ready_watch(struct ofono_sim *sim,
|
||||
ofono_sim_ready_notify_cb_t cb,
|
||||
void *data, ofono_destroy_func destroy);
|
||||
|
||||
void ofono_sim_remove_ready_watch(struct ofono_sim *sim, unsigned int id);
|
||||
|
||||
int ofono_sim_get_ready(struct ofono_sim *sim);
|
||||
void ofono_sim_set_ready(struct ofono_sim *sim);
|
||||
|
||||
/* This will queue an operation to read all available records with id from the
|
||||
* SIM. Callback cb will be called every time a record has been read, or once
|
||||
* if an error has occurred. For transparent files, the callback will only
|
||||
* be called once.
|
||||
*
|
||||
* Returns 0 if the request could be queued, -1 otherwise.
|
||||
*/
|
||||
int ofono_sim_read(struct ofono_sim *sim, int id,
|
||||
ofono_sim_file_read_cb_t cb, void *data);
|
||||
|
||||
int ofono_sim_write(struct ofono_sim *sim, int id,
|
||||
ofono_sim_file_write_cb_t cb,
|
||||
enum ofono_sim_file_structure structure, int record,
|
||||
const unsigned char *data, int length, void *userdata);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __OFONO_SIM_H */
|
|
@ -12,7 +12,7 @@ ofonod_SOURCES = main.c ofono.h log.c plugin.c \
|
|||
manager.c dbus.c util.h util.c \
|
||||
network.c voicecall.c ussd.c sms.c \
|
||||
call-settings.c call-forwarding.c call-meter.c \
|
||||
smsutil.h smsutil.c ssn.c call-barring.c sim.h sim.c \
|
||||
smsutil.h smsutil.c ssn.c call-barring.c sim.c \
|
||||
phonebook.c history.c simutil.h simutil.c \
|
||||
message-waiting.c
|
||||
|
||||
|
|
50
src/driver.h
50
src/driver.h
|
@ -56,13 +56,6 @@ struct ofono_network_operator {
|
|||
int tech;
|
||||
};
|
||||
|
||||
/* 51.011 Section 9.3 */
|
||||
enum ofono_sim_file_structure {
|
||||
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT = 0,
|
||||
OFONO_SIM_FILE_STRUCTURE_FIXED = 1,
|
||||
OFONO_SIM_FILE_STRUCTURE_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
|
||||
|
@ -97,20 +90,6 @@ typedef void (*ofono_signal_strength_cb_t)(const struct ofono_error *error,
|
|||
typedef void (*ofono_modem_attribute_query_cb_t)(const struct ofono_error *error,
|
||||
const char *attribute, void *data);
|
||||
|
||||
typedef void (*ofono_sim_file_info_cb_t)(const struct ofono_error *error,
|
||||
int filelength,
|
||||
enum ofono_sim_file_structure structure,
|
||||
int recordlength,
|
||||
const unsigned char access[3],
|
||||
void *data);
|
||||
|
||||
typedef void (*ofono_sim_read_cb_t)(const struct ofono_error *error,
|
||||
const unsigned char *sdata, int length,
|
||||
void *data);
|
||||
|
||||
typedef void (*ofono_imsi_cb_t)(const struct ofono_error *error,
|
||||
const char *imsi, void *data);
|
||||
|
||||
struct ofono_modem_attribute_ops {
|
||||
void (*query_manufacturer)(struct ofono_modem *modem,
|
||||
ofono_modem_attribute_query_cb_t cb, void *data);
|
||||
|
@ -206,32 +185,3 @@ void ofono_voicecall_disconnected(struct ofono_modem *modem, int id,
|
|||
int ofono_voicecall_register(struct ofono_modem *modem, struct ofono_voicecall_ops *ops);
|
||||
void ofono_voicecall_unregister(struct ofono_modem *modem);
|
||||
|
||||
struct ofono_sim_ops {
|
||||
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 (*read_file_cyclic)(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 (*write_file_cyclic)(struct ofono_modem *modem, int fileid,
|
||||
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);
|
||||
};
|
||||
|
||||
int ofono_sim_manager_register(struct ofono_modem *modem,
|
||||
struct ofono_sim_ops *ops);
|
||||
void ofono_sim_manager_unregister(struct ofono_modem *modem);
|
||||
|
||||
|
|
|
@ -72,7 +72,6 @@ struct ofono_modem {
|
|||
struct ofono_modem_data *modem_info;
|
||||
struct network_registration_data *network_registration;
|
||||
struct voicecalls_data *voicecalls;
|
||||
struct sim_manager_data *sim_manager;
|
||||
struct message_waiting_data *message_waiting;
|
||||
|
||||
GSList *history_contexts;
|
||||
|
@ -143,6 +142,8 @@ void __ofono_atom_free(struct ofono_atom *atom);
|
|||
#include <ofono/phonebook.h>
|
||||
#include <ofono/sms.h>
|
||||
|
||||
#include <ofono/sim.h>
|
||||
|
||||
#include <ofono/ssn.h>
|
||||
|
||||
typedef void (*ofono_ssn_mo_notify_cb)(int index, void *user);
|
||||
|
|
578
src/sim.c
578
src/sim.c
|
@ -37,11 +37,9 @@
|
|||
|
||||
#include "ofono.h"
|
||||
|
||||
#include "driver.h"
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "smsutil.h"
|
||||
#include "sim.h"
|
||||
#include "simutil.h"
|
||||
|
||||
#ifdef TEMP_FAILURE_RETRY
|
||||
|
@ -57,9 +55,11 @@
|
|||
#define SIM_CACHE_PATH_LEN(imsilen) (strlen(SIM_CACHE_PATH) - 2 + imsilen)
|
||||
#define SIM_CACHE_HEADER_SIZE 6
|
||||
|
||||
static GSList *g_drivers = NULL;
|
||||
|
||||
static gboolean sim_op_next(gpointer user_data);
|
||||
static gboolean sim_op_retrieve_next(gpointer user);
|
||||
static void sim_own_numbers_update(struct ofono_modem *modem);
|
||||
static void sim_own_numbers_update(struct ofono_sim *sim);
|
||||
|
||||
struct sim_file_op {
|
||||
int id;
|
||||
|
@ -74,27 +74,36 @@ struct sim_file_op {
|
|||
void *userdata;
|
||||
};
|
||||
|
||||
struct sim_manager_data {
|
||||
struct ofono_sim_ops *ops;
|
||||
struct ofono_sim {
|
||||
char *imsi;
|
||||
GSList *own_numbers;
|
||||
GSList *new_numbers;
|
||||
GSList *ready_notify;
|
||||
gboolean ready;
|
||||
GQueue *simop_q;
|
||||
gint simop_source;
|
||||
|
||||
unsigned char efmsisdn_length;
|
||||
unsigned char efmsisdn_records;
|
||||
unsigned int next_ready_watch_id;
|
||||
GSList *ready_watches;
|
||||
const struct ofono_sim_driver *driver;
|
||||
void *driver_data;
|
||||
struct ofono_atom *atom;
|
||||
};
|
||||
|
||||
struct msisdn_set_request {
|
||||
struct ofono_modem *modem;
|
||||
struct ofono_sim *sim;
|
||||
int pending;
|
||||
int failed;
|
||||
DBusMessage *msg;
|
||||
};
|
||||
|
||||
struct sim_ready_watch {
|
||||
unsigned int id;
|
||||
ofono_sim_ready_notify_cb_t notify;
|
||||
void *data;
|
||||
ofono_destroy_func destroy;
|
||||
};
|
||||
|
||||
static char **get_own_numbers(GSList *own_numbers)
|
||||
{
|
||||
int nelem = 0;
|
||||
|
@ -122,44 +131,10 @@ static void sim_file_op_free(struct sim_file_op *node)
|
|||
g_free(node);
|
||||
}
|
||||
|
||||
static struct sim_manager_data *sim_manager_create()
|
||||
{
|
||||
return g_try_new0(struct sim_manager_data, 1);
|
||||
}
|
||||
|
||||
static void sim_manager_destroy(gpointer userdata)
|
||||
{
|
||||
struct ofono_modem *modem = userdata;
|
||||
struct sim_manager_data *data = modem->sim_manager;
|
||||
|
||||
if (data->imsi) {
|
||||
g_free(data->imsi);
|
||||
data->imsi = NULL;
|
||||
}
|
||||
|
||||
if (data->own_numbers) {
|
||||
g_slist_foreach(data->own_numbers, (GFunc)g_free, NULL);
|
||||
g_slist_free(data->own_numbers);
|
||||
data->own_numbers = NULL;
|
||||
}
|
||||
|
||||
if (data->simop_source) {
|
||||
g_source_remove(data->simop_source);
|
||||
data->simop_source = 0;
|
||||
}
|
||||
|
||||
if (data->simop_q) {
|
||||
g_queue_foreach(data->simop_q, (GFunc)sim_file_op_free, NULL);
|
||||
g_queue_free(data->simop_q);
|
||||
data->simop_q = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static DBusMessage *sim_get_properties(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
struct ofono_modem *modem = data;
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct ofono_sim *sim = data;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter dict;
|
||||
|
@ -202,12 +177,12 @@ static void msisdn_set_done(struct msisdn_set_request *req)
|
|||
__ofono_dbus_pending_reply(&req->msg, reply);
|
||||
|
||||
/* Re-read the numbers and emit signal if needed */
|
||||
sim_own_numbers_update(req->modem);
|
||||
sim_own_numbers_update(req->sim);
|
||||
|
||||
g_free(req);
|
||||
}
|
||||
|
||||
static void msisdn_set_cb(struct ofono_modem *modem, int ok, void *data)
|
||||
static void msisdn_set_cb(int ok, void *data)
|
||||
{
|
||||
struct msisdn_set_request *req = data;
|
||||
|
||||
|
@ -220,10 +195,9 @@ static void msisdn_set_cb(struct ofono_modem *modem, int ok, void *data)
|
|||
msisdn_set_done(req);
|
||||
}
|
||||
|
||||
static gboolean set_own_numbers(struct ofono_modem *modem,
|
||||
static gboolean set_own_numbers(struct ofono_sim *sim,
|
||||
GSList *new_numbers, DBusMessage *msg)
|
||||
{
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct msisdn_set_request *req;
|
||||
int record;
|
||||
unsigned char efmsisdn[255];
|
||||
|
@ -234,7 +208,7 @@ static gboolean set_own_numbers(struct ofono_modem *modem,
|
|||
|
||||
req = g_new0(struct msisdn_set_request, 1);
|
||||
|
||||
req->modem = modem;
|
||||
req->sim = sim;
|
||||
req->msg = dbus_message_ref(msg);
|
||||
|
||||
for (record = 1; record <= sim->efmsisdn_records; record++) {
|
||||
|
@ -245,7 +219,7 @@ static gboolean set_own_numbers(struct ofono_modem *modem,
|
|||
} else
|
||||
memset(efmsisdn, 0xff, sim->efmsisdn_length);
|
||||
|
||||
if (ofono_sim_write(req->modem, SIM_EFMSISDN_FILEID,
|
||||
if (ofono_sim_write(req->sim, SIM_EFMSISDN_FILEID,
|
||||
msisdn_set_cb, OFONO_SIM_FILE_STRUCTURE_FIXED,
|
||||
record, efmsisdn,
|
||||
sim->efmsisdn_length, req) == 0)
|
||||
|
@ -263,8 +237,7 @@ static gboolean set_own_numbers(struct ofono_modem *modem,
|
|||
static DBusMessage *sim_set_property(DBusConnection *conn, DBusMessage *msg,
|
||||
void *data)
|
||||
{
|
||||
struct ofono_modem *modem = data;
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct ofono_sim *sim = data;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter var;
|
||||
DBusMessageIter var_elem;
|
||||
|
@ -321,7 +294,7 @@ static DBusMessage *sim_set_property(DBusConnection *conn, DBusMessage *msg,
|
|||
}
|
||||
|
||||
own_numbers = g_slist_reverse(own_numbers);
|
||||
set_ok = set_own_numbers(modem, own_numbers, msg);
|
||||
set_ok = set_own_numbers(sim, own_numbers, msg);
|
||||
|
||||
error:
|
||||
g_slist_foreach(own_numbers, (GFunc) g_free, 0);
|
||||
|
@ -334,14 +307,14 @@ error:
|
|||
return __ofono_error_invalid_args(msg);
|
||||
}
|
||||
|
||||
static GDBusMethodTable sim_manager_methods[] = {
|
||||
static GDBusMethodTable sim_methods[] = {
|
||||
{ "GetProperties", "", "a{sv}", sim_get_properties },
|
||||
{ "SetProperty", "sv", "", sim_set_property,
|
||||
G_DBUS_METHOD_FLAG_ASYNC },
|
||||
{ }
|
||||
};
|
||||
|
||||
static GDBusSignalTable sim_manager_signals[] = {
|
||||
static GDBusSignalTable sim_signals[] = {
|
||||
{ "PropertyChanged", "sv" },
|
||||
{ }
|
||||
};
|
||||
|
@ -368,13 +341,13 @@ static gboolean numbers_list_equal(GSList *a, GSList *b)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void sim_msisdn_read_cb(struct ofono_modem *modem, int ok,
|
||||
static void sim_msisdn_read_cb(int ok,
|
||||
enum ofono_sim_file_structure structure,
|
||||
int length, int record,
|
||||
const unsigned char *data,
|
||||
int record_length, void *userdata)
|
||||
{
|
||||
struct sim_manager_data *sim = userdata;
|
||||
struct ofono_sim *sim = userdata;
|
||||
int total;
|
||||
struct ofono_phone_number ph;
|
||||
|
||||
|
@ -409,6 +382,7 @@ check:
|
|||
sim->new_numbers = g_slist_reverse(sim->new_numbers);
|
||||
|
||||
if (!numbers_list_equal(sim->new_numbers, sim->own_numbers)) {
|
||||
const char *path = __ofono_atom_get_path(sim->atom);
|
||||
char **own_numbers;
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
|
@ -418,7 +392,7 @@ check:
|
|||
|
||||
own_numbers = get_own_numbers(sim->own_numbers);
|
||||
|
||||
ofono_dbus_signal_array_property_changed(conn, modem->path,
|
||||
ofono_dbus_signal_array_property_changed(conn, path,
|
||||
SIM_MANAGER_INTERFACE,
|
||||
"SubscriberNumbers",
|
||||
DBUS_TYPE_STRING,
|
||||
|
@ -432,22 +406,23 @@ check:
|
|||
sim->new_numbers = NULL;
|
||||
}
|
||||
|
||||
static void sim_own_numbers_update(struct ofono_modem *modem)
|
||||
static void sim_own_numbers_update(struct ofono_sim *sim)
|
||||
{
|
||||
ofono_sim_read(modem, SIM_EFMSISDN_FILEID,
|
||||
sim_msisdn_read_cb, modem->sim_manager);
|
||||
ofono_sim_read(sim, SIM_EFMSISDN_FILEID,
|
||||
sim_msisdn_read_cb, sim);
|
||||
}
|
||||
|
||||
static void sim_ready(struct ofono_modem *modem)
|
||||
static void sim_ready(void *user)
|
||||
{
|
||||
sim_own_numbers_update(modem);
|
||||
struct ofono_sim *sim = user;
|
||||
|
||||
sim_own_numbers_update(sim);
|
||||
}
|
||||
|
||||
static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
|
||||
void *data)
|
||||
{
|
||||
struct ofono_modem *modem = data;
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct ofono_sim *sim = data;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
ofono_error("Unable to read IMSI, emergency calls only");
|
||||
|
@ -456,20 +431,18 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
|
|||
|
||||
sim->imsi = g_strdup(imsi);
|
||||
|
||||
ofono_sim_set_ready(modem);
|
||||
ofono_sim_set_ready(sim);
|
||||
}
|
||||
|
||||
static void sim_retrieve_imsi(struct ofono_modem *modem)
|
||||
static void sim_retrieve_imsi(struct ofono_sim *sim)
|
||||
{
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
|
||||
if (!sim->ops->read_imsi) {
|
||||
if (!sim->driver->read_imsi) {
|
||||
ofono_error("IMSI retrieval not implemented,"
|
||||
" only emergency calls will be available");
|
||||
return;
|
||||
}
|
||||
|
||||
sim->ops->read_imsi(modem, sim_imsi_cb, modem);
|
||||
sim->driver->read_imsi(sim, sim_imsi_cb, sim);
|
||||
}
|
||||
|
||||
static int create_dirs(const char *filename, const mode_t mode)
|
||||
|
@ -500,20 +473,19 @@ static int create_dirs(const char *filename, const mode_t mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void sim_op_error(struct ofono_modem *modem)
|
||||
static void sim_op_error(struct ofono_sim *sim)
|
||||
{
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct sim_file_op *op = g_queue_pop_head(sim->simop_q);
|
||||
|
||||
if (g_queue_get_length(sim->simop_q) > 0)
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, modem);
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, sim);
|
||||
|
||||
if (op->is_read == TRUE)
|
||||
((ofono_sim_file_read_cb_t) op->cb)
|
||||
(modem, 0, 0, 0, 0, 0, 0, op->userdata);
|
||||
(0, 0, 0, 0, 0, 0, op->userdata);
|
||||
else
|
||||
((ofono_sim_file_write_cb_t) op->cb)
|
||||
(modem, 0, op->userdata);
|
||||
(0, op->userdata);
|
||||
|
||||
sim_file_op_free(op);
|
||||
}
|
||||
|
@ -546,19 +518,18 @@ static gboolean cache_record(const char *path, int current, int record_len,
|
|||
static void sim_op_retrieve_cb(const struct ofono_error *error,
|
||||
const unsigned char *data, int len, void *user)
|
||||
{
|
||||
struct ofono_modem *modem = user;
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct ofono_sim *sim = user;
|
||||
struct sim_file_op *op = g_queue_peek_head(sim->simop_q);
|
||||
int total = op->length / op->record_length;
|
||||
ofono_sim_file_read_cb_t cb = op->cb;
|
||||
char *imsi = sim->imsi;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
sim_op_error(modem);
|
||||
sim_op_error(sim);
|
||||
return;
|
||||
}
|
||||
|
||||
cb(modem, 1, op->structure, op->length, op->current,
|
||||
cb(1, op->structure, op->length, op->current,
|
||||
data, op->record_length, op->userdata);
|
||||
|
||||
if (op->cache && imsi) {
|
||||
|
@ -575,52 +546,49 @@ static void sim_op_retrieve_cb(const struct ofono_error *error,
|
|||
sim_file_op_free(op);
|
||||
|
||||
if (g_queue_get_length(sim->simop_q) > 0)
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next,
|
||||
modem);
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, sim);
|
||||
} else {
|
||||
op->current += 1;
|
||||
sim->simop_source = g_timeout_add(0, sim_op_retrieve_next,
|
||||
modem);
|
||||
sim->simop_source = g_timeout_add(0, sim_op_retrieve_next, sim);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean sim_op_retrieve_next(gpointer user)
|
||||
{
|
||||
struct ofono_modem *modem = user;
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct ofono_sim *sim = user;
|
||||
struct sim_file_op *op = g_queue_peek_head(sim->simop_q);
|
||||
|
||||
sim->simop_source = 0;
|
||||
|
||||
switch (op->structure) {
|
||||
case OFONO_SIM_FILE_STRUCTURE_TRANSPARENT:
|
||||
if (!sim->ops->read_file_transparent) {
|
||||
sim_op_error(modem);
|
||||
if (!sim->driver->read_file_transparent) {
|
||||
sim_op_error(sim);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sim->ops->read_file_transparent(modem, op->id, 0, op->length,
|
||||
sim_op_retrieve_cb, modem);
|
||||
sim->driver->read_file_transparent(sim, op->id, 0, op->length,
|
||||
sim_op_retrieve_cb, sim);
|
||||
break;
|
||||
case OFONO_SIM_FILE_STRUCTURE_FIXED:
|
||||
if (!sim->ops->read_file_linear) {
|
||||
sim_op_error(modem);
|
||||
if (!sim->driver->read_file_linear) {
|
||||
sim_op_error(sim);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sim->ops->read_file_linear(modem, op->id, op->current,
|
||||
sim->driver->read_file_linear(sim, op->id, op->current,
|
||||
op->record_length,
|
||||
sim_op_retrieve_cb, modem);
|
||||
sim_op_retrieve_cb, sim);
|
||||
break;
|
||||
case OFONO_SIM_FILE_STRUCTURE_CYCLIC:
|
||||
if (!sim->ops->read_file_cyclic) {
|
||||
sim_op_error(modem);
|
||||
if (!sim->driver->read_file_cyclic) {
|
||||
sim_op_error(sim);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sim->ops->read_file_cyclic(modem, op->id, op->current,
|
||||
sim->driver->read_file_cyclic(sim, op->id, op->current,
|
||||
op->record_length,
|
||||
sim_op_retrieve_cb, modem);
|
||||
sim_op_retrieve_cb, sim);
|
||||
break;
|
||||
default:
|
||||
ofono_error("Unrecognized file structure, this can't happen");
|
||||
|
@ -661,8 +629,7 @@ static void sim_op_info_cb(const struct ofono_error *error, int length,
|
|||
int record_length,
|
||||
const unsigned char access[3], void *data)
|
||||
{
|
||||
struct ofono_modem *modem = data;
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct ofono_sim *sim = data;
|
||||
struct sim_file_op *op = g_queue_peek_head(sim->simop_q);
|
||||
char *imsi = sim->imsi;
|
||||
enum sim_file_access update;
|
||||
|
@ -670,7 +637,7 @@ static void sim_op_info_cb(const struct ofono_error *error, int length,
|
|||
enum sim_file_access rehabilitate;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
sim_op_error(modem);
|
||||
sim_op_error(sim);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -696,7 +663,7 @@ static void sim_op_info_cb(const struct ofono_error *error, int length,
|
|||
|
||||
op->current = 1;
|
||||
|
||||
sim->simop_source = g_timeout_add(0, sim_op_retrieve_next, modem);
|
||||
sim->simop_source = g_timeout_add(0, sim_op_retrieve_next, sim);
|
||||
|
||||
if (op->cache && imsi) {
|
||||
char *path = g_strdup_printf(SIM_CACHE_PATH, imsi, op->id);
|
||||
|
@ -717,25 +684,23 @@ static void sim_op_info_cb(const struct ofono_error *error, int length,
|
|||
|
||||
static void sim_op_write_cb(const struct ofono_error *error, void *data)
|
||||
{
|
||||
struct ofono_modem *modem = data;
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct ofono_sim *sim = data;
|
||||
struct sim_file_op *op = g_queue_pop_head(sim->simop_q);
|
||||
ofono_sim_file_write_cb_t cb = op->cb;
|
||||
|
||||
if (g_queue_get_length(sim->simop_q) > 0)
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, modem);
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, sim);
|
||||
|
||||
if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
|
||||
cb(modem, 1, op->userdata);
|
||||
cb(1, op->userdata);
|
||||
else
|
||||
cb(modem, 0, op->userdata);
|
||||
cb(0, op->userdata);
|
||||
|
||||
sim_file_op_free(op);
|
||||
}
|
||||
|
||||
static gboolean sim_op_check_cached(struct ofono_modem *modem)
|
||||
static gboolean sim_op_check_cached(struct ofono_sim *sim)
|
||||
{
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
char *imsi = sim->imsi;
|
||||
struct sim_file_op *op = g_queue_peek_head(sim->simop_q);
|
||||
ofono_sim_file_read_cb_t cb = op->cb;
|
||||
|
@ -786,7 +751,7 @@ static gboolean sim_op_check_cached(struct ofono_modem *modem)
|
|||
|
||||
if (error_type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
ret = TRUE;
|
||||
cb(modem, 0, 0, 0, 0, 0, 0, 0);
|
||||
cb(0, 0, 0, 0, 0, 0, 0);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -798,7 +763,7 @@ static gboolean sim_op_check_cached(struct ofono_modem *modem)
|
|||
goto cleanup;
|
||||
|
||||
for (record = 0; record < file_length / record_length; record++) {
|
||||
cb(modem, 1, structure, file_length, record + 1,
|
||||
cb(1, structure, file_length, record + 1,
|
||||
&buffer[record * record_length], record_length,
|
||||
op->userdata);
|
||||
}
|
||||
|
@ -816,8 +781,7 @@ cleanup:
|
|||
|
||||
static gboolean sim_op_next(gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct ofono_sim *sim = user_data;
|
||||
struct sim_file_op *op;
|
||||
|
||||
sim->simop_source = 0;
|
||||
|
@ -828,35 +792,35 @@ static gboolean sim_op_next(gpointer user_data)
|
|||
op = g_queue_peek_head(sim->simop_q);
|
||||
|
||||
if (op->is_read == TRUE) {
|
||||
if (sim_op_check_cached(modem)) {
|
||||
if (sim_op_check_cached(sim)) {
|
||||
op = g_queue_pop_head(sim->simop_q);
|
||||
|
||||
sim_file_op_free(op);
|
||||
|
||||
if (g_queue_get_length(sim->simop_q) > 0)
|
||||
sim->simop_source =
|
||||
g_timeout_add(0, sim_op_next, modem);
|
||||
g_timeout_add(0, sim_op_next, sim);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sim->ops->read_file_info(modem, op->id, sim_op_info_cb, modem);
|
||||
sim->driver->read_file_info(sim, op->id, sim_op_info_cb, sim);
|
||||
} else {
|
||||
switch (op->structure) {
|
||||
case OFONO_SIM_FILE_STRUCTURE_TRANSPARENT:
|
||||
sim->ops->write_file_transparent(modem, op->id, 0,
|
||||
sim->driver->write_file_transparent(sim, op->id, 0,
|
||||
op->length, op->buffer,
|
||||
sim_op_write_cb, modem);
|
||||
sim_op_write_cb, sim);
|
||||
break;
|
||||
case OFONO_SIM_FILE_STRUCTURE_FIXED:
|
||||
sim->ops->write_file_linear(modem, op->id, op->current,
|
||||
sim->driver->write_file_linear(sim, op->id, op->current,
|
||||
op->length, op->buffer,
|
||||
sim_op_write_cb, modem);
|
||||
sim_op_write_cb, sim);
|
||||
break;
|
||||
case OFONO_SIM_FILE_STRUCTURE_CYCLIC:
|
||||
sim->ops->write_file_cyclic(modem, op->id,
|
||||
sim->driver->write_file_cyclic(sim, op->id,
|
||||
op->length, op->buffer,
|
||||
sim_op_write_cb, modem);
|
||||
sim_op_write_cb, sim);
|
||||
break;
|
||||
default:
|
||||
ofono_error("Unrecognized file structure, "
|
||||
|
@ -869,22 +833,21 @@ static gboolean sim_op_next(gpointer user_data)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
int ofono_sim_read(struct ofono_modem *modem, int id,
|
||||
int ofono_sim_read(struct ofono_sim *sim, int id,
|
||||
ofono_sim_file_read_cb_t cb, void *data)
|
||||
{
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct sim_file_op *op;
|
||||
|
||||
if (!cb)
|
||||
return -1;
|
||||
|
||||
if (modem->sim_manager == NULL)
|
||||
if (sim == NULL)
|
||||
return -1;
|
||||
|
||||
if (!sim->ops)
|
||||
if (!sim->driver)
|
||||
return -1;
|
||||
|
||||
if (!sim->ops->read_file_info)
|
||||
if (!sim->driver->read_file_info)
|
||||
return -1;
|
||||
|
||||
/* TODO: We must first check the EFust table to see whether
|
||||
|
@ -904,17 +867,16 @@ int ofono_sim_read(struct ofono_modem *modem, int id,
|
|||
g_queue_push_tail(sim->simop_q, op);
|
||||
|
||||
if (g_queue_get_length(sim->simop_q) == 1)
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, modem);
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, sim);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ofono_sim_write(struct ofono_modem *modem, int id,
|
||||
int ofono_sim_write(struct ofono_sim *sim, int id,
|
||||
ofono_sim_file_write_cb_t cb,
|
||||
enum ofono_sim_file_structure structure, int record,
|
||||
const unsigned char *data, int length, void *userdata)
|
||||
{
|
||||
struct sim_manager_data *sim = modem->sim_manager;
|
||||
struct sim_file_op *op;
|
||||
gconstpointer fn = NULL;
|
||||
|
||||
|
@ -924,18 +886,18 @@ int ofono_sim_write(struct ofono_modem *modem, int id,
|
|||
if (sim == NULL)
|
||||
return -1;
|
||||
|
||||
if (!sim->ops)
|
||||
if (!sim->driver)
|
||||
return -1;
|
||||
|
||||
switch (structure) {
|
||||
case OFONO_SIM_FILE_STRUCTURE_TRANSPARENT:
|
||||
fn = sim->ops->write_file_transparent;
|
||||
fn = sim->driver->write_file_transparent;
|
||||
break;
|
||||
case OFONO_SIM_FILE_STRUCTURE_FIXED:
|
||||
fn = sim->ops->write_file_linear;
|
||||
fn = sim->driver->write_file_linear;
|
||||
break;
|
||||
case OFONO_SIM_FILE_STRUCTURE_CYCLIC:
|
||||
fn = sim->ops->write_file_cyclic;
|
||||
fn = sim->driver->write_file_cyclic;
|
||||
break;
|
||||
default:
|
||||
ofono_error("Unrecognized file structure, this can't happen");
|
||||
|
@ -961,33 +923,256 @@ int ofono_sim_write(struct ofono_modem *modem, int id,
|
|||
g_queue_push_tail(sim->simop_q, op);
|
||||
|
||||
if (g_queue_get_length(sim->simop_q) == 1)
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, modem);
|
||||
sim->simop_source = g_timeout_add(0, sim_op_next, sim);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void initialize_sim_manager(struct ofono_modem *modem)
|
||||
const char *ofono_sim_get_imsi(struct ofono_sim *sim)
|
||||
{
|
||||
if (sim == NULL)
|
||||
return NULL;
|
||||
|
||||
return sim->imsi;
|
||||
}
|
||||
|
||||
static void remove_all_watches(struct ofono_sim *sim)
|
||||
{
|
||||
struct sim_ready_watch *watch;
|
||||
GSList *c;
|
||||
|
||||
for (c = sim->ready_watches; c; c = c->next) {
|
||||
watch = c->data;
|
||||
|
||||
if (watch->destroy)
|
||||
watch->destroy(watch->data);
|
||||
|
||||
g_free(watch);
|
||||
}
|
||||
|
||||
g_slist_free(sim->ready_watches);
|
||||
sim->ready_watches = NULL;
|
||||
}
|
||||
|
||||
unsigned int ofono_sim_add_ready_watch(struct ofono_sim *sim,
|
||||
ofono_sim_ready_notify_cb_t notify,
|
||||
void *data, ofono_destroy_func destroy)
|
||||
{
|
||||
struct sim_ready_watch *watch;
|
||||
|
||||
DBG("%p", sim);
|
||||
|
||||
if (sim == NULL)
|
||||
return 0;
|
||||
|
||||
if (notify == NULL)
|
||||
return 0;
|
||||
|
||||
watch = g_new0(struct sim_ready_watch, 1);
|
||||
|
||||
watch->id = ++sim->next_ready_watch_id;
|
||||
watch->notify = notify;
|
||||
watch->destroy = destroy;
|
||||
watch->data = data;
|
||||
|
||||
sim->ready_watches = g_slist_prepend(sim->ready_watches, watch);
|
||||
|
||||
DBG("id: %u", watch->id);
|
||||
|
||||
return watch->id;
|
||||
}
|
||||
|
||||
void ofono_sim_remove_ready_watch(struct ofono_sim *sim, unsigned int id)
|
||||
{
|
||||
struct sim_ready_watch *watch;
|
||||
GSList *p;
|
||||
GSList *c;
|
||||
|
||||
if (sim == NULL)
|
||||
return;
|
||||
|
||||
DBG("%p, %u", sim, id);
|
||||
|
||||
p = NULL;
|
||||
c = sim->ready_watches;
|
||||
|
||||
while (c) {
|
||||
watch = c->data;
|
||||
|
||||
if (watch->id != id) {
|
||||
p = c;
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p)
|
||||
p->next = c->next;
|
||||
else
|
||||
sim->ready_watches = c->next;
|
||||
|
||||
if (watch->destroy)
|
||||
watch->destroy(watch->data);
|
||||
|
||||
g_free(watch);
|
||||
g_slist_free_1(c);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int ofono_sim_get_ready(struct ofono_sim *sim)
|
||||
{
|
||||
if (sim == NULL)
|
||||
return 0;
|
||||
|
||||
if (sim->ready == TRUE)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ofono_sim_set_ready(struct ofono_sim *sim)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (sim == NULL)
|
||||
return;
|
||||
|
||||
if (sim->ready == TRUE)
|
||||
return;
|
||||
|
||||
sim->ready = TRUE;
|
||||
|
||||
for (l = sim->ready_watches; l; l = l->next) {
|
||||
struct sim_ready_watch *watch = l->data;
|
||||
|
||||
watch->notify(watch->data);
|
||||
}
|
||||
}
|
||||
|
||||
int ofono_sim_driver_register(const struct ofono_sim_driver *d)
|
||||
{
|
||||
DBG("driver: %p, name: %s", d, d->name);
|
||||
|
||||
if (d->probe == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
g_drivers = g_slist_prepend(g_drivers, (void *)d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ofono_sim_driver_unregister(const struct ofono_sim_driver *d)
|
||||
{
|
||||
DBG("driver: %p, name: %s", d, d->name);
|
||||
|
||||
g_drivers = g_slist_remove(g_drivers, (void *)d);
|
||||
}
|
||||
|
||||
static void sim_unregister(struct ofono_atom *atom)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
struct ofono_modem *modem = __ofono_atom_get_modem(atom);
|
||||
const char *path = __ofono_atom_get_path(atom);
|
||||
|
||||
if (!g_dbus_register_interface(conn, modem->path,
|
||||
g_dbus_unregister_interface(conn, path,
|
||||
SIM_MANAGER_INTERFACE);
|
||||
ofono_modem_remove_interface(modem, SIM_MANAGER_INTERFACE);
|
||||
}
|
||||
|
||||
static void sim_remove(struct ofono_atom *atom)
|
||||
{
|
||||
struct ofono_sim *sim = __ofono_atom_get_data(atom);
|
||||
|
||||
DBG("atom: %p", atom);
|
||||
|
||||
if (sim == NULL)
|
||||
return;
|
||||
|
||||
if (sim->driver && sim->driver->remove)
|
||||
sim->driver->remove(sim);
|
||||
|
||||
if (sim->imsi) {
|
||||
g_free(sim->imsi);
|
||||
sim->imsi = NULL;
|
||||
}
|
||||
|
||||
if (sim->own_numbers) {
|
||||
g_slist_foreach(sim->own_numbers, (GFunc)g_free, NULL);
|
||||
g_slist_free(sim->own_numbers);
|
||||
sim->own_numbers = NULL;
|
||||
}
|
||||
|
||||
if (sim->simop_source) {
|
||||
g_source_remove(sim->simop_source);
|
||||
sim->simop_source = 0;
|
||||
}
|
||||
|
||||
if (sim->simop_q) {
|
||||
g_queue_foreach(sim->simop_q, (GFunc)sim_file_op_free, NULL);
|
||||
g_queue_free(sim->simop_q);
|
||||
sim->simop_q = NULL;
|
||||
}
|
||||
|
||||
g_free(sim);
|
||||
}
|
||||
|
||||
struct ofono_sim *ofono_sim_create(struct ofono_modem *modem,
|
||||
const char *driver,
|
||||
void *data)
|
||||
{
|
||||
struct ofono_sim *sim;
|
||||
GSList *l;
|
||||
|
||||
if (driver == NULL)
|
||||
return NULL;
|
||||
|
||||
sim = g_try_new0(struct ofono_sim, 1);
|
||||
|
||||
if (sim == NULL)
|
||||
return NULL;
|
||||
|
||||
sim->driver_data = data;
|
||||
sim->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_SIM,
|
||||
sim_remove, sim);
|
||||
|
||||
for (l = g_drivers; l; l = l->next) {
|
||||
const struct ofono_sim_driver *drv = l->data;
|
||||
|
||||
if (g_strcmp0(drv->name, driver))
|
||||
continue;
|
||||
|
||||
if (drv->probe(sim) < 0)
|
||||
continue;
|
||||
|
||||
sim->driver = drv;
|
||||
break;
|
||||
}
|
||||
|
||||
return sim;
|
||||
}
|
||||
|
||||
void ofono_sim_register(struct ofono_sim *sim)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
struct ofono_modem *modem = __ofono_atom_get_modem(sim->atom);
|
||||
const char *path = __ofono_atom_get_path(sim->atom);
|
||||
|
||||
if (!g_dbus_register_interface(conn, path,
|
||||
SIM_MANAGER_INTERFACE,
|
||||
sim_manager_methods,
|
||||
sim_manager_signals,
|
||||
NULL, modem,
|
||||
sim_manager_destroy)) {
|
||||
ofono_error("Could not register SIMManager interface");
|
||||
sim_manager_destroy(modem);
|
||||
sim_methods, sim_signals, NULL,
|
||||
sim, NULL)) {
|
||||
ofono_error("Could not create %s interface",
|
||||
SIM_MANAGER_INTERFACE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ofono_debug("SIMManager interface for modem: %s created",
|
||||
modem->path);
|
||||
|
||||
ofono_modem_add_interface(modem, SIM_MANAGER_INTERFACE);
|
||||
|
||||
ofono_sim_ready_notify_register(modem, sim_ready);
|
||||
__ofono_atom_register(sim->atom, sim_unregister);
|
||||
|
||||
ofono_sim_add_ready_watch(sim, sim_ready, sim, NULL);
|
||||
|
||||
/* Perform SIM initialization according to 3GPP 31.102 Section 5.1.1.2
|
||||
* The assumption here is that if sim manager is being initialized,
|
||||
|
@ -1007,107 +1192,20 @@ static void initialize_sim_manager(struct ofono_modem *modem)
|
|||
* arbitrary files to be written or read, assuming their presence
|
||||
* in the EFust
|
||||
*/
|
||||
sim_retrieve_imsi(modem);
|
||||
sim_retrieve_imsi(sim);
|
||||
}
|
||||
|
||||
const char *ofono_sim_get_imsi(struct ofono_modem *modem)
|
||||
void ofono_sim_remove(struct ofono_sim *sim)
|
||||
{
|
||||
if (modem->sim_manager == NULL)
|
||||
return NULL;
|
||||
|
||||
return modem->sim_manager->imsi;
|
||||
__ofono_atom_free(sim->atom);
|
||||
}
|
||||
|
||||
int ofono_sim_ready_notify_register(struct ofono_modem *modem,
|
||||
ofono_sim_ready_notify_cb_t cb)
|
||||
void ofono_sim_set_data(struct ofono_sim *sim, void *data)
|
||||
{
|
||||
if (modem->sim_manager == NULL)
|
||||
return -1;
|
||||
|
||||
modem->sim_manager->ready_notify =
|
||||
g_slist_append(modem->sim_manager->ready_notify, cb);
|
||||
|
||||
return 0;
|
||||
sim->driver_data = data;
|
||||
}
|
||||
|
||||
void ofono_sim_ready_notify_unregister(struct ofono_modem *modem,
|
||||
ofono_sim_ready_notify_cb_t cb)
|
||||
void *ofono_sim_get_data(struct ofono_sim *sim)
|
||||
{
|
||||
if (modem->sim_manager == NULL)
|
||||
return;
|
||||
|
||||
modem->sim_manager->ready_notify =
|
||||
g_slist_remove(modem->sim_manager->ready_notify, cb);
|
||||
}
|
||||
|
||||
int ofono_sim_get_ready(struct ofono_modem *modem)
|
||||
{
|
||||
if (modem->sim_manager == NULL)
|
||||
return 0;
|
||||
|
||||
if (modem->sim_manager->ready == TRUE)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ofono_sim_set_ready(struct ofono_modem *modem)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
if (modem->sim_manager == NULL)
|
||||
return;
|
||||
|
||||
if (modem->sim_manager->ready == TRUE)
|
||||
return;
|
||||
|
||||
modem->sim_manager->ready = TRUE;
|
||||
|
||||
for (l = modem->sim_manager->ready_notify; l; l = l->next) {
|
||||
ofono_sim_ready_notify_cb_t cb = l->data;
|
||||
|
||||
cb(modem);
|
||||
}
|
||||
}
|
||||
|
||||
int ofono_sim_manager_register(struct ofono_modem *modem,
|
||||
struct ofono_sim_ops *ops)
|
||||
{
|
||||
if (modem == NULL)
|
||||
return -1;
|
||||
if (modem->sim_manager == NULL)
|
||||
return -1;
|
||||
|
||||
if (ops == NULL)
|
||||
return -1;
|
||||
|
||||
modem->sim_manager->ops = ops;
|
||||
|
||||
initialize_sim_manager(modem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ofono_sim_manager_unregister(struct ofono_modem *modem)
|
||||
{
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
g_dbus_unregister_interface(conn, modem->path,
|
||||
SIM_MANAGER_INTERFACE);
|
||||
ofono_modem_remove_interface(modem, SIM_MANAGER_INTERFACE);
|
||||
}
|
||||
|
||||
void ofono_sim_manager_init(struct ofono_modem *modem)
|
||||
{
|
||||
modem->sim_manager = sim_manager_create();
|
||||
}
|
||||
|
||||
void ofono_sim_manager_exit(struct ofono_modem *modem)
|
||||
{
|
||||
if (modem->sim_manager == NULL)
|
||||
return;
|
||||
|
||||
g_free(modem->sim_manager);
|
||||
|
||||
modem->sim_manager = NULL;
|
||||
return sim->driver_data;
|
||||
}
|
||||
|
|
58
src/sim.h
58
src/sim.h
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
typedef void (*ofono_sim_ready_notify_cb_t)(struct ofono_modem *modem);
|
||||
|
||||
typedef void (*ofono_sim_file_read_cb_t)(struct ofono_modem *modem, int ok,
|
||||
enum ofono_sim_file_structure structure,
|
||||
int total_length, int record,
|
||||
const unsigned char *data,
|
||||
int record_length, void *userdata);
|
||||
typedef void (*ofono_sim_file_write_cb_t)(struct ofono_modem *modem, int ok,
|
||||
void *userdata);
|
||||
|
||||
void ofono_sim_manager_init(struct ofono_modem *modem);
|
||||
void ofono_sim_manager_exit(struct ofono_modem *modem);
|
||||
|
||||
const char *ofono_sim_get_imsi(struct ofono_modem *modem);
|
||||
|
||||
int ofono_sim_ready_notify_register(struct ofono_modem *modem,
|
||||
ofono_sim_ready_notify_cb_t cb);
|
||||
void ofono_sim_ready_notify_unregister(struct ofono_modem *modem,
|
||||
ofono_sim_ready_notify_cb_t cb);
|
||||
|
||||
int ofono_sim_get_ready(struct ofono_modem *modem);
|
||||
void ofono_sim_set_ready(struct ofono_modem *modem);
|
||||
|
||||
/* This will queue an operation to read all available records with id from the
|
||||
* SIM. Callback cb will be called every time a record has been read, or once
|
||||
* if an error has occurred. For transparent files, the callback will only
|
||||
* be called once.
|
||||
*
|
||||
* Returns 0 if the request could be queued, -1 otherwise.
|
||||
*/
|
||||
int ofono_sim_read(struct ofono_modem *modem, int id,
|
||||
ofono_sim_file_read_cb_t cb, void *data);
|
||||
|
||||
int ofono_sim_write(struct ofono_modem *modem, int id,
|
||||
ofono_sim_file_write_cb_t cb,
|
||||
enum ofono_sim_file_structure structure, int record,
|
||||
const unsigned char *data, int length, void *userdata);
|
Loading…
Reference in New Issue