On 25 November 2010 13:29, Yang Gu <[email protected]> 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
_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono