[PATCH 1/3 v2] sms: store pending tx pdus on disk
--- src/sms.c | 15 +++ src/smsutil.c | 26 ++ src/smsutil.h |3 +++ 3 files changed, 44 insertions(+), 0 deletions(-) diff --git a/src/sms.c b/src/sms.c index 163eab0..e5e06db 100644 --- a/src/sms.c +++ b/src/sms.c @@ -77,6 +77,7 @@ struct ofono_sms { struct sms_assembly *assembly; guint ref; GQueue *txq; + unsigned long tx_counter; guint tx_source; struct ofono_message_waiting *mw; unsigned int mw_watch; @@ -111,6 +112,7 @@ struct tx_queue_entry { ofono_sms_txq_submit_cb_t cb; void *data; ofono_destroy_func destroy; + unsigned long id; }; static gboolean uuid_equal(gconstpointer v1, gconstpointer v2) @@ -1896,6 +1898,8 @@ int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list, { struct message *m = NULL; struct tx_queue_entry *entry; + int i; + GSList *l; entry = tx_queue_entry_new(list, flags); if (entry == NULL) @@ -1920,6 +1924,8 @@ int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list, sms-ref = sms-ref + 1; } + entry-id = sms-tx_counter++; + g_queue_push_tail(sms-txq, entry); if (g_queue_get_length(sms-txq) == 1) @@ -1928,6 +1934,15 @@ int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list, if (uuid) memcpy(uuid, entry-uuid, sizeof(*uuid)); + if (flags OFONO_SMS_SUBMIT_FLAG_EXPOSE_DBUS) { + for (i = 0, l = list; l; i++, l = l-next) { + struct sms *s = l-data; + sms_tx_store(sms-imsi, entry-id, entry-flags, + ofono_uuid_to_str(entry-uuid), + s, i); + } + } + if (cb) cb(sms, entry-uuid, data); diff --git a/src/smsutil.c b/src/smsutil.c index 5e1d233..9c6596f 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -48,6 +48,10 @@ #define SMS_SR_BACKUP_PATH STORAGEDIR /%s/sms_sr #define SMS_SR_BACKUP_PATH_FILE SMS_SR_BACKUP_PATH /%s-%s +#define SMS_TX_BACKUP_PATH STORAGEDIR /%s/tx_queue +#define SMS_TX_BACKUP_PATH_DIR SMS_TX_BACKUP_PATH /%lu-%lu-%s +#define SMS_TX_BACKUP_PATH_FILE SMS_TX_BACKUP_PATH_DIR /%03i + #define SMS_ADDR_FMT %24[0-9A-F] #define SMS_MSGID_FMT %40[0-9A-F] @@ -3143,6 +3147,28 @@ void status_report_assembly_expire(struct status_report_assembly *assembly, } } +gboolean sms_tx_store(const char *imsi, unsigned long id, unsigned long flags, + const char *uuid, struct sms *s, guint8 seq) +{ + int len; + unsigned char buf[177]; + + if (!imsi) + return FALSE; + + len = sms_serialize(buf, s); + + /* +* file name is: imsi/order in tx_queue-flags-uuid/order of pdus +*/ + if (write_file(buf, len, SMS_BACKUP_MODE, + SMS_TX_BACKUP_PATH_FILE, imsi, id, flags, uuid, + seq) != len) + return FALSE; + + return TRUE; +} + static inline GSList *sms_list_append(GSList *l, const struct sms *in) { struct sms *sms; diff --git a/src/smsutil.h b/src/smsutil.h index 4b6159f..46084ab 100644 --- a/src/smsutil.h +++ b/src/smsutil.h @@ -517,6 +517,9 @@ void status_report_assembly_add_fragment(struct status_report_assembly void status_report_assembly_expire(struct status_report_assembly *assembly, time_t before); +gboolean sms_tx_store(const char *imsi, unsigned long id, unsigned long flags, + const char *uuid, struct sms *s, guint8 seq); + GSList *sms_text_prepare(const char *to, const char *utf8, guint16 ref, gboolean use_16bit, gboolean use_delivery_reports); -- 1.7.2.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/3 v2] sms: delete sent sms messages from backup
--- src/sms.c |7 +++ src/smsutil.c | 45 + src/smsutil.h |5 + 3 files changed, 57 insertions(+), 0 deletions(-) diff --git a/src/sms.c b/src/sms.c index e5e06db..dd4d27c 100644 --- a/src/sms.c +++ b/src/sms.c @@ -766,6 +766,10 @@ static void tx_finished(const struct ofono_error *error, int mr, void *data) goto next_q; } + sms_tx_backup_remove(sms-imsi, entry-id, entry-flags, + ofono_uuid_to_str(entry-uuid), + entry-cur_pdu); + entry-cur_pdu += 1; entry-retry = 0; @@ -810,6 +814,9 @@ next_q: message_set_state(sms, entry-uuid, ms); } + sms_tx_backup_free(sms-imsi, entry-id, entry-flags, + ofono_uuid_to_str(entry-uuid)); + tx_queue_entry_destroy(entry); if (g_queue_peek_head(sms-txq)) { diff --git a/src/smsutil.c b/src/smsutil.c index 9c6596f..09da657 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -3169,6 +3169,51 @@ gboolean sms_tx_store(const char *imsi, unsigned long id, unsigned long flags, return TRUE; } +void sms_tx_backup_free(const char *imsi, unsigned long id, + unsigned long flags, const char *uuid) +{ + char *path; + struct dirent **entries; + int len; + + path = g_strdup_printf(SMS_TX_BACKUP_PATH_DIR, + imsi, id, flags, uuid); + + len = scandir(path, entries, NULL, versionsort); + + if (len 0) + return; + + while (len--) { + struct dirent *dir = entries[len]; + char *file = g_strdup_printf(%s/%s, path, dir-d_name); + + unlink(file); + + g_free(file); + g_free(entries[len]); + } + + g_free(entries); + + rmdir(path); + + g_free(path); +} + +void sms_tx_backup_remove(const char *imsi, unsigned long id, + unsigned long flags, const char *uuid, + guint8 seq) +{ + char *path; + + path = g_strdup_printf(SMS_TX_BACKUP_PATH_FILE, + imsi, id, flags, uuid, seq); + unlink(path); + + g_free(path); +} + static inline GSList *sms_list_append(GSList *l, const struct sms *in) { struct sms *sms; diff --git a/src/smsutil.h b/src/smsutil.h index 46084ab..fa4e453 100644 --- a/src/smsutil.h +++ b/src/smsutil.h @@ -519,6 +519,11 @@ void status_report_assembly_expire(struct status_report_assembly *assembly, gboolean sms_tx_store(const char *imsi, unsigned long id, unsigned long flags, const char *uuid, struct sms *s, guint8 seq); +void sms_tx_backup_remove(const char *imsi, unsigned long id, + unsigned long flags, const char *uuid, + guint8 seq); +void sms_tx_backup_free(const char *imsi, unsigned long id, + unsigned long flags, const char *uuid); GSList *sms_text_prepare(const char *to, const char *utf8, guint16 ref, gboolean use_16bit, -- 1.7.2.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 3/3 v2] sms: restore pending tx messages from backup
--- src/ofono.h |1 + src/sms.c | 75 ++ src/smsutil.c | 143 + src/smsutil.h |8 +++ 4 files changed, 227 insertions(+), 0 deletions(-) diff --git a/src/ofono.h b/src/ofono.h index 792134b..c8e6cf0 100644 --- a/src/ofono.h +++ b/src/ofono.h @@ -243,6 +243,7 @@ enum ofono_sms_submit_flag { OFONO_SMS_SUBMIT_FLAG_RECORD_HISTORY = 0x2, OFONO_SMS_SUBMIT_FLAG_RETRY = 0x4, OFONO_SMS_SUBMIT_FLAG_EXPOSE_DBUS = 0x8, + OFONO_SMS_SUBMIT_FLAG_REUSE_UUID = 0x10, }; typedef void (*ofono_sms_txq_submit_cb_t)(gboolean ok, void *data); diff --git a/src/sms.c b/src/sms.c index dd4d27c..42ca034 100644 --- a/src/sms.c +++ b/src/sms.c @@ -929,6 +929,9 @@ static struct tx_queue_entry *tx_queue_entry_new(GSList *msg_list, pdu-pdu_len, pdu-tpdu_len); } + if (flags OFONO_SMS_SUBMIT_FLAG_REUSE_UUID) + return entry; + if (sms_uuid_from_pdus(entry-pdus, entry-num_pdus, entry-uuid)) return entry; @@ -1808,6 +1811,77 @@ static void bearer_init_callback(const struct ofono_error *error, void *data) ofono_error(Error bootstrapping SMS Bearer Preference); } +static void sms_restore_tx_queue(struct ofono_sms *sms) +{ + GQueue *backupq; + struct txq_backup_entry *backup_entry; + struct ofono_uuid ofono_uuid; + + DBG(); + + backupq = sms_tx_queue_load(sms-imsi); + + while ((backup_entry = g_queue_pop_head(backupq))) { + struct message *m; + struct tx_queue_entry *txq_entry; + + decode_hex_own_buf(backup_entry-uuid, -1, NULL, 0, + ofono_uuid.uuid); + + backup_entry-flags |= OFONO_SMS_SUBMIT_FLAG_REUSE_UUID; + + txq_entry = tx_queue_entry_new(backup_entry-msg_list, + backup_entry-flags); + + if (txq_entry == NULL) + goto loop_out; + + txq_entry-flags = ~OFONO_SMS_SUBMIT_FLAG_REUSE_UUID; + + memcpy(txq_entry-uuid, ofono_uuid, sizeof(ofono_uuid)); + + m = message_create(txq_entry-uuid); + + if (m == NULL) { + tx_queue_entry_destroy(txq_entry); + goto loop_out; + } + + if (message_dbus_register(sms, m) == FALSE) { + tx_queue_entry_destroy(txq_entry); + goto loop_out; + } + + g_hash_table_insert(sms-messages, m-uuid, m); + m-entry = txq_entry; + + if (backup_entry-msg_list-next != NULL) { + if (sms-ref == 65536) + sms-ref = 1; + else + sms-ref = sms-ref + 1; + } + + txq_entry-id = sms-tx_counter++; + + g_queue_push_tail(sms-txq, txq_entry); + + if (g_queue_get_length(sms-txq) == 1) + sms-tx_source = g_timeout_add(0, tx_next, sms); + + if (backup_entry-flags OFONO_SMS_SUBMIT_FLAG_EXPOSE_DBUS) + emit_message_added(sms, m); +loop_out: + g_slist_foreach(backup_entry-msg_list, (GFunc)g_free, NULL); + g_slist_free(backup_entry-msg_list); + + g_free(backup_entry-uuid); + g_free(backup_entry); + } + + g_queue_free(backupq); +} + /* * Indicate oFono that a SMS driver is ready for operation * @@ -1871,6 +1945,7 @@ void ofono_sms_register(struct ofono_sms *sms) if (sms-driver-bearer_set) sms-driver-bearer_set(sms, sms-bearer, bearer_init_callback, sms); + sms_restore_tx_queue(sms); sms-text_handlers = __ofono_watchlist_new(g_free); sms-datagram_handlers = __ofono_watchlist_new(g_free); diff --git a/src/smsutil.c b/src/smsutil.c index 09da657..3d33a54 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -2327,6 +2327,15 @@ static gboolean sms_deserialize(const unsigned char *buf, return sms_decode(buf + 1, len - 1, FALSE, buf[0], sms); } +static gboolean sms_deserialize_outgoing(const unsigned char *buf, + struct sms *sms, int len) +{ + if (len 1) + return FALSE; + + return sms_decode(buf + 1, len - 1, TRUE, buf[0], sms); +} + static gboolean sms_assembly_extract_address(const char *straddr, struct sms_address *out) { @@ -3147,6 +3156,140 @@ void status_report_assembly_expire(struct status_report_assembly *assembly, } } +/* + * Each directory contains a file per pdu. + */ +static GSList *sms_tx_load(const char *imsi, const struct dirent *dir) +{ + GSList
Re: [PATCH 1/3] sms: store pending tx pdus on disk
On Mon, 06 Dec 2010 20:38:58 -0600 Denis Kenzior denk...@gmail.com wrote: snip + /* +* file name is: imsi/order in tx_queue-uuid/order of pdus +*/ + if (write_file(buf, len, SMS_BACKUP_MODE, + SMS_TX_BACKUP_PATH_FILE, imsi, id, uuid, + seq) != len) + return FALSE; + And where are you taking care of storing the other needed information? e.g. the tx_queue entry flags, retry count, etc? I can easily add the flags and retry count. As far as the etc that you mention, the only other information I see would be entry-cb and entry-data, which I was thinking might have to get lost. I am not sure how to persist that information on disk - do you have any suggestions? ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] simfs: make sim_fs_read_block work for 256 byte files
--- src/simfs.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/simfs.c b/src/simfs.c index 5f459ab..258a42f 100644 --- a/src/simfs.c +++ b/src/simfs.c @@ -59,6 +59,7 @@ static gboolean sim_fs_op_read_block(gpointer user_data); struct sim_fs_op { int id; unsigned char *buffer; + int bufoff; enum ofono_sim_file_structure structure; unsigned short offset; gboolean info_only; @@ -217,7 +218,6 @@ static void sim_fs_op_read_block_cb(const struct ofono_error *error, struct sim_fs_op *op = g_queue_peek_head(fs-op_q); int start_block; int end_block; - int bufoff; int dataoff; int tocopy; @@ -230,25 +230,25 @@ static void sim_fs_op_read_block_cb(const struct ofono_error *error, end_block = (op-offset + (op-num_bytes - 1)) / 256; if (op-current == start_block) { - bufoff = 0; + op-bufoff = 0; dataoff = op-offset % 256; tocopy = MIN(256 - op-offset % 256, op-num_bytes - op-current * 256); } else { - bufoff = (op-current - start_block - 1) * 256 + - op-offset % 256; dataoff = 0; tocopy = MIN(256, op-num_bytes - op-current * 256); } DBG(bufoff: %d, dataoff: %d, tocopy: %d, - bufoff, dataoff, tocopy); + op-bufoff, dataoff, tocopy); - memcpy(op-buffer + bufoff, data + dataoff, tocopy); + memcpy(op-buffer + op-bufoff, data + dataoff, tocopy); cache_block(fs, op-current, 256, data, len); op-current++; + op-bufoff += tocopy; + if (op-current end_block) { ofono_sim_file_read_cb_t cb = op-cb; -- 1.7.2.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/3] Persist TX SMS messages
This patch series implements a method of persisting pending outgoing sms messages on disk. Once an sms message has been submitted to the transmit queue, each pdu in the message is stored on disk until the driver indicates that it has been sent. Each tx_queue_entry is given an id number that represents it's order in the queue. A subdirectory per entry is created as id-uuid, in order to preserve order when the queue is loaded in the event of a crash. Within each subdirectory, each pdu is saved in order by sequence number. When an sms driver is ready for operation, the disk will be scanned for any saved pending tx sms messages. If there are any found, they will be loaded from disk and placed into the queue in order. Kristen Carlson Accardi (3): sms: store pending tx pdus on disk sms: delete sent sms messages from backup sms: restore pending tx messages from backup src/ofono.h |1 + src/sms.c | 64 src/smsutil.c | 180 + src/smsutil.h | 13 4 files changed, 258 insertions(+), 0 deletions(-) -- 1.7.2.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/3] sms: store pending tx pdus on disk
--- src/sms.c | 17 + src/smsutil.c | 26 ++ src/smsutil.h |3 +++ 3 files changed, 46 insertions(+), 0 deletions(-) diff --git a/src/sms.c b/src/sms.c index 12988c8..6eab0fa 100644 --- a/src/sms.c +++ b/src/sms.c @@ -52,6 +52,8 @@ static gboolean tx_next(gpointer user_data); static GSList *g_drivers = NULL; +static unsigned long tx_counter = 0; + enum message_state { MESSAGE_STATE_PENDING = 0, MESSAGE_STATE_SENT, @@ -111,6 +113,7 @@ struct tx_queue_entry { ofono_sms_txq_submit_cb_t cb; void *data; ofono_destroy_func destroy; + int id; }; static gboolean uuid_equal(gconstpointer v1, gconstpointer v2) @@ -1899,6 +1902,8 @@ int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list, { struct message *m = NULL; struct tx_queue_entry *entry; + int i; + GSList *l; entry = tx_queue_entry_new(list, flags); if (entry == NULL) @@ -1923,6 +1928,8 @@ int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list, sms-ref = sms-ref + 1; } + entry-id = tx_counter++; + g_queue_push_tail(sms-txq, entry); if (g_queue_get_length(sms-txq) == 1) @@ -1931,6 +1938,16 @@ int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list, if (uuid) memcpy(uuid, entry-uuid, sizeof(*uuid)); + i = 0; + + for (l = list; l; l = l-next) { + struct sms *s = l-data; + sms_tx_store(sms-imsi, entry-id, + ofono_uuid_to_str(entry-uuid), + s, i); + i++; + } + if (cb) cb(sms, entry-uuid, data); diff --git a/src/smsutil.c b/src/smsutil.c index e6dbf5f..4904419 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -48,6 +48,10 @@ #define SMS_SR_BACKUP_PATH STORAGEDIR /%s/sms_sr #define SMS_SR_BACKUP_PATH_FILE SMS_SR_BACKUP_PATH /%s-%s +#define SMS_TX_BACKUP_PATH STORAGEDIR /%s/tx_queue +#define SMS_TX_BACKUP_PATH_DIR SMS_TX_BACKUP_PATH /%lu-%s +#define SMS_TX_BACKUP_PATH_FILE SMS_TX_BACKUP_PATH_DIR /%03i + #define SMS_ADDR_FMT %24[0-9A-F] #define SMS_MSGID_FMT %40[0-9A-F] @@ -3125,6 +3129,28 @@ void status_report_assembly_expire(struct status_report_assembly *assembly, } } +gboolean sms_tx_store(const char *imsi, unsigned long id, const char *uuid, + struct sms *s, guint8 seq) +{ + int len; + unsigned char buf[177]; + + if (!imsi) + return FALSE; + + len = sms_serialize(buf, s); + + /* +* file name is: imsi/order in tx_queue-uuid/order of pdus +*/ + if (write_file(buf, len, SMS_BACKUP_MODE, + SMS_TX_BACKUP_PATH_FILE, imsi, id, uuid, + seq) != len) + return FALSE; + + return TRUE; +} + static inline GSList *sms_list_append(GSList *l, const struct sms *in) { struct sms *sms; diff --git a/src/smsutil.h b/src/smsutil.h index 4b05313..5279489 100644 --- a/src/smsutil.h +++ b/src/smsutil.h @@ -516,6 +516,9 @@ void status_report_assembly_add_fragment(struct status_report_assembly void status_report_assembly_expire(struct status_report_assembly *assembly, time_t before); +gboolean sms_tx_store(const char *imsi, unsigned long id, const char *uuid, + struct sms *s, guint8 seq); + GSList *sms_text_prepare(const char *to, const char *utf8, guint16 ref, gboolean use_16bit, gboolean use_delivery_reports); -- 1.7.2.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/3] sms: delete sent sms messages from backup
--- src/sms.c |9 + src/smsutil.c | 38 ++ src/smsutil.h |4 3 files changed, 51 insertions(+), 0 deletions(-) diff --git a/src/sms.c b/src/sms.c index 6eab0fa..f987946 100644 --- a/src/sms.c +++ b/src/sms.c @@ -769,6 +769,10 @@ static void tx_finished(const struct ofono_error *error, int mr, void *data) goto next_q; } + sms_tx_backup_remove(sms-imsi, entry-id, + ofono_uuid_to_str(entry-uuid), + entry-cur_pdu); + entry-cur_pdu += 1; entry-retry = 0; @@ -813,8 +817,13 @@ next_q: message_set_state(sms, entry-uuid, ms); } + sms_tx_backup_destroy(sms-imsi, entry-id, + ofono_uuid_to_str(entry-uuid)); + tx_queue_entry_destroy(entry); + tx_counter--; + if (g_queue_peek_head(sms-txq)) { DBG(Scheduling next); sms-tx_source = g_timeout_add(0, tx_next, sms); diff --git a/src/smsutil.c b/src/smsutil.c index 4904419..7a6b70a 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -3151,6 +3151,44 @@ gboolean sms_tx_store(const char *imsi, unsigned long id, const char *uuid, return TRUE; } +void sms_tx_backup_destroy(const char *imsi, unsigned long id, const char *uuid) +{ + char *path; + struct dirent **entries; + int len; + + path = g_strdup_printf(SMS_TX_BACKUP_PATH_DIR, + imsi, id, uuid); + + len = scandir(path, entries, NULL, versionsort); + while (len--) { + struct dirent *dir = entries[len]; + char *file = g_strdup_printf(%s/%s, path, dir-d_name); + + unlink(file); + + g_free(file); + g_free(entries[len]); + } + g_free(entries); + + rmdir(path); + + g_free(path); +} + +void sms_tx_backup_remove(const char *imsi, unsigned long id, const char *uuid, + guint8 seq) +{ + char *path; + + path = g_strdup_printf(SMS_TX_BACKUP_PATH_FILE, + imsi, id, uuid, seq); + unlink(path); + + g_free(path); +} + static inline GSList *sms_list_append(GSList *l, const struct sms *in) { struct sms *sms; diff --git a/src/smsutil.h b/src/smsutil.h index 5279489..2e2bae6 100644 --- a/src/smsutil.h +++ b/src/smsutil.h @@ -518,6 +518,10 @@ void status_report_assembly_expire(struct status_report_assembly *assembly, gboolean sms_tx_store(const char *imsi, unsigned long id, const char *uuid, struct sms *s, guint8 seq); +void sms_tx_backup_remove(const char *imsi, unsigned long id, const char *uuid, + guint8 seq); +void sms_tx_backup_destroy(const char *imsi, unsigned long id, + const char *uuid); GSList *sms_text_prepare(const char *to, const char *utf8, guint16 ref, gboolean use_16bit, -- 1.7.2.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 3/3] sms: restore pending tx messages from backup
--- src/ofono.h |1 + src/sms.c | 38 +++ src/smsutil.c | 116 + src/smsutil.h |6 +++ 4 files changed, 161 insertions(+), 0 deletions(-) diff --git a/src/ofono.h b/src/ofono.h index d1a4bdc..4777f70 100644 --- a/src/ofono.h +++ b/src/ofono.h @@ -241,6 +241,7 @@ enum ofono_sms_submit_flag { OFONO_SMS_SUBMIT_FLAG_RECORD_HISTORY = 0x2, OFONO_SMS_SUBMIT_FLAG_RETRY = 0x4, OFONO_SMS_SUBMIT_FLAG_EXPOSE_DBUS = 0x8, + OFONO_SMS_SUBMIT_FLAG_REUSE_UUID = 0x10, }; typedef void (*ofono_sms_txq_submit_cb_t)(gboolean ok, void *data); diff --git a/src/sms.c b/src/sms.c index f987946..be710b1 100644 --- a/src/sms.c +++ b/src/sms.c @@ -1814,6 +1814,40 @@ static void bearer_init_callback(const struct ofono_error *error, void *data) ofono_error(Error bootstrapping SMS Bearer Preference); } +static void sms_restore_tx_queue(struct ofono_sms *sms) +{ + GQueue *backupq; + unsigned int flags; + struct txq_backup_entry *entry; + struct ofono_uuid ofono_uuid; + + DBG(); + + flags = OFONO_SMS_SUBMIT_FLAG_RECORD_HISTORY; + flags |= OFONO_SMS_SUBMIT_FLAG_RETRY; + flags |= OFONO_SMS_SUBMIT_FLAG_REUSE_UUID; + + if (sms-use_delivery_reports) + flags |= OFONO_SMS_SUBMIT_FLAG_REQUEST_SR; + + backupq = sms_tx_queue_load(sms-imsi); + + while ((entry = g_queue_pop_head(backupq))) { + decode_hex_own_buf(entry-uuid, -1, NULL, 0, ofono_uuid.uuid); + + __ofono_sms_txq_submit(sms, entry-msg_list, flags, + ofono_uuid, NULL, NULL); + + g_slist_foreach(entry-msg_list, (GFunc)g_free, NULL); + g_slist_free(entry-msg_list); + + g_free(entry-uuid); + g_free(entry); + } + + g_queue_free(backupq); +} + /* * Indicate oFono that a SMS driver is ready for operation * @@ -1877,6 +1911,7 @@ void ofono_sms_register(struct ofono_sms *sms) if (sms-driver-bearer_set) sms-driver-bearer_set(sms, sms-bearer, bearer_init_callback, sms); + sms_restore_tx_queue(sms); sms-text_handlers = __ofono_watchlist_new(g_free); sms-datagram_handlers = __ofono_watchlist_new(g_free); @@ -1918,6 +1953,9 @@ int __ofono_sms_txq_submit(struct ofono_sms *sms, GSList *list, if (entry == NULL) return -ENOMEM; + if (flags OFONO_SMS_SUBMIT_FLAG_REUSE_UUID) + memcpy(entry-uuid, uuid, sizeof(*uuid)); + if (flags OFONO_SMS_SUBMIT_FLAG_EXPOSE_DBUS) { m = message_create(entry-uuid); if (m == NULL) diff --git a/src/smsutil.c b/src/smsutil.c index 7a6b70a..188b96e 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -2309,6 +2309,15 @@ static gboolean sms_deserialize(const unsigned char *buf, return sms_decode(buf + 1, len - 1, FALSE, buf[0], sms); } +static gboolean sms_deserialize_outgoing(const unsigned char *buf, + struct sms *sms, int len) +{ + if (len 1) + return FALSE; + + return sms_decode(buf + 1, len - 1, TRUE, buf[0], sms); +} + static gboolean sms_assembly_extract_address(const char *straddr, struct sms_address *out) { @@ -3129,6 +3138,113 @@ void status_report_assembly_expire(struct status_report_assembly *assembly, } } +/* + * Each directory contains a file per pdu. + */ +static GSList *sms_tx_load(const char *imsi, const struct dirent *dir) +{ + GSList *list = NULL; + struct dirent **pdus; + char *path; + int len, i, r; + unsigned char buf[177]; + struct sms s; + + if (dir-d_type != DT_DIR) + return NULL; + + path = g_strdup_printf(SMS_TX_BACKUP_PATH /%s, + imsi, dir-d_name); + + len = scandir(path, pdus, NULL, versionsort); + g_free(path); + + if (len 0) + return NULL; + + for (i = 0; i len; i++) { + if (pdus[i]-d_type != DT_REG) + continue; + + if ((strcmp(dir-d_name, .) == 0) || + (strcmp(dir-d_name, ..) == 0)) + continue; + + r = read_file(buf, sizeof(buf), SMS_TX_BACKUP_PATH /%s/%s, + imsi, dir-d_name, pdus[i]-d_name); + if (r 0) + continue; + + if (sms_deserialize_outgoing(buf, s, r) == FALSE) + continue; + + list = g_slist_prepend(list, g_memdup(s, sizeof(s))); + } + + for (i = 0; i len; i++) + g_free(pdus[i]); + + g_free(pdus); + + return g_slist_reverse(list); +} + +/* + * populate the queue with tx_backup_entry from
Re: [PATCH] simfs: fix incorrect math again
On Thu, 14 Oct 2010 11:18:00 -0700 Kristen Carlson Accardi kris...@linux.intel.com wrote: --- src/simfs.c |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/simfs.c b/src/simfs.c index fd768ef..bcb6ff8 100644 --- a/src/simfs.c +++ b/src/simfs.c @@ -231,8 +231,7 @@ static void sim_fs_op_read_block_cb(const struct ofono_error *error, tocopy = MIN(256 - op-offset % 256, op-num_bytes - op-current * 256); } else { - bufoff = (op-current - start_block - 1) * 256 + - op-offset % 256; + bufoff = op-current * 256; dataoff = 0; tocopy = MIN(256, op-num_bytes - op-current * 256); } @@ -294,8 +293,7 @@ static gboolean sim_fs_op_read_block(gpointer user_data) toread = MIN(256 - op-offset % 256, op-num_bytes - op-current * 256); } else { - bufoff = (op-current - start_block - 1) * 256 + - op-offset % 256; + bufoff = op-current * 256; seekoff = SIM_CACHE_HEADER_SIZE + op-current * 256; toread = MIN(256, op-num_bytes - op-current * 256); } Denis - any feedback on this patch? If we don't add this bugfix, reads 256 bytes will be broken. Thanks, Kristen ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] simfs: fix incorrect math again
--- src/simfs.c |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/simfs.c b/src/simfs.c index fd768ef..bcb6ff8 100644 --- a/src/simfs.c +++ b/src/simfs.c @@ -231,8 +231,7 @@ static void sim_fs_op_read_block_cb(const struct ofono_error *error, tocopy = MIN(256 - op-offset % 256, op-num_bytes - op-current * 256); } else { - bufoff = (op-current - start_block - 1) * 256 + - op-offset % 256; + bufoff = op-current * 256; dataoff = 0; tocopy = MIN(256, op-num_bytes - op-current * 256); } @@ -294,8 +293,7 @@ static gboolean sim_fs_op_read_block(gpointer user_data) toread = MIN(256 - op-offset % 256, op-num_bytes - op-current * 256); } else { - bufoff = (op-current - start_block - 1) * 256 + - op-offset % 256; + bufoff = op-current * 256; seekoff = SIM_CACHE_HEADER_SIZE + op-current * 256; toread = MIN(256, op-num_bytes - op-current * 256); } -- 1.7.2.3 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/4] simfs: cache images
--- src/simfs.c | 62 +++ src/simfs.h |4 +++ 2 files changed, 66 insertions(+), 0 deletions(-) diff --git a/src/simfs.c b/src/simfs.c index b5b12b4..5fbee8b 100644 --- a/src/simfs.c +++ b/src/simfs.c @@ -47,6 +47,7 @@ #define SIM_CACHE_PATH SIM_CACHE_BASEPATH /%04x #define SIM_CACHE_HEADER_SIZE 38 #define SIM_FILE_INFO_SIZE 6 +#define SIM_IMAGE_CACHE_PATH STORAGEDIR /%s-%i/images/%d.xpm #define SIM_FS_VERSION 1 @@ -722,6 +723,67 @@ int sim_fs_write(struct sim_fs *fs, int id, ofono_sim_file_write_cb_t cb, return 0; } +void sim_fs_cache_image(struct sim_fs *fs, const char *image, int id) +{ + const char *imsi; + enum ofono_sim_phase phase; + + if (fs == NULL || image == NULL) + return; + + imsi = ofono_sim_get_imsi(fs-sim); + phase = ofono_sim_get_phase(fs-sim); + + if (imsi) + write_file((const unsigned char *) image, strlen(image), + SIM_CACHE_MODE, SIM_IMAGE_CACHE_PATH, imsi, + phase, id); +} + +char *sim_fs_get_cached_image(struct sim_fs *fs, int id) +{ + const char *imsi; + enum ofono_sim_phase phase; + unsigned short image_length; + int fd; + char *buffer; + char *path; + int len; + struct stat st_buf; + + if (fs == NULL) + return NULL; + + imsi = ofono_sim_get_imsi(fs-sim); + phase = ofono_sim_get_phase(fs-sim); + + path = g_strdup_printf(SIM_IMAGE_CACHE_PATH, imsi, phase, id); + + TFR(stat(path, st_buf)); + + fd = TFR(open(path, O_RDONLY)); + + g_free(path); + + if (fd 0) + return NULL; + + image_length = st_buf.st_size; + + buffer = g_try_malloc0(image_length + 1); + + len = TFR(read(fd, buffer, image_length)); + + TFR(close(fd)); + + if (len != image_length) { + g_free(buffer); + return NULL; + } + + return buffer; +} + static void remove_cachefile(const char *imsi, enum ofono_sim_phase phase, const struct dirent *file) { diff --git a/src/simfs.h b/src/simfs.h index 6d5dded..c0b4c51 100644 --- a/src/simfs.h +++ b/src/simfs.h @@ -35,4 +35,8 @@ int sim_fs_write(struct sim_fs *fs, 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); +char *sim_fs_get_cached_image(struct sim_fs *fs, int id); + +void sim_fs_cache_image(struct sim_fs *fs, const char *image, int id); + void sim_fs_free(struct sim_fs *fs); -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/4] Icon patches (rebased)
Rebased old patch. Found some errors that had been introduced into the simfs code. Added file type to simutil, although I couldn't test it on any real hardware. Kristen Carlson Accardi (4): simfs: cache images sim: implement GetIcon simfs: fix incorrect math when calculating length to copy simutil: add file type for EFimg src/sim.c | 187 + src/simfs.c | 83 ++--- src/simfs.h |4 + src/simutil.c |1 + 4 files changed, 266 insertions(+), 9 deletions(-) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/4] sim: implement GetIcon
--- src/sim.c | 187 + 1 files changed, 187 insertions(+), 0 deletions(-) diff --git a/src/sim.c b/src/sim.c index 6f10d4c..a671a8d 100644 --- a/src/sim.c +++ b/src/sim.c @@ -43,6 +43,7 @@ #include simutil.h #include storage.h #include simfs.h +#include stkutil.h static GSList *g_drivers = NULL; @@ -721,6 +722,190 @@ static DBusMessage *sim_enter_pin(DBusConnection *conn, DBusMessage *msg, return NULL; } +static void sim_get_image_cb(gboolean 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); +} + +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; + 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) { + sim_get_image_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 (xpm == NULL) { + sim_get_image_cb(0, NULL, 0, image-user_data); + goto iidf_read_out; + } + + sim_fs_cache_image(sim-simfs, (const char *) xpm, + image-id); + + sim_get_image_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, + offset, image-clut_len, + sim_iidf_read_cb, image); + + return; + +iidf_read_out: + g_free(image-image); + g_free(image); +} + +static void sim_get_image(struct ofono_sim *sim, unsigned char id, + gpointer user_data) +{ + struct image_data *data; + unsigned char *efimg; + char *image; + + /* icon ids should start at 1, our array starts at zero */ + if (id == 0) { + sim_get_image_cb(0, NULL, 0, user_data); + return; + } + + id--; + + image = sim_fs_get_cached_image(sim-simfs, id); + + if (image == NULL) + goto read_image; + + sim_get_image_cb(1, image, strlen(image), user_data); + + g_free(image); + + return; + +read_image: + + if (sim-efimg_length = (id * 9)) { + sim_get_image_cb(0, 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_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, +
[PATCH 3/4] simfs: fix incorrect math when calculating length to copy
--- src/simfs.c | 21 - 1 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/simfs.c b/src/simfs.c index 5fbee8b..bfcdf23 100644 --- a/src/simfs.c +++ b/src/simfs.c @@ -229,14 +229,16 @@ static void sim_fs_op_read_block_cb(const struct ofono_error *error, if (op-current == start_block) { bufoff = 0; dataoff = op-offset % 256; - tocopy = MIN(256 - op-offset % 256, len); } else { - bufoff = (op-current - start_block - 1) * 256 + - op-offset % 256; + bufoff = op-current * 256; dataoff = 0; - tocopy = len; } + tocopy = op-num_bytes % 256; + + if ((tocopy == 0) || (op-current != end_block)) + tocopy = 256; + memcpy(fs-buffer + bufoff, data + dataoff, tocopy); cache_block(fs, op-current, 256, data, len); @@ -288,15 +290,16 @@ static gboolean sim_fs_op_read_block(gpointer user_data) bufoff = 0; seekoff = SIM_CACHE_HEADER_SIZE + op-current * 256 + op-offset % 256; - toread = MIN(256 - op-offset % 256, - op-length - op-current * 256); } else { - bufoff = (op-current - start_block - 1) * 256 + - op-offset % 256; + bufoff = op-current * 256; seekoff = SIM_CACHE_HEADER_SIZE + op-current * 256; - toread = MIN(256, op-length - op-current * 256); } + toread = op-num_bytes % 256; + + if ((toread == 0) || (op-current != end_block)) + toread = 256; + if (lseek(fs-fd, seekoff, SEEK_SET) == (off_t) -1) break; -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 4/4] simutil: add file type for EFimg
--- src/simutil.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/simutil.c b/src/simutil.c index 65ce1ac..ed0970c 100644 --- a/src/simutil.c +++ b/src/simutil.c @@ -69,6 +69,7 @@ static struct sim_ef_info ef_db[] = { { 0x2F05, ROOTMF, BINARY, 0, ALW,PIN }, { 0x2F06, ROOTMF, RECORD, 0, ALW,PIN }, { 0x2FE2, ROOTMF, BINARY, 10, ALW,NEV }, +{ 0x4F20, 0x5F50, BINARY, 0, PIN,ADM }, { 0x6F05, 0x7F20, BINARY, 0, ALW,PIN }, { 0x6F06, 0x, RECORD, 0, ALW,ADM }, { 0x6F2C, 0x7F20, BINARY, 16, PIN,PIN }, -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] TODO: update owner persist outgoing SMS messages task
--- TODO |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/TODO b/TODO index c4853ad..0c39da4 100644 --- a/TODO +++ b/TODO @@ -78,6 +78,7 @@ SMS Priority: High Complexity: C1 + Owner: Kristen Carlson Accardi kris...@linux.intel.com - Better unique ID for incoming / outgoing messages. Currently oFono uses a simple incremental counter stored in the settings store (NextMessageId). -- 1.7.2.2 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/3] sim: read EFiidf
EFiidf can be larger than 256 bytes, so allow callers to read portions of the EFiidf from a specified offset. Cache EFiidf files as blocks of 256 bytes so that it's not necessary to read the entire (potentially large) file. --- include/sim.h |4 + src/sim.c | 305 ++--- 2 files changed, 297 insertions(+), 12 deletions(-) diff --git a/include/sim.h b/include/sim.h index 36a99b9..67f8a6e 100644 --- a/include/sim.h +++ b/include/sim.h @@ -202,6 +202,10 @@ 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); + +int ofono_sim_read_bytes(struct ofono_sim *sim, int id, + unsigned short offset, int num_bytes, + ofono_sim_file_read_cb_t cb, void *data); #ifdef __cplusplus } #endif diff --git a/src/sim.c b/src/sim.c index f8884a2..bbcf609 100644 --- a/src/sim.c +++ b/src/sim.c @@ -46,7 +46,8 @@ #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_CACHE_HEADER_SIZE 38 +#define SIM_FILE_INFO_SIZE 6 static GSList *g_drivers = NULL; @@ -55,11 +56,14 @@ static gboolean sim_op_retrieve_next(gpointer user); static void sim_own_numbers_update(struct ofono_sim *sim); 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); struct sim_file_op { int id; gboolean cache; enum ofono_sim_file_structure structure; + unsigned short offset; + int num_bytes; int length; int record_length; int current; @@ -1517,23 +1521,45 @@ static void sim_op_error(struct ofono_sim *sim) } static gboolean cache_record(const char *path, int current, int record_len, - const unsigned char *data) + const unsigned char *data, int num_bytes, + enum ofono_sim_file_structure type) { int r = 0; int fd; - fd = TFR(open(path, O_WRONLY)); + fd = TFR(open(path, O_RDWR)); if (fd == -1) return FALSE; if (lseek(fd, (current - 1) * record_len + SIM_CACHE_HEADER_SIZE, SEEK_SET) != (off_t) -1) - r = TFR(write(fd, data, record_len)); + r = TFR(write(fd, data, num_bytes)); + + /* update present bit for this block if we are a transparent file */ + if (type == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) { + /* figure out which byte the right bit location is */ + int byte = (current - 1) / 8; + int bit = (current - 1) % 8; + guint8 cache; + + /* lseek to correct byte (skip file info) */ + lseek(fd, byte + SIM_FILE_INFO_SIZE, SEEK_SET); + + /* read byte */ + TFR(read(fd, cache, 1)); + + /* set present bit */ + cache |= (1 bit); + + /* write back */ + lseek(fd, byte + SIM_FILE_INFO_SIZE, SEEK_SET); + TFR(write(fd, cache, 1)); + } TFR(close(fd)); - if (r record_len) { + if (r num_bytes) { unlink(path); return FALSE; } @@ -1562,7 +1588,8 @@ static void sim_op_retrieve_cb(const struct ofono_error *error, imsi, sim-phase, op-id); op-cache = cache_record(path, op-current, op-record_length, - data); + data, op-record_length, + op-structure); g_free(path); } @@ -1667,12 +1694,17 @@ static void sim_op_info_cb(const struct ofono_error *error, int length, else op-record_length = record_length; - op-current = 1; - - sim-simop_source = g_timeout_add(0, sim_op_retrieve_next, sim); + if (op-num_bytes 0) + sim-simop_source = g_timeout_add(0, sim_op_read_block, sim); + else { + op-current = 1; + sim-simop_source = g_timeout_add(0, sim_op_retrieve_next, sim); + } if (op-cache imsi) { - unsigned char fileinfo[6]; + unsigned char fileinfo[SIM_CACHE_HEADER_SIZE]; + + memset(fileinfo, 0, SIM_CACHE_HEADER_SIZE); fileinfo[0] = error-type; fileinfo[1] = length 8; @@ -1681,8 +1713,9 @@ static void sim_op_info_cb(const struct ofono_error *error, int length, fileinfo[4] =
[PATCH 2/3] sim: Implement GetIcon
--- src/sim.c | 220 + 1 files changed, 220 insertions(+), 0 deletions(-) diff --git a/src/sim.c b/src/sim.c index bbcf609..d8c0d37 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 38 #define SIM_FILE_INFO_SIZE 6 +#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 (*sim_get_image_cb_t)(int ok, const char *xpm, int xpm_len, + void *user_data); +static void sim_get_image(struct ofono_sim *sim, unsigned char id, + sim_get_image_cb_t cb, gpointer user_data); + struct sim_file_op { int id; gboolean cache; @@ -93,6 +100,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]; @@ -736,6 +744,50 @@ static DBusMessage *sim_enter_pin(DBusConnection *conn, DBusMessage *msg, return NULL; } +static void 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); + + sim_get_image(sim, id, sim_get_image_cb, sim); + + return NULL; +} + static DBusMessage *sim_reset_pin(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -788,6 +840,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 }, { } }; @@ -2549,3 +2603,169 @@ 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; + 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, +
[PATCH 3/3] test: add get-icon script
--- test/get-icon | 25 + 1 files changed, 25 insertions(+), 0 deletions(-) create mode 100755 test/get-icon diff --git a/test/get-icon b/test/get-icon new file mode 100755 index 000..680ae13 --- /dev/null +++ b/test/get-icon @@ -0,0 +1,25 @@ +#!/usr/bin/python + +import dbus +import sys + +bus = dbus.SystemBus() + +if len(sys.argv) == 3: + path = sys.argv[1] + id = int(sys.argv[2], 16) +elif len(sys.argv) == 2: + manager = dbus.Interface(bus.get_object('org.ofono', '/'), +'org.ofono.Manager') + properties = manager.GetProperties() + path = properties[Modems][0] + id = int(sys.argv[1], 16) +else: + print %s [PATH] icon_id % (sys.argv[0]) + +simmanager = dbus.Interface(bus.get_object('org.ofono', path), + 'org.ofono.SimManager') + +xpm = simmanager.GetIcon(id) + +print Received xpm: %s % (xpm) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] todo: remove owner from notify_ready task
--- TODO |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/TODO b/TODO index a97f076..97f43e1 100644 --- a/TODO +++ b/TODO @@ -158,7 +158,6 @@ SIM / SIM File system Priority: High Complexity: C2 - Owner: Kristen Carlson Accardi kris...@linux.intel.com Modem Emulator -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/4] sim: read EFimg
--- src/sim.c | 50 ++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/src/sim.c b/src/sim.c index 04a708b..f8884a2 100644 --- a/src/sim.c +++ b/src/sim.c @@ -88,6 +88,8 @@ struct ofono_sim { unsigned char efmsisdn_records; unsigned char *efli; unsigned char efli_length; + unsigned char *efimg; + int efimg_length; enum ofono_sim_cphs_phase cphs_phase; unsigned char cphs_service_table[2]; struct ofono_watchlist *state_watches; @@ -958,6 +960,47 @@ static void sim_own_numbers_update(struct ofono_sim *sim) sim_msisdn_read_cb, sim); } +static void sim_efimg_read_cb(int ok, int length, int record, + const unsigned char *data, + int record_length, void *userdata) +{ + struct ofono_sim *sim = userdata; + unsigned char *efimg; + int num_records; + + if (!ok) + return; + + num_records = length / record_length; + + /* +* EFimg descriptors are 9 bytes long. +* Byte 1 of the record is the number of descriptors per record. +*/ + if ((record_length 10) || + ((record_length % 9 != 2) (record_length % 9 != 1))) + return; + + if (sim-efimg == NULL) { + sim-efimg = g_try_malloc0(num_records * 9); + + if (sim-efimg == NULL) + return; + + sim-efimg_length = num_records * 9; + } + + /* +* TBD - if we have more than one descriptor per record, +* pick the nicest one. For now we use the first one. +*/ + + /* copy descriptor into slot for this record */ + efimg = sim-efimg[(record - 1) * 9]; + + memcpy(efimg, data[1], 9); +} + static void sim_ready(void *user, enum ofono_sim_state new_state) { struct ofono_sim *sim = user; @@ -969,6 +1012,8 @@ static void sim_ready(void *user, enum ofono_sim_state new_state) ofono_sim_read(sim, SIM_EFSDN_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED, sim_sdn_read_cb, sim); + ofono_sim_read(sim, SIM_EFIMG_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED, + sim_efimg_read_cb, sim); } static void sim_imsi_cb(const struct ofono_error *error, const char *imsi, @@ -2002,6 +2047,11 @@ static void sim_free_state(struct ofono_sim *sim) } sim-mnc_length = 0; + + if (sim-efimg) { + g_free(sim-efimg); + sim-efimg = NULL; + } } void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH v2 0/6] icon support patches
Changes from last version: * bugfix in patch 3, read EFimg, sim_efimg_read_cb. Don't calculate num_records without first checking for ok * bugfix in patch 5, implement GetIcon, ofono_sim_get_image When calling back with error, use 0 as error code, not -1 Kristen Carlson Accardi (6): simutil: add fileid for EFimg stkutil: change uint32_t to guint32 sim: read EFimg sim: read EFiidf sim: implement GetIcon test: add get-icon script src/sim.c | 466 - src/simutil.h |1 + src/stkutil.h |2 +- test/get-icon | 25 +++ 4 files changed, 490 insertions(+), 4 deletions(-) create mode 100755 test/get-icon -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/6] simutil: add fileid for EFimg
--- src/simutil.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/simutil.h b/src/simutil.h index 4db950b..65e651a 100644 --- a/src/simutil.h +++ b/src/simutil.h @@ -22,6 +22,7 @@ enum sim_fileid { SIM_EFPL_FILEID = 0x2f05, SIM_EF_ICCID_FILEID = 0x2fe2, + SIM_EFIMG_FILEID = 0x4F20, SIM_EFLI_FILEID = 0x6f05, SIM_EF_CPHS_MWIS_FILEID = 0x6f11, SIM_EF_CPHS_INFORMATION_FILEID = 0x6f16, -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/6] stkutil: change uint32_t to guint32
This helps avoid needing to include any extra header files if stkutil.h is included in sim.c --- src/stkutil.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/stkutil.h b/src/stkutil.h index ea9294c..44d167a 100644 --- a/src/stkutil.h +++ b/src/stkutil.h @@ -852,7 +852,7 @@ struct stk_card_reader_id { struct stk_other_address { union { /* Network Byte Order */ - uint32_t ipv4; + guint32 ipv4; unsigned char ipv6[16]; } addr; enum stk_address_type type; -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 3/6] sim: read EFimg
--- src/sim.c | 49 + 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/src/sim.c b/src/sim.c index 04a708b..b273bdb 100644 --- a/src/sim.c +++ b/src/sim.c @@ -88,6 +88,8 @@ struct ofono_sim { unsigned char efmsisdn_records; unsigned char *efli; unsigned char efli_length; + unsigned char *efimg; + int efimg_length; enum ofono_sim_cphs_phase cphs_phase; unsigned char cphs_service_table[2]; struct ofono_watchlist *state_watches; @@ -958,6 +960,46 @@ static void sim_own_numbers_update(struct ofono_sim *sim) sim_msisdn_read_cb, sim); } +static void sim_efimg_read_cb(int ok, int length, int record, + const unsigned char *data, + int record_length, void *userdata) +{ + struct ofono_sim *sim = userdata; + unsigned char *efimg; + int num_records; + + if (!ok) + return; + + num_records = length / record_length; + + /* +* EFimg descriptors are 9 bytes long. +* Byte 1 of the record is the number of descriptors per record. +*/ + if (record_length 10) + return; + + if (sim-efimg == NULL) { + sim-efimg = g_try_malloc0(num_records * 9); + + if (sim-efimg == NULL) + return; + + sim-efimg_length = num_records * 9; + } + + /* +* TBD - if we have more than one descriptor per record, +* pick the nicest one. For now we use the first one. +*/ + + /* copy descriptor into slot for this record */ + efimg = sim-efimg[(record - 1) * 9]; + + memcpy(efimg, data[1], 9); +} + static void sim_ready(void *user, enum ofono_sim_state new_state) { struct ofono_sim *sim = user; @@ -969,6 +1011,8 @@ static void sim_ready(void *user, enum ofono_sim_state new_state) ofono_sim_read(sim, SIM_EFSDN_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED, sim_sdn_read_cb, sim); + ofono_sim_read(sim, SIM_EFIMG_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED, + sim_efimg_read_cb, sim); } static void sim_imsi_cb(const struct ofono_error *error, const char *imsi, @@ -2002,6 +2046,11 @@ static void sim_free_state(struct ofono_sim *sim) } sim-mnc_length = 0; + + if (sim-efimg) { + g_free(sim-efimg); + sim-efimg = NULL; + } } void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 4/6] sim: read EFiidf
EFiidf can be larger than 256 bytes, so allow callers to read portions of the EFiidf from a specified offset. Cache EFiidf files as blocks of 256 bytes so that it's not necessary to read the entire (potentially large) file. --- src/sim.c | 201 - 1 files changed, 198 insertions(+), 3 deletions(-) diff --git a/src/sim.c b/src/sim.c index b273bdb..a9557fc 100644 --- a/src/sim.c +++ b/src/sim.c @@ -47,6 +47,7 @@ #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 static GSList *g_drivers = NULL; @@ -55,16 +56,20 @@ static gboolean sim_op_retrieve_next(gpointer user); static void sim_own_numbers_update(struct ofono_sim *sim); 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); struct sim_file_op { int id; gboolean cache; enum ofono_sim_file_structure structure; + unsigned short offset; + int num_bytes; int length; int record_length; int current; gconstpointer cb; gboolean is_read; + gboolean is_image; void *buffer; void *userdata; }; @@ -1666,9 +1671,13 @@ static void sim_op_info_cb(const struct ofono_error *error, int length, else op-record_length = record_length; - op-current = 1; - sim-simop_source = g_timeout_add(0, sim_op_retrieve_next, sim); + if (op-is_image) + sim-simop_source = g_timeout_add(0, sim_op_read_block, sim); + else { + op-current = 1; + sim-simop_source = g_timeout_add(0, sim_op_retrieve_next, sim); + } if (op-cache imsi) { unsigned char fileinfo[6]; @@ -1750,6 +1759,12 @@ static gboolean sim_op_check_cached(struct ofono_sim *sim) structure = fileinfo[3]; record_length = (fileinfo[4] 8) | fileinfo[5]; + if (op-is_image) { + op-length = file_length; + ret = TRUE; + goto cleanup; + } + if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) record_length = file_length; @@ -1789,6 +1804,170 @@ cleanup: return ret; } +static void sim_op_read_block_cb(const struct ofono_error *error, + const unsigned char *data, int len, void *user) +{ + struct ofono_sim *sim = user; + struct sim_file_op *op = g_queue_peek_head(sim-simop_q); + int start_block, end_block; + int start, length; + unsigned char *buf; + + if ((error-type != OFONO_ERROR_TYPE_NO_ERROR) || (len == 0)) { + sim_op_error(sim); + return; + } + + /* cache this block */ + write_file(data, len, SIM_CACHE_MODE, SIM_IIDF_CACHE_PATH, + sim-imsi, sim-phase, op-id, op-current); + + /* buffer this block */ + start_block = op-offset / 256; + end_block = (op-offset + (op-num_bytes - 1)) / 256; + + if (op-current == start_block) { + start = op-offset % 256; + buf = op-buffer; + } else { + start = 0; + buf = op-buffer + (op-current * 256); + } + + length = op-num_bytes % 256; + + if ((length == 0) || (op-current != end_block)) + length = 256; + + memcpy(buf, data[start], length); + + op-current++; + + sim-simop_source = g_timeout_add(0, sim_op_read_block, sim); +} + +static gboolean sim_op_check_cached_block(struct ofono_sim *sim) +{ + struct sim_file_op *op = g_queue_peek_head(sim-simop_q); + char *path; + int fd; + char *imsi = sim-imsi; + int start_block, end_block; + int start, length, len; + unsigned char *buf; + + if (!imsi) + return FALSE; + + path = g_strdup_printf(SIM_IIDF_CACHE_PATH, imsi, sim-phase, op-id, + op-current); + + if (path == NULL) + return FALSE; + + fd = TFR(open(path, O_RDONLY)); + g_free(path); + + if (fd == -1) { + if (errno != ENOENT) + DBG(Error %i opening cache file for + fileid %04x, IMSI %s, + errno, op-id, imsi); + + return FALSE; + } + + /* figure out where we should start reading from */ + start_block = op-offset / 256; + end_block = (op-offset + (op-num_bytes - 1)) / 256; + + if (op-current == start_block) { + start = op-offset % 256; + buf = op-buffer; + } else { + start = 0; + buf = op-buffer + (op-current * 256); + } + +
[PATCH 5/6] sim: implement GetIcon
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 a9557fc..b4468ca 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]; @@ -737,6 +745,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) { @@ -789,6 +841,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 }, { } }; @@ -2462,3 +2516,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); +
[PATCH 6/6] test: add get-icon script
--- test/get-icon | 25 + 1 files changed, 25 insertions(+), 0 deletions(-) create mode 100755 test/get-icon diff --git a/test/get-icon b/test/get-icon new file mode 100755 index 000..680ae13 --- /dev/null +++ b/test/get-icon @@ -0,0 +1,25 @@ +#!/usr/bin/python + +import dbus +import sys + +bus = dbus.SystemBus() + +if len(sys.argv) == 3: + path = sys.argv[1] + id = int(sys.argv[2], 16) +elif len(sys.argv) == 2: + manager = dbus.Interface(bus.get_object('org.ofono', '/'), +'org.ofono.Manager') + properties = manager.GetProperties() + path = properties[Modems][0] + id = int(sys.argv[1], 16) +else: + print %s [PATH] icon_id % (sys.argv[0]) + +simmanager = dbus.Interface(bus.get_object('org.ofono', path), + 'org.ofono.SimManager') + +xpm = simmanager.GetIcon(id) + +print Received xpm: %s % (xpm) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/2] ofono_sim_ready_notify
When entering a PIN, wait for the driver to notify us that the sim is ready before querying the password again and proceeding with the rest of sim initialization Kristen Carlson Accardi (2): sim: add ofono_sim_ready_notify() support atmodem: call sim_ready_notify when epev is received drivers/atmodem/sim.c | 12 include/sim.h |2 ++ src/sim.c | 25 +++-- 3 files changed, 33 insertions(+), 6 deletions(-) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/2] sim: add ofono_sim_ready_notify() support
--- include/sim.h |2 ++ src/sim.c | 25 +++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/sim.h b/include/sim.h index 36a99b9..9b7d52e 100644 --- a/include/sim.h +++ b/include/sim.h @@ -187,6 +187,8 @@ enum ofono_sim_state ofono_sim_get_state(struct ofono_sim *sim); void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted); +void ofono_sim_ready_notify(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 diff --git a/src/sim.c b/src/sim.c index 04a708b..b76a263 100644 --- a/src/sim.c +++ b/src/sim.c @@ -56,6 +56,9 @@ static void sim_own_numbers_update(struct ofono_sim *sim); static void sim_pin_check(struct ofono_sim *sim); static void sim_set_ready(struct ofono_sim *sim); +#define SIM_STATUS_READY 1 +#define SIM_STATUS_WAITING_FOR_READY (1 1) + struct sim_file_op { int id; gboolean cache; @@ -78,6 +81,7 @@ struct ofono_sim { GSList *new_numbers; GSList *service_numbers; gboolean sdn_ready; + unsigned int status; enum ofono_sim_state state; enum ofono_sim_password_type pin_type; gboolean locked_pins[OFONO_SIM_PASSWORD_SIM_PUK]; /* Number of PINs */ @@ -686,15 +690,20 @@ static void sim_enter_pin_cb(const struct ofono_error *error, void *data) { struct ofono_sim *sim = data; DBusMessage *reply; + gboolean ok = (error-type == OFONO_ERROR_TYPE_NO_ERROR); - if (error-type != OFONO_ERROR_TYPE_NO_ERROR) + if (!ok) reply = __ofono_error_failed(sim-pending); else reply = dbus_message_new_method_return(sim-pending); __ofono_dbus_pending_reply(sim-pending, reply); - sim_pin_check(sim); + if (ok (sim-status SIM_STATUS_READY)) { + sim-status = ~SIM_STATUS_WAITING_FOR_READY; + sim_pin_check(sim); + } else + sim-status |= SIM_STATUS_WAITING_FOR_READY; } static DBusMessage *sim_enter_pin(DBusConnection *conn, DBusMessage *msg, @@ -2002,6 +2011,18 @@ static void sim_free_state(struct ofono_sim *sim) } sim-mnc_length = 0; + + sim-status = 0; +} + +void ofono_sim_ready_notify(struct ofono_sim *sim) +{ + sim-status |= SIM_STATUS_READY; + + if (sim-status SIM_STATUS_WAITING_FOR_READY) { + sim-status = ~SIM_STATUS_WAITING_FOR_READY; + sim_pin_check(sim); + } } void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/2] atmodem: call sim_ready_notify when epev is received
--- drivers/atmodem/sim.c | 12 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c index 21bc933..44ecc1a 100644 --- a/drivers/atmodem/sim.c +++ b/drivers/atmodem/sim.c @@ -537,13 +537,16 @@ static gboolean at_epev_unregister(gpointer user_data) static void at_epev_notify(GAtResult *result, gpointer user_data) { struct cb_data *cbd = user_data; - struct sim_data *sd = cbd-user; + struct ofono_sim *sim = cbd-user; + struct sim_data *sd = ofono_sim_get_data(sim); ofono_sim_lock_unlock_cb_t cb = cbd-cb; struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR }; if (sd-epev_source) return; + ofono_sim_ready_notify(sim); + cb(error, cbd-data); sd-epev_source = g_timeout_add(0, at_epev_unregister, sd); @@ -553,7 +556,8 @@ static void at_pin_send_cb(gboolean ok, GAtResult *result, gpointer user_data) { struct cb_data *cbd = user_data; - struct sim_data *sd = cbd-user; + struct ofono_sim *sim = cbd-user; + struct sim_data *sd = ofono_sim_get_data(sim); ofono_sim_lock_unlock_cb_t cb = cbd-cb; struct ofono_error error; @@ -590,15 +594,15 @@ static void at_lock_unlock_cb(gboolean ok, GAtResult *result, static void at_pin_send(struct ofono_sim *sim, const char *passwd, ofono_sim_lock_unlock_cb_t cb, void *data) { - struct sim_data *sd = ofono_sim_get_data(sim); struct cb_data *cbd = cb_data_new(cb, data); + struct sim_data *sd = ofono_sim_get_data(sim); char buf[64]; int ret; if (!cbd) goto error; - cbd-user = sd; + cbd-user = sim; snprintf(buf, sizeof(buf), AT+CPIN=\%s\, passwd); -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 4/6] sim: read EFiidf
On Wed, 25 Aug 2010 16:17:13 -0500 Denis Kenzior denk...@gmail.com wrote: From: Denis Kenzior denk...@gmail.com To: ofono@ofono.org CC: Kristen Carlson Accardi kris...@linux.intel.com, Andrzej Zaborowski andrew.zaborow...@intel.com Subject: Re: [PATCH 4/6] sim: read EFiidf Date: Wed, 25 Aug 2010 16:17:13 -0500 User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100528 Lightning/1.0b1 Thunderbird/3.0.5 Hi Kristen, On 08/25/2010 06:00 AM, Kristen Carlson Accardi wrote: EFiidf can be larger than 256 bytes, so allow callers to read portions of the EFiidf from a specified offset. Cache EFiidf files as blocks of 256 bytes so that it's not necessary to read the entire (potentially large) file. --- src/sim.c | 201 - 1 files changed, 198 insertions(+), 3 deletions(-) diff --git a/src/sim.c b/src/sim.c index b273bdb..a9557fc 100644 --- a/src/sim.c +++ b/src/sim.c @@ -47,6 +47,7 @@ #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 static GSList *g_drivers = NULL; @@ -55,16 +56,20 @@ static gboolean sim_op_retrieve_next(gpointer user); static void sim_own_numbers_update(struct ofono_sim *sim); 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); struct sim_file_op { int id; gboolean cache; enum ofono_sim_file_structure structure; + unsigned short offset; + int num_bytes; int length; int record_length; int current; gconstpointer cb; gboolean is_read; + gboolean is_image; void *buffer; void *userdata; }; @@ -1666,9 +1671,13 @@ static void sim_op_info_cb(const struct ofono_error *error, int length, else op-record_length = record_length; - op-current = 1; - sim-simop_source = g_timeout_add(0, sim_op_retrieve_next, sim); + if (op-is_image) + sim-simop_source = g_timeout_add(0, sim_op_read_block, sim); + else { + op-current = 1; + sim-simop_source = g_timeout_add(0, sim_op_retrieve_next, sim); + } if (op-cache imsi) { unsigned char fileinfo[6]; @@ -1750,6 +1759,12 @@ static gboolean sim_op_check_cached(struct ofono_sim *sim) structure = fileinfo[3]; record_length = (fileinfo[4] 8) | fileinfo[5]; + if (op-is_image) { + op-length = file_length; + ret = TRUE; + goto cleanup; + } + if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) record_length = file_length; @@ -1789,6 +1804,170 @@ cleanup: return ret; } +static void sim_op_read_block_cb(const struct ofono_error *error, + const unsigned char *data, int len, void *user) +{ + struct ofono_sim *sim = user; + struct sim_file_op *op = g_queue_peek_head(sim-simop_q); + int start_block, end_block; + int start, length; + unsigned char *buf; + + if ((error-type != OFONO_ERROR_TYPE_NO_ERROR) || (len == 0)) { + sim_op_error(sim); + return; + } + + /* cache this block */ + write_file(data, len, SIM_CACHE_MODE, SIM_IIDF_CACHE_PATH, + sim-imsi, sim-phase, op-id, op-current); + + /* buffer this block */ + start_block = op-offset / 256; + end_block = (op-offset + (op-num_bytes - 1)) / 256; + + if (op-current == start_block) { + start = op-offset % 256; + buf = op-buffer; + } else { + start = 0; + buf = op-buffer + (op-current * 256); + } + + length = op-num_bytes % 256; + + if ((length == 0) || (op-current != end_block)) + length = 256; + + memcpy(buf, data[start], length); + + op-current++; + + sim-simop_source = g_timeout_add(0, sim_op_read_block, sim); +} + +static gboolean sim_op_check_cached_block(struct ofono_sim *sim) +{ + struct sim_file_op *op = g_queue_peek_head(sim-simop_q); + char *path; + int fd; + char *imsi = sim-imsi; + int start_block, end_block; + int start, length, len; + unsigned char *buf; + + if (!imsi) + return FALSE; + + path = g_strdup_printf(SIM_IIDF_CACHE_PATH, imsi, sim-phase, op-id, + op-current); My initial feeling is that we should treat blocks just like we treat records today. We should not write them to separate files. Can we unify the two approaches somehow? Perhaps by storing a bitmap in the cache header, and update the bitmap every time we write the record / block to the cache. We can use idmap.c
[PATCH 1/4] sim: read EFimg
--- src/sim.c | 49 + 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/src/sim.c b/src/sim.c index 04a708b..dc47901 100644 --- a/src/sim.c +++ b/src/sim.c @@ -88,6 +88,8 @@ struct ofono_sim { unsigned char efmsisdn_records; unsigned char *efli; unsigned char efli_length; + unsigned char *efimg; + int efimg_length; enum ofono_sim_cphs_phase cphs_phase; unsigned char cphs_service_table[2]; struct ofono_watchlist *state_watches; @@ -958,6 +960,46 @@ static void sim_own_numbers_update(struct ofono_sim *sim) sim_msisdn_read_cb, sim); } +static void sim_efimg_read_cb(int ok, int length, int record, + const unsigned char *data, + int record_length, void *userdata) +{ + struct ofono_sim *sim = userdata; + unsigned char *efimg; + int num_records; + + if (!ok) + return; + + num_records = length / record_length; + + /* +* EFimg descriptors are 9 bytes long. +* Byte 1 of the record is the number of descriptors per record. +*/ + if ((record_length % 9 != 2) (record_length % 9 != 1)) + return; + + if (sim-efimg == NULL) { + sim-efimg = g_try_malloc0(num_records * 9); + + if (sim-efimg == NULL) + return; + + sim-efimg_length = num_records * 9; + } + + /* +* TBD - if we have more than one descriptor per record, +* pick the nicest one. For now we use the first one. +*/ + + /* copy descriptor into slot for this record */ + efimg = sim-efimg[(record - 1) * 9]; + + memcpy(efimg, data[1], 9); +} + static void sim_ready(void *user, enum ofono_sim_state new_state) { struct ofono_sim *sim = user; @@ -969,6 +1011,8 @@ static void sim_ready(void *user, enum ofono_sim_state new_state) ofono_sim_read(sim, SIM_EFSDN_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED, sim_sdn_read_cb, sim); + ofono_sim_read(sim, SIM_EFIMG_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED, + sim_efimg_read_cb, sim); } static void sim_imsi_cb(const struct ofono_error *error, const char *imsi, @@ -2002,6 +2046,11 @@ static void sim_free_state(struct ofono_sim *sim) } sim-mnc_length = 0; + + if (sim-efimg) { + g_free(sim-efimg); + sim-efimg = NULL; + } } void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/2] sim: add sim_ready_notify
--- include/sim.h |2 ++ src/sim.c | 22 ++ 2 files changed, 24 insertions(+), 0 deletions(-) diff --git a/include/sim.h b/include/sim.h index 36a99b9..9b7d52e 100644 --- a/include/sim.h +++ b/include/sim.h @@ -187,6 +187,8 @@ enum ofono_sim_state ofono_sim_get_state(struct ofono_sim *sim); void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted); +void ofono_sim_ready_notify(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 diff --git a/src/sim.c b/src/sim.c index a450b30..55499fc 100644 --- a/src/sim.c +++ b/src/sim.c @@ -56,6 +56,9 @@ static void sim_own_numbers_update(struct ofono_sim *sim); static void sim_pin_check(struct ofono_sim *sim); static void sim_set_ready(struct ofono_sim *sim); +#define SIM_STATUS_READY 1 +#define SIM_STATUS_WAITING_FOR_PIN (1 1) + struct sim_file_op { int id; gboolean cache; @@ -78,6 +81,7 @@ struct ofono_sim { GSList *new_numbers; GSList *service_numbers; gboolean sdn_ready; + unsigned int status; enum ofono_sim_state state; enum ofono_sim_password_type pin_type; gboolean locked_pins[OFONO_SIM_PASSWORD_SIM_PUK]; /* Number of PINs */ @@ -1191,6 +1195,14 @@ checkdone: static void sim_pin_check(struct ofono_sim *sim) { + if (!(sim-status SIM_STATUS_READY)) { + sim-status |= SIM_STATUS_WAITING_FOR_PIN; + return; + } + + if (sim-status SIM_STATUS_WAITING_FOR_PIN) + sim-status = ~(SIM_STATUS_WAITING_FOR_PIN); + if (!sim-driver-query_passwd_state) { sim_initialize_after_pin(sim); return; @@ -2004,6 +2016,16 @@ static void sim_free_state(struct ofono_sim *sim) } sim-mnc_length = 0; + + sim-status = 0; +} + +void ofono_sim_ready_notify(struct ofono_sim *sim) +{ + sim-status |= SIM_STATUS_READY; + + if (sim-status SIM_STATUS_WAITING_FOR_PIN) + sim_pin_check(sim); } void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/2] mbm: use sim_ready_notify
--- plugins/mbm.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/plugins/mbm.c b/plugins/mbm.c index 8541aaf..5a82bf2 100644 --- a/plugins/mbm.c +++ b/plugins/mbm.c @@ -335,8 +335,11 @@ static void mbm_pre_sim(struct ofono_modem *modem) sim = ofono_sim_create(modem, OFONO_VENDOR_MBM, atmodem, data-modem_port); - if (data-have_sim sim) + if (sim) ofono_sim_inserted_notify(sim, TRUE); + + if (data-have_sim) + ofono_sim_ready_notify(sim); } static void mbm_post_sim(struct ofono_modem *modem) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] todo: add owner for sim ready notification task
--- TODO |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/TODO b/TODO index 97f43e1..a97f076 100644 --- a/TODO +++ b/TODO @@ -158,6 +158,7 @@ SIM / SIM File system Priority: High Complexity: C2 + Owner: Kristen Carlson Accardi kris...@linux.intel.com Modem Emulator -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] simfilesystem: correct sw2 response for binary read
according to spec, sw2 should be the number of bytes read, which is just length. --- src/simfilesystem.cpp |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/simfilesystem.cpp b/src/simfilesystem.cpp index d193328..6e05039 100644 --- a/src/simfilesystem.cpp +++ b/src/simfilesystem.cpp @@ -226,7 +226,7 @@ void SimFileSystem::crsm( const QString args ) sw2 = 0x02; } else if ( length ) { sw1 = 0x9f; -sw2 = length - offset; +sw2 = length; response = QAtUtils::toHex( contents.mid( offset, length ) ); } else { -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/6] simutil: add fileid for EFimg
--- src/simutil.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/simutil.h b/src/simutil.h index 29194ca..1cfc4af 100644 --- a/src/simutil.h +++ b/src/simutil.h @@ -22,6 +22,7 @@ enum sim_fileid { SIM_EFPL_FILEID = 0x2f05, SIM_EF_ICCID_FILEID = 0x2fe2, + SIM_EFIMG_FILEID = 0x4F20, SIM_EFLI_FILEID = 0x6f05, SIM_EF_CPHS_MWIS_FILEID = 0x6f11, SIM_EF_CPHS_INFORMATION_FILEID = 0x6f16, -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/6] stkutil: change uint32_t to guint32
This helps avoid needing to include any extra header files if stkutil.h is included in sim.c --- src/stkutil.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/stkutil.h b/src/stkutil.h index ea9294c..44d167a 100644 --- a/src/stkutil.h +++ b/src/stkutil.h @@ -852,7 +852,7 @@ struct stk_card_reader_id { struct stk_other_address { union { /* Network Byte Order */ - uint32_t ipv4; + guint32 ipv4; unsigned char ipv6[16]; } addr; enum stk_address_type type; -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 3/6] sim: read EFimg
Read EFimg when the sim is ready, and store it in memory. --- src/sim.c | 47 +++ 1 files changed, 47 insertions(+), 0 deletions(-) diff --git a/src/sim.c b/src/sim.c index d2ed780..6d723bb 100644 --- a/src/sim.c +++ b/src/sim.c @@ -88,6 +88,8 @@ struct ofono_sim { unsigned char efmsisdn_records; unsigned char *efli; unsigned char efli_length; + unsigned char *efimg; + int efimg_length; enum ofono_sim_cphs_phase cphs_phase; unsigned char cphs_service_table[2]; struct ofono_watchlist *state_watches; @@ -1001,6 +1003,44 @@ static void sim_own_numbers_update(struct ofono_sim *sim) sim_msisdn_read_cb, sim); } +static void sim_efimg_read_cb(int ok, int length, int record, + const unsigned char *data, + int record_length, void *userdata) +{ + struct ofono_sim *sim = userdata; + unsigned char *efimg; + int num_records = length / record_length; + + if (!ok) + return; + + /* +* EFimg descriptors are 9 bytes long. +* Byte 1 of the record is the number of descriptors per record. +*/ + if (record_length 10) + return; + + if (sim-efimg == NULL) { + sim-efimg = g_try_malloc0(num_records * 9); + + if (sim-efimg == NULL) + return; + + sim-efimg_length = num_records * 9; + } + + /* +* TBD - if we have more than one descriptor per record, +* pick the nicest one. For now we use the first one. +*/ + + /* copy descriptor into slot for this record */ + efimg = sim-efimg[(record - 1) * 9]; + + memcpy(efimg, data[1], 9); +} + static void sim_ready(void *user, enum ofono_sim_state new_state) { struct ofono_sim *sim = user; @@ -1015,6 +1055,8 @@ static void sim_ready(void *user, enum ofono_sim_state new_state) sim_ad_read_cb, sim); ofono_sim_read(sim, SIM_EFSDN_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED, sim_sdn_read_cb, sim); + ofono_sim_read(sim, SIM_EFIMG_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED, + sim_efimg_read_cb, sim); } static void sim_cphs_information_read_cb(int ok, int length, int record, @@ -1934,6 +1976,11 @@ static void sim_free_state(struct ofono_sim *sim) g_strfreev(sim-language_prefs); sim-language_prefs = NULL; } + + if (sim-efimg) { + g_free(sim-efimg); + sim-efimg = NULL; + } } void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 4/6] sim: read EFiidf
EFiidf can be larger than 256 bytes, so allow callers to read portions of the EFiidf from a specified offset. Cache EFiidf files as blocks of 256 bytes so that it's not necessary to read the entire (potentially large) file. --- src/sim.c | 201 - 1 files changed, 198 insertions(+), 3 deletions(-) diff --git a/src/sim.c b/src/sim.c index 6d723bb..d79c5e1 100644 --- a/src/sim.c +++ b/src/sim.c @@ -47,6 +47,7 @@ #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 static GSList *g_drivers = NULL; @@ -55,16 +56,20 @@ static gboolean sim_op_retrieve_next(gpointer user); static void sim_own_numbers_update(struct ofono_sim *sim); 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); struct sim_file_op { int id; gboolean cache; enum ofono_sim_file_structure structure; + unsigned short offset; + int num_bytes; int length; int record_length; int current; gconstpointer cb; gboolean is_read; + gboolean is_image; void *buffer; void *userdata; }; @@ -1610,9 +1615,13 @@ static void sim_op_info_cb(const struct ofono_error *error, int length, else op-record_length = record_length; - op-current = 1; - sim-simop_source = g_timeout_add(0, sim_op_retrieve_next, sim); + if (op-is_image) + sim-simop_source = g_timeout_add(0, sim_op_read_block, sim); + else { + op-current = 1; + sim-simop_source = g_timeout_add(0, sim_op_retrieve_next, sim); + } if (op-cache imsi) { unsigned char fileinfo[6]; @@ -1694,6 +1703,12 @@ static gboolean sim_op_check_cached(struct ofono_sim *sim) structure = fileinfo[3]; record_length = (fileinfo[4] 8) | fileinfo[5]; + if (op-is_image) { + op-length = file_length; + ret = TRUE; + goto cleanup; + } + if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) record_length = file_length; @@ -1733,6 +1748,170 @@ cleanup: return ret; } +static void sim_op_read_block_cb(const struct ofono_error *error, + const unsigned char *data, int len, void *user) +{ + struct ofono_sim *sim = user; + struct sim_file_op *op = g_queue_peek_head(sim-simop_q); + int start_block, end_block; + int start, length; + unsigned char *buf; + + if ((error-type != OFONO_ERROR_TYPE_NO_ERROR) || (len == 0)) { + sim_op_error(sim); + return; + } + + /* cache this block */ + write_file(data, len, SIM_CACHE_MODE, SIM_IIDF_CACHE_PATH, + sim-imsi, sim-phase, op-id, op-current); + + /* buffer this block */ + start_block = op-offset / 256; + end_block = (op-offset + (op-num_bytes - 1)) / 256; + + if (op-current == start_block) { + start = op-offset % 256; + buf = op-buffer; + } else { + start = 0; + buf = op-buffer + (op-current * 256); + } + + length = op-num_bytes % 256; + + if ((length == 0) || (op-current != end_block)) + length = 256; + + memcpy(buf, data[start], length); + + op-current++; + + sim-simop_source = g_timeout_add(0, sim_op_read_block, sim); +} + +static gboolean sim_op_check_cached_block(struct ofono_sim *sim) +{ + struct sim_file_op *op = g_queue_peek_head(sim-simop_q); + char *path; + int fd; + char *imsi = sim-imsi; + int start_block, end_block; + int start, length, len; + unsigned char *buf; + + if (!imsi) + return FALSE; + + path = g_strdup_printf(SIM_IIDF_CACHE_PATH, imsi, sim-phase, op-id, + op-current); + + if (path == NULL) + return FALSE; + + fd = TFR(open(path, O_RDONLY)); + g_free(path); + + if (fd == -1) { + if (errno != ENOENT) + DBG(Error %i opening cache file for + fileid %04x, IMSI %s, + errno, op-id, imsi); + + return FALSE; + } + + /* figure out where we should start reading from */ + start_block = op-offset / 256; + end_block = (op-offset + (op-num_bytes - 1)) / 256; + + if (op-current == start_block) { + start = op-offset % 256; + buf = op-buffer; + } else { + start = 0; + buf = op-buffer + (op-current * 256); + } + +
[PATCH 5/6] sim: implement GetIcon
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); +
[PATCH v2 0/6] Icon support
Changes from last version: * Can now read files 256 bytes * Implemented cache for EFiidf file blocks * Implemented cache for generated xpms * bugfixes and cleanups Kristen Carlson Accardi (6): simutil: add fileid for EFimg stkutil: change uint32_t to guint32 sim: read EFimg sim: read EFiidf sim: implement GetIcon test: add get-icon script src/sim.c | 464 - src/simutil.h |1 + src/stkutil.h |2 +- test/get-icon | 25 +++ 4 files changed, 488 insertions(+), 4 deletions(-) create mode 100755 test/get-icon -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 6/6] test: add get-icon script
--- test/get-icon | 25 + 1 files changed, 25 insertions(+), 0 deletions(-) create mode 100755 test/get-icon diff --git a/test/get-icon b/test/get-icon new file mode 100755 index 000..680ae13 --- /dev/null +++ b/test/get-icon @@ -0,0 +1,25 @@ +#!/usr/bin/python + +import dbus +import sys + +bus = dbus.SystemBus() + +if len(sys.argv) == 3: + path = sys.argv[1] + id = int(sys.argv[2], 16) +elif len(sys.argv) == 2: + manager = dbus.Interface(bus.get_object('org.ofono', '/'), +'org.ofono.Manager') + properties = manager.GetProperties() + path = properties[Modems][0] + id = int(sys.argv[1], 16) +else: + print %s [PATH] icon_id % (sys.argv[0]) + +simmanager = dbus.Interface(bus.get_object('org.ofono', path), + 'org.ofono.SimManager') + +xpm = simmanager.GetIcon(id) + +print Received xpm: %s % (xpm) -- 1.7.2.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/7] add support for icons
This is still a wip, but I wanted to get your feedback on what I've got so far. The patch allow partial reads of files is still pretty much what I had before, so I haven't addressed any of your issues with it. It still doesn't do files 256, and I'm just using the existing read functions with a couple modifications. I've got some outstanding questions that I noted in comments in the patches. These patches do work with phonesim - so you can play with the test script if you feel like it. Kristen Carlson Accardi (7): simutil: add fileid for EFimg stkutil: change uint32_t to guint32 sim: read EFimg sim: allow partial reads of files sim: read an image from an EFiidf sim: implement GetIcon dbus interface test: add get-icon script include/sim.h | 11 +++ src/sim.c | 274 ++-- src/simutil.h |1 + src/stkutil.h |2 +- test/get-icon | 25 + 5 files changed, 302 insertions(+), 11 deletions(-) create mode 100755 test/get-icon ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 4/7] sim: allow partial reads of files
--- include/sim.h |5 + src/sim.c | 54 -- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/include/sim.h b/include/sim.h index 36a99b9..6c5a657 100644 --- a/include/sim.h +++ b/include/sim.h @@ -198,6 +198,11 @@ int ofono_sim_read(struct ofono_sim *sim, int id, enum ofono_sim_file_structure expected, ofono_sim_file_read_cb_t cb, void *data); +int ofono_sim_read_bytes(struct ofono_sim *sim, int id, + enum ofono_sim_file_structure expected_type, + unsigned short offset, int num_bytes, + 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, diff --git a/src/sim.c b/src/sim.c index 6d723bb..fa3823b 100644 --- a/src/sim.c +++ b/src/sim.c @@ -60,6 +60,8 @@ struct sim_file_op { int id; gboolean cache; enum ofono_sim_file_structure structure; + unsigned short offset; + int num_bytes; int length; int record_length; int current; @@ -1498,7 +1500,7 @@ static void sim_op_retrieve_cb(const struct ofono_error *error, return; } - cb(1, op-length, op-current, data, op-record_length, op-userdata); + cb(1, len, op-current, data, op-record_length, op-userdata); if (op-cache imsi) { char *path = g_strdup_printf(SIM_CACHE_PATH, @@ -1536,7 +1538,16 @@ static gboolean sim_op_retrieve_next(gpointer user) return FALSE; } - sim-driver-read_file_transparent(sim, op-id, 0, op-length, + if (op-num_bytes 0) + op-num_bytes = op-length; + + if (op-offset + op-num_bytes op-length) { + sim_op_error(sim); + return FALSE; + } + + sim-driver-read_file_transparent(sim, op-id, op-offset, + op-num_bytes, sim_op_retrieve_cb, sim); break; case OFONO_SIM_FILE_STRUCTURE_FIXED: @@ -1663,6 +1674,8 @@ static gboolean sim_op_check_cached(struct ofono_sim *sim) unsigned int record; guint8 *buffer = NULL; gboolean ret = FALSE; + unsigned int read_bytes; + unsigned int num_records; if (!imsi) return FALSE; @@ -1694,8 +1707,19 @@ static gboolean sim_op_check_cached(struct ofono_sim *sim) structure = fileinfo[3]; record_length = (fileinfo[4] 8) | fileinfo[5]; - if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) - record_length = file_length; + if (op-num_bytes 0) + op-num_bytes = file_length; + + read_bytes = op-num_bytes; + + num_records = file_length / record_length; + + /* add a seek to the correct offset here */ + if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) { + TFR(lseek(fd, op-offset, SEEK_CUR)); + num_records = 1; + record_length = read_bytes; + } if (record_length == 0 || file_length record_length) goto cleanup; @@ -1707,18 +1731,18 @@ static gboolean sim_op_check_cached(struct ofono_sim *sim) goto cleanup; } - buffer = g_try_malloc(file_length); + buffer = g_try_malloc(read_bytes); if (buffer == NULL) goto cleanup; - len = TFR(read(fd, buffer, file_length)); + len = TFR(read(fd, buffer, read_bytes)); - if (len (ssize_t)file_length) + if (len (ssize_t) read_bytes) goto cleanup; - for (record = 0; record file_length / record_length; record++) { - cb(1, file_length, record + 1, buffer[record * record_length], + for (record = 0; record num_records; record++) { + cb(1, read_bytes, record + 1, buffer[record * record_length], record_length, op-userdata); } @@ -1787,8 +1811,9 @@ static gboolean sim_op_next(gpointer user_data) return FALSE; } -int ofono_sim_read(struct ofono_sim *sim, int id, +int ofono_sim_read_bytes(struct ofono_sim *sim, int id, enum ofono_sim_file_structure expected_type, + unsigned short offset, int num_bytes, ofono_sim_file_read_cb_t cb, void *data) { struct sim_file_op *op; @@ -1819,6 +1844,8 @@ int ofono_sim_read(struct ofono_sim *sim, int id, op-cb = cb; op-userdata = data; op-is_read = TRUE; + op-offset = offset; + op-num_bytes = num_bytes; g_queue_push_tail(sim-simop_q, op); @@ -1828,6 +1855,13
[PATCH 5/7] sim: read an image from an EFiidf
--- include/sim.h |6 +++ src/sim.c | 127 + 2 files changed, 133 insertions(+), 0 deletions(-) diff --git a/include/sim.h b/include/sim.h index 6c5a657..1303203 100644 --- a/include/sim.h +++ b/include/sim.h @@ -113,6 +113,9 @@ typedef void (*ofono_sim_lock_unlock_cb_t)(const struct ofono_error *error, typedef void (*ofono_sim_locked_cb_t)(const struct ofono_error *error, int locked, void *data); +typedef void (*ofono_sim_get_image_cb_t)(int ok, const char *xpm, int xpm_len, + void *userdata); + struct ofono_sim_driver { const char *name; int (*probe)(struct ofono_sim *sim, unsigned int vendor, void *data); @@ -177,6 +180,9 @@ enum ofono_sim_phase ofono_sim_get_phase(struct ofono_sim *sim); enum ofono_sim_cphs_phase ofono_sim_get_cphs_phase(struct ofono_sim *sim); const unsigned char *ofono_sim_get_cphs_service_table(struct ofono_sim *sim); +void ofono_sim_get_image(struct ofono_sim *sim, unsigned char id, + ofono_sim_get_image_cb_t cb, gpointer user_data); + unsigned int ofono_sim_add_state_watch(struct ofono_sim *sim, ofono_sim_state_event_notify_cb_t cb, void *data, ofono_destroy_func destroy); diff --git a/src/sim.c b/src/sim.c index fa3823b..e19fb06 100644 --- a/src/sim.c +++ b/src/sim.c @@ -42,6 +42,7 @@ #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 @@ -2231,3 +2232,129 @@ 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; + const unsigned char *image; + const unsigned char *clut; + unsigned short clut_len; + gboolean need_clut; + ofono_sim_get_image_cb_t user_cb; + gpointer user_data; +}; + +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; + + /* +* make sure everthing was ok, and that what we read matched +* what we asked for. If not, return an error to the caller +*/ + 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) + image-image = data; + else + image-clut = data; + + /* convert to xpm, free stuff, and call user callback */ + xpm = stk_image_to_xpm(image-image, image-iid_len, + image-scheme, image-clut, + image-clut_len); + + image-user_cb(ok, xpm, strlen(xpm), image-user_data); + + 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: + /* TBD - what if image-image was memduped? */ + g_free(image); +} + +static void print_image_descriptor(struct image_data *data) +{ + g_print(image id: 0x%x\n, data-iidf_id); + g_print(width: %d\n, data-width); + g_print(height: %d\n, data-height); + g_print(len: %d\n, data-iid_len); + g_print(iidf offset: %d\n, data-iidf_offset); +} + +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; + + 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]; +
[PATCH 7/7] test: add get-icon script
--- test/get-icon | 25 + 1 files changed, 25 insertions(+), 0 deletions(-) create mode 100755 test/get-icon diff --git a/test/get-icon b/test/get-icon new file mode 100755 index 000..680ae13 --- /dev/null +++ b/test/get-icon @@ -0,0 +1,25 @@ +#!/usr/bin/python + +import dbus +import sys + +bus = dbus.SystemBus() + +if len(sys.argv) == 3: + path = sys.argv[1] + id = int(sys.argv[2], 16) +elif len(sys.argv) == 2: + manager = dbus.Interface(bus.get_object('org.ofono', '/'), +'org.ofono.Manager') + properties = manager.GetProperties() + path = properties[Modems][0] + id = int(sys.argv[1], 16) +else: + print %s [PATH] icon_id % (sys.argv[0]) + +simmanager = dbus.Interface(bus.get_object('org.ofono', path), + 'org.ofono.SimManager') + +xpm = simmanager.GetIcon(id) + +print Received xpm: %s % (xpm) -- 1.7.1.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] simfilesystem: make EFimg a linear fixed file type
--- src/simfilesystem.cpp |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/src/simfilesystem.cpp b/src/simfilesystem.cpp index 6781ac9..d193328 100644 --- a/src/simfilesystem.cpp +++ b/src/simfilesystem.cpp @@ -110,7 +110,7 @@ static SimFileInfo const knownFiles[] = {2F05,3F00, EFpl,0x11ff44, FILE_TYPE_TRANSPARENT}, {5F50,7F10, DFgraphics, 0, FILE_TYPE_TRANSPARENT}, -{4F20,5F50, EFimg, 0x14ff44, FILE_TYPE_TRANSPARENT}, +{4F20,5F50, EFimg, 0x14ff44, FILE_TYPE_LINEAR_FIXED}, {4F01,5F50, EFimg1, 0x14ff44, FILE_TYPE_TRANSPARENT}, {4F02,5F50, EFimg2, 0x14ff44, FILE_TYPE_TRANSPARENT}, {4F03,5F50, EFimg3, 0x14ff44, FILE_TYPE_TRANSPARENT}, -- 1.7.1.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] sim: allow partial reads of tranparent files
Implement ofono_sim_read_bytes(). For transparent files, this will read num_bytes from a specified offset of a given fileid. --- include/sim.h |5 + src/sim.c | 29 ++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/include/sim.h b/include/sim.h index 36a99b9..15cd6b8 100644 --- a/include/sim.h +++ b/include/sim.h @@ -198,6 +198,11 @@ int ofono_sim_read(struct ofono_sim *sim, int id, enum ofono_sim_file_structure expected, ofono_sim_file_read_cb_t cb, void *data); +int ofono_sim_read_bytes(struct ofono_sim *sim, int id, + enum ofono_sim_file_structure expected, + unsigned short offset, int num_bytes, + 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, diff --git a/src/sim.c b/src/sim.c index 2514e7b..cd1cbf5 100644 --- a/src/sim.c +++ b/src/sim.c @@ -60,6 +60,8 @@ struct sim_file_op { int id; gboolean cache; enum ofono_sim_file_structure structure; + unsigned short offset; + int num_bytes; int length; int record_length; int current; @@ -1434,7 +1436,7 @@ static void sim_op_retrieve_cb(const struct ofono_error *error, return; } - cb(1, op-length, op-current, data, op-record_length, op-userdata); + cb(1, len, op-current, data, op-record_length, op-userdata); if (op-cache imsi) { char *path = g_strdup_printf(SIM_CACHE_PATH, @@ -1472,7 +1474,16 @@ static gboolean sim_op_retrieve_next(gpointer user) return FALSE; } - sim-driver-read_file_transparent(sim, op-id, 0, op-length, + if (op-offset + op-num_bytes op-length) { + sim_op_error(sim); + return FALSE; + } + + if (op-num_bytes 0) + op-num_bytes = op-length; + + sim-driver-read_file_transparent(sim, op-id, op-offset, + op-num_bytes, sim_op_retrieve_cb, sim); break; case OFONO_SIM_FILE_STRUCTURE_FIXED: @@ -1723,8 +1734,9 @@ static gboolean sim_op_next(gpointer user_data) return FALSE; } -int ofono_sim_read(struct ofono_sim *sim, int id, +int ofono_sim_read_bytes(struct ofono_sim *sim, int id, enum ofono_sim_file_structure expected_type, + unsigned short offset, int num_bytes, ofono_sim_file_read_cb_t cb, void *data) { struct sim_file_op *op; @@ -1755,6 +1767,10 @@ int ofono_sim_read(struct ofono_sim *sim, int id, op-cb = cb; op-userdata = data; op-is_read = TRUE; + op-offset = offset; + + if (num_bytes 0) + op-num_bytes = num_bytes; g_queue_push_tail(sim-simop_q, op); @@ -1764,6 +1780,13 @@ int ofono_sim_read(struct ofono_sim *sim, int id, return 0; } +int ofono_sim_read(struct ofono_sim *sim, int id, + enum ofono_sim_file_structure expected_type, + ofono_sim_file_read_cb_t cb, void *data) +{ + return ofono_sim_read_bytes(sim, id, expected_type, 0, -1, cb, 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, -- 1.7.1.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/2] convert images to xpm
Changes since last version: * whitespace changes * corrected sanity tests * changed signature to pass clut and clut_len to function * updated unit tests for new signature Kristen Carlson Accardi (2): stkutil: convert img to xpm test-stkutil: unit test for img to xpm converter src/stkutil.c | 147 ++ src/stkutil.h |9 ++ unit/test-stkutil.c | 247 +++ 3 files changed, 403 insertions(+), 0 deletions(-) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/2] stkutil: convert img to xpm
--- src/stkutil.c | 147 + src/stkutil.h |9 2 files changed, 156 insertions(+), 0 deletions(-) diff --git a/src/stkutil.c b/src/stkutil.c index 9cac850..ae4cc32 100644 --- a/src/stkutil.c +++ b/src/stkutil.c @@ -6076,3 +6076,150 @@ char *stk_text_to_html(const char *utf8, /* return characters from string. Caller must free char data */ return g_string_free(string, FALSE); } + +static const char chars_table[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', + 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', + 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '+', '.' }; + +char *stk_image_to_xpm(const unsigned char *img, unsigned int len, + enum stk_img_scheme scheme, const unsigned char *clut, + unsigned short clut_len) +{ + guint8 width, height; + unsigned int ncolors, nbits, entry, cpp; + unsigned int i, j; + int bit, k; + GString *xpm; + unsigned int pos = 0; + const char xpm_header[] = /* XPM */\n; + const char declaration[] = static char *xpm[] = {\n; + char c[3]; + + if (img == NULL) + return NULL; + + /* sanity check length */ + if (len 3) + return NULL; + + width = img[pos++]; + height = img[pos++]; + + if (scheme == STK_IMG_SCHEME_BASIC) { + nbits = 1; + ncolors = 2; + } else { + /* sanity check length */ + if ((pos + 4 len) || (clut == NULL)) + return NULL; + + nbits = img[pos++]; + ncolors = img[pos++]; + + /* the value of zero should be interpreted as 256 */ + if (ncolors == 0) + ncolors = 256; + + /* skip clut offset bytes */ + pos += 2; + + if ((ncolors * 3) clut_len) + return NULL; + } + + if (pos + ((width * height + 7) / 8) len) + return NULL; + + /* determine the number of chars need to represent the pixel */ + cpp = ncolors 64 ? 2 : 1; + + /* +* space needed: +* header line +* declaration and beginning of assignment line +* values - max length of 19 +* colors - ncolors * (cpp + whitespace + deliminators + color) +* pixels - width * height * cpp + height deliminators ,\n +* end of assignment - 2 chars }; +*/ + xpm = g_string_sized_new(strlen(xpm_header) + strlen(declaration) + + 19 + ((cpp + 14) * ncolors) + + (width * height * cpp) + (4 * height) + 2); + if (xpm == NULL) + return NULL; + + /* add header, declaration, values */ + g_string_append(xpm, xpm_header); + g_string_append(xpm, declaration); + g_string_append_printf(xpm, \%d %d %d %d\,\n, width, height, + ncolors, cpp); + + /* create colors */ + if (scheme == STK_IMG_SCHEME_BASIC) { + g_string_append(xpm, \0\tc #00\,\n); + g_string_append(xpm, \1\tc #FF\,\n); + } else { + for (i = 0; i ncolors; i++) { + /* lookup char representation of this number */ + if (ncolors 64) { + c[0] = chars_table[i / 64]; + c[1] = chars_table[i % 64]; + c[2] = '\0'; + } else { + c[0] = chars_table[i % 64]; + c[1] = '\0'; + } + + if ((i == (ncolors - 1)) + scheme == STK_IMG_SCHEME_TRANSPARENCY) + g_string_append_printf(xpm, + \%s\tc None\,\n, c); + else + g_string_append_printf(xpm, + \%s\tc #%02hhX%02hhX%02hhX\,\n, + c, clut[0], clut[1], clut[2]); + clut += 3; + } + } + + /* height rows of width pixels */ + k = 7; + for (i = 0; i height; i++) { + g_string_append(xpm, \); + for (j = 0; j width; j++) { + entry = 0; + for (bit = nbits - 1; bit = 0; bit--) { + entry |= (img[pos] k 0x1) bit; + k--; + + /* see if we crossed a byte boundary */
[PATCH 2/2] test-stkutil: unit test for img to xpm converter
--- unit/test-stkutil.c | 247 +++ 1 files changed, 247 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 1d7485a..10cedca 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -22693,6 +22693,240 @@ static void test_html_attr(gconstpointer data) check_text_attr_html(test-text_attr, test-text, test-html); } +struct img_xpm_test { + const unsigned char *img; + unsigned int len; + const unsigned char *clut; + unsigned short clut_len; + guint8 scheme; + char *xpm; +}; + +const unsigned char img1[] = { 0x05, 0x05, 0xFE, 0xEB, 0xBF, 0xFF, 0xFF, 0xFF }; + +const unsigned char img2[] = { 0x08, 0x08, 0x02, 0x03, 0x00, 0x16, 0xAA, + 0xAA, 0x80, 0x02, 0x85, 0x42, 0x81, + 0x42, 0x81, 0x42, 0x81, 0x52, 0x80, + 0x02, 0xAA, 0xAA, 0xFF, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF }; + +const unsigned char img3[] = { 0x2E, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x77, 0xFE, 0x00, + 0x00, 0x00, 0x01, 0xBF, 0xF8, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1A, 0x03, + 0x80, 0x00, 0x00, 0x00, 0x6B, 0xF6, 0xBC, 0x00, + 0x00, 0x01, 0xAF, 0xD8, 0x38, 0x00, 0x00, 0x06, + 0xBF, 0x60, 0x20, 0x00, 0x00, 0x1A, 0xFD, 0x80, + 0x40, 0x00, 0x00, 0x6B, 0xF6, 0x00, 0x80, 0x00, + 0x01, 0xA0, 0x1F, 0x02, 0x00, 0x00, 0x06, 0xFF, + 0xE4, 0x04, 0x00, 0x00, 0x1B, 0xFF, 0x90, 0x10, + 0x00, 0x00, 0x6D, 0xEE, 0x40, 0x40, 0x00, 0x01, + 0xBF, 0xF9, 0x01, 0x00, 0x00, 0x6F, 0xFF, 0xE4, + 0x04, 0x00, 0x00, 0x1B, 0xFF, 0x90, 0x10, 0x00, + 0x00, 0x6F, 0xFE, 0x40, 0x40, 0x00, 0x01, 0xBF, + 0xF9, 0x01, 0x00, 0x00, 0x06, 0xFF, 0xE6, 0x04, + 0x00, 0x00, 0x1B, 0xFF, 0x88, 0x10, 0x00, 0x00, + 0x6F, 0xFE, 0x20, 0x40, 0x00, 0x01, 0xBF, 0xF8, + 0x66, 0x00, 0x00, 0x06, 0xFF, 0xE0, 0xF0, 0x00, + 0x00, 0x1B, 0xFF, 0x80, 0x80, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x21, 0x08, 0x44, 0xEE, 0x00, 0x48, 0xC4, + 0x31, 0x92, 0x20, 0x01, 0x25, 0x11, 0x45, 0x50, + 0x80, 0x07, 0x14, 0x45, 0x15, 0x43, 0x80, 0x12, + 0x71, 0x1C, 0x4D, 0x08, 0x00, 0x4A, 0x24, 0x89, + 0x32, 0x20, 0x01, 0xC8, 0x9E, 0x24, 0x4E, + 0xE0 }; + +const unsigned char img4[] = { 0x18, 0x10, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x8F, + 0x3C, 0xF1, 0x89, 0x20, 0x81, 0x89, 0x20, + 0x81, 0x89, 0x20, 0xF1, 0x89, 0x20, 0x11, + 0x89, 0x20, 0x11, 0x89, 0x20, 0x11, 0x8F, + 0x3C, 0xF1, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFF }; + +const unsigned char img5[] = { 0x08, 0x08, 0xFF, 0x03, 0xA5, 0x99, 0x99, + 0xA5, 0xC3, 0xFF }; + +static struct img_xpm_test xpm_test_1 = { + .img = img1, + .len = sizeof(img1), + .scheme = STK_IMG_SCHEME_BASIC, + .xpm = /* XPM */\n + static char *xpm[] = {\n + \5 5 2 1\,\n + \0c #00\,\n + \1c #FF\,\n + \1\,\n + \11011\,\n + \10101\,\n + \11011\,\n + \1\,\n + };, +}; + +static struct img_xpm_test xpm_test_2 = { + .img = img2, + .len = sizeof(img2), + .clut = img2 + 0x16, + .clut_len = 0x09, + .scheme = STK_IMG_SCHEME_COLOR, + .xpm = /* XPM */\n + static char *xpm[] = {\n + \8 8 3 1\,\n + \0c #FF\,\n + \1c #00FF00\,\n + \2c #FF\,\n + \\,\n +
Re: [PATCH 1/2] stkutil: convert img to xpm
On Fri, 23 Jul 2010 16:46:51 -0500 Denis Kenzior denk...@gmail.com wrote: Hi Kristen, On 07/23/2010 04:39 PM, Kristen Carlson Accardi wrote: On Fri, 23 Jul 2010 16:03:16 -0500 Denis Kenzior denk...@gmail.com wrote: Hi Kristen, On 07/23/2010 03:52 PM, Kristen Carlson Accardi wrote: On Fri, 23 Jul 2010 15:03:59 -0500 Denis Kenzior denk...@gmail.com wrote: This also brings up another point. You're assuming that the caller is appending the CLUT right after the image data and massaging the clut offset appropriately. This is a really bad idea since the caller will have to do some significant pre-processing. You can handle this in one of two ways: 1. Assume the calling logic will read the entire image file before calling this function. In this case, modifying the signature as follows might be a good idea: char *stk_image_to_xpm(const unsigned char *file, unsigned short file_len, enum stk_img_scheme scheme, unsigned short img_offset, unsigned short img_len); 2. Assume the calling logic is clever and will optimize reading of the file, including peeking into the image header to determine the where the CLUT is located and reading it. In this case you can either reuse the signature from 1 above, or come up with something else. Remember, reading from the SIM is extremely slow, so any and all clever optimization tricks are definitely wanted. So, is it likely given normal usage that we'll access an image a single image at a time, or is it more likely that we'll access a bunch of images all at once? It may be better to read an entire image data file (with multiple images) and keep it cached if we are likely to immediately need the other images. In which case I'd be inclined to just pass in the entire data image file and the offset like you have above. If we are only likely to use a single image for any given length of time, then it seems better to have the caller be smart and pass us the clut. The problem is we just don't know, so we have to assume the worst case. Anything that minimizes the number of reads is a good thing (TM). For instance, you might have couple of dozen images from EFimg dispersed among multiple EFiidf files. Each EFiidf file might be 65K in length, but EFimg files might only refer to about 10k from all of them. It is perfectly OK for EFiidf to contain mostly garbage (e.g. for future updates, installation of new SIM Toolkit applications on the SIM + associated image data, etc) So you simply can't assume any sort of packing or efficient storage use. In this case, a clever algorithm that minimizes the number of SIM fetches is needed. Regards, -Denis If that is the case then I propose we assume a smart algorithm fetched our data for us and change the signature to something like this: unsigned char *stk_image_to_xpm(const unsigned char *image_body, enum stk_image_scheme scheme, unsigned int height, unsigned int width, unsigned int ncolors, const unsigned char *clut); We would assume that the caller has done all the sanity checking on the file and handed us a clut of appropriate size as well. You sure you want unsigned char * as the return and not char *? Oops - no, I typed that wrong. Also, you might want to change unsigned ints to unsigned chars. The image size and CLUT size can never be more than 256. The image size can be greater than 256, but I think you mean the value of height, width, and ncolors can never be greater than 256, which is true. ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/2] convert img to xpm
Changes from last version: * Added length parameter * created enum for scheme * added sanity checking for img length * added character lookup table to keep color strings to no more than 2 chars per pixel. Kristen Carlson Accardi (2): stkutil: convert img to xpm test-stkutil: unit test for img to xpm converter src/stkutil.c | 148 +++ src/stkutil.h |8 ++ unit/test-stkutil.c | 240 +++ 3 files changed, 396 insertions(+), 0 deletions(-) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/2] test-stkutil: unit test for img to xpm converter
--- unit/test-stkutil.c | 240 +++ 1 files changed, 240 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 1d7485a..ea65621 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -22693,6 +22693,233 @@ static void test_html_attr(gconstpointer data) check_text_attr_html(test-text_attr, test-text, test-html); } +struct img_xpm_test { + const unsigned char *img; + unsigned int len; + guint8 scheme; + char *xpm; +}; + +const unsigned char img1[] = { 0x05, 0x05, 0xFE, 0xEB, 0xBF, 0xFF, 0xFF, 0xFF }; + +const unsigned char img2[] = { 0x08, 0x08, 0x02, 0x03, 0x00, 0x16, 0xAA, + 0xAA, 0x80, 0x02, 0x85, 0x42, 0x81, + 0x42, 0x81, 0x42, 0x81, 0x52, 0x80, + 0x02, 0xAA, 0xAA, 0xFF, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF }; + +const unsigned char img3[] = { 0x2E, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x77, 0xFE, 0x00, + 0x00, 0x00, 0x01, 0xBF, 0xF8, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1A, 0x03, + 0x80, 0x00, 0x00, 0x00, 0x6B, 0xF6, 0xBC, 0x00, + 0x00, 0x01, 0xAF, 0xD8, 0x38, 0x00, 0x00, 0x06, + 0xBF, 0x60, 0x20, 0x00, 0x00, 0x1A, 0xFD, 0x80, + 0x40, 0x00, 0x00, 0x6B, 0xF6, 0x00, 0x80, 0x00, + 0x01, 0xA0, 0x1F, 0x02, 0x00, 0x00, 0x06, 0xFF, + 0xE4, 0x04, 0x00, 0x00, 0x1B, 0xFF, 0x90, 0x10, + 0x00, 0x00, 0x6D, 0xEE, 0x40, 0x40, 0x00, 0x01, + 0xBF, 0xF9, 0x01, 0x00, 0x00, 0x6F, 0xFF, 0xE4, + 0x04, 0x00, 0x00, 0x1B, 0xFF, 0x90, 0x10, 0x00, + 0x00, 0x6F, 0xFE, 0x40, 0x40, 0x00, 0x01, 0xBF, + 0xF9, 0x01, 0x00, 0x00, 0x06, 0xFF, 0xE6, 0x04, + 0x00, 0x00, 0x1B, 0xFF, 0x88, 0x10, 0x00, 0x00, + 0x6F, 0xFE, 0x20, 0x40, 0x00, 0x01, 0xBF, 0xF8, + 0x66, 0x00, 0x00, 0x06, 0xFF, 0xE0, 0xF0, 0x00, + 0x00, 0x1B, 0xFF, 0x80, 0x80, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x21, 0x08, 0x44, 0xEE, 0x00, 0x48, 0xC4, + 0x31, 0x92, 0x20, 0x01, 0x25, 0x11, 0x45, 0x50, + 0x80, 0x07, 0x14, 0x45, 0x15, 0x43, 0x80, 0x12, + 0x71, 0x1C, 0x4D, 0x08, 0x00, 0x4A, 0x24, 0x89, + 0x32, 0x20, 0x01, 0xC8, 0x9E, 0x24, 0x4E, + 0xE0 }; + +const unsigned char img4[] = { 0x18, 0x10, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x8F, + 0x3C, 0xF1, 0x89, 0x20, 0x81, 0x89, 0x20, + 0x81, 0x89, 0x20, 0xF1, 0x89, 0x20, 0x11, + 0x89, 0x20, 0x11, 0x89, 0x20, 0x11, 0x8F, + 0x3C, 0xF1, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFF }; + +const unsigned char img5[] = { 0x08, 0x08, 0xFF, 0x03, 0xA5, 0x99, 0x99, + 0xA5, 0xC3, 0xFF }; + +static struct img_xpm_test xpm_test_1 = { + .img = img1, + .len = sizeof(img1), + .scheme = STK_IMG_SCHEME_BASIC, + .xpm = /* XPM */\n + static char *xpm[] = {\n + \5 5 2 1\,\n + \0c #00\,\n + \1c #FF\,\n + \1\,\n + \11011\,\n + \10101\,\n + \11011\,\n + \1\,\n + };, +}; + +static struct img_xpm_test xpm_test_2 = { + .img = img2, + .len = sizeof(img2), + .scheme = STK_IMG_SCHEME_COLOR, + .xpm = /* XPM */\n + static char *xpm[] = {\n + \8 8 3 1\,\n + \0c #FF\,\n + \1c #00FF00\,\n + \2c #FF\,\n + \\,\n + \2002\,\n + \20111002\,\n + \20011002\,\n + \20011002\,\n +
[PATCH 0/2] convert img to xpm
Kristen Carlson Accardi (2): stkutil: convert img to xpm test-stkutil: unit test for img to xpm converter src/stkutil.c | 108 src/stkutil.h |1 + unit/test-stkutil.c | 233 +++ 3 files changed, 342 insertions(+), 0 deletions(-) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/2] test-stkutil: unit test for img to xpm converter
--- unit/test-stkutil.c | 233 +++ 1 files changed, 233 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 1d7485a..97eb1c5 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -22693,6 +22693,226 @@ static void test_html_attr(gconstpointer data) check_text_attr_html(test-text_attr, test-text, test-html); } +struct img_xpm_test { + const unsigned char *img; + guint8 scheme; + char *xpm; +}; + +const unsigned char img1[] = { 0x05, 0x05, 0xFE, 0xEB, 0xBF, 0xFF, 0xFF, 0xFF }; + +const unsigned char img2[] = { 0x08, 0x08, 0x02, 0x03, 0x00, 0x16, 0xAA, + 0xAA, 0x80, 0x02, 0x85, 0x42, 0x81, + 0x42, 0x81, 0x42, 0x81, 0x52, 0x80, + 0x02, 0xAA, 0xAA, 0xFF, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF }; + +const unsigned char img3[] = { 0x2E, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x77, 0xFE, 0x00, + 0x00, 0x00, 0x01, 0xBF, 0xF8, 0x00, 0x00, 0x00, + 0x06, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1A, 0x03, + 0x80, 0x00, 0x00, 0x00, 0x6B, 0xF6, 0xBC, 0x00, + 0x00, 0x01, 0xAF, 0xD8, 0x38, 0x00, 0x00, 0x06, + 0xBF, 0x60, 0x20, 0x00, 0x00, 0x1A, 0xFD, 0x80, + 0x40, 0x00, 0x00, 0x6B, 0xF6, 0x00, 0x80, 0x00, + 0x01, 0xA0, 0x1F, 0x02, 0x00, 0x00, 0x06, 0xFF, + 0xE4, 0x04, 0x00, 0x00, 0x1B, 0xFF, 0x90, 0x10, + 0x00, 0x00, 0x6D, 0xEE, 0x40, 0x40, 0x00, 0x01, + 0xBF, 0xF9, 0x01, 0x00, 0x00, 0x6F, 0xFF, 0xE4, + 0x04, 0x00, 0x00, 0x1B, 0xFF, 0x90, 0x10, 0x00, + 0x00, 0x6F, 0xFE, 0x40, 0x40, 0x00, 0x01, 0xBF, + 0xF9, 0x01, 0x00, 0x00, 0x06, 0xFF, 0xE6, 0x04, + 0x00, 0x00, 0x1B, 0xFF, 0x88, 0x10, 0x00, 0x00, + 0x6F, 0xFE, 0x20, 0x40, 0x00, 0x01, 0xBF, 0xF8, + 0x66, 0x00, 0x00, 0x06, 0xFF, 0xE0, 0xF0, 0x00, + 0x00, 0x1B, 0xFF, 0x80, 0x80, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1C, 0x21, 0x08, 0x44, 0xEE, 0x00, 0x48, 0xC4, + 0x31, 0x92, 0x20, 0x01, 0x25, 0x11, 0x45, 0x50, + 0x80, 0x07, 0x14, 0x45, 0x15, 0x43, 0x80, 0x12, + 0x71, 0x1C, 0x4D, 0x08, 0x00, 0x4A, 0x24, 0x89, + 0x32, 0x20, 0x01, 0xC8, 0x9E, 0x24, 0x4E, + 0xE0 }; + +const unsigned char img4[] = { 0x18, 0x10, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x01, + 0x80, 0x00, 0x01, 0x80, 0x00, 0x01, 0x8F, + 0x3C, 0xF1, 0x89, 0x20, 0x81, 0x89, 0x20, + 0x81, 0x89, 0x20, 0xF1, 0x89, 0x20, 0x11, + 0x89, 0x20, 0x11, 0x89, 0x20, 0x11, 0x8F, + 0x3C, 0xF1, 0x80, 0x00, 0x01, 0x80, 0x00, + 0x01, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFF }; + +const unsigned char img5[] = { 0x08, 0x08, 0xFF, 0x03, 0xA5, 0x99, 0x99, + 0xA5, 0xC3, 0xFF }; + +static struct img_xpm_test xpm_test_1 = { + .img = img1, + .scheme = 0x11, + .xpm = /* XPM */\n + static char *xpm[] = {\n + \5 5 2 1\,\n + \0c #00\,\n + \1c #FF\,\n + \1\,\n + \11011\,\n + \10101\,\n + \11011\,\n + \1\,\n + };, +}; + +static struct img_xpm_test xpm_test_2 = { + .img = img2, + .scheme = 0x21, + .xpm = /* XPM */\n + static char *xpm[] = {\n + \8 8 3 1\,\n + \0c #FF\,\n + \1c #00FF00\,\n + \2c #FF\,\n + \\,\n + \2002\,\n + \20111002\,\n + \20011002\,\n + \20011002\,\n + \20011102\,\n + \2002\,\n + \\,\n + };, +}; + +static struct
[PATCH 0/9] html text attribute patches
Changed from last version: * incorporated feedback from latest review * dropped invalid test from html text attributes unit test Kristen Carlson Accardi (9): stkutil: display text attributes as html test-stkutil: add unit test for html text attributes test-stkutil: add html attribute test for Display Text tests test-stkutil: add html attribute tests for get_inkey_test test-stkutil: add html attribute tests for get_input_test test-stkutil: add html attribute tests for play_tone_test test-stkutil: add html attribute test for setup_menu_test test-stkutil: add html attribute test for select_item_test test-stkutil: add html attribute tests for setup idle mode tests src/stkutil.c | 225 +++ src/stkutil.h |2 + unit/test-stkutil.c | 765 -- 3 files changed, 900 insertions(+), 92 deletions(-) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/9] stkutil: display text attributes as html
--- src/stkutil.c | 225 + src/stkutil.h |2 + 2 files changed, 227 insertions(+), 0 deletions(-) diff --git a/src/stkutil.c b/src/stkutil.c index c45f985..522021c 100644 --- a/src/stkutil.c +++ b/src/stkutil.c @@ -5853,3 +5853,228 @@ const unsigned char *stk_pdu_from_envelope(const struct stk_envelope *envelope, return pdu; } + +static const char *html_colors[] = { + #00, /* Black */ + #808080, /* Dark Grey */ + #C11B17, /* Dark Red */ + #FBB117, /* Dark Yellow */ + #347235, /* Dark Green */ + #307D7E, /* Dark Cyan */ + #A0, /* Dark Blue */ + #C031C7, /* Dark Magenta */ + #C0C0C0, /* Grey */ + #FF, /* White */ + #FF, /* Bright Red */ + #00, /* Bright Yellow */ + #00FF00, /* Bright Green */ + #00, /* Bright Cyan */ + #FF, /* Bright Blue */ + #FF00FF, /* Bright Magenta */ +}; + +#define STK_TEXT_FORMAT_ALIGN_MASK 0x03 +#define STK_TEXT_FORMAT_FONT_MASK 0x0C +#define STK_TEXT_FORMAT_STYLE_MASK 0xF0 +#define STK_DEFAULT_TEXT_ALIGNMENT 0x00 +#define STK_TEXT_FORMAT_INIT 0x9003 + +/* Defined in ETSI 123 40 9.2.3.24.10.1.1 */ +enum stk_text_format_code { + STK_TEXT_FORMAT_LEFT_ALIGN = 0x00, + STK_TEXT_FORMAT_CENTER_ALIGN = 0x01, + STK_TEXT_FORMAT_RIGHT_ALIGN = 0x02, + STK_TEXT_FORMAT_NO_ALIGN = 0x03, + STK_TEXT_FORMAT_FONT_SIZE_LARGE = 0x04, + STK_TEXT_FORMAT_FONT_SIZE_SMALL = 0x08, + STK_TEXT_FORMAT_FONT_SIZE_RESERVED = 0x0c, + STK_TEXT_FORMAT_STYLE_BOLD = 0x10, + STK_TEXT_FORMAT_STYLE_ITALIC = 0x20, + STK_TEXT_FORMAT_STYLE_UNDERLINED = 0x40, + STK_TEXT_FORMAT_STYLE_STRIKETHROUGH = 0x80, +}; + +static void end_format(GString *string, guint16 attr) +{ + guint code = attr 0xFF; + guint color = (attr 8) 0xFF; + + if ((code ~STK_TEXT_FORMAT_ALIGN_MASK) || color) + g_string_append(string, /span); + + if ((code STK_TEXT_FORMAT_ALIGN_MASK) != STK_TEXT_FORMAT_NO_ALIGN) + g_string_append(string, /div); +} + +static void start_format(GString *string, guint16 attr) +{ + guint8 code = attr 0xFF; + guint8 color = (attr 8) 0xFF; + guint8 align = code STK_TEXT_FORMAT_ALIGN_MASK; + guint8 font = code STK_TEXT_FORMAT_FONT_MASK; + guint8 style = code STK_TEXT_FORMAT_STYLE_MASK; + int fg = color 0x0f; + int bg = (color 4) 0x0f; + + /* align formatting applies to a block of text */ + if (align != STK_TEXT_FORMAT_NO_ALIGN) + g_string_append(string, div style=\); + + switch (align) { + case STK_TEXT_FORMAT_RIGHT_ALIGN: + g_string_append(string, text-align: right;\); + break; + case STK_TEXT_FORMAT_CENTER_ALIGN: + g_string_append(string, text-align: center;\); + break; + case STK_TEXT_FORMAT_LEFT_ALIGN: + g_string_append(string, text-align: left;\); + break; + } + + if ((font == 0) (style == 0) (color == 0)) + return; + + /* font, style, and color are inline */ + g_string_append(string, span style=\); + + switch (font) { + case STK_TEXT_FORMAT_FONT_SIZE_LARGE: + g_string_append(string, font-size: big;); + break; + case STK_TEXT_FORMAT_FONT_SIZE_SMALL: + g_string_append(string, font-size: small;); + break; + } + + if (style STK_TEXT_FORMAT_STYLE_BOLD) + g_string_append(string, font-weight: bold;); + if (style STK_TEXT_FORMAT_STYLE_ITALIC) + g_string_append(string, font-style: italic;); + if (style STK_TEXT_FORMAT_STYLE_UNDERLINED) + g_string_append(string, text-decoration: underline;); + if (style STK_TEXT_FORMAT_STYLE_STRIKETHROUGH) + g_string_append(string, text-decoration: line-through;); + + /* add any color */ + if (fg) + g_string_append_printf(string, color: %s;, html_colors[fg]); + if (bg) + g_string_append_printf(string, background-color: %s;, + html_colors[bg]); + g_string_append(string, \); +} + +char *stk_text_to_html(const char *utf8, + const unsigned short *attrs, int num_attrs) +{ + long text_len = g_utf8_strlen(utf8, -1); + GString *string = g_string_sized_new(strlen(utf8) + 1); + short *formats; + int pos, i, j; + guint16 start, end, len, attr, prev_attr; + guint8 code, color, align; + const char *text = utf8; + int attrs_len = num_attrs * 4; + + formats = g_try_new0(gint16, (text_len + 1)); + if (formats == NULL) { + g_string_free(string, TRUE); + return NULL; + } + + /* we will need formatting
[PATCH 3/9] test-stkutil: add html attribute test for Display Text tests
--- unit/test-stkutil.c | 211 +++ 1 files changed, 211 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 2a56259..bca2899 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -537,6 +537,7 @@ struct display_text_test { struct stk_duration duration; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + const char *html; }; unsigned char display_text_111[] = { 0xD0, 0x1A, 0x81, 0x03, 0x01, 0x21, 0x80, @@ -632,6 +633,69 @@ unsigned char display_text_711[] = { 0xD0, 0x19, 0x81, 0x03, 0x01, 0x21, 0x80, 0x63, 0x6F, 0x6E, 0x64, 0x84, 0x02, 0x01, 0x0A }; +unsigned char display_text_811[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x00, 0xB4 }; + +unsigned char display_text_821[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x01, 0xB4 }; + +unsigned char display_text_831[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x02, 0xB4 }; + +unsigned char display_text_841[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x04, 0xB4 }; + +unsigned char display_text_851[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x08, 0xB4 }; + +unsigned char display_text_861[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x10, 0xB4 }; + +unsigned char display_text_871[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x20, 0xB4 }; + +unsigned char display_text_881[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x40, 0xB4 }; + +unsigned char display_text_891[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x80, 0xB4 }; + unsigned char display_text_911[] = { 0xD0, 0x10, 0x81, 0x03, 0x01, 0x21, 0x80,
[PATCH 2/9] test-stkutil: add unit test for html text attributes
--- unit/test-stkutil.c | 96 +++ 1 files changed, 96 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index dbd5b5e..2a56259 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -478,6 +478,29 @@ static inline void check_cdma_sms_tpdu( check_common_byte_array(command, test); } +static void check_text_attr_html(const struct stk_text_attribute *test, + char *text, const char *expected_html) +{ + char *html; + unsigned short attrs[256]; + int i; + + if (expected_html == NULL) + return; + + for (i = 0; i test-len; i += 4) { + attrs[i] = test-attributes[i]; + attrs[i + 1] = test-attributes[i + 1]; + attrs[i + 2] = test-attributes[i + 2]; + attrs[i + 3] = test-attributes[i + 3]; + } + html = stk_text_to_html(text, attrs, test-len / 4); + + g_assert(memcmp(html, expected_html, strlen(expected_html)) == 0); + + g_free(html); +} + /* Defined in TS 102.223 Section 8.72 */ static void check_text_attr(const struct stk_text_attribute *command, const struct stk_text_attribute *test) @@ -22139,6 +22162,70 @@ static const struct envelope_test timer_expiration_data_221a = { }, }; +struct html_attr_test { + char *text; + struct stk_text_attribute text_attr; + char *html; +}; + +static struct html_attr_test html_attr_data_1 = { + .text = Blue green green green, + .text_attr = { + .len = 8, + .attributes = { 0x00, 0x00, 0x03, 0x94, 0x00, 0x04, 0x03, + 0x96 }, + }, + .html = span style=\color: #A0;background-color: #FF;\ + Blue/spanspan style=\color: #347235;background-color: + #FF;\ green green green/span, +}; + +static struct html_attr_test html_attr_data_2 = { + .text = abc, + .text_attr = { + .len = 8, + .attributes = { 0x00, 0x02, 0x03, 0x94, 0x01, 0x02, 0x03, + 0x96 }, + }, + .html = span style=\color: #347235;background-color: #FF;\ + a/spanspan style=\color: #A0;background-color: + #FF;\bc/span, +}; + +static struct html_attr_test html_attr_data_3 = { + .text = 1 2, 2 1, 1 0 == 0\nSpecial Chars are Fun\r\nTo Write, + .text_attr = { + .len = 4, + .attributes = { 0x00, 0x00, 0x03, 0x00 }, + }, + .html = 1 lt; 2, 2 gt; 1, 1 amp; 0 == 0br/Special Chars are Fun + br/To Write, +}; + +static struct html_attr_test html_attr_data_4 = { + .text = €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ + €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ + €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ + €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ + €€€€€€€€€€€€€€€, + .text_attr = { + .len = 4, + .attributes = { 0x00, 0x00, 0x03, 0x94 }, + }, + .html = span style=\color: #347235;background-color: #FF;\ + €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ + €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ + €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ + €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ + €€€€€€€€€€€€€€€/span, +}; + +static void test_html_attr(gconstpointer data) +{ + const struct html_attr_test *test = data; + check_text_attr_html(test-text_attr, test-text, test-html); +} + int main(int argc, char **argv) { g_test_init(argc, argv, NULL); @@ -24146,5 +24233,14 @@ int
[PATCH 4/9] test-stkutil: add html attribute tests for get_inkey_test
--- unit/test-stkutil.c | 75 --- 1 files changed, 59 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index bca2899..c38b272 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -984,6 +984,7 @@ struct get_inkey_test { struct stk_duration duration; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char get_inkey_111[] = { 0xD0, 0x15, 0x81, 0x03, 0x01, 0x22, @@ -1589,7 +1590,9 @@ static struct get_inkey_test get_inkey_data_911 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Enter \+\/span/div, }; static struct get_inkey_test get_inkey_data_912 = { @@ -1607,7 +1610,10 @@ static struct get_inkey_test get_inkey_data_921 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Enter \+\/span + /div, }; static struct get_inkey_test get_inkey_data_922 = { @@ -1625,7 +1631,10 @@ static struct get_inkey_test get_inkey_data_931 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Enter \+\/span + /div, }; static struct get_inkey_test get_inkey_data_932 = { @@ -1643,7 +1652,10 @@ static struct get_inkey_test get_inkey_data_941 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x04, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-size: + big;color: #347235;background-color: #00;\Enter \+\ + /span/div, }; static struct get_inkey_test get_inkey_data_942 = { @@ -1654,7 +1666,9 @@ static struct get_inkey_test get_inkey_data_942 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Enter \#\/span/div, }; static struct get_inkey_test get_inkey_data_943 = { @@ -1672,7 +1686,10 @@ static struct get_inkey_test get_inkey_data_951 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x08, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-size: + small;color: #347235;background-color: #00;\ + Enter \+\/span/div, }; static struct get_inkey_test get_inkey_data_952 = { @@ -1683,7 +1700,9 @@ static struct get_inkey_test get_inkey_data_952 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Enter \#\/span/div, }; static struct get_inkey_test get_inkey_data_953 = { @@ -1701,7 +1720,10 @@ static struct get_inkey_test get_inkey_data_961 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x10, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-weight: + bold;color: #347235;background-color: #00;\Enter \+\ + /span/div, }; static struct get_inkey_test get_inkey_data_962 = { @@ -1712,7 +1734,9 @@ static struct get_inkey_test get_inkey_data_962 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Enter \#\/span/div, }; static struct get_inkey_test get_inkey_data_963 = { @@ -1730,7 +1754,10 @@ static struct get_inkey_test get_inkey_data_971 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x20, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-style: + italic;color: #347235;background-color: #00;\ + Enter \+\/span/div, }; static struct get_inkey_test get_inkey_data_972 = { @@ -1741,7 +1768,9 @@ static struct get_inkey_test get_inkey_data_972 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color:
[PATCH 5/9] test-stkutil: add html attribute tests for get_input_test
--- unit/test-stkutil.c | 75 --- 1 files changed, 59 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index c38b272..bb09270 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -1964,6 +1964,7 @@ struct get_input_test { struct stk_icon_id icon_id; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char get_input_111[] = { 0xD0, 0x1B, 0x81, 0x03, 0x01, 0x23, @@ -2799,7 +2800,9 @@ static struct get_input_test get_input_data_811 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Enter 12345/span/div }; static struct get_input_test get_input_data_812 = { @@ -2825,7 +2828,10 @@ static struct get_input_test get_input_data_821 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Enter 12345/span + /div, }; static struct get_input_test get_input_data_822 = { @@ -2851,7 +2857,10 @@ static struct get_input_test get_input_data_831 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Enter 12345/span + /div, }; static struct get_input_test get_input_data_832 = { @@ -2877,7 +2886,10 @@ static struct get_input_test get_input_data_841 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x04, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-size: + big;color: #347235;background-color: #00;\Enter 12345 + /span/div, }; static struct get_input_test get_input_data_842 = { @@ -2892,7 +2904,9 @@ static struct get_input_test get_input_data_842 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Enter 2/span/div }; static struct get_input_test get_input_data_843 = { @@ -2918,7 +2932,10 @@ static struct get_input_test get_input_data_851 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x08, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-size: + small;color: #347235;background-color: #00;\Enter + 12345/span/div, }; static struct get_input_test get_input_data_852 = { @@ -2933,7 +2950,9 @@ static struct get_input_test get_input_data_852 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Enter 2/span/div, }; static struct get_input_test get_input_data_853 = { @@ -2959,7 +2978,10 @@ static struct get_input_test get_input_data_861 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x10, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-weight: + bold;color: #347235;background-color: #00;\Enter + 12345/span/div }; static struct get_input_test get_input_data_862 = { @@ -2974,7 +2996,9 @@ static struct get_input_test get_input_data_862 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Enter 2/span/div, }; static struct get_input_test get_input_data_863 = { @@ -3000,7 +3024,10 @@ static struct get_input_test get_input_data_871 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x20, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-style: + italic;color: #347235;background-color: #00;\Enter + 12345/span/div, }; static struct get_input_test get_input_data_872 = { @@ -3015,7 +3042,9 @@ static struct get_input_test get_input_data_872 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: +
[PATCH 6/9] test-stkutil: add html attribute tests for play_tone_test
--- unit/test-stkutil.c | 82 +-- 1 files changed, 66 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index bb09270..d1a633f 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -3351,6 +3351,7 @@ struct play_tone_test { struct stk_icon_id icon_id; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char play_tone_111[] = { 0xD0, 0x1B, 0x81, 0x03, 0x01, 0x20, @@ -4121,7 +4122,10 @@ static struct play_tone_test play_tone_data_411 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Text Attribute 1/span + /div, }; static struct play_tone_test play_tone_data_412 = { @@ -4149,7 +4153,10 @@ static struct play_tone_test play_tone_data_421 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Text Attribute 1/span + /div, }; static struct play_tone_test play_tone_data_422 = { @@ -4177,7 +4184,10 @@ static struct play_tone_test play_tone_data_431 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Text Attribute 1/span + /div, }; static struct play_tone_test play_tone_data_432 = { @@ -4205,7 +4215,10 @@ static struct play_tone_test play_tone_data_441 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x04, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-size: + big;color: #347235;background-color: #00;\ + Text Attribute 1/span/div, }; static struct play_tone_test play_tone_data_442 = { @@ -4221,7 +4234,10 @@ static struct play_tone_test play_tone_data_442 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Text Attribute 2/span + /div, }; static struct play_tone_test play_tone_data_443 = { @@ -4249,7 +4265,10 @@ static struct play_tone_test play_tone_data_451 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x08, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-size: + small;color: #347235;background-color: #00;\ + Text Attribute 1/span/div, }; static struct play_tone_test play_tone_data_452 = { @@ -4265,7 +4284,10 @@ static struct play_tone_test play_tone_data_452 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Text Attribute 2/span + /div, }; static struct play_tone_test play_tone_data_453 = { @@ -4293,7 +4315,10 @@ static struct play_tone_test play_tone_data_461 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0E, 0x10, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-weight: + bold;color: #347235;background-color: #00;\ + Text Attribute/span/div 1 }; static struct play_tone_test play_tone_data_462 = { @@ -4309,7 +4334,10 @@ static struct play_tone_test play_tone_data_462 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Text Attribute 2/span + /div, }; static struct play_tone_test play_tone_data_463 = { @@ -4337,7 +4365,10 @@ static struct play_tone_test play_tone_data_471 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0E, 0x20, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-style: + italic;color: #347235;background-color: #00;\ + Text Attribute/span/div 1, }; static struct play_tone_test play_tone_data_472 = { @@ -4353,7 +4384,10 @@ static struct play_tone_test play_tone_data_472 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00,
[PATCH 9/9] test-stkutil: add html attribute tests for setup idle mode tests
--- unit/test-stkutil.c | 84 +-- 1 files changed, 68 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 20a3902..1d7485a 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -13994,6 +13994,7 @@ struct setup_idle_mode_text_test { struct stk_icon_id icon_id; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char setup_idle_mode_text_111[] = { 0xD0, 0x1A, 0x81, 0x03, @@ -14426,7 +14427,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_411 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 1/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_412 = { @@ -1,7 +14448,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_421 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 1/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_422 = { @@ -14462,7 +14469,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_431 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 1/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_432 = { @@ -14480,7 +14490,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_441 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x04, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-size: + big;color: #347235;background-color: #00;\ + Idle Mode Text 1/span/div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_442 = { @@ -14491,7 +14504,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_442 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 2/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_443 = { @@ -14509,7 +14525,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_451 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x08, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-size: + small;color: #347235;background-color: #00;\ + Idle Mode Text 1/span/div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_452 = { @@ -14520,7 +14539,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_452 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 2/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_453 = { @@ -14538,7 +14560,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_461 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x10, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\font-weight: + bold;color: #347235;background-color: #00;\ + Idle Mode Text 1/span/div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_462 = { @@ -14549,7 +14574,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_462 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = div style=\text-align: left;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 2/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_463 = { @@ -14567,7 +14595,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_471 = { .text_attr = { .len = 4, .attributes =
Re: [PATCH 1/9] stkutil: display text attributes as html
On Thu, 08 Jul 2010 17:49:56 -0500 Denis Kenzior denk...@gmail.com wrote: + /* +* if the alignment is the same as either the default +* or the last alignment used, don't set any alignment +* value. +*/ + if (start == 0) + align = STK_DEFAULT_TEXT_ALIGNMENT; + else { + align = (formats[start - 1] 0xFF) + STK_TEXT_FORMAT_ALIGN_MASK; + if (align == STK_TEXT_FORMAT_NO_ALIGN) + align = STK_DEFAULT_TEXT_ALIGNMENT; + } + + if ((code STK_TEXT_FORMAT_ALIGN_MASK) == align) + code |= STK_TEXT_FORMAT_NO_ALIGN; + So I think the above code is actually incorrect. The spec talks about Language dependent (default) alignment being equal to STK_DEFAULT_TEXT_ALIGNMENT. So if the SIM sends us a Left aligned attribute, it really means Left aligned. Maybe something like this is enough? if (start == 0) align = STK_TEXT_FORMAT_NO_ALIGN; else align = formats[start - 1] STK_TEXT_FORMAT_ALIGN_MASK; I agree with you that this does not match the spec. I did this deliberately, because I had a problem deciding how to deal with the test case which you requested I include, which was defined in test_sms.c (header_test). I included the test case below for your reference. static struct html_attr_test html_attr_data_1 = { .text = EMS messages can contain italic, bold, large, small and colored text, .text_attr = { .len = 20, .attributes = { 0x19, 0x06, 0x20, 0x00, 0x21, 0x04, 0x10, 0x00, 0x27, 0x05, 0x04, 0x00, 0x2E, 0x05, 0x08, 0x00, 0x38, 0x07, 0x00, 0x2B }, }, .html = EMS messages can contain span style=\font-style: italic;\italic/span, span style=\font-weight: bold;\ bold/span, span style=\font-size: big;\large/span, span style=\font-size: small;\small/span and span style=\color: #00;background-color: #C11B17;\ colored/span text, }; So, you have your first formatting at start position 0x19, with format code 0x20, and color not set (0x00). Since previously you had no formatting from the beginning to byte 0x19, and this formatting specifies an alignment value of 0, if we interpret this the way you suggest we will now insert a div tag with left alignment specified at character 0x19, which would cause a break in the text. So, we can chose to interpret left alignment as really meaning left alignment, which would be correct according to the spec, but if this test case is truly representative of what SIMs might send us, then we are going to have some weird looking strings resulting. How would you suggest handling this? ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 1/9] stkutil: display text attributes as html
On Fri, 09 Jul 2010 17:13:57 -0500 Denis Kenzior denk...@gmail.com wrote: Hi Kristen, I agree with you that this does not match the spec. I did this deliberately, because I had a problem deciding how to deal with the test case which you requested I include, which was defined in test_sms.c (header_test). I included the test case below for your reference. static struct html_attr_test html_attr_data_1 = { .text = EMS messages can contain italic, bold, large, small and colored text, .text_attr = { .len = 20, .attributes = { 0x19, 0x06, 0x20, 0x00, 0x21, 0x04, 0x10, 0x00, 0x27, 0x05, 0x04, 0x00, 0x2E, 0x05, 0x08, 0x00, 0x38, 0x07, 0x00, 0x2B }, }, .html = EMS messages can contain span style=\font-style: italic;\italic/span, span style=\font-weight: bold;\ bold/span, span style=\font-size: big;\large/span, span style=\font-size: small;\small/span and span style=\color: #00;background-color: #C11B17;\ colored/span text, }; So, you have your first formatting at start position 0x19, with format code 0x20, and color not set (0x00). Since previously you had no formatting from the beginning to byte 0x19, and this formatting specifies an alignment value of 0, if we interpret this the way you suggest we will now insert a div tag with left alignment specified at character 0x19, which would cause a break in the text. So, we can chose to interpret left alignment as really meaning left alignment, which would be correct according to the spec, but if this test case is truly representative of what SIMs might send us, then we are going to have some weird looking strings resulting. How would you suggest handling this? The above test is pretty arbitrary, so I wouldn't worry too much about it. I think that the explicit left alignment is better and is in line with tests from 102.384. However, maybe generating some additional SMS messages with EMS text attributes for testing might be a good idea. See if anyone has an old Sony Ericsson mobile around? Regards, -Denis I'll delete this test then. Not sure if I'll be able to find a Sony Ericsson laying around, so adding other SMS messages might need to be delayed. ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/9] html text attribute patches
Changes since last version: * made utf8 safe * changed signature to use 16 bit arrays for attributes * changed signature to use number of attributes rather than length of attribute * assume attributes are always 4 bytes * incorporated other feedback from last review * added unit test for utf8 text Kristen Carlson Accardi (9): stkutil: display text attributes as html test-stkutil: add unit test for html text attributes test-stkutil: add html attribute test for Display Text tests test-stkutil: add html attribute tests for get_inkey_test test-stkutil: add html attribute tests for get_input_test test-stkutil: add html attribute tests for play_tone_test test-stkutil: add html attribute test for setup_menu_test test-stkutil: add html attribute test for select_item_test test-stkutil: add html attribute tests for setup idle mode tests src/stkutil.c | 229 src/stkutil.h |2 + unit/test-stkutil.c | 714 --- 3 files changed, 853 insertions(+), 92 deletions(-) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 4/9] test-stkutil: add html attribute tests for get_inkey_test
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 6f781ed..e48ab0d 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -977,6 +977,7 @@ struct get_inkey_test { struct stk_duration duration; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char get_inkey_111[] = { 0xD0, 0x15, 0x81, 0x03, 0x01, 0x22, @@ -1582,7 +1583,9 @@ static struct get_inkey_test get_inkey_data_911 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \+\/span, }; static struct get_inkey_test get_inkey_data_912 = { @@ -1600,7 +1603,10 @@ static struct get_inkey_test get_inkey_data_921 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Enter \+\/span + /div, }; static struct get_inkey_test get_inkey_data_922 = { @@ -1618,7 +1624,10 @@ static struct get_inkey_test get_inkey_data_931 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Enter \+\/span + /div, }; static struct get_inkey_test get_inkey_data_932 = { @@ -1636,7 +1645,9 @@ static struct get_inkey_test get_inkey_data_941 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Enter \+\/span, }; static struct get_inkey_test get_inkey_data_942 = { @@ -1647,7 +1658,9 @@ static struct get_inkey_test get_inkey_data_942 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \#\/span, }; static struct get_inkey_test get_inkey_data_943 = { @@ -1665,7 +1678,9 @@ static struct get_inkey_test get_inkey_data_951 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Enter \+\/span, }; static struct get_inkey_test get_inkey_data_952 = { @@ -1676,7 +1691,9 @@ static struct get_inkey_test get_inkey_data_952 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \#\/span, }; static struct get_inkey_test get_inkey_data_953 = { @@ -1694,7 +1711,9 @@ static struct get_inkey_test get_inkey_data_961 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Enter \+\/span, }; static struct get_inkey_test get_inkey_data_962 = { @@ -1705,7 +1724,9 @@ static struct get_inkey_test get_inkey_data_962 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \#\/span, }; static struct get_inkey_test get_inkey_data_963 = { @@ -1723,7 +1744,9 @@ static struct get_inkey_test get_inkey_data_971 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Enter \+\/span, }; static struct get_inkey_test get_inkey_data_972 = { @@ -1734,7 +1757,9 @@ static struct get_inkey_test get_inkey_data_972 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \#\/span, }; static struct get_inkey_test get_inkey_data_973 = { @@ -1752,7 +1777,9 @@ static struct get_inkey_test get_inkey_data_981 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x40, 0xB4 } - } + }, + .html = span style=\text-decoration: underline;color: #347235; +
[PATCH 5/9] test-stkutil: add html attribute tests for get_input_test
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index e48ab0d..ffa2b4c 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -1951,6 +1951,7 @@ struct get_input_test { struct stk_icon_id icon_id; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char get_input_111[] = { 0xD0, 0x1B, 0x81, 0x03, 0x01, 0x23, @@ -2786,7 +2787,9 @@ static struct get_input_test get_input_data_811 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 12345/span }; static struct get_input_test get_input_data_812 = { @@ -2812,7 +2815,10 @@ static struct get_input_test get_input_data_821 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Enter 12345/span + /div, }; static struct get_input_test get_input_data_822 = { @@ -2838,7 +2844,10 @@ static struct get_input_test get_input_data_831 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Enter 12345/span + /div, }; static struct get_input_test get_input_data_832 = { @@ -2864,7 +2873,9 @@ static struct get_input_test get_input_data_841 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Enter 12345/span, }; static struct get_input_test get_input_data_842 = { @@ -2879,7 +2890,9 @@ static struct get_input_test get_input_data_842 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 2/span }; static struct get_input_test get_input_data_843 = { @@ -2905,7 +2918,9 @@ static struct get_input_test get_input_data_851 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Enter 12345/span, }; static struct get_input_test get_input_data_852 = { @@ -2920,7 +2935,9 @@ static struct get_input_test get_input_data_852 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 2/span }; static struct get_input_test get_input_data_853 = { @@ -2946,7 +2963,9 @@ static struct get_input_test get_input_data_861 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Enter 12345/span }; static struct get_input_test get_input_data_862 = { @@ -2961,7 +2980,9 @@ static struct get_input_test get_input_data_862 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 2/span }; static struct get_input_test get_input_data_863 = { @@ -2987,7 +3008,9 @@ static struct get_input_test get_input_data_871 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Enter 12345/span }; static struct get_input_test get_input_data_872 = { @@ -3002,7 +3025,9 @@ static struct get_input_test get_input_data_872 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 2/span }; static struct get_input_test get_input_data_873 = { @@ -3028,7 +3053,9 @@ static struct get_input_test get_input_data_881 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x40, 0xB4 } - } + }, + .html = span style=\text-decoration: underline;color: #347235; +
[PATCH 7/9] test-stkutil: add html attribute test for setup_menu_test
--- unit/test-stkutil.c | 50 ++ 1 files changed, 38 insertions(+), 12 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 03d7067..cf06333 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -4657,6 +4657,7 @@ struct setup_menu_test { struct stk_item_icon_id_list item_icon_id_list; struct stk_text_attribute text_attr; struct stk_item_text_attribute_list item_text_attr_list; + char *html; }; static unsigned char setup_menu_111[] = { 0xD0, 0x3B, 0x81, 0x03, 0x01, 0x25, @@ -5470,7 +5471,9 @@ static struct setup_menu_test setup_menu_data_611 = { .len = 12, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_612 = { @@ -5503,7 +5506,10 @@ static struct setup_menu_test setup_menu_data_621 = { .len = 12, .list = { 0x00, 0x06, 0x01, 0xB4, 0x00, 0x06, 0x01, 0xB4, 0x00, 0x06, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Toolkit Menu 1/span + /div }; static struct setup_menu_test setup_menu_data_622 = { @@ -5540,7 +5546,10 @@ static struct setup_menu_test setup_menu_data_631 = { .len = 12, .list = { 0x00, 0x06, 0x02, 0xB4, 0x00, 0x06, 0x02, 0xB4, 0x00, 0x06, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Toolkit Menu 1/span + /div }; static struct setup_menu_test setup_menu_data_632 = { @@ -5573,7 +5582,9 @@ static struct setup_menu_test setup_menu_data_641 = { .len = 12, .list = { 0x00, 0x06, 0x04, 0xB4, 0x00, 0x06, 0x04, 0xB4, 0x00, 0x06, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_642 = { @@ -5594,7 +5605,9 @@ static struct setup_menu_test setup_menu_data_642 = { .len = 12, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Menu 2/span, }; static struct setup_menu_test setup_menu_data_643 = { @@ -5627,7 +5640,9 @@ static struct setup_menu_test setup_menu_data_651 = { .len = 12, .list = { 0x00, 0x06, 0x08, 0xB4, 0x00, 0x06, 0x08, 0xB4, 0x00, 0x06, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_661 = { @@ -5648,7 +5663,9 @@ static struct setup_menu_test setup_menu_data_661 = { .len = 12, .list = { 0x00, 0x06, 0x10, 0xB4, 0x00, 0x06, 0x10, 0xB4, 0x00, 0x06, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_671 = { @@ -5669,7 +5686,9 @@ static struct setup_menu_test setup_menu_data_671 = { .len = 12, .list = { 0x00, 0x06, 0x20, 0xB4, 0x00, 0x06, 0x20, 0xB4, 0x00, 0x06, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Toolkit Menu 1/span }; static struct setup_menu_test setup_menu_data_681 = { @@ -5690,7 +5709,9 @@ static struct setup_menu_test setup_menu_data_681 = { .len = 12, .list = { 0x00, 0x06, 0x40, 0xB4, 0x00, 0x06, 0x40, 0xB4, 0x00, 0x06, 0x40, 0xB4 } - } + }, + .html = span style=\text-decoration: underline;color: #347235; + background-color: #00;\Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_691 = { @@ -5711,7 +5732,9 @@ static struct setup_menu_test setup_menu_data_691 = { .len = 12, .list = { 0x00, 0x06, 0x80, 0xB4, 0x00, 0x06, 0x80, 0xB4, 0x00, 0x06, 0x80, 0xB4 } - } + }, + .html = span style=\text-decoration: line-through;color: #347235; + background-color: #00;\Toolkit Menu 1/span
[PATCH 9/9] test-stkutil: add html attribute tests for setup idle mode tests
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 7993813..348c991 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -13932,6 +13932,7 @@ struct setup_idle_mode_text_test { struct stk_icon_id icon_id; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char setup_idle_mode_text_111[] = { 0xD0, 0x1A, 0x81, 0x03, @@ -14364,7 +14365,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_411 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_412 = { @@ -14382,7 +14385,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_421 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 1/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_422 = { @@ -14400,7 +14406,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_431 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 1/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_432 = { @@ -14418,7 +14427,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_441 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_442 = { @@ -14429,7 +14440,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_442 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Idle Mode Text 2/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_443 = { @@ -14447,7 +14460,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_451 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_452 = { @@ -14458,7 +14473,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_452 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Idle Mode Text 2/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_453 = { @@ -14476,7 +14493,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_461 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_462 = { @@ -14487,7 +14506,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_462 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Idle Mode Text 2/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_463 = { @@ -14505,7 +14526,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_471 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_472 = { @@ -14516,7 +14539,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_472 = {
[PATCH 8/9] test-stkutil: add html attribute test for select_item_test
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index cf06333..7993813 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -5944,6 +5944,7 @@ struct select_item_test { struct stk_text_attribute text_attr; struct stk_item_text_attribute_list item_text_attr_list; struct stk_frame_id frame_id; + char *html; }; static unsigned char select_item_111[] = { 0xD0, 0x3D, 0x81, 0x03, 0x01, 0x24, @@ -6990,7 +6991,9 @@ static struct select_item_test select_item_data_911 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Select 1/span, }; static struct select_item_test select_item_data_912 = { @@ -7020,7 +7023,10 @@ static struct select_item_test select_item_data_921 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x01, 0xB4, 0x00, 0x06, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Toolkit Select 1/span + /div, }; static struct select_item_test select_item_data_922 = { @@ -7050,7 +7056,10 @@ static struct select_item_test select_item_data_931 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x02, 0xB4, 0x00, 0x06, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Toolkit Select 1/span + /div }; static struct select_item_test select_item_data_932 = { @@ -7080,7 +7089,9 @@ static struct select_item_test select_item_data_941 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x04, 0xB4, 0x00, 0x06, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Toolkit Select 1/span, }; static struct select_item_test select_item_data_942 = { @@ -7099,7 +7110,9 @@ static struct select_item_test select_item_data_942 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Select 2/span, }; static struct select_item_test select_item_data_943 = { @@ -7129,7 +7142,9 @@ static struct select_item_test select_item_data_951 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x08, 0xB4, 0x00, 0x06, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Toolkit Select 1/span, }; static struct select_item_test select_item_data_952 = { @@ -7148,7 +7163,9 @@ static struct select_item_test select_item_data_952 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Select 2/span, }; static struct select_item_test select_item_data_953 = { @@ -7178,7 +7195,9 @@ static struct select_item_test select_item_data_961 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x10, 0xB4, 0x00, 0x06, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Toolkit Select 1/span, }; static struct select_item_test select_item_data_962 = { @@ -7197,7 +7216,9 @@ static struct select_item_test select_item_data_962 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Select 2/span, }; static struct select_item_test select_item_data_963 = { @@ -7227,7 +7248,9 @@ static struct select_item_test select_item_data_971 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x20, 0xB4, 0x00, 0x06, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Toolkit Select 1/span }; static struct select_item_test select_item_data_972 = { @@ -7246,7 +7269,9 @@ static struct select_item_test select_item_data_972 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4,
Re: [PATCH 1/3] stkutil: display text attributes as html
On Thu, 01 Jul 2010 11:30:07 -0500 Denis Kenzior denk...@gmail.com wrote: + start = attrs[i++]; + len = attrs[i++]; + code = attrs[i++]; You might want to be extra paranoid here that attrs_len is a multiple of 4. attrs_len does not have to be a multiple of 4. I will add a sanity check to attrs_len to make sure it is at least = i + 3. + + if (i attrs_len) + color = attrs[i++]; + else + color = 0; + + if (len == 0) + end = text_len; + else + end = start + len; + + /* sanity check values */ + if (start end || end text_len) + continue; + + /* +* if the alignment is the same as either the default +* or the last alignment used, don't set any alignment +* value. +*/ + if (start == 0) + align = STK_DEFAULT_TEXT_ALIGNMENT; Are attributes which do not contain start = 0 valid? If so, you might take extra care here. Yes start can be nonzero, but I don't understand what you are asking here. If start is not equal to zero, we have already made sure it is not greater than the end. Thanks, Kristen ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 01/10] stkutil: display text attributes as html
--- src/stkutil.c | 219 + src/stkutil.h |2 + 2 files changed, 221 insertions(+), 0 deletions(-) diff --git a/src/stkutil.c b/src/stkutil.c index 6f072e7..5da356c 100644 --- a/src/stkutil.c +++ b/src/stkutil.c @@ -5819,3 +5819,222 @@ const unsigned char *stk_pdu_from_envelope(const struct stk_envelope *envelope, return pdu; } + +static const char *html_colors[] = { + #00, /* Black */ + #808080, /* Dark Grey */ + #C11B17, /* Dark Red */ + #FBB117, /* Dark Yellow */ + #347235, /* Dark Green */ + #307D7E, /* Dark Cyan */ + #A0, /* Dark Blue */ + #C031C7, /* Dark Magenta */ + #C0C0C0, /* Grey */ + #FF, /* White */ + #FF, /* Bright Red */ + #00, /* Bright Yellow */ + #00FF00, /* Bright Green */ + #00, /* Bright Cyan */ + #FF, /* Bright Blue */ + #FF00FF, /* Bright Magenta */ +}; + +#define STK_TEXT_FORMAT_ALIGN_MASK 0x03 +#define STK_TEXT_FORMAT_FONT_MASK 0x0C +#define STK_TEXT_FORMAT_STYLE_MASK 0xF0 +#define STK_DEFAULT_TEXT_ALIGNMENT 0x00 +#define STK_TEXT_FORMAT_INIT -1 + +/* Defined in ETSI 123 40 9.2.3.24.10.1.1 */ +enum stk_text_format_code { + STK_TEXT_FORMAT_LEFT_ALIGN = 0x00, + STK_TEXT_FORMAT_CENTER_ALIGN = 0x01, + STK_TEXT_FORMAT_RIGHT_ALIGN = 0x02, + STK_TEXT_FORMAT_NO_ALIGN = 0x03, + STK_TEXT_FORMAT_FONT_SIZE_LARGE = 0x04, + STK_TEXT_FORMAT_FONT_SIZE_SMALL = 0x08, + STK_TEXT_FORMAT_FONT_SIZE_RESERVED = 0x0c, + STK_TEXT_FORMAT_STYLE_BOLD = 0x10, + STK_TEXT_FORMAT_STYLE_ITALIC = 0x20, + STK_TEXT_FORMAT_STYLE_UNDERLINED = 0x40, + STK_TEXT_FORMAT_STYLE_STRIKETHROUGH = 0x80, +}; + + +static void end_format(GString *string, guint8 code, guint8 color) +{ + if ((code ~STK_TEXT_FORMAT_ALIGN_MASK) || color) + g_string_append(string, /span); + + if ((code STK_TEXT_FORMAT_ALIGN_MASK) != STK_TEXT_FORMAT_NO_ALIGN) + g_string_append(string, /div); +} + +static void start_format(GString *string, guint8 code, guint8 color) +{ + guint8 align = code STK_TEXT_FORMAT_ALIGN_MASK; + guint8 font = code STK_TEXT_FORMAT_FONT_MASK; + guint8 style = code STK_TEXT_FORMAT_STYLE_MASK; + int fg = color 0x0f; + int bg = (color 4) 0x0f; + + /* align formatting applies to a block of test */ + if (align != STK_TEXT_FORMAT_NO_ALIGN) + g_string_append(string, div style=\); + + switch (align) { + case STK_TEXT_FORMAT_RIGHT_ALIGN: + g_string_append(string, text-align: right;\); + break; + case STK_TEXT_FORMAT_CENTER_ALIGN: + g_string_append(string, text-align: center;\); + break; + case STK_TEXT_FORMAT_LEFT_ALIGN: + g_string_append(string, text-align: left;\); + break; + } + + if (((code ~STK_TEXT_FORMAT_ALIGN_MASK) == 0) (color == 0)) + return; + + /* font, style, and color are inline */ + g_string_append(string, span style=\); + + switch (font) { + case STK_TEXT_FORMAT_FONT_SIZE_LARGE: + g_string_append(string, font-size: big;); + break; + case STK_TEXT_FORMAT_FONT_SIZE_SMALL: + g_string_append(string, font-size: small;); + break; + } + + switch (style) { + case STK_TEXT_FORMAT_STYLE_BOLD: + g_string_append(string, font-weight: bold;); + break; + case STK_TEXT_FORMAT_STYLE_ITALIC: + g_string_append(string, font-style: italic;); + break; + case STK_TEXT_FORMAT_STYLE_UNDERLINED: + g_string_append(string, text-decoration: underline;); + break; + case STK_TEXT_FORMAT_STYLE_STRIKETHROUGH: + g_string_append(string, text-decoration: line-through;); + break; + } + + /* add any color */ + if (fg) + g_string_append_printf(string, color: %s;, html_colors[fg]); + if (bg) + g_string_append_printf(string, background-color: %s;, + html_colors[bg]); + g_string_append(string, \); +} + +char *stk_text_to_html(const char *text, int text_len, + const unsigned char *attrs, int attrs_len) +{ + GString *string = g_string_sized_new(text_len + 1); + int *formats; + int pos, i, j, attr, prev_attr; + guint8 start, end, code, color, len, align; + + formats = g_try_malloc0(sizeof(int) * (text_len + 1)); + if (formats == NULL) + return NULL; + + /* we will need formatting at the position beyond the last char */ + for (i = 0; i = text_len; i++) + formats[i] = STK_TEXT_FORMAT_INIT; + + for (i = 0; i+3 attrs_len; i += 4) { +
[PATCH 00/10] html text attributes patches
Incorporated feedback from last review. Added requested unit tests. Kristen Carlson Accardi (10): stkutil: display text attributes as html test-stkutil: add unit test for html text attributes test-stkutil: add html attribute test for Display Text tests test-stkutil: add html attribute tests for get_inkey_test test-stkutil: add html attribute tests for get_input_test test-stkutil: add html attribute tests for play_tone_test test-stkutil: add html attribute test for setup_menu_test test-stkutil: add html attribute test for select_item_test test-stkutil: add html attribute tests for setup idle mode tests test-stkutil: add html_attr_test for special chars src/stkutil.c | 219 src/stkutil.h |2 + unit/test-stkutil.c | 687 --- 3 files changed, 816 insertions(+), 92 deletions(-) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 02/10] test-stkutil: add unit test for html text attributes
--- unit/test-stkutil.c | 76 +++ 1 files changed, 76 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 8b7e254..57e894b 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -472,6 +472,22 @@ static inline void check_cdma_sms_tpdu( check_common_byte_array(command, test); } +static void check_text_attr_html(const struct stk_text_attribute *test, + char *text, const char *expected_html) +{ + char *html; + + if (expected_html == NULL) + return; + + html = stk_text_to_html(text, strlen(text), test-attributes, + test-len); + + g_assert(memcmp(html, expected_html, strlen(expected_html)) == 0); + + g_free(html); +} + /* Defined in TS 102.223 Section 8.72 */ static void check_text_attr(const struct stk_text_attribute *command, const struct stk_text_attribute *test) @@ -21923,6 +21939,59 @@ static const struct envelope_test timer_expiration_data_221a = { }, }; +struct html_attr_test { + char *text; + struct stk_text_attribute text_attr; + char *html; +}; + +static struct html_attr_test html_attr_data_1 = { + .text = EMS messages can contain italic, bold, large, small and + colored text, + .text_attr = { + .len = 20, + .attributes = { 0x19, 0x06, 0x20, 0x00, 0x21, 0x04, 0x10, 0x00, + 0x27, 0x05, 0x04, 0x00, 0x2E, 0x05, 0x08, 0x00, + 0x38, 0x07, 0x00, 0x2B }, + }, + .html = EMS messages can contain span style=\font-style: + italic;\italic/span, span style=\font-weight: bold;\ + bold/span, span style=\font-size: big;\large/span, + span style=\font-size: small;\small/span and + span style=\color: #00;background-color: #C11B17;\ + colored/span text, +}; + +static struct html_attr_test html_attr_data_2 = { + .text = Blue green green green, + .text_attr = { + .len = 8, + .attributes = { 0x00, 0x00, 0x00, 0x94, 0x00, 0x04, 0x00, + 0x96 }, + }, + .html = span style=\color: #A0;background-color: #FF;\ + Blue/spanspan style=\color: #347235;background-color: + #FF;\ green green green/span, +}; + +static struct html_attr_test html_attr_data_3 = { + .text = abc, + .text_attr = { + .len = 8, + .attributes = { 0x00, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00, + 0x96 }, + }, + .html = span style=\color: #347235;background-color: #FF;\ + a/spanspan style=\color: #A0;background-color: + #FF;\bc/span, +}; + +static void test_html_attr(gconstpointer data) +{ + const struct html_attr_test *test = data; + check_text_attr_html(test-text_attr, test-text, test-html); +} + int main(int argc, char **argv) { g_test_init(argc, argv, NULL); @@ -23930,5 +23999,12 @@ int main(int argc, char **argv) g_test_add_data_func(/teststk/Timer Expiration 2.2.1A, timer_expiration_data_221a, test_envelope_encoding); + g_test_add_data_func(/teststk/HTML Attribute Test 1, + html_attr_data_1, test_html_attr); + g_test_add_data_func(/teststk/HTML Attribute Test 2, + html_attr_data_2, test_html_attr); + g_test_add_data_func(/teststk/HTML Attribute Test 3, + html_attr_data_3, test_html_attr); + return g_test_run(); } -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 03/10] test-stkutil: add html attribute test for Display Text tests
--- unit/test-stkutil.c | 204 +++ 1 files changed, 204 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 57e894b..bc0e018 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -524,6 +524,7 @@ struct display_text_test { struct stk_duration duration; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + const char *html; }; unsigned char display_text_111[] = { 0xD0, 0x1A, 0x81, 0x03, 0x01, 0x21, 0x80, @@ -619,6 +620,69 @@ unsigned char display_text_711[] = { 0xD0, 0x19, 0x81, 0x03, 0x01, 0x21, 0x80, 0x63, 0x6F, 0x6E, 0x64, 0x84, 0x02, 0x01, 0x0A }; +unsigned char display_text_811[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x00, 0xB4 }; + +unsigned char display_text_821[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x01, 0xB4 }; + +unsigned char display_text_831[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x02, 0xB4 }; + +unsigned char display_text_841[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x04, 0xB4 }; + +unsigned char display_text_851[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x08, 0xB4 }; + +unsigned char display_text_861[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x10, 0xB4 }; + +unsigned char display_text_871[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x20, 0xB4 }; + +unsigned char display_text_881[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x40, 0xB4 }; + +unsigned char display_text_891[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x80, 0xB4 }; + unsigned char display_text_911[] = { 0xD0, 0x10, 0x81, 0x03, 0x01, 0x21, 0x80,
[PATCH 04/10] test-stkutil: add html attribute tests for get_inkey_test
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index bc0e018..3b19227 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -964,6 +964,7 @@ struct get_inkey_test { struct stk_duration duration; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char get_inkey_111[] = { 0xD0, 0x15, 0x81, 0x03, 0x01, 0x22, @@ -1569,7 +1570,9 @@ static struct get_inkey_test get_inkey_data_911 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \+\/span, }; static struct get_inkey_test get_inkey_data_912 = { @@ -1587,7 +1590,10 @@ static struct get_inkey_test get_inkey_data_921 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Enter \+\/span + /div, }; static struct get_inkey_test get_inkey_data_922 = { @@ -1605,7 +1611,10 @@ static struct get_inkey_test get_inkey_data_931 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Enter \+\/span + /div, }; static struct get_inkey_test get_inkey_data_932 = { @@ -1623,7 +1632,9 @@ static struct get_inkey_test get_inkey_data_941 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Enter \+\/span, }; static struct get_inkey_test get_inkey_data_942 = { @@ -1634,7 +1645,9 @@ static struct get_inkey_test get_inkey_data_942 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \#\/span, }; static struct get_inkey_test get_inkey_data_943 = { @@ -1652,7 +1665,9 @@ static struct get_inkey_test get_inkey_data_951 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Enter \+\/span, }; static struct get_inkey_test get_inkey_data_952 = { @@ -1663,7 +1678,9 @@ static struct get_inkey_test get_inkey_data_952 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \#\/span, }; static struct get_inkey_test get_inkey_data_953 = { @@ -1681,7 +1698,9 @@ static struct get_inkey_test get_inkey_data_961 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Enter \+\/span, }; static struct get_inkey_test get_inkey_data_962 = { @@ -1692,7 +1711,9 @@ static struct get_inkey_test get_inkey_data_962 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \#\/span, }; static struct get_inkey_test get_inkey_data_963 = { @@ -1710,7 +1731,9 @@ static struct get_inkey_test get_inkey_data_971 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Enter \+\/span, }; static struct get_inkey_test get_inkey_data_972 = { @@ -1721,7 +1744,9 @@ static struct get_inkey_test get_inkey_data_972 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter \#\/span, }; static struct get_inkey_test get_inkey_data_973 = { @@ -1739,7 +1764,9 @@ static struct get_inkey_test get_inkey_data_981 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x09, 0x40, 0xB4 } - } + }, + .html = span style=\text-decoration: underline;color: #347235; +
[PATCH 06/10] test-stkutil: add html attribute tests for play_tone_test
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 4d22d94..3ab3528 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -3319,6 +3319,7 @@ struct play_tone_test { struct stk_icon_id icon_id; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char play_tone_111[] = { 0xD0, 0x1B, 0x81, 0x03, 0x01, 0x20, @@ -4089,7 +4090,9 @@ static struct play_tone_test play_tone_data_411 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Text Attribute 1/span, }; static struct play_tone_test play_tone_data_412 = { @@ -4117,7 +4120,10 @@ static struct play_tone_test play_tone_data_421 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Text Attribute 1/span + /div, }; static struct play_tone_test play_tone_data_422 = { @@ -4145,7 +4151,10 @@ static struct play_tone_test play_tone_data_431 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Text Attribute 1/span + /div, }; static struct play_tone_test play_tone_data_432 = { @@ -4173,7 +4182,9 @@ static struct play_tone_test play_tone_data_441 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Text Attribute 1/span, }; static struct play_tone_test play_tone_data_442 = { @@ -4189,7 +4200,9 @@ static struct play_tone_test play_tone_data_442 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Text Attribute 2/span, }; static struct play_tone_test play_tone_data_443 = { @@ -4217,7 +4230,9 @@ static struct play_tone_test play_tone_data_451 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Text Attribute 1/span, }; static struct play_tone_test play_tone_data_452 = { @@ -4233,7 +4248,9 @@ static struct play_tone_test play_tone_data_452 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Text Attribute 2/span, }; static struct play_tone_test play_tone_data_453 = { @@ -4261,7 +4278,9 @@ static struct play_tone_test play_tone_data_461 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0E, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Text Attribute/span 1 }; static struct play_tone_test play_tone_data_462 = { @@ -4277,7 +4296,9 @@ static struct play_tone_test play_tone_data_462 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Text Attribute 2/span, }; static struct play_tone_test play_tone_data_463 = { @@ -4305,7 +4326,9 @@ static struct play_tone_test play_tone_data_471 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0E, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Text Attribute/span 1, }; static struct play_tone_test play_tone_data_472 = { @@ -4321,7 +4344,9 @@ static struct play_tone_test play_tone_data_472 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Text Attribute 2/span, }; static struct play_tone_test play_tone_data_473 = { @@ -4349,7 +4374,9 @@ static struct play_tone_test play_tone_data_481 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x40, 0xB4 } - } + }, +
[PATCH 05/10] test-stkutil: add html attribute tests for get_input_test
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 3b19227..4d22d94 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -1938,6 +1938,7 @@ struct get_input_test { struct stk_icon_id icon_id; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char get_input_111[] = { 0xD0, 0x1B, 0x81, 0x03, 0x01, 0x23, @@ -2773,7 +2774,9 @@ static struct get_input_test get_input_data_811 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 12345/span }; static struct get_input_test get_input_data_812 = { @@ -2799,7 +2802,10 @@ static struct get_input_test get_input_data_821 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Enter 12345/span + /div, }; static struct get_input_test get_input_data_822 = { @@ -2825,7 +2831,10 @@ static struct get_input_test get_input_data_831 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Enter 12345/span + /div, }; static struct get_input_test get_input_data_832 = { @@ -2851,7 +2860,9 @@ static struct get_input_test get_input_data_841 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Enter 12345/span, }; static struct get_input_test get_input_data_842 = { @@ -2866,7 +2877,9 @@ static struct get_input_test get_input_data_842 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 2/span }; static struct get_input_test get_input_data_843 = { @@ -2892,7 +2905,9 @@ static struct get_input_test get_input_data_851 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Enter 12345/span, }; static struct get_input_test get_input_data_852 = { @@ -2907,7 +2922,9 @@ static struct get_input_test get_input_data_852 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 2/span }; static struct get_input_test get_input_data_853 = { @@ -2933,7 +2950,9 @@ static struct get_input_test get_input_data_861 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Enter 12345/span }; static struct get_input_test get_input_data_862 = { @@ -2948,7 +2967,9 @@ static struct get_input_test get_input_data_862 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 2/span }; static struct get_input_test get_input_data_863 = { @@ -2974,7 +2995,9 @@ static struct get_input_test get_input_data_871 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Enter 12345/span }; static struct get_input_test get_input_data_872 = { @@ -2989,7 +3012,9 @@ static struct get_input_test get_input_data_872 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Enter 2/span }; static struct get_input_test get_input_data_873 = { @@ -3015,7 +3040,9 @@ static struct get_input_test get_input_data_881 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x0B, 0x40, 0xB4 } - } + }, + .html = span style=\text-decoration: underline;color: #347235; +
[PATCH 07/10] test-stkutil: add html attribute test for setup_menu_test
--- unit/test-stkutil.c | 50 ++ 1 files changed, 38 insertions(+), 12 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 3ab3528..fca4526 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -4644,6 +4644,7 @@ struct setup_menu_test { struct stk_item_icon_id_list item_icon_id_list; struct stk_text_attribute text_attr; struct stk_item_text_attribute_list item_text_attr_list; + char *html; }; static unsigned char setup_menu_111[] = { 0xD0, 0x3B, 0x81, 0x03, 0x01, 0x25, @@ -5457,7 +5458,9 @@ static struct setup_menu_test setup_menu_data_611 = { .len = 12, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_612 = { @@ -5490,7 +5493,10 @@ static struct setup_menu_test setup_menu_data_621 = { .len = 12, .list = { 0x00, 0x06, 0x01, 0xB4, 0x00, 0x06, 0x01, 0xB4, 0x00, 0x06, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Toolkit Menu 1/span + /div }; static struct setup_menu_test setup_menu_data_622 = { @@ -5527,7 +5533,10 @@ static struct setup_menu_test setup_menu_data_631 = { .len = 12, .list = { 0x00, 0x06, 0x02, 0xB4, 0x00, 0x06, 0x02, 0xB4, 0x00, 0x06, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Toolkit Menu 1/span + /div }; static struct setup_menu_test setup_menu_data_632 = { @@ -5560,7 +5569,9 @@ static struct setup_menu_test setup_menu_data_641 = { .len = 12, .list = { 0x00, 0x06, 0x04, 0xB4, 0x00, 0x06, 0x04, 0xB4, 0x00, 0x06, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_642 = { @@ -5581,7 +5592,9 @@ static struct setup_menu_test setup_menu_data_642 = { .len = 12, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Menu 2/span, }; static struct setup_menu_test setup_menu_data_643 = { @@ -5614,7 +5627,9 @@ static struct setup_menu_test setup_menu_data_651 = { .len = 12, .list = { 0x00, 0x06, 0x08, 0xB4, 0x00, 0x06, 0x08, 0xB4, 0x00, 0x06, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_661 = { @@ -5635,7 +5650,9 @@ static struct setup_menu_test setup_menu_data_661 = { .len = 12, .list = { 0x00, 0x06, 0x10, 0xB4, 0x00, 0x06, 0x10, 0xB4, 0x00, 0x06, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_671 = { @@ -5656,7 +5673,9 @@ static struct setup_menu_test setup_menu_data_671 = { .len = 12, .list = { 0x00, 0x06, 0x20, 0xB4, 0x00, 0x06, 0x20, 0xB4, 0x00, 0x06, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Toolkit Menu 1/span }; static struct setup_menu_test setup_menu_data_681 = { @@ -5677,7 +5696,9 @@ static struct setup_menu_test setup_menu_data_681 = { .len = 12, .list = { 0x00, 0x06, 0x40, 0xB4, 0x00, 0x06, 0x40, 0xB4, 0x00, 0x06, 0x40, 0xB4 } - } + }, + .html = span style=\text-decoration: underline;color: #347235; + background-color: #00;\Toolkit Menu 1/span, }; static struct setup_menu_test setup_menu_data_691 = { @@ -5698,7 +5719,9 @@ static struct setup_menu_test setup_menu_data_691 = { .len = 12, .list = { 0x00, 0x06, 0x80, 0xB4, 0x00, 0x06, 0x80, 0xB4, 0x00, 0x06, 0x80, 0xB4 } - } + }, + .html = span style=\text-decoration: line-through;color: #347235; + background-color: #00;\Toolkit Menu 1/span
[PATCH 08/10] test-stkutil: add html attribute test for select_item_test
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index fca4526..ada02c0 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -5927,6 +5927,7 @@ struct select_item_test { struct stk_text_attribute text_attr; struct stk_item_text_attribute_list item_text_attr_list; struct stk_frame_id frame_id; + char *html; }; static unsigned char select_item_111[] = { 0xD0, 0x3D, 0x81, 0x03, 0x01, 0x24, @@ -6973,7 +6974,9 @@ static struct select_item_test select_item_data_911 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Select 1/span, }; static struct select_item_test select_item_data_912 = { @@ -7003,7 +7006,10 @@ static struct select_item_test select_item_data_921 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x01, 0xB4, 0x00, 0x06, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Toolkit Select 1/span + /div, }; static struct select_item_test select_item_data_922 = { @@ -7033,7 +7039,10 @@ static struct select_item_test select_item_data_931 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x02, 0xB4, 0x00, 0x06, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Toolkit Select 1/span + /div }; static struct select_item_test select_item_data_932 = { @@ -7063,7 +7072,9 @@ static struct select_item_test select_item_data_941 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x04, 0xB4, 0x00, 0x06, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Toolkit Select 1/span, }; static struct select_item_test select_item_data_942 = { @@ -7082,7 +7093,9 @@ static struct select_item_test select_item_data_942 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Select 2/span, }; static struct select_item_test select_item_data_943 = { @@ -7112,7 +7125,9 @@ static struct select_item_test select_item_data_951 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x08, 0xB4, 0x00, 0x06, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Toolkit Select 1/span, }; static struct select_item_test select_item_data_952 = { @@ -7131,7 +7146,9 @@ static struct select_item_test select_item_data_952 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Select 2/span, }; static struct select_item_test select_item_data_953 = { @@ -7161,7 +7178,9 @@ static struct select_item_test select_item_data_961 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x10, 0xB4, 0x00, 0x06, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Toolkit Select 1/span, }; static struct select_item_test select_item_data_962 = { @@ -7180,7 +7199,9 @@ static struct select_item_test select_item_data_962 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4, 0x00, 0x06, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Toolkit Select 2/span, }; static struct select_item_test select_item_data_963 = { @@ -7210,7 +7231,9 @@ static struct select_item_test select_item_data_971 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x20, 0xB4, 0x00, 0x06, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Toolkit Select 1/span }; static struct select_item_test select_item_data_972 = { @@ -7229,7 +7252,9 @@ static struct select_item_test select_item_data_972 = { .item_text_attr_list = { .len = 8, .list = { 0x00, 0x06, 0x00, 0xB4,
[PATCH 09/10] test-stkutil: add html attribute tests for setup idle mode tests
--- unit/test-stkutil.c | 69 +++ 1 files changed, 53 insertions(+), 16 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index ada02c0..74e2ec2 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -13719,6 +13719,7 @@ struct setup_idle_mode_text_test { struct stk_icon_id icon_id; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + char *html; }; static unsigned char setup_idle_mode_text_111[] = { 0xD0, 0x1A, 0x81, 0x03, @@ -14151,7 +14152,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_411 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_412 = { @@ -14169,7 +14172,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_421 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x01, 0xB4 } - } + }, + .html = div style=\text-align: center;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 1/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_422 = { @@ -14187,7 +14193,10 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_431 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x02, 0xB4 } - } + }, + .html = div style=\text-align: right;\span style=\color: + #347235;background-color: #00;\Idle Mode Text 1/span + /div, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_432 = { @@ -14205,7 +14214,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_441 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x04, 0xB4 } - } + }, + .html = span style=\font-size: big;color: #347235; + background-color: #00;\Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_442 = { @@ -14216,7 +14227,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_442 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Idle Mode Text 2/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_443 = { @@ -14234,7 +14247,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_451 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x08, 0xB4 } - } + }, + .html = span style=\font-size: small;color: #347235; + background-color: #00;\Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_452 = { @@ -14245,7 +14260,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_452 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Idle Mode Text 2/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_453 = { @@ -14263,7 +14280,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_461 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x10, 0xB4 } - } + }, + .html = span style=\font-weight: bold;color: #347235; + background-color: #00;\Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_462 = { @@ -14274,7 +14293,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_462 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x00, 0xB4 } - } + }, + .html = span style=\color: #347235;background-color: #00;\ + Idle Mode Text 2/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_463 = { @@ -14292,7 +14313,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_471 = { .text_attr = { .len = 4, .attributes = { 0x00, 0x10, 0x20, 0xB4 } - } + }, + .html = span style=\font-style: italic;color: #347235; + background-color: #00;\Idle Mode Text 1/span, }; static struct setup_idle_mode_text_test setup_idle_mode_text_data_472 = { @@ -14303,7 +14326,9 @@ static struct setup_idle_mode_text_test setup_idle_mode_text_data_472 = {
[PATCH 10/10] test-stkutil: add html_attr_test for special chars
--- unit/test-stkutil.c | 12 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 74e2ec2..c2e1327 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -22383,6 +22383,16 @@ static struct html_attr_test html_attr_data_3 = { #FF;\bc/span, }; +static struct html_attr_test html_attr_data_4 = { + .text = 1 2, 2 1, 1 0 == 0\nSpecial Chars are Fun\r\nTo Write, + .text_attr = { + .len = 4, + .attributes = { 0x00, 0x00, 0x00 }, + }, + .html = 1 lt; 2, 2 gt; 1, 1 amp; 0 == 0br/Special Chars are Fun + br/To Write, +}; + static void test_html_attr(gconstpointer data) { const struct html_attr_test *test = data; @@ -24420,6 +24430,8 @@ int main(int argc, char **argv) html_attr_data_2, test_html_attr); g_test_add_data_func(/teststk/HTML Attribute Test 3, html_attr_data_3, test_html_attr); + g_test_add_data_func(/teststk/HTML Attribute Test 4, + html_attr_data_4, test_html_attr); return g_test_run(); } -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 1/3] stkutil: display text attributes as html
On Thu, 01 Jul 2010 16:15:35 -0500 Denis Kenzior denk...@gmail.com wrote: On 07/01/2010 03:54 PM, Kristen Carlson Accardi wrote: On Thu, 01 Jul 2010 13:54:16 -0500 Denis Kenzior denk...@gmail.com wrote: Hi Kristen, On 07/01/2010 01:29 PM, Kristen Carlson Accardi wrote: On Thu, 01 Jul 2010 11:30:07 -0500 Denis Kenzior denk...@gmail.com wrote: + start = attrs[i++]; + len = attrs[i++]; + code = attrs[i++]; You might want to be extra paranoid here that attrs_len is a multiple of 4. attrs_len does not have to be a multiple of 4. I will add a sanity check to attrs_len to make sure it is at least = i + 3. Then this code is incorrect, as it handles len 3 attrs only at the end of the array. Also please note that SIM Toolkit Text Attributes are always coded on 4 bytes (see 102.223 Section 8.72 for details). You might want to assume 4 byte alignment or invent a data structure for these attributes. I should have said that attrs_len does not always have to be a multiple of 4 -- it is allowed to only have 3 byte attrs as the last attribute, so the code is correct. However, since not all attributes are required to be of len 4, we can't just assume attrs_len is a multiple of 4. How do you figure this? From 23.040 Section 9.2.3.24.10.1.1 Text Formatting Octet 4 This Octet may be omitted by setting the IED length accordingly. This isn't the clearest language, so my interpretation of this is you may omit one byte if you set the length properly. Clearly the spec tell you that the byte is optional, so I think it would be wrong to assume that all are 4 bytes. Also, since obviously we can't support mixed 3 and 4 byte fields since we'd have no way to know if the next byte was the start of the next attribute, it's got to be at the end of the array. From 102.223 Section 8.72: The Text Formatting is a sequence of one or several Text Formatting items, each coded on 4 bytes. The Text Formatting scheme used is the same as the Text Formatting defined in TS 123 040 [27]. So you either have to support a mixed 3 4 byte fields or you assume all fields are 4 bytes. Regards, -Denis ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/3] html text attribute patches
Modified stkutil per last review. Added unit tests for Display Text tests. I will add the rest of the unit tests after this patch series is reviewed. Kristen Carlson Accardi (3): stkutil: display text attributes as html test-stkutil: add unit test for html text attributes test-stkutil: add html attribute test for Display Text tests src/stkutil.c | 190 ++ src/stkutil.h | 23 unit/test-stkutil.c | 280 +++ 3 files changed, 493 insertions(+), 0 deletions(-) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/3] test-stkutil: add unit test for html text attributes
--- unit/test-stkutil.c | 76 +++ 1 files changed, 76 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 8b7e254..57e894b 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -472,6 +472,22 @@ static inline void check_cdma_sms_tpdu( check_common_byte_array(command, test); } +static void check_text_attr_html(const struct stk_text_attribute *test, + char *text, const char *expected_html) +{ + char *html; + + if (expected_html == NULL) + return; + + html = stk_text_to_html(text, strlen(text), test-attributes, + test-len); + + g_assert(memcmp(html, expected_html, strlen(expected_html)) == 0); + + g_free(html); +} + /* Defined in TS 102.223 Section 8.72 */ static void check_text_attr(const struct stk_text_attribute *command, const struct stk_text_attribute *test) @@ -21923,6 +21939,59 @@ static const struct envelope_test timer_expiration_data_221a = { }, }; +struct html_attr_test { + char *text; + struct stk_text_attribute text_attr; + char *html; +}; + +static struct html_attr_test html_attr_data_1 = { + .text = EMS messages can contain italic, bold, large, small and + colored text, + .text_attr = { + .len = 20, + .attributes = { 0x19, 0x06, 0x20, 0x00, 0x21, 0x04, 0x10, 0x00, + 0x27, 0x05, 0x04, 0x00, 0x2E, 0x05, 0x08, 0x00, + 0x38, 0x07, 0x00, 0x2B }, + }, + .html = EMS messages can contain span style=\font-style: + italic;\italic/span, span style=\font-weight: bold;\ + bold/span, span style=\font-size: big;\large/span, + span style=\font-size: small;\small/span and + span style=\color: #00;background-color: #C11B17;\ + colored/span text, +}; + +static struct html_attr_test html_attr_data_2 = { + .text = Blue green green green, + .text_attr = { + .len = 8, + .attributes = { 0x00, 0x00, 0x00, 0x94, 0x00, 0x04, 0x00, + 0x96 }, + }, + .html = span style=\color: #A0;background-color: #FF;\ + Blue/spanspan style=\color: #347235;background-color: + #FF;\ green green green/span, +}; + +static struct html_attr_test html_attr_data_3 = { + .text = abc, + .text_attr = { + .len = 8, + .attributes = { 0x00, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00, + 0x96 }, + }, + .html = span style=\color: #347235;background-color: #FF;\ + a/spanspan style=\color: #A0;background-color: + #FF;\bc/span, +}; + +static void test_html_attr(gconstpointer data) +{ + const struct html_attr_test *test = data; + check_text_attr_html(test-text_attr, test-text, test-html); +} + int main(int argc, char **argv) { g_test_init(argc, argv, NULL); @@ -23930,5 +23999,12 @@ int main(int argc, char **argv) g_test_add_data_func(/teststk/Timer Expiration 2.2.1A, timer_expiration_data_221a, test_envelope_encoding); + g_test_add_data_func(/teststk/HTML Attribute Test 1, + html_attr_data_1, test_html_attr); + g_test_add_data_func(/teststk/HTML Attribute Test 2, + html_attr_data_2, test_html_attr); + g_test_add_data_func(/teststk/HTML Attribute Test 3, + html_attr_data_3, test_html_attr); + return g_test_run(); } -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 3/3] test-stkutil: add html attribute test for Display Text tests
--- unit/test-stkutil.c | 204 +++ 1 files changed, 204 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 57e894b..bc0e018 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -524,6 +524,7 @@ struct display_text_test { struct stk_duration duration; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + const char *html; }; unsigned char display_text_111[] = { 0xD0, 0x1A, 0x81, 0x03, 0x01, 0x21, 0x80, @@ -619,6 +620,69 @@ unsigned char display_text_711[] = { 0xD0, 0x19, 0x81, 0x03, 0x01, 0x21, 0x80, 0x63, 0x6F, 0x6E, 0x64, 0x84, 0x02, 0x01, 0x0A }; +unsigned char display_text_811[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x00, 0xB4 }; + +unsigned char display_text_821[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x01, 0xB4 }; + +unsigned char display_text_831[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x02, 0xB4 }; + +unsigned char display_text_841[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x04, 0xB4 }; + +unsigned char display_text_851[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x08, 0xB4 }; + +unsigned char display_text_861[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x10, 0xB4 }; + +unsigned char display_text_871[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x20, 0xB4 }; + +unsigned char display_text_881[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x40, 0xB4 }; + +unsigned char display_text_891[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x80, 0xB4 }; + unsigned char display_text_911[] = { 0xD0, 0x10, 0x81, 0x03, 0x01, 0x21, 0x80,
[PATCH 1/3] stkutil: display text attributes as html
--- src/stkutil.c | 190 + src/stkutil.h | 23 +++ 2 files changed, 213 insertions(+), 0 deletions(-) diff --git a/src/stkutil.c b/src/stkutil.c index 6f072e7..843e06b 100644 --- a/src/stkutil.c +++ b/src/stkutil.c @@ -5819,3 +5819,193 @@ const unsigned char *stk_pdu_from_envelope(const struct stk_envelope *envelope, return pdu; } + +static const char *html_colors[] = { + #00, /* Black */ + #808080, /* Dark Grey */ + #C11B17, /* Dark Red */ + #FBB117, /* Dark Yellow */ + #347235, /* Dark Green */ + #307D7E, /* Dark Cyan */ + #A0, /* Dark Blue */ + #C031C7, /* Dark Magenta */ + #C0C0C0, /* Grey */ + #FF, /* White */ + #FF, /* Bright Red */ + #00, /* Bright Yellow */ + #00FF00, /* Bright Green */ + #00, /* Bright Cyan */ + #FF, /* Bright Blue */ + #FF00FF, /* Bright Magenta */ +}; + +static void end_format(GString *string, guint8 code) +{ + g_string_append(string, /span); + + if ((code STK_TEXT_FORMAT_ALIGN_MASK) != STK_TEXT_FORMAT_NO_ALIGN) + g_string_append(string, /div); +} + +static void start_format(GString *string, guint8 code, guint8 color) +{ + guint8 align = code STK_TEXT_FORMAT_ALIGN_MASK; + guint8 font = code STK_TEXT_FORMAT_FONT_MASK; + guint8 style = code STK_TEXT_FORMAT_STYLE_MASK; + int fg = color 0x0f; + int bg = (color 4) 0x0f; + + /* align formatting applies to a block of test */ + if (align != STK_TEXT_FORMAT_NO_ALIGN) + g_string_append(string, div style=\); + + switch (align) { + case STK_TEXT_FORMAT_RIGHT_ALIGN: + g_string_append(string, text-align: right;\); + break; + case STK_TEXT_FORMAT_CENTER_ALIGN: + g_string_append(string, text-align: center;\); + break; + case STK_TEXT_FORMAT_LEFT_ALIGN: + g_string_append(string, text-align: left;\); + break; + } + + /* font, style, and color are inline */ + g_string_append(string, span style=\); + + switch (font) { + case STK_TEXT_FORMAT_FONT_SIZE_LARGE: + g_string_append(string, font-size: big;); + break; + case STK_TEXT_FORMAT_FONT_SIZE_SMALL: + g_string_append(string, font-size: small;); + break; + } + + switch (style) { + case STK_TEXT_FORMAT_STYLE_BOLD: + g_string_append(string, font-weight: bold;); + break; + case STK_TEXT_FORMAT_STYLE_ITALIC: + g_string_append(string, font-style: italic;); + break; + case STK_TEXT_FORMAT_STYLE_UNDERLINED: + g_string_append(string, text-decoration: underline;); + break; + case STK_TEXT_FORMAT_STYLE_STRIKETHROUGH: + g_string_append(string, text-decoration: line-through;); + break; + } + + /* add any color */ + if (fg) + g_string_append_printf(string, color: %s;, html_colors[fg]); + if (bg) + g_string_append_printf(string, background-color: %s;, + html_colors[bg]); + g_string_append(string, \); +} + +char *stk_text_to_html(char *text, int text_len, + const unsigned char *attrs, int attrs_len) +{ + GString *string = g_string_sized_new(text_len + 1); + int formats[257]; /* maximum number of chars in text + 1 */ + int pos = 0, i, j, attr, prev_attr; + guint8 start, end, code, color, len, align; + + /* we will need formatting at the position beyond the last char */ + for (i = 0; i = text_len; i++) + formats[i] = STK_TEXT_FORMAT_INIT; + + i = 0; + + while (i attrs_len) { + start = attrs[i++]; + len = attrs[i++]; + code = attrs[i++]; + + if (i attrs_len) + color = attrs[i++]; + else + color = 0; + + if (len == 0) + end = text_len; + else + end = start + len; + + /* sanity check values */ + if (start end || end text_len) + continue; + + /* +* if the alignment is the same as either the default +* or the last alignment used, don't set any alignment +* value. +*/ + if (start == 0) + align = STK_DEFAULT_TEXT_ALIGNMENT; + else { + align = (formats[start -1] 0xFF) + STK_TEXT_FORMAT_ALIGN_MASK; + if (align == STK_TEXT_FORMAT_NO_ALIGN) +
[PATCH 1/2] stkutil: display text attributes as html
--- src/stkutil.c | 167 + src/stkutil.h | 32 +++ 2 files changed, 199 insertions(+), 0 deletions(-) diff --git a/src/stkutil.c b/src/stkutil.c index 6f072e7..73449e2 100644 --- a/src/stkutil.c +++ b/src/stkutil.c @@ -26,6 +26,7 @@ #include string.h #include stdlib.h #include stdint.h +#include stdio.h #include glib.h @@ -5819,3 +5820,169 @@ const unsigned char *stk_pdu_from_envelope(const struct stk_envelope *envelope, return pdu; } + +static const char *html_colors[] = { + #00, /* Black */ + #808080, /* Dark Grey */ + #C11B17, /* Dark Red */ + #FBB117, /* Dark Yellow */ + #347235, /* Dark Green */ + #307D7E, /* Dark Cyan */ + #A0, /* Dark Blue */ + #C031C7, /* Dark Magenta */ + #C0C0C0, /* Grey */ + #FF, /* White */ + #FF, /* Bright Red */ + #00, /* Bright Yellow */ + #00FF00, /* Bright Green */ + #00, /* Bright Cyan */ + #FF, /* Bright Blue */ + #FF00FF, /* Bright Magenta */ +}; + +static void end_format(GString *string, guint8 code) +{ + g_string_append(string, /span); + + if ((code STK_TEXT_FORMAT_ALIGN_MASK) != STK_TEXT_FORMAT_NO_ALIGN) + g_string_append(string, /div); +} + +static void start_format(GString *string, guint8 code, guint8 color) +{ + guint8 align = code STK_TEXT_FORMAT_ALIGN_MASK; + guint8 font = code STK_TEXT_FORMAT_FONT_MASK; + guint8 style = code STK_TEXT_FORMAT_STYLE_MASK; + int fg = color 0x0f; + int bg = (color 4) 0x0f; + + /* align formatting applies to a block of test */ + if (align != STK_TEXT_FORMAT_NO_ALIGN) + g_string_append(string, div style=\); + + if (align == STK_TEXT_FORMAT_RIGHT_ALIGN) + g_string_append(string, text-align: right;\); + else if (align == STK_TEXT_FORMAT_CENTER_ALIGN) + g_string_append(string, text-align: center;\); + else if (align == STK_TEXT_FORMAT_LEFT_ALIGN) + g_string_append(string, text-align: left;\); + + /* font, style, and color are inline */ + g_string_append(string, span style=\); + + if (font == STK_TEXT_FORMAT_FONT_SIZE_LARGE) + g_string_append(string, font-size: big;); + else if (font == STK_TEXT_FORMAT_FONT_SIZE_SMALL) + g_string_append(string, font-size: small;); + + if (style == STK_TEXT_FORMAT_STYLE_BOLD) + g_string_append(string, font-weight: bold;); + else if (style == STK_TEXT_FORMAT_STYLE_ITALIC) + g_string_append(string, font-style: italic;); + else if (style == STK_TEXT_FORMAT_STYLE_UNDERLINED) + g_string_append(string, text-decoration: underline;); + else if (style == STK_TEXT_FORMAT_STYLE_STRIKETHROUGH) + g_string_append(string, text-decoration: line-through;); + + /* add any color */ + if (fg) + g_string_append_printf(string, color: %s;, html_colors[fg]); + if (bg) + g_string_append_printf(string, background-color: %s;, + html_colors[bg]); + g_string_append(string, \); +} + +char *stk_text_to_html(char *text, int text_len, + const unsigned char *attrs, int attrs_len) +{ + GString *string = g_string_sized_new(text_len + 1); + gint formats[257]; /* maximum number of chars in text + 1 */ + int pos = 0, attr, i, j, prev_attr; + guint8 start, end, code, color, len, align; + + /* we will need formatting at the position beyond the last char */ + for (i = 0; i = text_len; i++) + formats[i] = STK_TEXT_FORMAT_INIT; + + i = 0; + + while (i attrs_len) { + start = attrs[i++]; + len = attrs[i++]; + code = attrs[i++]; + + if (i attrs_len) + color = attrs[i++]; + else + color = 0; + + if (len == 0) + end = text_len; + else + end = start + len; + + /* sanity check values */ + if (start end || end text_len) + continue; + + /* +* if the alignment is the same as either the default +* or the last alignment used, don't set any alignment +* value. +*/ + if (start == 0) + align = STK_DEFAULT_TEXT_ALIGNMENT; + else { + align = get_align(formats[start - 1]); + if (align == STK_TEXT_FORMAT_NO_ALIGN) + align = STK_DEFAULT_TEXT_ALIGNMENT; + } + + if ((code STK_TEXT_FORMAT_ALIGN_MASK) == align) +
[PATCH 2/2] test-stkutil: add html attribute display tests
--- unit/test-stkutil.c | 64 +++ 1 files changed, 64 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index 8b7e254..3c0ac78 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -21923,6 +21923,63 @@ static const struct envelope_test timer_expiration_data_221a = { }, }; +struct html_attr_test { + char *text; + const unsigned char *attrs; + unsigned int attrs_len; + char *output; +}; + +unsigned char html_attr_1[] = { 0x19, 0x06, 0x20, 0x00, 0x21, 0x04, 0x10, 0x00, + 0x27, 0x05, 0x04, 0x00, 0x2E, 0x05, 0x08, 0x00, + 0x38, 0x07, 0x00, 0x2B }; + +unsigned char html_attr_2[] = {0x00, 0x00, 0x00, 0x94, 0x00, 0x04, 0x00, 0x96 }; + +unsigned char html_attr_3[] = { 0x00, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00, 0x96 }; + +static struct html_attr_test html_attr_data_1 = { + .text = EMS messages can contain italic, bold, large, small and + colored text, + .attrs = html_attr_1, + .attrs_len = sizeof(html_attr_1), + .output = EMS messages can contain span style=\font-style: italic;\ + italic/span, span style=\font-weight: bold;\bold/span, + span style=\font-size: big;\large/span, + span style=\font-size: small;\small/span and + span style=\color: #00;background-color: #C11B17;\colored + /span text, +}; + +static struct html_attr_test html_attr_data_2 = { + .text = Blue green green green, + .attrs = html_attr_2, + .attrs_len = sizeof(html_attr_2), + .output = span style=\color: #A0;background-color: #FF;\Blue + /spanspan style=\color: #347235;background-color: #FF;\ +green green green/span, +}; + +static struct html_attr_test html_attr_data_3 = { + .text = abc, + .attrs = html_attr_3, + .attrs_len = sizeof(html_attr_3), + .output = span style=\color: #347235;background-color: #FF;\ + a/spanspan style=\color: #A0;background-color: #FF;\ + bc/span, +}; + +static void test_html_attr(gconstpointer data) +{ + const struct html_attr_test *test = data; + char *html; + + html = stk_text_to_html(test-text, strlen(test-text), test-attrs, + test-attrs_len); + g_assert(memcmp(html, test-output, strlen(test-output)) == 0); + g_free(html); +} + int main(int argc, char **argv) { g_test_init(argc, argv, NULL); @@ -23930,5 +23987,12 @@ int main(int argc, char **argv) g_test_add_data_func(/teststk/Timer Expiration 2.2.1A, timer_expiration_data_221a, test_envelope_encoding); + g_test_add_data_func(/teststk/HTML Attribute Test 1, + html_attr_data_1, test_html_attr); + g_test_add_data_func(/teststk/HTML Attribute Test 2, + html_attr_data_2, test_html_attr); + g_test_add_data_func(/teststk/HTML Attribute Test 3, + html_attr_data_3, test_html_attr); + return g_test_run(); } -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/2] convert display text attributes to HTML
Kristen Carlson Accardi (2): stkutil: convert text attributes to html test-stkutil: add html formatted text tests src/stkutil.c | 165 + src/stkutil.h | 22 + unit/test-stkutil.c | 257 +++ 3 files changed, 444 insertions(+), 0 deletions(-) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/2] test-stkutil: add html formatted text tests
--- unit/test-stkutil.c | 257 +++ 1 files changed, 257 insertions(+), 0 deletions(-) diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c index c586a7b..21fd02d 100644 --- a/unit/test-stkutil.c +++ b/unit/test-stkutil.c @@ -28,6 +28,9 @@ #include stdlib.h #include string.h #include stdint.h +#include fcntl.h + +#include sys/stat.h #include glib.h #include glib/gprintf.h @@ -508,6 +511,7 @@ struct display_text_test { struct stk_duration duration; struct stk_text_attribute text_attr; struct stk_frame_id frame_id; + const char *test_name; }; unsigned char display_text_111[] = { 0xD0, 0x1A, 0x81, 0x03, 0x01, 0x21, 0x80, @@ -603,6 +607,69 @@ unsigned char display_text_711[] = { 0xD0, 0x19, 0x81, 0x03, 0x01, 0x21, 0x80, 0x63, 0x6F, 0x6E, 0x64, 0x84, 0x02, 0x01, 0x0A }; +unsigned char display_text_811[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x00, 0xB4 }; + +unsigned char display_text_821[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x01, 0xB4 }; + +unsigned char display_text_831[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x02, 0xB4 }; + +unsigned char display_text_841[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x04, 0xB4 }; + +unsigned char display_text_851[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x08, 0xB4 }; + +unsigned char display_text_861[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x10, 0xB4 }; + +unsigned char display_text_871[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x20, 0xB4 }; + +unsigned char display_text_881[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31, 0xD0, + 0x04, 0x00, 0x10, 0x40, 0xB4 }; + +unsigned char display_text_891[] = { 0xD0, 0x22, 0x81, 0x03, 0x01, 0x21, 0x80, + 0x82, 0x02, 0x81, 0x02, 0x8D, 0x11, + 0x04, 0x54, 0x65, 0x78, 0x74, 0x20, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x31,
Re: [PATCH 1/2] stkutil: convert text attributes to html
On Tue, 22 Jun 2010 00:45:39 +0200 andrzej zaborowski balr...@gmail.com wrote: This approach with having so many queues seems a little heavy. On irc I proposed that probably we don't need to implement this behaviour fully and maybe could make some assumptions to simplify it. I'm not sure what you mean when you say heavy. Are you saying that you feel it has too much overhead? I wonder if that is really an issue for this functionality. To me this code seems to be easier to read than what you propose. ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 1/2] stkutil: convert text attributes to html
On Tue, 22 Jun 2010 00:45:39 +0200 andrzej zaborowski balr...@gmail.com wrote: Can we always end_format() and start_format() when the formatting changes, and just once instead of in a loop? Here's a test case that I'm worried about: text is abc attribute 1 (red text) starts at 0, len 2 attribute 2 (blue text) starts at 1, len 2 the generated html, by my reading will look like this: span style=color: red;aspan style=color: blue;b/spanc/span I ran this test just to make sure, the generated html is not as you fear and is correct (I used different colors though) htmlbodyspan style=color: #347235;background-color: #FF;aspan style=color: #A0;background-color: #FF;b/span/spanc/body/html I can add this exact test as a unit test if you would like. ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 1/2] stkutil: convert text attributes to html
On Mon, 21 Jun 2010 19:51:06 -0700 Kristen Carlson Accardi kris...@linux.intel.com wrote: On Tue, 22 Jun 2010 00:45:39 +0200 andrzej zaborowski balr...@gmail.com wrote: Can we always end_format() and start_format() when the formatting changes, and just once instead of in a loop? Here's a test case that I'm worried about: text is abc attribute 1 (red text) starts at 0, len 2 attribute 2 (blue text) starts at 1, len 2 the generated html, by my reading will look like this: span style=color: red;aspan style=color: blue;b/spanc/span I ran this test just to make sure, the generated html is not as you fear and is correct (I used different colors though) htmlbodyspan style=color: #347235;background-color: #FF;aspan style=color: #A0;background-color: #FF;b/span/spanc/body/html Hum, ok, this is not correct I see your concern and will fix. ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH] stkutil: convert text attributes to html
--- src/stkutil.c | 203 + src/stkutil.h | 21 ++ 2 files changed, 224 insertions(+), 0 deletions(-) diff --git a/src/stkutil.c b/src/stkutil.c index 8ac1dba..dbcb6ac 100644 --- a/src/stkutil.c +++ b/src/stkutil.c @@ -4307,3 +4307,206 @@ const unsigned char *stk_pdu_from_envelope(const struct stk_envelope *envelope, return pdu; } + +static GString *mapColourToHtml(GString *string, guint8 colour) +{ + GString *result = string; + int fg = colour 0x0f; + int bg = (colour 4) 0x0f; + static const char *html_colors[] = { + #00, /* Black */ + #808080, /* Dark Grey */ + #C11B17, /* Dark Red */ + #FBB117, /* Dark Yellow */ + #347235, /* Dark Green */ + #307D7E, /* Dark Cyan */ + #A0, /* Dark Blue */ + #C031C7, /* Dark Magenta */ + #C0C0C0, /* Grey */ + #FF, /* White */ + #FF, /* Bright Red */ + #00, /* Bright Yellow */ + #00FF00, /* Bright Green */ + #00, /* Bright Cyan */ + #FF, /* Bright Blue */ + #FF00FF, /* Bright Magenta */ + }; + + if (colour == 0) + return string; + + if (fg) { + result = g_string_append(result, color: ); + result = g_string_append(result, html_colors[fg]); + result = g_string_append_c(result, ';'); + } + if (bg) { + result = g_string_append(result, background-color: ); + result = g_string_append(result, html_colors[bg]); + result = g_string_append_c(result, ';'); + } + + + return result; +} + +static GString *endFormat(GString *string) +{ + return g_string_append(string, /p); +} + +static GString *mapFormatToHtml(GString *string, guint8 code, guint8 colour) +{ + GString *result = string; + guint8 align = code STK_TEXT_FORMAT_ALIGN_MASK; + guint8 font = code STK_TEXT_FORMAT_FONT_MASK; + guint8 style = code STK_TEXT_FORMAT_STYLE_MASK; + + /* formatting applies to a block of test */ + result = g_string_append(result, p style=\); + + if (align == STK_TEXT_FORMAT_RIGHT_ALIGN) + result = g_string_append(result, text-align: right;); + else if (align == STK_TEXT_FORMAT_CENTER_ALIGN) + result = g_string_append(result, text-align: center;); + else if (align == STK_TEXT_FORMAT_LEFT_ALIGN) + result = g_string_append(result, text-align: left;); + + if (font == STK_TEXT_FORMAT_FONT_SIZE_LARGE) + result = g_string_append(result, font-size: big;); + else if (font == STK_TEXT_FORMAT_FONT_SIZE_SMALL) + result = g_string_append(result, font-size: small;); + + if (style == STK_TEXT_FORMAT_STYLE_BOLD) + result = g_string_append(result, font-weight: bold;); + else if (style == STK_TEXT_FORMAT_STYLE_ITALIC) + result = g_string_append(result, font-style: italic;); + else if (style == STK_TEXT_FORMAT_STYLE_UNDERLINED) + result = g_string_append(result, text-decoration: underline;); + else if (style == STK_TEXT_FORMAT_STYLE_STRIKETHROUGH) + result = g_string_append(result, + text-decoration: line-through;); + + /* add any color */ + result = mapColourToHtml(result, colour); + + result = g_string_append(result, \); + + return result; +} + +static gboolean isSpecialChar(char c) +{ + return (c == '\n' || c == '\r' || c == '' || c == '' || c == ''); +} + +static gboolean mapCharToHtml(char *s, int pos, int len, + GString **string) +{ + gboolean rval = FALSE; + GString *result = *string; + unsigned char c = s[pos]; + + switch (c) { + case '\n': + result = g_string_append(result, br); + break; + case '\r': + result = g_string_append(result, br); + if ((pos + 1 len) (s[pos + 1] == '\n')) + rval = TRUE; + break; + case '': + result = g_string_append(result, lt;); + break; + case '': + result = g_string_append(result, gt;); + break; + case '': + result = g_string_append(result, amp;); + break; + } + *string = result; + return rval; +} + +static GString *copyText(GString *string, char *text, + int *start_pos, int start, int end) +{ + GString *result = string; + int pos = *start_pos; + + while (pos start