On 25 November 2010 13:29, Yang Gu <yang.gu(a)intel.com> wrote:
---
src/smsutil.c | 6 +-
src/stk.c | 113 +++++++++++++++++++++++++++++++++++++++++
src/stkagent.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/stkagent.h | 14 +++++
src/stkutil.c | 2 +-
5 files changed, 284 insertions(+), 4 deletions(-)
diff --git a/src/smsutil.c b/src/smsutil.c
index e6dbf5f..5394817 100644
--- a/src/smsutil.c
+++ b/src/smsutil.c
@@ -324,10 +324,10 @@ gboolean sms_encode_scts(const struct sms_scts *in, unsigned char
*pdu,
if (in->year > 99)
return FALSE;
- if (in->month > 12)
+ if (in->month > 12 || in->month == 0)
return FALSE;
- if (in->day > 31)
+ if (in->day > 31 || in->day == 0)
return FALSE;
if (in->hour > 23)
@@ -339,7 +339,7 @@ gboolean sms_encode_scts(const struct sms_scts *in, unsigned char
*pdu,
if (in->second > 59)
return FALSE;
- if ((in->timezone > 12*4-1) || (in->timezone < -(12*4-1)))
+ if ((in->timezone > 12*4) || (in->timezone < -(12*4-1)))
Please ignore my comment about the range in the other, because you
already fixed this :)
return FALSE;
pdu = pdu + *offset;
diff --git a/src/stk.c b/src/stk.c
index ac2e646..1f3817f 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -1992,6 +1992,114 @@ static gboolean handle_command_refresh(const struct stk_command
*cmd,
return TRUE;
}
+static void request_time_cb(enum stk_agent_result result, unsigned char year,
+ unsigned char month, unsigned char day,
+ unsigned char hour, unsigned char minute,
+ unsigned char second, char timezone,
+ void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ static struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+ struct stk_response rsp;
+
+ stk->respond_on_exit = FALSE;
+
+ switch (result) {
+ case STK_AGENT_RESULT_OK:
+ memset(&rsp, 0, sizeof(rsp));
+
+ rsp.result.type = STK_RESULT_TYPE_SUCCESS;
+ rsp.provide_local_info.datetime.year = year;
+ rsp.provide_local_info.datetime.month = month;
+ rsp.provide_local_info.datetime.day = day;
+ rsp.provide_local_info.datetime.hour = hour;
+ rsp.provide_local_info.datetime.minute = minute;
+ rsp.provide_local_info.datetime.second = second;
+ rsp.provide_local_info.datetime.timezone = timezone;
+
+ if (stk_respond(stk, &rsp, stk_command_cb))
+ stk_command_cb(&error, stk);
+
+ break;
+
+ case STK_AGENT_RESULT_BACK:
+ send_simple_response(stk, STK_RESULT_TYPE_GO_BACK);
+ break;
Note that "Backward move", "No reponse" and "User
terminated" are not
allowed responses for Provide Local Info in TS102.223 6.11.
+
+ case STK_AGENT_RESULT_TIMEOUT:
+ send_simple_response(stk, STK_RESULT_TYPE_NO_RESPONSE);
+ break;
+
+ case STK_AGENT_RESULT_TERMINATE:
+ send_simple_response(stk, STK_RESULT_TYPE_USER_TERMINATED);
+ break;
+ }
+}
+
+static void request_lang_cb(enum stk_agent_result result, char *lang,
+ void *user_data)
+{
+ struct ofono_stk *stk = user_data;
+ static struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
+ struct stk_response rsp;
+
+ stk->respond_on_exit = FALSE;
+
+ switch (result) {
+ case STK_AGENT_RESULT_OK:
+ memset(&rsp, 0, sizeof(rsp));
+
+ rsp.result.type = STK_RESULT_TYPE_SUCCESS;
+ rsp.provide_local_info.language = lang;
+
+ if (stk_respond(stk, &rsp, stk_command_cb))
+ stk_command_cb(&error, stk);
+
+ break;
+
+ case STK_AGENT_RESULT_BACK:
+ send_simple_response(stk, STK_RESULT_TYPE_GO_BACK);
+ break;
+
+ case STK_AGENT_RESULT_TIMEOUT:
+ send_simple_response(stk, STK_RESULT_TYPE_NO_RESPONSE);
+ break;
+
+ case STK_AGENT_RESULT_TERMINATE:
+ send_simple_response(stk, STK_RESULT_TYPE_USER_TERMINATED);
+ break;
+ }
+}
+
+static gboolean handle_command_provide_local_info(const struct stk_command *cmd,
+ struct stk_response *rsp, struct ofono_stk *stk)
+{
+ int timeout = stk->timeout * 1000;
+ int err;
+
+ switch (cmd->qualifier) {
+ case 3:
+ DBG("Date, time and time zone");
+ err = stk_agent_request_time(stk->current_agent,
+ request_time_cb,
+ stk, NULL, timeout);
+ return FALSE;
+
+ case 4:
+ DBG("Language setting");
+ err = stk_agent_request_lang(stk->current_agent,
+ request_lang_cb,
+ stk, NULL, timeout);
+ return FALSE;
+
+ default:
+ ofono_info("Unsupported Provide Local Info qualifier: %d",
+ cmd->qualifier);
+ rsp->result.type = STK_RESULT_TYPE_NOT_CAPABLE;
+ return TRUE;
+ }
+}
+
static void send_dtmf_cancel(struct ofono_stk *stk)
{
struct ofono_voicecall *vc = NULL;
@@ -2424,6 +2532,11 @@ void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
&rsp, stk);
break;
+ case STK_COMMAND_TYPE_PROVIDE_LOCAL_INFO:
+ respond = handle_command_provide_local_info(stk->pending_cmd,
+ &rsp, stk);
+ break;
+
case STK_COMMAND_TYPE_SEND_DTMF:
respond = handle_command_send_dtmf(stk->pending_cmd,
&rsp, stk);
diff --git a/src/stkagent.c b/src/stkagent.c
index 5cf83e4..78620d5 100644
--- a/src/stkagent.c
+++ b/src/stkagent.c
@@ -956,3 +956,156 @@ int stk_agent_loop_tone(struct stk_agent *agent, const char *text,
return 0;
}
+
+static void get_time_cb(DBusPendingCall *call, void *data)
+{
+ struct stk_agent *agent = data;
+ stk_agent_time_cb cb = agent->user_cb;
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ enum stk_agent_result result;
+ gboolean remove_agent;
+ int year_dbus;
+ unsigned char year;
+ unsigned char month;
+ unsigned char day;
+ unsigned char hour;
+ unsigned char minute;
+ unsigned char second;
+ int timezone_dbus;
+ char timezone;
I think you need to use "signed char" to achieve the same type as
int8_t/guin8 because the sign of "char" depends on the ABI.
+
+ if (check_error(agent, reply,
+ ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
+ &result) == -EINVAL) {
Go back and Terminate are not allowed for this command. (same comment as above)
+ remove_agent = TRUE;
+ goto error;
+ }
+
+ if (result != STK_AGENT_RESULT_OK) {
+ cb(result, 0, 0, 0, 0, 0, 0, 0xFF, agent->user_data);
+ goto done;
+ }
+
+ if (dbus_message_get_args(reply, NULL,
+ DBUS_TYPE_INT32, &year_dbus,
+ DBUS_TYPE_BYTE, &month,
+ DBUS_TYPE_BYTE, &day,
+ DBUS_TYPE_BYTE, &hour,
+ DBUS_TYPE_BYTE, &minute,
+ DBUS_TYPE_BYTE, &second,
+ DBUS_TYPE_INT32, &timezone_dbus,
+ DBUS_TYPE_INVALID) == FALSE) {
+ ofono_error("Can't parse the reply to RequestTime()");
+ remove_agent = TRUE;
+ goto error;
+ }
+
+ if (year_dbus < 1900) {
+ ofono_error("Invalid year");
+ remove_agent = TRUE;
+ goto error;
+ }
I believe the range is actually 1970-2069 or similar (only values 0-99
in the sms header are allowed)
> +
> + if (year_dbus >= 2000)
> + year = year_dbus - 2000;
> + else
> + year = year_dbus - 1900;
> +
> + timezone = timezone_dbus;
> +
> + cb(result, year, month, day, hour, minute, second, timezone,
> + agent->user_data);
> +
> + CALLBACK_END();
> +}
> +
> +int stk_agent_request_time(struct stk_agent *agent, stk_agent_time_cb cb,
> + void *user_data, ofono_destroy_func destroy,
> + int timeout)
> +{
> + DBusConnection *conn = ofono_dbus_get_connection();
> +
> + agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
> + OFONO_SIM_APP_INTERFACE,
> + "RequestTime");
> + if (agent->msg == NULL)
> + return -ENOMEM;
> +
> + dbus_message_append_args(agent->msg, DBUS_TYPE_INVALID);
> +
> + if (dbus_connection_send_with_reply(conn, agent->msg,
&agent->call,
> + timeout) == FALSE ||
> + agent->call == NULL)
> + return -EIO;
> +
> + agent->user_cb = cb;
> + agent->user_data = user_data;
> + agent->user_destroy = destroy;
> +
> + dbus_pending_call_set_notify(agent->call, get_time_cb, agent, NULL);
> +
> + return 0;
> +}
> +
> +static void get_lang_cb(DBusPendingCall *call, void *data)
> +{
> + struct stk_agent *agent = data;
> + stk_agent_string_cb cb = agent->user_cb;
> + DBusMessage *reply = dbus_pending_call_steal_reply(call);
> + enum stk_agent_result result;
> + gboolean remove_agent;
> + char *lang;
+
+ if (check_error(agent, reply,
+ ALLOWED_ERROR_GO_BACK | ALLOWED_ERROR_TERMINATE,
+ &result) == -EINVAL) {
> +
remove_agent = TRUE;
> + goto error;
> + }
> +
> + if (result != STK_AGENT_RESULT_OK) {
> + cb(result, NULL, agent->user_data);
> + goto done;
> + }
> +
> + if (dbus_message_get_args(reply, NULL,
> + DBUS_TYPE_STRING, &lang,
> + DBUS_TYPE_INVALID) == FALSE ||
> + strlen(lang) != 2) {
> + ofono_error("Can't parse the reply to
RequestLanguage()");
> + remove_agent = TRUE;
> + goto error;
> + }
> +
> + cb(result, lang, agent->user_data);
> +
> + CALLBACK_END();
> +}
> +
> +int stk_agent_request_lang(struct stk_agent *agent, stk_agent_string_cb cb,
> + void *user_data, ofono_destroy_func destroy,
> + int timeout)
> +{
> + DBusConnection *conn = ofono_dbus_get_connection();
> +
> + agent->msg = dbus_message_new_method_call(agent->bus, agent->path,
> + OFONO_SIM_APP_INTERFACE,
> +
"RequestLanguage");
> + if (agent->msg == NULL)
> + return -ENOMEM;
> +
> + dbus_message_append_args(agent->msg, DBUS_TYPE_INVALID);
> +
> + if (dbus_connection_send_with_reply(conn, agent->msg,
&agent->call,
> + timeout) == FALSE ||
> + agent->call == NULL)
> + return -EIO;
> +
> + agent->user_cb = cb;
> + agent->user_data = user_data;
> + agent->user_destroy = destroy;
> +
> + dbus_pending_call_set_notify(agent->call, get_lang_cb, agent, NULL);
> +
> + return 0;
> +}
> diff --git a/src/stkagent.h b/src/stkagent.h
> index c8e1886..a60cf23 100644
> --- a/src/stkagent.h
> +++ b/src/stkagent.h
> @@ -59,6 +59,12 @@ typedef void (*stk_agent_string_cb)(enum stk_agent_result result,
> typedef void (*stk_agent_tone_cb)(enum stk_agent_result result,
> void *user_data);
>
> +typedef void (*stk_agent_time_cb)(enum stk_agent_result result,
> + unsigned char year, unsigned char month,
> + unsigned char day, unsigned char hour,
> + unsigned char minute, unsigned char second,
> + char timezone, void *user_data);
> +
> struct stk_agent *stk_agent_new(const char *path, const char *sender,
> ofono_bool_t remove_on_terminate);
>
> @@ -136,3 +142,11 @@ int stk_agent_loop_tone(struct stk_agent *agent, const char
*text,
>
> void append_menu_items_variant(DBusMessageIter *iter,
> const struct stk_menu_item *items);
> +
> +int stk_agent_request_time(struct stk_agent *agent, stk_agent_time_cb cb,
> + void *user_data, ofono_destroy_func destroy,
> + int timeout);
> +
> +int stk_agent_request_lang(struct stk_agent *agent, stk_agent_string_cb cb,
> + void *user_data, ofono_destroy_func destroy,
> + int timeout);
> diff --git a/src/stkutil.c b/src/stkutil.c
> index 377ceff..48ce93b 100644
> --- a/src/stkutil.c
> +++ b/src/stkutil.c
> @@ -4553,7 +4553,7 @@ static gboolean build_dataobj_datetime_timezone(struct
stk_tlv_builder *tlv,
> return TRUE;
>
> /* Time zone information is optional */
> - if (scts->timezone == (gint8) 0xff) {
> + if (scts->timezone == -48) {
Ah, -48 is also a good value :)
But wouldn't the parser also need to translate 0xff into -48?
Best regards