From: Kristen Carlson Accardi <kristen@linux.intel.com>
To: ofono@ofono.org
Subject: [PATCH 5/6] sim: implement GetIcon
Date: Wed, 18 Aug 2010 04:25:22 -0700 [thread overview]
Message-ID: <1282130723-10488-6-git-send-email-kristen@linux.intel.com> (raw)
In-Reply-To: <1282130723-10488-1-git-send-email-kristen@linux.intel.com>
[-- Attachment #1: Type: text/plain, Size: 7029 bytes --]
create an interface to allow a caller to request an icon by id
via dbus. Convert iidf files to xpm format and cache.
---
src/sim.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 216 insertions(+), 0 deletions(-)
diff --git a/src/sim.c b/src/sim.c
index d79c5e1..f24c40f 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -42,12 +42,14 @@
#include "smsutil.h"
#include "simutil.h"
#include "storage.h"
+#include "stkutil.h"
#define SIM_CACHE_MODE 0600
#define SIM_CACHE_PATH STORAGEDIR "/%s-%i/%04x"
#define SIM_CACHE_PATH_LEN(imsilen) (strlen(SIM_CACHE_PATH) - 3 + imsilen)
#define SIM_CACHE_HEADER_SIZE 6
#define SIM_IIDF_CACHE_PATH SIM_CACHE_PATH ".%02x"
+#define SIM_IMAGE_CACHE_PATH STORAGEDIR "%s-%i/images/%d.xpm"
static GSList *g_drivers = NULL;
@@ -58,6 +60,11 @@ static void sim_pin_check(struct ofono_sim *sim);
static void sim_set_ready(struct ofono_sim *sim);
static gboolean sim_op_read_block(gpointer user_data);
+typedef void (*ofono_sim_get_image_cb_t)(int ok, const char *xpm, int xpm_len,
+ void *user_data);
+static void ofono_sim_get_image(struct ofono_sim *sim, unsigned char id,
+ ofono_sim_get_image_cb_t cb, gpointer user_data);
+
struct sim_file_op {
int id;
gboolean cache;
@@ -94,6 +101,7 @@ struct ofono_sim {
unsigned char *efli;
unsigned char efli_length;
unsigned char *efimg;
+ unsigned short image_cache[256];
int efimg_length;
enum ofono_sim_cphs_phase cphs_phase;
unsigned char cphs_service_table[2];
@@ -733,6 +741,50 @@ static DBusMessage *sim_enter_pin(DBusConnection *conn, DBusMessage *msg,
return NULL;
}
+static void ofono_sim_get_image_cb(int ok, const char *xpm, int xpm_len,
+ void *userdata)
+{
+ struct ofono_sim *sim = userdata;
+ DBusMessage *reply;
+
+ if (!ok)
+ reply = __ofono_error_failed(sim->pending);
+ else {
+ reply = dbus_message_new_method_return(sim->pending);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &xpm,
+ DBUS_TYPE_INVALID);
+ }
+
+ __ofono_dbus_pending_reply(&sim->pending, reply);
+}
+
+static DBusMessage *sim_get_icon(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_sim *sim = data;
+ unsigned char id;
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &id,
+ DBUS_TYPE_INVALID) == FALSE)
+ return __ofono_error_invalid_args(msg);
+
+ /* zero means no icon */
+ if (id == 0)
+ return __ofono_error_invalid_args(msg);
+
+ if (sim->pending)
+ return __ofono_error_busy(msg);
+
+ if (sim->efimg == NULL)
+ return __ofono_error_not_implemented(msg);
+
+ sim->pending = dbus_message_ref(msg);
+
+ ofono_sim_get_image(sim, id, ofono_sim_get_image_cb, sim);
+
+ return NULL;
+}
+
static DBusMessage *sim_reset_pin(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -785,6 +837,8 @@ static GDBusMethodTable sim_methods[] = {
G_DBUS_METHOD_FLAG_ASYNC },
{ "UnlockPin", "ss", "", sim_unlock_pin,
G_DBUS_METHOD_FLAG_ASYNC },
+ { "GetIcon", "y", "s", sim_get_icon,
+ G_DBUS_METHOD_FLAG_ASYNC },
{ }
};
@@ -2392,3 +2446,165 @@ void *ofono_sim_get_data(struct ofono_sim *sim)
{
return sim->driver_data;
}
+
+struct image_data {
+ struct ofono_sim *sim;
+ unsigned char width;
+ unsigned char height;
+ enum stk_img_scheme scheme;
+ unsigned short iidf_id;
+ unsigned short iidf_offset;
+ unsigned short iid_len;
+ void *image;
+ unsigned short clut_len;
+ gboolean need_clut;
+ ofono_sim_get_image_cb_t user_cb;
+ gpointer user_data;
+ unsigned char id;
+};
+
+static void sim_iidf_read_cb(int ok, int length, int record,
+ const unsigned char *data,
+ int record_length, void *userdata)
+{
+ struct image_data *image = userdata;
+ unsigned short offset;
+ unsigned short num_entries;
+ char *xpm;
+ struct ofono_sim *sim = image->sim;
+
+ if (!ok) {
+ image->user_cb(ok, NULL, 0, image->user_data);
+ goto iidf_read_out;
+ }
+
+ if (image->need_clut == FALSE) {
+ if (image->scheme == STK_IMG_SCHEME_BASIC) {
+ xpm = stk_image_to_xpm(data, image->iid_len,
+ image->scheme, NULL, 0);
+ } else {
+ xpm = stk_image_to_xpm(image->image, image->iid_len,
+ image->scheme, data,
+ image->clut_len);
+ }
+
+ if (sim->imsi) {
+ write_file((const unsigned char *) xpm, strlen(xpm),
+ SIM_CACHE_MODE, SIM_IMAGE_CACHE_PATH,
+ sim->imsi, sim->phase, image->id);
+
+ sim->image_cache[image->id] = strlen(xpm);
+ }
+
+ image->user_cb(ok, xpm, strlen(xpm), image->user_data);
+
+ g_free(xpm);
+
+ goto iidf_read_out;
+ }
+
+ offset = data[4] << 8 | data[5];
+ num_entries = data[3];
+
+ if (num_entries == 0)
+ num_entries = 256;
+
+ /* indicate that we're on our second read */
+ image->need_clut = FALSE;
+
+ image->clut_len = num_entries * 3;
+
+ image->image = g_memdup(data, length);
+
+ /* read the clut data */
+ ofono_sim_read_bytes(image->sim, image->iidf_id,
+ OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+ offset, image->clut_len,
+ sim_iidf_read_cb, image);
+
+ return;
+
+iidf_read_out:
+ g_free(image->image);
+ g_free(image);
+}
+
+static void ofono_sim_get_image(struct ofono_sim *sim, unsigned char id,
+ ofono_sim_get_image_cb_t cb, gpointer user_data)
+{
+ struct image_data *data;
+ unsigned char *efimg;
+ unsigned short image_length;
+
+ /* icon ids should start at 1, our array starts at zero */
+ if (id == 0) {
+ cb(-1, NULL, 0, user_data);
+ return;
+ }
+
+ id--;
+
+ /* check the image cache to see if we've already got this one */
+ image_length = sim->image_cache[id];
+
+ if (image_length > 0) {
+ int fd;
+ char *imsi = sim->imsi;
+ char *buffer;
+ char *path = g_strdup_printf(SIM_IMAGE_CACHE_PATH, imsi,
+ sim->phase,
+ id);
+
+ fd = TFR(open(path, O_RDONLY));
+
+ g_free(path);
+
+ if (fd < 0)
+ goto read_image;
+
+ buffer = g_try_malloc0(image_length);
+
+ TFR(read(fd, buffer, image_length));
+
+ cb(1, buffer, image_length, user_data);
+
+ g_free(buffer);
+
+ return;
+ }
+
+read_image:
+
+ if (sim->efimg_length < (id * 9)) {
+ cb(-1, NULL, 0, user_data);
+ return;
+ }
+
+ efimg = &sim->efimg[id * 9];
+
+ data = g_try_new0(struct image_data, 1);
+ if (data == NULL)
+ return;
+
+ data->width = efimg[0];
+ data->height = efimg[1];
+ data->scheme = efimg[2];
+ data->iidf_id = efimg[3] << 8 | efimg[4];
+ data->iidf_offset = efimg[5] << 8 | efimg[6];
+ data->iid_len = efimg[7] << 8 | efimg[8];
+ data->user_cb = cb;
+ data->user_data = user_data;
+ data->sim = sim;
+ data->id = id;
+
+ if (data->scheme == STK_IMG_SCHEME_BASIC)
+ data->need_clut = FALSE;
+ else
+ data->need_clut = TRUE;
+
+ /* read the image data */
+ ofono_sim_read_bytes(sim, data->iidf_id,
+ OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+ data->iidf_offset, data->iid_len,
+ sim_iidf_read_cb, data);
+}
--
1.7.2.1
next prev parent reply other threads:[~2010-08-18 11:25 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-18 11:25 [PATCH v2 0/6] Icon support Kristen Carlson Accardi
2010-08-18 11:25 ` [PATCH 1/6] simutil: add fileid for EFimg Kristen Carlson Accardi
2010-08-18 11:25 ` [PATCH 2/6] stkutil: change uint32_t to guint32 Kristen Carlson Accardi
2010-08-18 11:25 ` [PATCH 3/6] sim: read EFimg Kristen Carlson Accardi
2010-08-25 18:03 ` Denis Kenzior
2010-08-18 11:25 ` [PATCH 4/6] sim: read EFiidf Kristen Carlson Accardi
2010-08-18 11:25 ` Kristen Carlson Accardi [this message]
2010-08-18 11:25 ` [PATCH 6/6] test: add get-icon script Kristen Carlson Accardi
-- strict thread matches above, loose matches on Subject: below --
2010-08-25 11:00 [PATCH v2 0/6] icon support patches Kristen Carlson Accardi
2010-08-25 11:00 ` [PATCH 5/6] sim: implement GetIcon Kristen Carlson Accardi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1282130723-10488-6-git-send-email-kristen@linux.intel.com \
--to=kristen@linux.intel.com \
--cc=ofono@ofono.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.