---
 src/stk.c |  148 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 123 insertions(+), 25 deletions(-)

diff --git a/src/stk.c b/src/stk.c
index d42a05f..7a43264 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -257,6 +257,22 @@ void __ofono_cbs_sim_download(struct ofono_stk *stk, const 
struct cbs *msg)
                stk_cbs_download_cb(stk, FALSE, NULL, -1);
 }
 
+static char *dbus_apply_text_attributes(const char *text,
+                                       const struct stk_text_attribute *attr)
+{
+       uint16_t buf[256], *i = buf;
+       const uint8_t *j = attr->attributes;
+       const uint8_t *end = j + attr->len;
+
+       if (attr->len & 3)
+               return NULL;
+
+       while (j < end)
+               *i++ = *j++;
+
+       return stk_text_to_html(text, buf, attr->len / 4);
+}
+
 static struct stk_menu *stk_menu_create(const char *title,
                const struct stk_text_attribute *title_attr,
                const struct stk_icon_id *icon, GSList *items,
@@ -268,6 +284,7 @@ static struct stk_menu *stk_menu_create(const char *title,
        struct stk_menu *ret;
        GSList *l;
        int i;
+       struct stk_text_attribute attr;
 
        DBG("");
 
@@ -281,7 +298,11 @@ static struct stk_menu *stk_menu_create(const char *title,
        if (ret == NULL)
                return NULL;
 
-       ret->title = g_strdup(title ? title : "");
+       ret->title = dbus_apply_text_attributes(title ? title : "",
+                                               title_attr);
+       if (!ret->title)
+               ret->title = g_strdup(title ? title : "");
+
        memcpy(&ret->icon, icon, sizeof(ret->icon));
        ret->items = g_new0(struct stk_menu_item, len + 1);
        ret->default_item = -1;
@@ -290,10 +311,21 @@ static struct stk_menu *stk_menu_create(const char *title,
 
        for (l = items, i = 0; l; l = l->next, i++) {
                struct stk_item *item = l->data;
+               char *text;
 
-               ret->items[i].text = g_strdup(item->text);
                ret->items[i].item_id = item->id;
 
+               text = NULL;
+               if (item_attrs && item_attrs->len) {
+                       memcpy(attr.attributes, &item_attrs->list[i * 4], 4);
+                       attr.len = 4;
+
+                       text = dbus_apply_text_attributes(item->text, &attr);
+               }
+               if (!text)
+                       text = strdup(item->text);
+               ret->items[i].text = text;
+
                if (item_icon_ids && item_icon_ids->len)
                        ret->items[i].icon_id = item_icon_ids->list[i];
 
@@ -390,7 +422,8 @@ static void emit_menu_changed(struct ofono_stk *stk)
        g_dbus_send_message(conn, signal);
 }
 
-static void stk_alpha_id_set(struct ofono_stk *stk, const char *text,
+static void stk_alpha_id_set(struct ofono_stk *stk,
+               const char *text, const struct stk_text_attribute *attr,
                const struct stk_icon_id *icon)
 {
        /* TODO */
@@ -762,7 +795,8 @@ static gboolean handle_command_send_sms(const struct 
stk_command *cmd,
 
        stk->cancel_cmd = send_sms_cancel;
 
-       stk_alpha_id_set(stk, cmd->send_sms.alpha_id, &cmd->send_sms.icon_id);
+       stk_alpha_id_set(stk, cmd->send_sms.alpha_id, &cmd->send_sms.text_attr,
+                               &cmd->send_sms.icon_id);
 
        return FALSE;
 }
@@ -773,17 +807,26 @@ static gboolean handle_command_set_idle_text(const struct 
stk_command *cmd,
 {
        DBusConnection *conn = ofono_dbus_get_connection();
        const char *path = __ofono_atom_get_path(stk->atom);
-       const char *idle_mode_text;
+       char *idle_mode_text = NULL;
 
-       if (stk->idle_mode_text) {
-               g_free(stk->idle_mode_text);
-               stk->idle_mode_text = NULL;
+       if (cmd->setup_idle_mode_text.text) {
+               idle_mode_text = dbus_apply_text_attributes(
+                                       cmd->setup_idle_mode_text.text,
+                                       &cmd->setup_idle_mode_text.text_attr);
+
+               if (!idle_mode_text) {
+                       rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+
+                       return TRUE;
+               }
        }
 
-       if (cmd->setup_idle_mode_text.text)
-               stk->idle_mode_text = g_strdup(cmd->setup_idle_mode_text.text);
+       if (stk->idle_mode_text)
+               g_free(stk->idle_mode_text);
 
-       idle_mode_text = stk->idle_mode_text ? stk->idle_mode_text : "";
+       stk->idle_mode_text = idle_mode_text;
+
+       idle_mode_text = idle_mode_text ? idle_mode_text : "";
        ofono_dbus_signal_property_changed(conn, path, OFONO_STK_INTERFACE,
                                                "IdleModeText",
                                                DBUS_TYPE_STRING,
@@ -1166,6 +1209,14 @@ static gboolean handle_command_display_text(const struct 
stk_command *cmd,
        struct stk_command_display_text *dt = &stk->pending_cmd->display_text;
        uint8_t qualifier = stk->pending_cmd->qualifier;
        ofono_bool_t priority = (qualifier & (1 << 0)) != 0;
+       char *text = dbus_apply_text_attributes(dt->text, &dt->text_attr);
+       int err;
+
+       if (!text) {
+               rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+
+               return TRUE;
+       }
 
        if (dt->duration.interval) {
                timeout = dt->duration.interval;
@@ -1179,10 +1230,13 @@ static gboolean handle_command_display_text(const 
struct stk_command *cmd,
                }
        }
 
-       /* We most likely got an out of memory error, tell SIM to retry */
-       if (stk_agent_display_text(stk->current_agent, dt->text, &dt->icon_id,
+       err = stk_agent_display_text(stk->current_agent, text, &dt->icon_id,
                                        priority, display_text_cb, stk,
-                                       display_text_destroy, timeout) < 0) {
+                                       display_text_destroy, timeout);
+       g_free(text);
+
+       /* We most likely got an out of memory error, tell SIM to retry */
+       if (err < 0) {
                rsp->result.type = STK_RESULT_TYPE_TERMINAL_BUSY;
                return TRUE;
        }
@@ -1316,6 +1370,7 @@ static gboolean handle_command_get_inkey(const struct 
stk_command *cmd,
 {
        int timeout = stk->timeout * 1000;
        const struct stk_command_get_inkey *gi = &cmd->get_inkey;
+       char *text = dbus_apply_text_attributes(gi->text, &gi->text_attr);
        uint8_t qualifier = stk->pending_cmd->qualifier;
        gboolean alphabet = (qualifier & (1 << 0)) != 0;
        gboolean ucs2 = (qualifier & (1 << 1)) != 0;
@@ -1326,6 +1381,12 @@ static gboolean handle_command_get_inkey(const struct 
stk_command *cmd,
         */
        int err;
 
+       if (!text) {
+               rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+
+               return TRUE;
+       }
+
        if (gi->duration.interval) {
                timeout = gi->duration.interval;
                switch (gi->duration.unit) {
@@ -1342,18 +1403,19 @@ static gboolean handle_command_get_inkey(const struct 
stk_command *cmd,
 
        if (yesno)
                err = stk_agent_request_confirmation(stk->current_agent,
-                                                       gi->text, &gi->icon_id,
+                                                       text, &gi->icon_id,
                                                        request_confirmation_cb,
                                                        stk, NULL, timeout);
        else if (alphabet)
-               err = stk_agent_request_key(stk->current_agent, gi->text,
+               err = stk_agent_request_key(stk->current_agent, text,
                                                &gi->icon_id, ucs2,
                                                request_key_cb, stk, NULL,
                                                timeout);
        else
-               err = stk_agent_request_digit(stk->current_agent, gi->text,
+               err = stk_agent_request_digit(stk->current_agent, text,
                                                &gi->icon_id, request_key_cb,
                                                stk, NULL, timeout);
+       g_free(text);
 
        if (err < 0) {
                /*
@@ -1414,26 +1476,34 @@ static gboolean handle_command_get_input(const struct 
stk_command *cmd,
 {
        int timeout = stk->timeout * 1000;
        const struct stk_command_get_input *gi = &cmd->get_input;
+       char *text = dbus_apply_text_attributes(gi->text, &gi->text_attr);
        uint8_t qualifier = stk->pending_cmd->qualifier;
        gboolean alphabet = (qualifier & (1 << 0)) != 0;
        gboolean ucs2 = (qualifier & (1 << 1)) != 0;
        gboolean hidden = (qualifier & (1 << 2)) != 0;
        int err;
 
+       if (!text) {
+               rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+
+               return TRUE;
+       }
+
        if (alphabet)
-               err = stk_agent_request_input(stk->current_agent, gi->text,
+               err = stk_agent_request_input(stk->current_agent, text,
                                                &gi->icon_id, gi->default_text,
                                                ucs2, gi->resp_len.min,
                                                gi->resp_len.max, hidden,
                                                request_string_cb,
                                                stk, NULL, timeout);
        else
-               err = stk_agent_request_digits(stk->current_agent, gi->text,
+               err = stk_agent_request_digits(stk->current_agent, text,
                                                &gi->icon_id, gi->default_text,
                                                gi->resp_len.min,
                                                gi->resp_len.max, hidden,
                                                request_string_cb,
                                                stk, NULL, timeout);
+       g_free(text);
 
        if (err < 0) {
                /*
@@ -1500,6 +1570,7 @@ static void confirm_call_cb(enum stk_agent_result result, 
gboolean confirm,
        uint8_t qualifier = stk->pending_cmd->qualifier;
        static unsigned char busy_on_call_result[] = { 0x02 };
        static unsigned char no_cause_result[] = { 0x00 };
+       char *alpha_id = NULL;
        struct ofono_voicecall *vc = NULL;
        struct ofono_atom *vc_atom;
        struct stk_response rsp;
@@ -1535,11 +1606,22 @@ static void confirm_call_cb(enum stk_agent_result 
result, gboolean confirm,
                return;
        }
 
+       if (sc->alpha_id_call_setup) {
+               alpha_id = dbus_apply_text_attributes(sc->alpha_id_call_setup,
+                                               &sc->text_attr_call_setup);
+               if (!alpha_id) {
+                       send_simple_response(stk,
+                                       STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD);
+                       return;
+               }
+       }
+
        err = __ofono_voicecall_dial(vc, sc->addr.number, sc->addr.ton_npi,
-                                       sc->alpha_id_call_setup,
-                                       sc->icon_id_call_setup.id,
+                                       alpha_id, sc->icon_id_call_setup.id,
                                        qualifier >> 1, call_setup_connected,
                                        stk);
+       g_free(alpha_id);
+
        if (err >= 0) {
                stk->cancel_cmd = call_setup_cancel;
 
@@ -1582,6 +1664,7 @@ static gboolean handle_command_set_up_call(const struct 
stk_command *cmd,
        const struct stk_command_setup_call *sc = &cmd->setup_call;
        uint8_t qualifier = cmd->qualifier;
        static unsigned char busy_on_call_result[] = { 0x02 };
+       char *alpha_id = NULL;
        struct ofono_voicecall *vc = NULL;
        struct ofono_atom *vc_atom;
        int err;
@@ -1617,9 +1700,19 @@ static gboolean handle_command_set_up_call(const struct 
stk_command *cmd,
                return TRUE;
        }
 
-       err = stk_agent_confirm_call(stk->current_agent, sc->alpha_id_usr_cfm,
+       if (sc->alpha_id_usr_cfm) {
+               alpha_id = dbus_apply_text_attributes(sc->alpha_id_usr_cfm,
+                                                       &sc->text_attr_usr_cfm);
+               if (!alpha_id) {
+                       rsp->result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
+                       return TRUE;
+               }
+       }
+
+       err = stk_agent_confirm_call(stk->current_agent, alpha_id,
                                        &sc->icon_id_usr_cfm, confirm_call_cb,
                                        stk, NULL, stk->timeout * 1000);
+       g_free(alpha_id);
 
        if (err < 0) {
                /*
@@ -1794,7 +1887,9 @@ static gboolean handle_command_send_ussd(const struct 
stk_command *cmd,
                return TRUE;
        }
 
-       stk_alpha_id_set(stk, cmd->send_ussd.alpha_id, &cmd->send_ussd.icon_id);
+       stk_alpha_id_set(stk, cmd->send_ussd.alpha_id,
+                               &cmd->send_ussd.text_attr,
+                               &cmd->send_ussd.icon_id);
 
        return FALSE;
 }
@@ -1974,7 +2069,9 @@ static gboolean handle_command_send_dtmf(const struct 
stk_command *cmd,
                return TRUE;
        }
 
-       stk_alpha_id_set(stk, cmd->send_dtmf.alpha_id, &cmd->send_dtmf.icon_id);
+       stk_alpha_id_set(stk, cmd->send_dtmf.alpha_id,
+                               &cmd->send_dtmf.text_attr,
+                               &cmd->send_dtmf.icon_id);
 
        /*
         * Note that we don't strictly require an agent to be connected,
@@ -2204,7 +2301,8 @@ void ofono_stk_proactive_command_handled_notify(struct 
ofono_stk *stk,
 
        case STK_COMMAND_TYPE_SEND_SMS:
                stk_alpha_id_set(stk, cmd->send_sms.alpha_id,
-                                       &cmd->send_sms.icon_id);
+                               &cmd->send_sms.text_attr,
+                               &cmd->send_sms.icon_id);
                break;
        }
 
-- 
1.7.1.86.g0e460.dirty

_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to