From: Denis Kenzior <denkenz@gmail.com>
To: ofono@ofono.org
Subject: Re: [PATCH 2/8] stk: Allow registering proactive command handlers.
Date: Wed, 23 Jun 2010 14:44:30 -0500 [thread overview]
Message-ID: <201006231444.30791.denkenz@gmail.com> (raw)
In-Reply-To: <1277205651-29369-2-git-send-email-andrew.zaborowski@intel.com>
[-- Attachment #1: Type: text/plain, Size: 7124 bytes --]
Hi Andrew,
> Synchronous handlers can fill in the struct stk_respone *rsp
> parameter and return TRUE. Async handlers can ignore that parameter
> and return FALSE. They have to call stk_respond() at some point.
> ---
> src/stk.c | 151
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files
> changed, 135 insertions(+), 16 deletions(-)
>
> diff --git a/src/stk.c b/src/stk.c
> index b5c6919..0d7fc33 100644
> --- a/src/stk.c
> +++ b/src/stk.c
> @@ -39,14 +39,80 @@
>
> static GSList *g_drivers = NULL;
>
> +typedef void (*generic_cb_t)(const struct ofono_error *error,
> + struct ofono_stk *stk);
> +
> +typedef void (*envelope_cb_t)(const struct ofono_error *error,
> + const unsigned char *data,
> + int length, struct ofono_stk *stk);
> +
I prefer to keep typedefs to a minimum. Since these are copies from
include/stk.h with a different type, I think I'd prefer to simply use those
callbacks instead.
> +typedef gboolean (*command_handler_t)(const struct stk_command *cmd,
> + struct stk_response *rsp,
> + struct ofono_stk *stk);
> +
Since we're not using a true public-api registration framework (yet?) lets not
typedef this one.
> struct ofono_stk {
> const struct ofono_stk_driver *driver;
> void *driver_data;
> struct ofono_atom *atom;
> + command_handler_t handlers[STK_COMMAND_TYPE_END_SESSION + 1];
As discussed on IRC, lets just do switch/case for now.
> + struct stk_command *pending_cmd;
> };
>
> +static void stk_respond(struct ofono_stk *stk,
> + struct stk_response *rsp, generic_cb_t cb)
> +{
> + struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
> + const guint8 *tlv;
> + unsigned int tlv_len;
> +
> + rsp->src = STK_DEVICE_IDENTITY_TYPE_TERMINAL;
> + rsp->dst = STK_DEVICE_IDENTITY_TYPE_UICC;
> + rsp->number = stk->pending_cmd->number;
> + rsp->type = stk->pending_cmd->type;
> + rsp->qualifier = stk->pending_cmd->qualifier;
> +
> + if (stk->driver->terminal_response == NULL) {
> + cb(&error, stk);
> + return;
> + }
What do you think of returning an int here (e.g. -ENOTSUPPORTED) instead of
calling a callback? I think that would make things a bit cleaner.
> +
> + tlv = stk_pdu_from_response(rsp, &tlv_len);
> + if (!tlv) {
> + cb(&error, stk);
> + return;
Perhaps -EINVAL here?
> + }
> +
> + stk->driver->terminal_response(stk, tlv_len, tlv,
> + (ofono_stk_generic_cb_t) cb, stk);
> +}
> +
> +static void stk_send_envelope(struct ofono_stk *stk, struct stk_envelope
> *e, + envelope_cb_t cb)
> +{
> + struct ofono_error error = { .type = OFONO_ERROR_TYPE_FAILURE };
> + const guint8 *tlv;
> + unsigned int tlv_len;
> +
> + e->dst = STK_DEVICE_IDENTITY_TYPE_UICC;
> +
> + if (stk->driver->envelope == NULL) {
> + cb(&error, NULL, -1, stk);
> + return;
Same comments as above for returning -errno.
> + }
> +
> + tlv = stk_pdu_from_envelope(e, &tlv_len);
> + if (!tlv) {
> + cb(&error, NULL, -1, stk);
> + return;
> + }
> +
> + stk->driver->envelope(stk, tlv_len, tlv,
> + (ofono_stk_envelope_cb_t) cb, stk);
> +}
> +
> static void stk_cbs_download_cb(const struct ofono_error *error,
> - const unsigned char *data, int len, void *user)
> + const unsigned char *data, int len,
> + struct ofono_stk *stk)
> {
> if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
> ofono_error("CellBroadcast download to UICC failed");
> @@ -55,34 +121,46 @@ static void stk_cbs_download_cb(const struct
> ofono_error *error, return;
> }
>
> + if (len)
> + ofono_error("CellBroadcast download returned %i bytes of data",
> + len);
> +
> DBG("CellBroadcast download to UICC reported no error");
> }
>
> void __ofono_cbs_sim_download(struct ofono_stk *stk, const struct cbs
> *msg) {
> - const guint8 *tlv;
> - unsigned int tlv_len;
> struct stk_envelope e;
>
> - if (stk->driver->envelope == NULL)
> - return;
> + memset(&e, 0, sizeof(e));
>
> e.type = STK_ENVELOPE_TYPE_CBS_PP_DOWNLOAD;
> e.src = STK_DEVICE_IDENTITY_TYPE_NETWORK;
> - e.dst = STK_DEVICE_IDENTITY_TYPE_UICC;
> memcpy(&e.cbs_pp_download.page, msg, sizeof(msg));
>
> - tlv = stk_pdu_from_envelope(&e, &tlv_len);
> - if (!tlv)
> + stk_send_envelope(stk, &e, stk_cbs_download_cb);
> +}
> +
> +static void stk_command_cb(const struct ofono_error *error,
> + struct ofono_stk *stk)
> +{
> + stk_command_free(stk->pending_cmd);
> + stk->pending_cmd = NULL;
> +
> + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
> + ofono_error("TERMINAL RESPONSE to a UICC command failed");
> + /* "The ME may retry to deliver the same Cell Broadcast
> + * page." */
> return;
> + }
>
> - stk->driver->envelope(stk, tlv_len, tlv, stk_cbs_download_cb, stk);
> + DBG("TERMINAL RESPONSE to a command reported no errors");
> }
>
> void ofono_stk_proactive_command_notify(struct ofono_stk *stk,
> int length, const unsigned char *pdu)
> {
> - struct stk_command *cmd;
> + struct stk_response rsp;
> char *buf;
> int i;
>
> @@ -93,23 +171,64 @@ void ofono_stk_proactive_command_notify(struct
> ofono_stk *stk, for (i = 0; i < length; i ++)
> sprintf(buf + i * 2, "%02hhx", pdu[i]);
>
> - cmd = stk_command_new_from_pdu(pdu, length);
> - if (!cmd) {
> + stk->pending_cmd = stk_command_new_from_pdu(pdu, length);
> + if (!stk->pending_cmd) {
> ofono_error("Can't parse proactive command: %s", buf);
>
> - /* TODO: return TERMINAL RESPONSE with permanent error */
> + /*
> + * Nothing we can do, we'd need at least Command Details
> + * to be able to respond with an error.
> + */
> goto done;
> }
>
> - /* TODO: execute */
> - ofono_info("Proactive command PDU: %s", buf);
> + ofono_debug("Proactive command PDU: %s", buf);
> +
> + memset(&rsp, 0, sizeof(rsp));
>
> - stk_command_free(cmd);
> + switch (stk->pending_cmd->status) {
> + case STK_PARSE_RESULT_OK:
> + if (stk->handlers[stk->pending_cmd->type]) {
> + if (stk->handlers[stk->pending_cmd->type](
> + stk->pending_cmd, &rsp, stk) == TRUE)
> + break;
> +
> + return;
> + }
> + /* Fall through */
> +
> + case STK_PARSE_RESULT_TYPE_NOT_UNDERSTOOD:
> + default:
> + rsp.result.type = STK_RESULT_TYPE_COMMAND_NOT_UNDERSTOOD;
> + break;
> +
> + case STK_PARSE_RESULT_MISSING_VALUE:
> + rsp.result.type = STK_RESULT_TYPE_MINIMUM_NOT_MET;
> + break;
> +
> + case STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD:
> + rsp.result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
> + break;
> + }
> +
> + stk_respond(stk, &rsp, stk_command_cb);
>
> done:
> g_free(buf);
> }
>
> +static gboolean stk_command_handler_register(struct ofono_stk *stk,
> + enum stk_command_type type,
> + command_handler_t handler)
> +{
> + if (stk->handlers[type])
> + return FALSE;
> +
> + stk->handlers[type] = handler;
> +
> + return TRUE;
> +}
> +
> int ofono_stk_driver_register(const struct ofono_stk_driver *d)
> {
> DBG("driver: %p, name: %s", d, d->name);
>
Thanks,
-Denis
next prev parent reply other threads:[~2010-06-23 19:44 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-22 11:20 [PATCH 1/8] stkutil: Refactor command parser error handling Andrzej Zaborowski
2010-06-22 11:20 ` [PATCH 2/8] stk: Allow registering proactive command handlers Andrzej Zaborowski
2010-06-23 19:44 ` Denis Kenzior [this message]
2010-06-23 22:08 ` Andrzej Zaborowski
2010-06-22 11:20 ` [PATCH 3/8] stk: Handle the More Time command as a nop Andrzej Zaborowski
2010-06-22 11:20 ` [PATCH 4/8] stk: Add SimApplication interface Andrzej Zaborowski
2010-06-23 21:25 ` Denis Kenzior
2010-06-22 11:20 ` [PATCH 5/8] stk: Forget previous command if a new one comes Andrzej Zaborowski
2010-06-22 11:20 ` [PATCH 6/8] Add a proactive command cancel notification Andrzej Zaborowski
2010-06-22 11:20 ` [PATCH 7/8] mbmmodem: Cancel running command on *STKEND Andrzej Zaborowski
2010-06-22 11:20 ` [PATCH 8/8] stk: Handle the Display Text command Andrzej Zaborowski
2010-06-23 19:36 ` [PATCH 1/8] stkutil: Refactor command parser error handling Denis Kenzior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201006231444.30791.denkenz@gmail.com \
--to=denkenz@gmail.com \
--cc=ofono@ofono.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox