Re: [PATCH] emulator: add AT hook_control_cb() CB and register it

2011-03-30 Thread Guillaume Zajac

Hi Denis,

On 30/03/2011 05:49, Denis Kenzior wrote:

Hi Guillaume,

On 03/24/2011 05:25 AM, Guillaume Zajac wrote:

---
  src/emulator.c |   44 +---
  1 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/src/emulator.c b/src/emulator.c
index c84f0a9..586c7ec 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -177,6 +177,41 @@ error:
g_at_server_send_final(em-server, G_AT_SERVER_RESULT_ERROR);
  }

+static void hook_control_cb(GAtServer *server, GAtServerRequestType type,

Can you rename this dun_ath_cb, since this is pretty much dun specific

Ok I will do it.

+   GAtResult *result, gpointer user_data)
+{
+   struct ofono_emulator *em = user_data;
+   GAtResultIter iter;
+   int val;
+
+   DBG();
+
+   if (type != G_AT_SERVER_REQUEST_TYPE_SET)
+   goto error;

Wouldn't we be also getting G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY here?

Sorry I forgot it. I will add thise case.

+
+   if (em-ppp == NULL)
+   goto error;
+
+   g_at_result_iter_init(iter, result);
+   g_at_result_iter_next(iter, );
+
+   if (g_at_result_iter_next_number(iter,val) == FALSE)
+   goto error;
+
+   if (val != 0)
+   goto error;
+
+   g_at_ppp_unref(em-ppp);
+   em-ppp = NULL;
+
+   g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+
+   return;
+
+error:
+   g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+}
+
  static void brsf_cb(GAtServer *server, GAtServerRequestType type,
GAtResult *result, gpointer user_data)
  {
@@ -466,10 +501,13 @@ void ofono_emulator_register(struct ofono_emulator *em, 
int fd)

__ofono_atom_register(em-atom, emulator_unregister);

-   if (em-type == OFONO_EMULATOR_TYPE_DUN)
+   if (em-type == OFONO_EMULATOR_TYPE_DUN) {
g_at_server_register(em-server, D, dial_cb, em, NULL);
-   else if (em-type == OFONO_EMULATOR_TYPE_HFP)
-   g_at_server_set_echo(em-server, FALSE);
+   g_at_server_register(em-server, H, hook_control_cb, em, 
NULL);
+   } else {
+   if (em-type == OFONO_EMULATOR_TYPE_HFP)
+   g_at_server_set_echo(em-server, FALSE);

I'd really prefer this to use a switch/case statement.

Ok.

+   }
  }

  static void emulator_remove(struct ofono_atom *atom)


This patch is also in the set of patches I have sent for escape sequence 
detection because I needed it to complete gsmdial tests.
Should I resend the set of patches with this patch updated ? or I should 
wait for your feedback on the complete set of patches?


Kind regards,
Guillaume

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


Re: [PATCH] atmodem: gnss aggregate xml

2011-03-30 Thread Jarko Poutiainen
Hi Marcel,

On Tue, 2011-03-29 at 16:14 +0300, Marcel Holtmann wrote:
 Hi Jarko,
 
 this is never ever going to work. Global and public variables are a big
 no no.
 
 First of all it would need to be static, but that is not going to help
 you since the GNSS atom can be instantiated multiple times. oFono
 supports multiple modems at the same time. And then you end up in a big
 mess.
 
 Regards
 
 Marcel

Oops sorry about that. Shouldn't do anything in haste.

Br,
Jarko

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


RE: [PATCH 1/3] core: notify watches of already registered atoms

2011-03-30 Thread Mika.Liljeberg
Hi Denis,

 On 03/29/2011 02:48 AM, Mika Liljeberg wrote:
  ---
   src/modem.c |   16 +++-
   1 files changed, 15 insertions(+), 1 deletions(-)
  
  diff --git a/src/modem.c b/src/modem.c
  index 655994b..d22c718 100644
  --- a/src/modem.c
  +++ b/src/modem.c
  @@ -271,6 +271,9 @@ unsigned int 
 __ofono_modem_add_atom_watch(struct ofono_modem *modem,
  void *data, 
 ofono_destroy_func destroy)
   {
  struct atom_watch *watch;
  +   unsigned int id;
  +   GSList *l;
  +   struct ofono_atom *atom;
   
  if (notify == NULL)
  return 0;
  @@ -282,8 +285,19 @@ unsigned int 
 __ofono_modem_add_atom_watch(struct ofono_modem *modem,
  watch-item.destroy = destroy;
  watch-item.notify_data = data;
   
  -   return __ofono_watchlist_add_item(modem-atom_watches,
  +   id = __ofono_watchlist_add_item(modem-atom_watches,
  (struct 
 ofono_watchlist_item *)watch);
  +
  +   for (l = modem-atoms; l; l = l-next) {
  +   atom = l-data;
  +
  +   if (atom-type != type || atom-unregister == NULL)
  +   continue;
  +
  +   notify(atom, 
 OFONO_ATOM_WATCH_CONDITION_REGISTERED, data);
  +   }
  +
  +   return id;
   }
   
   gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem,
 
 This patch is behavior changing.  Whether this is a good idea 
 or not I'm
 still undecided, though I see its merits.
 
 However, I don't see how it is fixing anything.  The watches 
 are called
 only upon registration (which means the driver is probed and 
 ready).  So
 even if you create two netreg atoms in hopes of probing the 
 modem type,
 only one should ever register and this code should not be needed.

I do have an actual bug, which this patch fixes. I've been investigating why, 
with isiusb, the gprs atom sometimes fails to receive the network registration 
status and therefore fails to attach to the GPRS service. It turns out that the 
problem comes from the client side code pattern for registering atom watches. 
The code assumes that there will only be a single atom of the same type 
(registered or not).

Basically, gprs atom and the alternative netreg atoms are probing in parallel 
and may register themselves in a random order. If gprs finishes first, it will 
correctly get a call to its watch handler when one of the netreg atoms 
completes its registration. However, if the order is reversed and gprs finishes 
after the netreg atom, the following snippet of code tries to find the already 
registered netreg atom:

netreg_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_NETREG);

if (netreg_atom  __ofono_atom_get_registered(netreg_atom))
netreg_watch(netreg_atom,
OFONO_ATOM_WATCH_CONDITION_REGISTERED, gprs);

The trouble here is that __ofono_modem_find_atom() just returns the first 
neterg atom it finds, regardless of whether it is registered or not. In this 
case it happens to be the wrong netreg (wgmodem2.5 version, which fails to 
probe), even though the other netreg atom is already present and registered. 
Because of this, the watch funtion is never called.

I realize that there are other ways to fix this. The client side pattern could 
be changed to use __ofono_modem_foreach_atom() to look for already registered 
atoms, instead of doing the same within the __ofono_modem_add_atom_watch() as 
in my patch. This would introduce quite a bit of more code. Alternatively, an 
__ofono_modem_find_registered_atom() function could be introduced to look for a 
registerd atom of a certain type (might be a good idea to do this in any case). 
Or isiusb (and any other similar cases) could be revectored to not probe 
multiple atoms of the same type in parallel. However, we already create 
multiple GPRS context atoms as a matter of course, so the assumption that there 
will only be a single instance is no longer valid for all atom types anyway. 
IMO, it would be good to get rid of the assumption altogether.

So, I like my patch because it removes a lot of copy-paste code and does not 
assume anything about how many atoms of a certain type there can be.

Regards,

MikaL
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH] atmodem: gnss aggregate xml

2011-03-30 Thread Jarko Poutiainen
---
Hi,

ok this is the very final patch from me for this. The parsing could be done 
better I know but seems to work. Hopefully this will any way give some idea for 
somebody else to finalise this.

br,
Jarko
 drivers/atmodem/gnss.c |  135 ++--
 1 files changed, 119 insertions(+), 16 deletions(-)

diff --git a/drivers/atmodem/gnss.c b/drivers/atmodem/gnss.c
index e102815..719fb6d 100644
--- a/drivers/atmodem/gnss.c
+++ b/drivers/atmodem/gnss.c
@@ -45,6 +45,7 @@
 struct gnss_data {
GAtChat *chat;
unsigned int vendor;
+   char *xml_data;
 };
 
 static const char *none_prefix[] = { NULL };
@@ -136,40 +137,138 @@ error:
 }
 
 static gboolean gnss_parse_report(GAtResult *result, const char *prefix,
-   const char **xml)
+   char **xml, struct gnss_data *gd)
 {
GAtResultIter iter;
+   char *buf, *temp_xml;
+   int len, old_len, xml_len;
+   const char *xml_result;
+
+   buf = NULL;
+   temp_xml = NULL;
+   xml_result = NULL;
+   xml_len = 0;
+   old_len = 0;
+   len = 0;
 
g_at_result_iter_init(iter, result);
 
-   if (!g_at_result_iter_next(iter, prefix))
-   return FALSE;
+   if (!g_at_result_iter_next(iter, prefix)) {
+   if (gd-xml_data) {
+   g_free(gd-xml_data);
+   gd-xml_data = NULL;
+   }
+   goto error;
+   }
 
-   if (!g_at_result_iter_next_unquoted_string(iter, xml))
+   if (!g_at_result_iter_next_unquoted_string(iter, xml_result)) {
+   if (gd-xml_data) {
+   g_free(gd-xml_data);
+   gd-xml_data = NULL;
+   }
+   goto error;
+   }
+
+   if (xml_result == NULL) {
+   if (gd-xml_data) {
+   g_free(gd-xml_data);
+   gd-xml_data = NULL;
+   }
+   goto error;
+   }
+
+   len = strlen(xml_result);
+
+   if (len == 0)
return FALSE;
 
-   return TRUE;
+   while ((xml_result[len-1] == '\n') || (xml_result[len-1] == '\r') ||
+   (xml_result[len-1] == ' ')) {
+   len = len - 1;
+   }
+
+   temp_xml = g_try_new(char, len+1);
+   if (!temp_xml) {
+   if (gd-xml_data) {
+   g_free(gd-xml_data);
+   gd-xml_data = NULL;
+   }
+   goto error;
+   }
+
+   g_memmove(temp_xml, xml_result, len);
+   temp_xml[len] = '\0';
+
+   if (temp_xml[len-1] == ''  temp_xml[len-2] == 's'
+temp_xml[len-3] == 'o'
+temp_xml[len-4] == 'p'
+temp_xml[len-5] == '/') {
+   if (gd-xml_data) {
+   old_len = strlen(gd-xml_data);
+   buf = g_try_new(char, (old_len+len+1));
+   if (!buf) {
+   g_free(gd-xml_data);
+   g_free(temp_xml);
+   gd-xml_data = NULL;
+   goto error;
+   }
+
+   xml_len = sprintf(buf, %s, gd-xml_data);
+   xml_len += sprintf(buf + xml_len, %s, temp_xml);
+   buf[xml_len] = '\0';
+   g_free(gd-xml_data);
+   g_free(temp_xml);
+   gd-xml_data = NULL;
+   *xml = buf;
+   return TRUE;
+   } else {
+   *xml = temp_xml;
+   return TRUE;
+   }
+   } else {
+   if (gd-xml_data) {
+   old_len = strlen(gd-xml_data);
+   buf = g_try_new(char, (old_len+len+1));
+   if (!buf) {
+   g_free(gd-xml_data);
+   g_free(temp_xml);
+   gd-xml_data = NULL;
+   goto error;
+   }
+
+   xml_len = sprintf(buf, %s, gd-xml_data);
+   xml_len += sprintf(buf + xml_len, %s, temp_xml);
+   buf[xml_len] = '\0';
+   g_free(gd-xml_data);
+   gd-xml_data = buf;
+   g_free(temp_xml);
+   return FALSE;
+   } else {
+   gd-xml_data = temp_xml;
+   return FALSE;
+   }
+   }
+
+error:
+   ofono_error(Unable to parse CPOSR notification);
+   return FALSE;
 }
 
 static void gnss_report(GAtResult *result, gpointer user_data)
 {
-   const char *xml;
+   struct ofono_gnss *gnss = user_data;
+   struct gnss_data *gd = 

RE: [PATCH 0/1] isimodem: fix network registration for older modems

2011-03-30 Thread Mika.Liljeberg
Hi Claudio,

 Thank you so much for your support and help, please let us 
 know once you
 have the patch.

I posted a few patches yesterday, which should improve things.

   is it possible to know the list of supported mobile phone as 
   3g modem ?
  
  We don't have a list of supported phones as such as we're 
 not systematically tesing oFono against old Nokia phones. The 
 isiusb plugin is primarily a development aid, allowing us to 
 test isimodem drivers on a PC instead of on-target. There are 
 some limitations in using the isimodem driver over USB this 
 way. All functionality may not be available with all phones. 
 Mostly it works fine, though.
 
 I see. 
 
 Since each phone can potentially use a different way to talk to the pc
 (Android: rndis, Nokia: AT commands / PPP interface over USB if I
 understand it correctly), we are trying to understand which of these
 methods (hence which phone family) is preferable to be used/supported
 with connman / oFono.
 Do you have any suggestion for us?

My advice is to use whatever works for you. Currently, oFono recognizes Nokia 
phones only via the isiusb plugin, so that is pretty much the only option. 
However, most Nokia phones also support AT commands over USB ACM and should be 
relatively easy to get working with oFono, if you're willing to write a new 
plugin or modify the current nokia plugin for Nokia USB modems to include 
support for Nokia phones. Patches are welcome.

Br,

MikaL
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


Re: [PATCH 1/4] stk-api.txt: Introduce a new API to display abortable information

2011-03-30 Thread Marcel Holtmann
Hi Denis,

   doc/stk-api.txt |   11 +++
   1 files changed, 11 insertions(+), 0 deletions(-)
  
  diff --git a/doc/stk-api.txt b/doc/stk-api.txt
  index f8a115e..fc69bb9 100644
  --- a/doc/stk-api.txt
  +++ b/doc/stk-api.txt
  @@ -252,6 +252,7 @@ Methods byte RequestSelection(string title, 
  byte icon_id,
  Possible Errors: [service].Error.SimToolkit.EndSession
   
  void DisplayActionInformation(string text, byte icon_id)
  +   [noreply]
   
  Supplies a text string and/or icon concerning the
  current activity in the terminal and UICC.  The
  @@ -267,6 +268,16 @@ Methodsbyte RequestSelection(string 
  title, byte icon_id,
  confirmation message to oFono and then should open
  the launch browser with the given url.
   
  +   void DisplayAbortableActionInfo(string text, byte icon_id)
  +
 
 I've thought some more about this and I think we should name this method
 'DisplayAction'

then it might be a good idea to rename DisplayActionInformation into
somthing like DisplayInformation to keep them all a bit simpler.

Regards

Marcel


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


Re: [PATCH 3/6] stk: Introduce BIP command handlers

2011-03-30 Thread Andrzej Zaborowski
Hi Philippe,

I understand that this is a stub but I have some comments just for reference.

On 22 March 2011 13:51, Philippe Nunes philippe.nu...@linux.intel.com wrote:
 ---
  src/stk.c |  307 
 +
  1 files changed, 307 insertions(+), 0 deletions(-)

 diff --git a/src/stk.c b/src/stk.c
 index 68b6240..d224360 100644
 --- a/src/stk.c
 +++ b/src/stk.c
 @@ -79,6 +79,9 @@ struct ofono_stk {

        __ofono_sms_sim_download_cb_t sms_pp_cb;
        void *sms_pp_userdata;
 +       struct stk_channel channel;
 +       struct stk_channel_data rx_buffer;
 +       struct stk_channel_data tx_buffer;
  };

  struct envelope_op {
 @@ -2548,6 +2551,285 @@ static gboolean handle_command_launch_browser(const 
 struct stk_command *cmd,
        return FALSE;
  }

 +static void confirm_open_channel_cb(enum stk_agent_result result,
 +                                       gboolean confirm,
 +                                       void *user_data)
 +{
 +       struct ofono_stk *stk = user_data;
 +       unsigned char no_cause[] = { 0x00 };
 +       struct ofono_error failure = { .type = OFONO_ERROR_TYPE_FAILURE };
 +       struct stk_response rsp;
 +
 +       stk-respond_on_exit = FALSE;
 +
 +       switch (result) {
 +       case STK_AGENT_RESULT_TERMINATE:
 +               send_simple_response(stk, STK_RESULT_TYPE_USER_TERMINATED);
 +               return;
 +
 +       case STK_AGENT_RESULT_TIMEOUT:
 +               confirm = FALSE;
 +               /* Fall through */
 +
 +       case STK_AGENT_RESULT_OK:
 +               if (confirm)
 +                       break;
 +               /* Fall through */
 +
 +       default:
 +               memset(rsp, 0, sizeof(rsp));
 +               ADD_ERROR_RESULT(rsp.result, STK_RESULT_TYPE_TERMINAL_BUSY,
 +                                       no_cause);
 +
 +               if (stk_respond(stk, rsp, stk_command_cb))
 +                       stk_command_cb(failure, stk);
 +
 +               return;
 +       }
 +
 +       /*
 +        * TODO
 +        * setup the channel
 +        */
 +
 +       /* For now, return  Command beyond terminal's capabilities */
 +       send_simple_response(stk, STK_RESULT_TYPE_NOT_CAPABLE);
 +}
 +
 +static gboolean handle_command_open_channel(const struct stk_command *cmd,
 +                                               struct stk_response *rsp,
 +                                               struct ofono_stk *stk)
 +{
 +       const struct stk_command_open_channel *oc = cmd-open_channel;
 +       char *alpha_id;
 +       int err;
 +
 +       /* Don't ask for user confirmation if AID is a null data object*/
 +       if (oc-alpha_id  strlen(oc-alpha_id) == 0) {
 +               /*
 +                * TODO
 +                * setup the channel
 +                */
 +
 +               /* For now, return  Command beyond terminal's capabilities 
 */
 +               rsp-result.type = STK_RESULT_TYPE_NOT_CAPABLE;
 +               return TRUE;
 +       }
 +
 +       alpha_id = dbus_apply_text_attributes(oc-alpha_id ? oc-alpha_id : 
 ,
 +                                                       oc-text_attr);
 +       if (alpha_id == NULL) {
 +               rsp-result.type = STK_RESULT_TYPE_DATA_NOT_UNDERSTOOD;
 +               return TRUE;
 +       }
 +
 +       err = stk_agent_confirm_open_channel(stk-current_agent, alpha_id,
 +                                               oc-icon_id,
 +                                               confirm_open_channel_cb,
 +                                               stk, NULL, stk-timeout * 
 1000);
 +       g_free(alpha_id);

What if no AlphaId or Icon are provided?  Also why don't we just use
stk_alpha_id_set?

Another thing, is that AFAICS this series wants to support only one
channel at a time, right?  Then we need to check if a channel is
already open (non-NULL) and return busy.  In the
close/transmit/receive functions we need to make sure that the channel
is non NULL and the channel id matches.

Also it looks like the patches are in reverse order because unit tests
are added before implementation, and stk.c functions are added before
stkagent.c functions.

 +
 +       if (err  0) {
 +               unsigned char no_cause_result[] = { 0x00 };
 +
 +               /*
 +                * We most likely got an out of memory error, tell SIM
 +                * to retry
 +                */
 +               ADD_ERROR_RESULT(rsp-result, STK_RESULT_TYPE_TERMINAL_BUSY,
 +                                       no_cause_result);
 +               return TRUE;
 +       }
 +
 +       stk-respond_on_exit = TRUE;
 +       stk-cancel_cmd = stk_request_cancel;
 +
 +       return FALSE;
 +}
 +
 +static void channel_activity_cb(enum stk_agent_result result, void 
 *user_data)
 +{
 +       struct ofono_stk *stk = user_data;
 +
 +       if (result == STK_AGENT_RESULT_TERMINATE) {
 +               stk-respond_on_exit = FALSE;
 +               send_simple_response(stk, 

[PATCH v2 1/4] stk-api.txt: Introduce the new API DisplayAction

2011-03-30 Thread Philippe Nunes
---
 doc/stk-api.txt |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/doc/stk-api.txt b/doc/stk-api.txt
index f8a115e..0bcc6b5 100644
--- a/doc/stk-api.txt
+++ b/doc/stk-api.txt
@@ -252,6 +252,7 @@ Methods byte RequestSelection(string title, 
byte icon_id,
Possible Errors: [service].Error.SimToolkit.EndSession
 
void DisplayActionInformation(string text, byte icon_id)
+   [noreply]
 
Supplies a text string and/or icon concerning the
current activity in the terminal and UICC.  The
@@ -267,6 +268,16 @@ Methodsbyte RequestSelection(string title, 
byte icon_id,
confirmation message to oFono and then should open
the launch browser with the given url.
 
+   void DisplayAction(string text, byte icon_id)
+
+   Supplies a text string and/or icon concerning the
+   current activity in the terminal and UICC. The
+   text should be displayed to the user on screen
+   until the call is canceled using Cancel() or until the
+   user decides to end the session.
+
+   Possible Errors: [service].Error.SimToolkit.EndSession
+
void Cancel() [noreply]
 
Asks the agent to cancel any ongoing operation in
-- 
1.7.1

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


[PATCH v2 2/4] stk: Handle user termination for Send DTMF

2011-03-30 Thread Philippe Nunes
---
 src/stk.c |   26 +-
 1 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/stk.c b/src/stk.c
index 94ad396..780e0c2 100644
--- a/src/stk.c
+++ b/src/stk.c
@@ -473,6 +473,16 @@ static void emit_menu_changed(struct ofono_stk *stk)
g_dbus_send_message(conn, signal);
 }
 
+static void user_termination_cb(enum stk_agent_result result, void *user_data)
+{
+   struct ofono_stk *stk = user_data;
+
+   if (result == STK_AGENT_RESULT_TERMINATE) {
+   stk-respond_on_exit = FALSE;
+   send_simple_response(stk, STK_RESULT_TYPE_USER_TERMINATED);
+   }
+}
+
 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)
@@ -484,7 +494,13 @@ static void stk_alpha_id_set(struct ofono_stk *stk,
 * and no alpha identifier cases equally. This may be changed once
 * better idea is found out.
 */
-   if (alpha != NULL)
+   if (alpha == NULL)
+   return;
+
+   if (stk-respond_on_exit)
+   stk_agent_display_action(stk-current_agent, alpha, icon,
+   user_termination_cb, stk, NULL);
+   else
stk_agent_display_action_info(stk-current_agent, alpha, icon);
 
g_free(alpha);
@@ -2329,10 +2345,6 @@ 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.text_attr,
-   cmd-send_dtmf.icon_id);
-
/*
 * Note that we don't strictly require an agent to be connected,
 * but to comply with 6.4.24 we need to send a End Session when
@@ -2342,6 +2354,10 @@ static gboolean handle_command_send_dtmf(const struct 
stk_command *cmd,
stk-cancel_cmd = send_dtmf_cancel;
stk-dtmf_id = err;
 
+   stk_alpha_id_set(stk, cmd-send_dtmf.alpha_id,
+   cmd-send_dtmf.text_attr,
+   cmd-send_dtmf.icon_id);
+
return FALSE;
 }
 
-- 
1.7.1

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


[PATCH v2 4/4] test-stk-menu: Extend to support DisplayAction method

2011-03-30 Thread Philippe Nunes
---
 test/test-stk-menu |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/test/test-stk-menu b/test/test-stk-menu
index 639fe77..1fde700 100755
--- a/test/test-stk-menu
+++ b/test/test-stk-menu
@@ -198,6 +198,16 @@ class StkAgent(dbus.service.Object):
print Text: %s % (text)
print Icon: %d % (icon)
 
+   @dbus.service.method(org.ofono.SimToolkitAgent,
+   in_signature=sy, out_signature=)
+   def DisplayAction(self, text, icon):
+   print Text: (%s) % (text)
+   print Icon: (%d) % (icon)
+   key = raw_input(Press 't' to terminate the session )
+
+   if key == 't':
+   raise EndSession(User wishes to terminate session)
+
 def property_changed(name, value):
print SimToolKit property: %s changed to '%s' % (name, value)
 
-- 
1.7.1

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


[PATCH v2 3/4] stkagent: Call the new display method when user termination is allowed

2011-03-30 Thread Philippe Nunes
---
 src/stkagent.c |   61 
 src/stkagent.h |9 
 2 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/src/stkagent.c b/src/stkagent.c
index 2395182..15ad4fa 100644
--- a/src/stkagent.c
+++ b/src/stkagent.c
@@ -1081,3 +1081,64 @@ int stk_agent_confirm_launch_browser(struct stk_agent 
*agent, const char *text,
 
return 0;
 }
+
+static void display_action_cb(DBusPendingCall *call, void *data)
+{
+   struct stk_agent *agent = data;
+   stk_agent_user_termination_cb cb = agent-user_cb;
+   DBusMessage *reply = dbus_pending_call_steal_reply(call);
+   enum stk_agent_result result;
+   gboolean remove_agent;
+
+   if (check_error(agent, reply,
+   ALLOWED_ERROR_TERMINATE, result) == -EINVAL) {
+   remove_agent = TRUE;
+   goto error;
+   }
+
+   if (dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID) == FALSE) {
+   ofono_error(Can't parse the reply to DisplayAction());
+   remove_agent = TRUE;
+   goto error;
+   }
+
+   cb(result, agent-user_data);
+   goto done;
+
+   CALLBACK_END();
+}
+
+int stk_agent_display_action(struct stk_agent *agent,
+   const char *text,
+   const struct stk_icon_id *icon,
+   stk_agent_user_termination_cb cb,
+   void *user_data,
+   ofono_destroy_func destroy)
+{
+   DBusConnection *conn = ofono_dbus_get_connection();
+
+   agent-msg = dbus_message_new_method_call(agent-bus, agent-path,
+   OFONO_SIM_APP_INTERFACE,
+   DisplayAction);
+   if (agent-msg == NULL)
+   return -ENOMEM;
+
+   dbus_message_append_args(agent-msg,
+   DBUS_TYPE_STRING, text,
+   DBUS_TYPE_BYTE, icon-id,
+   DBUS_TYPE_INVALID);
+
+   if (dbus_connection_send_with_reply(conn, agent-msg, agent-call,
+   0) == 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, display_action_cb,
+   agent, NULL);
+
+   return 0;
+}
diff --git a/src/stkagent.h b/src/stkagent.h
index 1f0c4fa..fd60824 100644
--- a/src/stkagent.h
+++ b/src/stkagent.h
@@ -60,6 +60,9 @@ 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_user_termination_cb)(enum stk_agent_result result,
+   void *user_data);
+
 struct stk_agent *stk_agent_new(const char *path, const char *sender,
ofono_bool_t remove_on_terminate);
 
@@ -147,3 +150,9 @@ int stk_agent_confirm_launch_browser(struct stk_agent 
*agent, const char *text,
void *user_data,
ofono_destroy_func destroy,
int timeout);
+
+int stk_agent_display_action(struct stk_agent *agent, const char *text,
+   const struct stk_icon_id *icon,
+   stk_agent_user_termination_cb cb,
+   void *user_data,
+   ofono_destroy_func destroy);
-- 
1.7.1

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


RE: [PATCH v2 2/4] voicecall: refactor emergency number list handling

2011-03-30 Thread Jeevaka.Badrappan
Hi Denis,

Denis Kenzior wrote:
 Hi Jeevaka,
 
 void emit_en_list_changed(struct ofono_voicecall *vc)  static void
 set_new_ecc(struct ofono_voicecall *vc)  {
  int i = 0;
 +GSList *l;
 
  g_slist_foreach(vc-en_list, (GFunc) g_free, NULL); 
 g_slist_free(vc-en_list); @@ -2079,6 +2081,12 @@ static void
  set_new_ecc(struct ofono_voicecall *vc) vc-en_list =
  vc-new_en_list; vc-new_en_list = NULL;
 
 +for (l = vc-sim_en_list; l; l = l-next) {
 +if (!g_slist_find_custom(vc-en_list, l-data,
number_compare))
 +vc-en_list = g_slist_prepend(vc-en_list,
 +
 g_strdup(l-data));
 +}
 +
  while (default_en_list[i]) {
  GSList *l;
 
 @@ -2120,10 +2128,11 @@ static void ecc_g2_read_cb(int ok, int
 total_length, int record,data += 3; 
 
  if (en[0] != '\0')
 -vc-new_en_list =
 g_slist_prepend(vc-new_en_list,
 +vc-sim_en_list =
 g_slist_prepend(vc-sim_en_list,
 
 g_strdup(en));
 
 To preserve the old behavior, can we also check that the
 number is not on the default_en_list?

SIM ecc number check with default_en_list is already taken care inside
set_new_ecc function. 

Regards,
Jeevaka

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


[PATCH] sim: add +CNUM support for HFP emulator

2011-03-30 Thread Frédéric Danis
---
 src/sim.c |   58 ++
 1 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/src/sim.c b/src/sim.c
index 98d4cc4..a9e73e6 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -106,6 +106,7 @@ struct ofono_sim {
const struct ofono_sim_driver *driver;
void *driver_data;
struct ofono_atom *atom;
+   unsigned int hfp_watch;
 };
 
 struct msisdn_set_request {
@@ -2519,6 +2520,56 @@ struct ofono_sim *ofono_sim_create(struct ofono_modem 
*modem,
return sim;
 }
 
+static void emulator_cnum_cb(struct ofono_emulator *em,
+   struct ofono_emulator_request *req, void *userdata)
+{
+   struct ofono_sim *sim = userdata;
+   struct ofono_error result;
+   GSList *l;
+   const char *phone;
+   /*
+* '+CNUM: ,+,,,4' + phone number + phone type on 3 digits max
+* + terminating null
+*/
+   char buf[OFONO_MAX_PHONE_NUMBER_LENGTH + 18 + 1];
+
+   result.error = 0;
+
+   switch (ofono_emulator_request_get_type(req)) {
+   case OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY:
+   for (l = sim-own_numbers; l; l = l-next) {
+   struct ofono_phone_number *ph = l-data;
+
+   phone = phone_number_to_string(ph);
+   sprintf(buf, +CNUM: ,\%s\,%d,,4, phone, ph-type);
+   ofono_emulator_send_info(em, buf, TRUE);
+   }
+
+   result.type = OFONO_ERROR_TYPE_NO_ERROR;
+   ofono_emulator_send_final(em, result);
+   break;
+
+   default:
+   result.type = OFONO_ERROR_TYPE_FAILURE;
+   ofono_emulator_send_final(em, result);
+   };
+}
+
+static void emulator_hfp_init(struct ofono_atom *atom, void *data)
+{
+   struct ofono_emulator *em = __ofono_atom_get_data(atom);
+
+   ofono_emulator_add_handler(em, +CNUM, emulator_cnum_cb, data, NULL);
+}
+
+static void emulator_hfp_watch(struct ofono_atom *atom,
+   enum ofono_atom_watch_condition cond,
+   void *data)
+{
+   if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED)
+   emulator_hfp_init(atom, data);
+}
+
 void ofono_sim_register(struct ofono_sim *sim)
 {
DBusConnection *conn = ofono_dbus_get_connection();
@@ -2545,6 +2596,13 @@ void ofono_sim_register(struct ofono_sim *sim)
 
if (sim-state  OFONO_SIM_STATE_NOT_PRESENT)
sim_initialize(sim);
+
+   sim-hfp_watch = __ofono_modem_add_atom_watch(modem,
+   OFONO_ATOM_TYPE_EMULATOR_HFP,
+   emulator_hfp_watch, sim, NULL);
+
+   __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
+   emulator_hfp_init, sim);
 }
 
 void ofono_sim_remove(struct ofono_sim *sim)
-- 
1.7.1

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


[PATCH] doc: add data-call.txt

2011-03-30 Thread Guillaume Zajac
---
 doc/data-call.txt |   47 +++
 1 files changed, 47 insertions(+), 0 deletions(-)
 create mode 100644 doc/data-call.txt

diff --git a/doc/data-call.txt b/doc/data-call.txt
new file mode 100644
index 000..f407560
--- /dev/null
+++ b/doc/data-call.txt
@@ -0,0 +1,47 @@
+DialUp Networking diagram
+=
+
+This diagram explains how oFono and ConnMan are interacting to
+handle a data call from a DUN client.
+1) GAtServer receive ATD*99#.
+2) The GAtPPP server is setup.
+3) oFono through GAtPPP notify ConnMan that he needs a TUN/TAP interface.
+4) oFono is notified that TUN/TAP interface is created and can start exchanging
+PPP packets with DUN client. Those PPP packets are converted into IP stream
+and transmitted to/received from TUN/TAP interface.
+5) ConnMan is selecting which interface to send IP packets (WiFi, 3G, ethX, 
...).
+
+****
+||  ATD*99#   ||
+|   DUN Client   |---|GAtServer   |
+||---*   ||
+**|   **
+  | |
+  PPP | | setup_ppp()
+  Packets | |
+  | |
+  | V   Need
+  |**   /dev/net/tun **
+  *---||   interface||
+   | GAtPPP |--| ConnMan|
+  *---||   interface||
+  |**   created  **
+  IP  |  |
+  Stream  |  |Create
+  |**|/dev/net/tun
+  ||||interface
+  *---|TUN/TAP interface   |---*
+   ||
+   **
+  IP | Stream
+ routed with | ConnMan rules
+   *-**
+   | ||
+   | ||
+   V VV
+*-*   *-*  *-*
+| |   | |  | |
+|  WiFi   |   |   Modem |  |EthX |
+| |   | |  | |
+*-*   *-*  *-*
+
-- 
1.7.1

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


Re: [PATCH] doc: add data-call.txt

2011-03-30 Thread Marcel Holtmann
Hi Guillaume,

  doc/data-call.txt |   47 +++
  1 files changed, 47 insertions(+), 0 deletions(-)
  create mode 100644 doc/data-call.txt

looks great. Just call it doc/dialup-overview.txt since data-call is a
little unclear what this is about.

Regards

Marcel


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


Re: [PATCH] emulator: add AT hook_control_cb() CB and register it

2011-03-30 Thread Denis Kenzior
Hi Guillaume,

 This patch is also in the set of patches I have sent for escape sequence
 detection because I needed it to complete gsmdial tests.
 Should I resend the set of patches with this patch updated ? or I should
 wait for your feedback on the complete set of patches?
 

Yes I noticed you put this patch in the other series after I sent the
review.  Please wait for my review of that series before resending.  I
will attempt to do that today.

Regards,
-Denis
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCHv2] doc: add dialup-overview.txt

2011-03-30 Thread Guillaume Zajac
---
 doc/dialup-overview.txt |   47 +++
 1 files changed, 47 insertions(+), 0 deletions(-)
 create mode 100644 doc/dialup-overview.txt

diff --git a/doc/dialup-overview.txt b/doc/dialup-overview.txt
new file mode 100644
index 000..f407560
--- /dev/null
+++ b/doc/dialup-overview.txt
@@ -0,0 +1,47 @@
+DialUp Networking diagram
+=
+
+This diagram explains how oFono and ConnMan are interacting to
+handle a data call from a DUN client.
+1) GAtServer receive ATD*99#.
+2) The GAtPPP server is setup.
+3) oFono through GAtPPP notify ConnMan that he needs a TUN/TAP interface.
+4) oFono is notified that TUN/TAP interface is created and can start exchanging
+PPP packets with DUN client. Those PPP packets are converted into IP stream
+and transmitted to/received from TUN/TAP interface.
+5) ConnMan is selecting which interface to send IP packets (WiFi, 3G, ethX, 
...).
+
+****
+||  ATD*99#   ||
+|   DUN Client   |---|GAtServer   |
+||---*   ||
+**|   **
+  | |
+  PPP | | setup_ppp()
+  Packets | |
+  | |
+  | V   Need
+  |**   /dev/net/tun **
+  *---||   interface||
+   | GAtPPP |--| ConnMan|
+  *---||   interface||
+  |**   created  **
+  IP  |  |
+  Stream  |  |Create
+  |**|/dev/net/tun
+  ||||interface
+  *---|TUN/TAP interface   |---*
+   ||
+   **
+  IP | Stream
+ routed with | ConnMan rules
+   *-**
+   | ||
+   | ||
+   V VV
+*-*   *-*  *-*
+| |   | |  | |
+|  WiFi   |   |   Modem |  |EthX |
+| |   | |  | |
+*-*   *-*  *-*
+
-- 
1.7.1

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


Re: [PATCHv2] doc: add dialup-overview.txt

2011-03-30 Thread Marcel Holtmann
Hi Guillaume,

  doc/dialup-overview.txt |   47 
 +++
  1 files changed, 47 insertions(+), 0 deletions(-)
  create mode 100644 doc/dialup-overview.txt

patch has been applied. Thanks.

Regards

Marcel


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


Re: [PATCH v2 1/4] stk-api.txt: Introduce the new API DisplayAction

2011-03-30 Thread Denis Kenzior
Hi Philippe,

On 03/30/2011 05:27 AM, Philippe Nunes wrote:
 ---
  doc/stk-api.txt |   11 +++
  1 files changed, 11 insertions(+), 0 deletions(-)
 

I applied all four patches in this series, thanks for these.  I did
apply them in a slightly different (more logical, at least to me ;)
order and reworded the commit messages.

Regards,
-Denis
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


Re: [PATCH 1/3] core: notify watches of already registered atoms

2011-03-30 Thread Denis Kenzior
Hi Mika,

 I do have an actual bug, which this patch fixes. I've been investigating why, 
 with isiusb, the gprs atom sometimes fails to receive the network 
 registration status and therefore fails to attach to the GPRS service. It 
 turns out that the problem comes from the client side code pattern for 
 registering atom watches. The code assumes that there will only be a single 
 atom of the same type (registered or not).
 
 Basically, gprs atom and the alternative netreg atoms are probing in parallel 
 and may register themselves in a random order. If gprs finishes first, it 
 will correctly get a call to its watch handler when one of the netreg atoms 
 completes its registration. However, if the order is reversed and gprs 
 finishes after the netreg atom, the following snippet of code tries to find 
 the already registered netreg atom:
 
 netreg_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_NETREG);
 
 if (netreg_atom  __ofono_atom_get_registered(netreg_atom))
 netreg_watch(netreg_atom,
 OFONO_ATOM_WATCH_CONDITION_REGISTERED, gprs);
 
 The trouble here is that __ofono_modem_find_atom() just returns the first 
 neterg atom it finds, regardless of whether it is registered or not. In this 
 case it happens to be the wrong netreg (wgmodem2.5 version, which fails to 
 probe), even though the other netreg atom is already present and registered. 
 Because of this, the watch funtion is never called.
 

I changed the behavior of __ofono_modem_find_atom to only return ones
that are registered.  This is really what we want anyway, the only
exception was the devinfo atom which was never being registered.
However, I fixed that as well.

 I realize that there are other ways to fix this. The client side pattern 
 could be changed to use __ofono_modem_foreach_atom() to look for already 
 registered atoms, instead of doing the same within the 
 __ofono_modem_add_atom_watch() as in my patch. This would introduce quite a 
 bit of more code. Alternatively, an __ofono_modem_find_registered_atom() 
 function could be introduced to look for a registerd atom of a certain type 
 (might be a good idea to do this in any case). Or isiusb (and any other 
 similar cases) could be revectored to not probe multiple atoms of the same 
 type in parallel. However, we already create multiple GPRS context atoms as a 
 matter of course, so the assumption that there will only be a single instance 
 is no longer valid for all atom types anyway. IMO, it would be good to get 
 rid of the assumption altogether.
 

The current code was really not setup to have multiple netreg atoms.
That is just not something we wanted to allow.  This might be OK in this
particular case where a single driver is involved.  However, if some
modem driver ends up creating every single atom twice to figure out what
modem is on the other side, then it is a serious performance issue.
Ideally I'd like the modem driver to be fixed.

 So, I like my patch because it removes a lot of copy-paste code and does not 
 assume anything about how many atoms of a certain type there can be.
 

In the end I agree and I applied all three of your patches and caught
some other occurrences you missed.

Regards,
-Denis
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


Re: [PATCH] sim: add +CNUM support for HFP emulator

2011-03-30 Thread Denis Kenzior
Hi Frédéric,

On 03/30/2011 08:49 AM, Frédéric Danis wrote:
 ---
  src/sim.c |   58 ++
  1 files changed, 58 insertions(+), 0 deletions(-)
 
 diff --git a/src/sim.c b/src/sim.c
 index 98d4cc4..a9e73e6 100644
 --- a/src/sim.c
 +++ b/src/sim.c
 @@ -106,6 +106,7 @@ struct ofono_sim {
   const struct ofono_sim_driver *driver;
   void *driver_data;
   struct ofono_atom *atom;
 + unsigned int hfp_watch;
  };
  
  struct msisdn_set_request {
 @@ -2519,6 +2520,56 @@ struct ofono_sim *ofono_sim_create(struct ofono_modem 
 *modem,
   return sim;
  }
  
 +static void emulator_cnum_cb(struct ofono_emulator *em,
 + struct ofono_emulator_request *req, void *userdata)
 +{
 + struct ofono_sim *sim = userdata;
 + struct ofono_error result;
 + GSList *l;
 + const char *phone;
 + /*
 +  * '+CNUM: ,+,,,4' + phone number + phone type on 3 digits max
 +  * + terminating null
 +  */
 + char buf[OFONO_MAX_PHONE_NUMBER_LENGTH + 18 + 1];
 +
 + result.error = 0;
 +
 + switch (ofono_emulator_request_get_type(req)) {
 + case OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY:
 + for (l = sim-own_numbers; l; l = l-next) {
 + struct ofono_phone_number *ph = l-data;
 +
 + phone = phone_number_to_string(ph);
 + sprintf(buf, +CNUM: ,\%s\,%d,,4, phone, ph-type);
 + ofono_emulator_send_info(em, buf, TRUE);

You should only use TRUE on the last CNUM.  Please see the documentation
for g_at_server_send_info in gatserver.h for more details.

 + }
 +
 + result.type = OFONO_ERROR_TYPE_NO_ERROR;
 + ofono_emulator_send_final(em, result);
 + break;
 +
 + default:
 + result.type = OFONO_ERROR_TYPE_FAILURE;
 + ofono_emulator_send_final(em, result);
 + };
 +}
 +
 +static void emulator_hfp_init(struct ofono_atom *atom, void *data)
 +{
 + struct ofono_emulator *em = __ofono_atom_get_data(atom);
 +
 + ofono_emulator_add_handler(em, +CNUM, emulator_cnum_cb, data, NULL);
 +}
 +
 +static void emulator_hfp_watch(struct ofono_atom *atom,
 + enum ofono_atom_watch_condition cond,
 + void *data)
 +{
 + if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED)
 + emulator_hfp_init(atom, data);
 +}
 +
  void ofono_sim_register(struct ofono_sim *sim)
  {
   DBusConnection *conn = ofono_dbus_get_connection();
 @@ -2545,6 +2596,13 @@ void ofono_sim_register(struct ofono_sim *sim)
  
   if (sim-state  OFONO_SIM_STATE_NOT_PRESENT)
   sim_initialize(sim);
 +
 + sim-hfp_watch = __ofono_modem_add_atom_watch(modem,
 + OFONO_ATOM_TYPE_EMULATOR_HFP,
 + emulator_hfp_watch, sim, NULL);
 +
 + __ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_EMULATOR_HFP,
 + emulator_hfp_init, sim);

With the new add_atom_watch semantics the foreach should not be
necessary any longer.

  }
  
  void ofono_sim_remove(struct ofono_sim *sim)

Regards,
-Denis
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


Re: [PATCH 03/18] gathdlc: add mechansim to detect '+++' escape sequence

2011-03-30 Thread Denis Kenzior
Hi Guillaume,

On 03/25/2011 10:25 AM, Guillaume Zajac wrote:
 ---
  gatchat/gathdlc.c |  114 
 +
  1 files changed, 114 insertions(+), 0 deletions(-)
 
 diff --git a/gatchat/gathdlc.c b/gatchat/gathdlc.c
 index 7c45454..21e4533 100644
 --- a/gatchat/gathdlc.c
 +++ b/gatchat/gathdlc.c
 @@ -50,6 +50,13 @@
  
  #define HDLC_FCS(fcs, c) crc_ccitt_byte(fcs, c)
  
 +/* Amount of fiftieths of second to detect '+++'.
 + * Range is 0 to 0xff.
 + */
 +#define ESC_TIME 0x32

Where is this coming from?  Is this supposed to be controlled by an
S-register?  If so, you might want to use a proper variable for this.

 +
 +#define GUARD_TIMEOUTS   1000/* Pause time before and after '+++' 
 sequence */
 +

This seems redundant to the ESC_TIME timeout...

  struct _GAtHDLC {
   gint ref_count;
   GAtIO *io;
 @@ -68,6 +75,12 @@ struct _GAtHDLC {
   gboolean in_read_handler;
   gboolean destroyed;
   gboolean no_carrier_detect;
 + GAtSuspendFunc suspend_func;
 + gpointer suspend_data;
 + guint cmpt;
 + guint suspend_timeout;
 + guint pause_timeout;

You never clean up these g_sources (e.g. in the case where GAtHDLC is
forcefully removed).  This is a big no no in a library, you must clean
up after yourself in all cases.

I would also replace the suspend_timeout with a GTimer directly.

 + gboolean paused;
  };
  
  static void hdlc_record(int fd, gboolean in, guint8 *data, guint16 length)
 @@ -130,6 +143,47 @@ guint32 g_at_hdlc_get_recv_accm(GAtHDLC *hdlc)
   return hdlc-recv_accm;
  }
  
 +void g_at_hdlc_set_suspend_function(GAtHDLC *hdlc, GAtSuspendFunc func,
 + gpointer user_data)
 +{
 + if (hdlc == NULL)
 + return;
 +
 + hdlc-suspend_func = func;
 + hdlc-suspend_data = user_data;
 +}
 +
 +static gboolean paused_timeout_cb(gpointer user_data)
 +{
 + GAtHDLC *hdlc = user_data;
 +
 + hdlc-paused = TRUE;
 +
 + return FALSE;
 +}
 +
 +static gboolean susp_timeout_cb(gpointer user_data)
 +{
 + GAtHDLC *hdlc = user_data;
 +
 + hdlc-cmpt = 0;
 +
 + return FALSE;
 +}
 +
 +static gboolean hdlc_suspend(gpointer user_data)
 +{
 + GAtHDLC *hdlc = user_data;
 +
 + g_at_io_set_write_handler(hdlc-io, NULL, NULL);
 + g_at_io_set_read_handler(hdlc-io, NULL, NULL);
 +
 + if (hdlc-suspend_func)
 + hdlc-suspend_func(hdlc-suspend_data);
 +
 + return FALSE;
 +}
 +
  static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
  {
   GAtHDLC *hdlc = user_data;
 @@ -142,6 +196,13 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer 
 user_data)
  
   hdlc-in_read_handler = TRUE;
  
 + /*
 +  * We delete the the paused_timeout_cb or hdlc_suspend as soons as
 +  * we read a data.
 +  */
 + if (hdlc-pause_timeout  0)
 + g_source_remove(hdlc-pause_timeout);
 +
   while (pos  len) {
   /*
* We try to detect NO CARRIER conditions here.  We
 @@ -153,6 +214,21 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer 
 user_data)
   hdlc-decode_offset == 0  *buf == '\r')
   break;
  
 + /*
 +  * If there was no character for 1 second we try to detect
 +  * the '+' character to suspend data call if 3 '+' are
 +  * detected in less than 20 * ESC_TIME milliseconds.
 +  */
 + if (*buf == '+'  hdlc-paused) {
 + if (hdlc-cmpt == 0)
 + hdlc-suspend_timeout = g_timeout_add (20 * 
 ESC_TIME,
 + susp_timeout_cb, hdlc);
 + hdlc-cmpt++;
 + } else {
 + hdlc-cmpt = 0;
 + hdlc-paused = FALSE;
 + }
 +
   if (hdlc-decode_escape == TRUE) {
   unsigned char val = *buf ^ HDLC_TRANS;
  
 @@ -190,6 +266,9 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer 
 user_data)
   }
   }
  
 + if (hdlc-cmpt == 3)
 + goto suspend;
 +
  out:
   ring_buffer_drain(rbuf, pos);
  
 @@ -197,6 +276,37 @@ out:
  
   if (hdlc-destroyed)
   g_free(hdlc);
 +
 + /*
 +  * If there were no data pause for GUARD_TIMEOUTS ms,
 +  * we try again to check it.
 +  */
 + if (!hdlc-paused)
 + hdlc-pause_timeout = g_timeout_add (GUARD_TIMEOUTS,
 + paused_timeout_cb,
 + hdlc);
 +
 + return;
 +
 +suspend:
 + /*
 +  * If the suspend timeout still exists,
 +  * delete it.
 +  */
 + if (hdlc-suspend_timeout  0)
 + g_source_remove(hdlc-suspend_timeout);
 +
 + /*
 +  * Restart the counter and reset the ring buffer.
 +  */
 

Re: [PATCH 05/18] gatppp: add g_at_ppp_set_suspend_function() definition

2011-03-30 Thread Denis Kenzior
Hi Guillaume,

On 03/25/2011 10:25 AM, Guillaume Zajac wrote:
 ---
  gatchat/gatppp.c |8 
  1 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c
 index 993b5ea..9df6b8e 100644
 --- a/gatchat/gatppp.c
 +++ b/gatchat/gatppp.c
 @@ -467,6 +467,14 @@ void g_at_ppp_set_debug(GAtPPP *ppp, GAtDebugFunc func, 
 gpointer user_data)
   ppp-debug_data = user_data;
  }
  
 +void g_at_ppp_set_suspend_function(GAtPPP *ppp, GAtSuspendFunc func, 
 gpointer user_data)
 +{
 + if (ppp == NULL)
 + return;
 +
 + g_at_hdlc_set_suspend_function(ppp-hdlc, func, user_data);
 +}
 +

This is really not enough, you must also shut down the read watch on the
TUN device, so that we don't try to forward packets from TUN to HDLC
while we're suspended.

  void g_at_ppp_shutdown(GAtPPP *ppp)
  {
   if (ppp-phase == PPP_PHASE_DEAD || ppp-phase == PPP_PHASE_TERMINATION)

Regards,
-Denis
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


Re: [PATCH 18/18] gsmdial: implement mechanism to send +++ - ATO0 - +++ - ATH0

2011-03-30 Thread Denis Kenzior
Hi Guillaume,

On 03/25/2011 10:25 AM, Guillaume Zajac wrote:
 ---
  gatchat/gsmdial.c |  164 
  1 files changed, 138 insertions(+), 26 deletions(-)
 
 diff --git a/gatchat/gsmdial.c b/gatchat/gsmdial.c
 index 92a7ff2..f1b485e 100644
 --- a/gatchat/gsmdial.c
 +++ b/gatchat/gsmdial.c
 @@ -40,6 +40,8 @@
  
  #define IFCONFIG_PATH /sbin/ifconfig
  
 +#define GUARD_TIMEOUTS 1500
 +
  static const char *none_prefix[] = { NULL };
  static const char *cfun_prefix[] = { +CFUN:, NULL };
  static const char *creg_prefix[] = { +CREG:, NULL };
 @@ -238,32 +240,6 @@ static gboolean execute(const char *cmd)
   return TRUE;
  }
  
 -static void ppp_connect(const char *iface, const char *local, const char 
 *peer,
 - const char *dns1, const char *dns2,
 - gpointer user_data)
 -{
 - char buf[512];
 -
 - /* print out the negotiated address and dns server */
 - g_print(Network Device: %s\n, iface);
 - g_print(IP Address: %s\n, local);
 - g_print(Peer IP Address: %s\n, peer);
 - g_print(Primary DNS Server: %s\n, dns1);
 - g_print(Secondary DNS Server: %s\n, dns2);
 -
 - if (getuid() != 0) {
 - g_print(Need root privilege to config PPP interface\n);
 - return;
 - }
 -
 - snprintf(buf, sizeof(buf), %s %s up, IFCONFIG_PATH, iface);
 - execute(buf);
 -
 - snprintf(buf, sizeof(buf), %s %s %s pointopoint %s, IFCONFIG_PATH,
 - iface, local, peer);
 - execute(buf);
 -}
 -
  static void no_carrier_notify(GAtResult *result, gpointer user_data)
  {
   char buf[64];
 @@ -294,6 +270,142 @@ static void ppp_disconnect(GAtPPPDisconnectReason 
 reason, gpointer user_data)
   g_at_chat_resume(modem);
  }
  
 +static void power_down_ppp(gboolean ok, GAtResult *result, gpointer 
 user_data)
 +{
 + if (!ok)
 + return;
 +
 + g_at_ppp_unref(ppp);
 + ppp = NULL;
 +}
 +
 +static gboolean send_ATH0(gpointer user_data)
 +{
 + /* Resume AT chat to send ATH0 */
 + g_at_chat_resume(modem);
 + g_at_chat_send(modem, ATH0, none_prefix, power_down_ppp, NULL, NULL);
 +
 + return FALSE;
 +}
 +
 +static gboolean suspend_and_close(gpointer user_data)
 +{
 + g_print(Send +++\n);
 + /* Send the escape sequence to suspend PPP server*/
 + g_at_io_write(g_at_chat_get_io(modem), +++, 3);
 + 
 + /*
 +  * Wait GUARD_TIMEOUTS ms before sending ATH0 cmd
 +  * according to guard timeouts
 +  */
 + g_timeout_add(GUARD_TIMEOUTS, send_ATH0, NULL);
 +
 + return FALSE;
 +}
 +
 +static void ppp_suspend_close(gpointer data)
 +{
 + /* Delete the write done CB */
 + g_at_io_set_write_done(g_at_chat_get_io(modem), NULL, NULL);
 +
 + /*
 +  * We are sure there are no more PPP packets to be written,
 +  * we can suspend PPP client
 +  */
 + g_at_ppp_suspend(ppp);
 +
 + /* Wait GUARD_TIMEOUTS ms before sending escape sequence */
 + g_timeout_add(GUARD_TIMEOUTS, suspend_and_close, NULL);
 +}
 +
 +static void suspend_gat_chat(gboolean ok, GAtResult *result, gpointer 
 user_data)
 +{
 + /*
 +  * As soon as the command is treated by AT server
 +  * we can suspend AT chat and resume PPP client
 +  */
 + g_at_chat_suspend(modem);
 + g_at_ppp_resume(ppp);
 +
 + /*
 +  * We wait for another PPP packet to be written
 +  * to suspend again PPP server and close it
 +  */
 + g_at_io_set_write_done(g_at_chat_get_io(modem), ppp_suspend_close, 
 NULL);
 +}
 +
 +static gboolean send_ATO0(gpointer user_data)
 +{
 + /* Resume AT chat to send ATO0 */
 + g_at_chat_resume(modem);
 + g_at_chat_send(modem, ATO0, none_prefix, suspend_gat_chat, NULL, 
 NULL);
 +
 + return FALSE;
 +}
 +
 +static gboolean suspend_resume(gpointer user_data)
 +{
 + g_print(Send +++\n);
 + /* Send the escape sequence to suspend PPP server*/
 + g_at_io_write(g_at_chat_get_io(modem), +++, 3);
 +
 + /*
 +  * Wait GUARD_TIMEOUTS ms before sending ATO0 cmd
 +  * according to guard timeouts
 +  */
 + g_timeout_add(GUARD_TIMEOUTS, send_ATO0, NULL);
 +
 + return FALSE;
 +}
 +
 +static void ppp_suspend_resume(gpointer data)
 +{
 + /* Delete the write done CB */
 + g_at_io_set_write_done(g_at_chat_get_io(modem), NULL, NULL);
 +
 + /*
 +  * We are sure there are no more PPP packets to be written,
 +  * we can suspend PPP client
 +  */
 + g_at_ppp_suspend(ppp);
 +
 + /* Wait GUARD_TIMEOUTS ms before sending escape sequence */
 + g_timeout_add(GUARD_TIMEOUTS, suspend_resume, NULL);
 +}
 +

The logic for sending a guard timeout, +++, guard timeout should really
belong in GAtChat, otherwise every single client has to repeat the same
state machine.

 +static void ppp_connect(const char *iface, const char *local, const char 
 *peer,
 + const char *dns1, const char *dns2,
 + 

[PATCH] stkutil: Add typo/cleaning modifications

2011-03-30 Thread Philippe Nunes
---
 src/stkutil.c |4 ++--
 src/stkutil.h |2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/stkutil.c b/src/stkutil.c
index c64cb7a..3418b4b 100644
--- a/src/stkutil.c
+++ b/src/stkutil.c
@@ -5493,7 +5493,7 @@ const unsigned char *stk_pdu_from_response(const struct 
stk_response *response,
 * Min = N.
 *
 * However comprehension required is set for many of the TLVs in
-* TS 102 384 conformace tests so we set it per command and per
+* TS 102 384 conformance tests so we set it per command and per
 * data object type.
 */
tag = STK_DATA_OBJECT_TYPE_DEVICE_IDENTITIES;
@@ -6269,7 +6269,7 @@ char *stk_image_to_xpm(const unsigned char *img, unsigned 
int len,
 
/*
 * space needed:
-*  header line
+*  header line
 *  declaration and beginning of assignment line
 *  values - max length of 19
 *  colors - ncolors * (cpp + whitespace + deliminators + color)
diff --git a/src/stkutil.h b/src/stkutil.h
index f2df23f..1b38dec 100644
--- a/src/stkutil.h
+++ b/src/stkutil.h
@@ -245,7 +245,7 @@ enum stk_result_type {
STK_RESULT_TYPE_USER_REJECT =   0x22,
STK_RESULT_TYPE_USER_CANCEL =   0x23,
STK_RESULT_TYPE_TIMER_CONFLICT =0x24,
-   STK_RESULT_TYPE_CALL_CONTROL_TEMPORARY =0x25,
+   STK_RESULT_TYPE_CALL_CONTROL_TEMPORARY =0x25,
STK_RESULT_TYPE_BROWSER_TEMPORARY = 0x26,
STK_RESULT_TYPE_MMS_TEMPORARY = 0x27,
 
-- 
1.7.1

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


[PATCH v2 1/2] stkutil: Complete the TLV parsing/builder to support BIP commands

2011-03-30 Thread Philippe Nunes
---
 src/stkutil.c |  287 +---
 src/stkutil.h |  132 ++-
 2 files changed, 380 insertions(+), 39 deletions(-)

diff --git a/src/stkutil.c b/src/stkutil.c
index c64cb7a..94be192 100644
--- a/src/stkutil.c
+++ b/src/stkutil.c
@@ -1264,8 +1264,20 @@ static gboolean parse_dataobj_bearer_description(
 
data = comprehension_tlv_iter_get_data(iter);
bd-type = data[0];
-   bd-len = len - 1;
-   memcpy(bd-pars, data + 1, bd-len);
+
+   /* Parse only the packet data service bearer parameters */
+   if (bd-type != STK_BEARER_TYPE_GPRS_UTRAN)
+   return FALSE;
+
+   if (len  7)
+   return FALSE;
+
+   bd-gprs.precedence = data[1];
+   bd-gprs.delay = data[2];
+   bd-gprs.reliability = data[3];
+   bd-gprs.peak = data[4];
+   bd-gprs.mean = data[5];
+   bd-gprs.pdp_type = data[6];
 
return TRUE;
 }
@@ -1355,8 +1367,16 @@ static gboolean parse_dataobj_other_address(
return FALSE;
 
data = comprehension_tlv_iter_get_data(iter);
+
+   if (data[0] != STK_ADDRESS_IPV4  data[0] != STK_ADDRESS_IPV6)
+   return FALSE;
+
oa-type = data[0];
-   memcpy(oa-addr, data + 1, len - 1);
+
+   if (oa-type == STK_ADDRESS_IPV4)
+   memcpy(oa-addr.ipv4, data + 1, 4);
+   else
+   memcpy(oa-addr.ipv6, data + 1, 16);
 
return TRUE;
 }
@@ -1604,16 +1624,48 @@ static gboolean parse_dataobj_esn(struct 
comprehension_tlv_iter *iter,
 static gboolean parse_dataobj_network_access_name(
struct comprehension_tlv_iter *iter, void *user)
 {
-   struct stk_network_access_name *nan = user;
+   char **apn = user;
const unsigned char *data;
unsigned int len = comprehension_tlv_iter_get_length(iter);
+   unsigned char label_size;
+   unsigned char offset = 0;
+   char decoded_apn[100];
 
-   if (len == 0)
+   if (len == 0 || len  100)
return FALSE;
 
data = comprehension_tlv_iter_get_data(iter);
-   nan-len = len;
-   memcpy(nan-name, data, len);
+   /*
+* As specified in TS 23 003 Section 9
+* The APN consists of one or more labels. Each label is coded as
+* a one octet length field followed by that number of octets coded
+* as 8 bit ASCII characters
+*/
+
+   while (len) {
+   label_size = *data;
+
+   if (label_size  (len-1))
+   return FALSE;
+
+   memcpy(decoded_apn + offset, data + 1, label_size);
+
+   data += label_size + 1;
+   offset += label_size;
+
+   len -= label_size + 1;
+   if (len) {
+   decoded_apn[offset] = '.';
+   offset += 1;
+   }
+   }
+
+   *apn = g_try_malloc(offset + 1);
+   if (*apn == NULL)
+   return FALSE;
+
+   memcpy(*apn, decoded_apn, offset);
+   (*apn)[offset] = '\0';
 
return TRUE;
 }
@@ -3274,7 +3326,68 @@ static enum stk_command_parse_result 
parse_launch_browser(
STK_DATA_OBJECT_TYPE_INVALID);
 }
 
-/* TODO: parse_open_channel */
+static void destroy_open_channel(struct stk_command *command)
+{
+   g_free(command-open_channel.alpha_id);
+   g_free(command-open_channel.text_usr);
+   g_free(command-open_channel.text_passwd);
+}
+
+static enum stk_command_parse_result parse_open_channel(
+   struct stk_command *command,
+   struct comprehension_tlv_iter *iter)
+{
+   struct stk_command_open_channel *obj = command-open_channel;
+   enum stk_command_parse_result status;
+
+   if (command-qualifier = 0x08)
+   return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+   if (command-src != STK_DEVICE_IDENTITY_TYPE_UICC)
+   return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+   if (command-dst != STK_DEVICE_IDENTITY_TYPE_TERMINAL)
+   return STK_PARSE_RESULT_DATA_NOT_UNDERSTOOD;
+
+   command-destructor = destroy_open_channel;
+
+   /*
+* parse the Open Channel data objects related to packet data service
+* bearer
+*/
+   status = parse_dataobj(iter,
+   STK_DATA_OBJECT_TYPE_ALPHA_ID, 0,
+   obj-alpha_id,
+   STK_DATA_OBJECT_TYPE_ICON_ID, 0,
+   obj-icon_id,
+   STK_DATA_OBJECT_TYPE_BEARER_DESCRIPTION,
+   DATAOBJ_FLAG_MANDATORY | DATAOBJ_FLAG_MINIMUM,
+   obj-bearer_desc,
+   STK_DATA_OBJECT_TYPE_BUFFER_SIZE,
+   DATAOBJ_FLAG_MANDATORY | DATAOBJ_FLAG_MINIMUM,
+   

[PATCH v2 2/2] test-stkutil: Add unit tests for BIP commands

2011-03-30 Thread Philippe Nunes
---
 unit/test-stkutil.c | 1170 ++-
 1 files changed, 1153 insertions(+), 17 deletions(-)

diff --git a/unit/test-stkutil.c b/unit/test-stkutil.c
index aa62aac..1706f1d 100644
--- a/unit/test-stkutil.c
+++ b/unit/test-stkutil.c
@@ -470,6 +470,59 @@ static void check_provisioning_file_references(GSList 
*command,
g_assert(test[i].len == 0);
 }
 
+/* Defined in TS 102.223 Section 8.52 */
+static void check_bearer_desc(const struct stk_bearer_description *command,
+   const struct stk_bearer_description *test)
+{
+   g_assert(command-type == test-type);
+
+   if (test-type == STK_BEARER_TYPE_GPRS_UTRAN) {
+
+   check_common_byte(command-gprs.precedence,
+   test-gprs.precedence);
+   check_common_byte(command-gprs.delay,
+   test-gprs.delay);
+   check_common_byte(command-gprs.reliability,
+   test-gprs.reliability);
+   check_common_byte(command-gprs.peak,
+   test-gprs.peak);
+   check_common_byte(command-gprs.mean,
+   test-gprs.mean);
+   check_common_byte(command-gprs.pdp_type,
+   test-gprs.pdp_type);
+   return;
+   }
+}
+
+/* Defined in TS 102.223 Section 8.53 */
+static inline void check_channel_data(
+   const struct stk_common_byte_array *command,
+   const struct stk_common_byte_array *test)
+{
+   check_common_byte_array(command, test);
+}
+
+/* Defined in TS 102.223 Section 8.58 */
+static inline void check_other_address(
+   const struct stk_other_address *command,
+   const struct stk_other_address *test)
+{
+   check_common_byte(command-type, test-type);
+
+   if (test-type == STK_ADDRESS_IPV4)
+   g_assert(command-addr.ipv4 == test-addr.ipv4);
+   else
+   g_assert(g_mem_equal(command-addr.ipv6, test-addr.ipv6, 16));
+}
+
+/* Defined in TS 102.223 Section 8.59 */
+static void check_uicc_te_interface(const struct stk_uicc_te_interface 
*command,
+   const struct stk_uicc_te_interface *test)
+{
+   check_common_byte(command-protocol, test-protocol);
+   g_assert(command-port == test-port);
+}
+
 /* Defined in TS 102.223 Section 8.60 */
 static inline void check_aid(const struct stk_aid *command,
const struct stk_aid *test)
@@ -477,6 +530,13 @@ static inline void check_aid(const struct stk_aid *command,
g_assert(g_mem_equal(command-aid, test-aid, test-len));
 }
 
+/* Defined in TS 102.223 Section 8.70 */
+static inline void check_network_access_name(const char *command,
+   const char *test)
+{
+   check_common_text(command, test);
+}
+
 /* Defined in TS 102.223 Section 8.71 */
 static inline void check_cdma_sms_tpdu(
const struct stk_common_byte_array *command,
@@ -16913,6 +16973,639 @@ static void test_launch_browser(gconstpointer data)
stk_command_free(command);
 }
 
+struct open_channel_test {
+   const unsigned char *pdu;
+   unsigned int pdu_len;
+   unsigned char qualifier;
+   char *alpha_id;
+   struct stk_icon_id icon_id;
+   struct stk_bearer_description bearer_desc;
+   unsigned short buf_size;
+   char *apn;
+   struct stk_other_address local_addr;
+   char *text_usr;
+   char *text_passwd;
+   struct stk_uicc_te_interface uti;
+   struct stk_other_address data_dest_addr;
+   struct stk_text_attribute text_attr;
+   struct stk_frame_id frame_id;
+};
+
+static unsigned char open_channel_211[] = { 0xD0, 0x36, 0x81, 0x03, 0x01, 0x40,
+   0x01, 0x82, 0x02, 0x81, 0x82,
+   0x35, 0x07, 0x02, 0x03, 0x04,
+   0x03, 0x04, 0x1F, 0x02, 0x39,
+   0x02, 0x05, 0x78, 0x0D, 0x08,
+   0xF4, 0x55, 0x73, 0x65, 0x72,
+   0x4C, 0x6F, 0x67, 0x0D, 0x08,
+   0xF4, 0x55, 0x73, 0x65, 0x72,
+   0x50, 0x77, 0x64, 0x3C, 0x03,
+   0x01, 0xAD, 0x9C, 0x3E, 0x05,
+   0x21, 0x01, 0x01, 0x01, 0x01 };
+
+static unsigned char open_channel_221[] = { 0xD0, 0x42, 0x81, 0x03, 0x01, 0x40,
+   0x01, 0x82, 0x02, 0x81, 0x82,
+   0x35, 0x07, 0x02, 0x03, 0x04,
+   

Re: [PATCH] stkutil: Add typo/cleaning modifications

2011-03-30 Thread Denis Kenzior
Hi Philippe,

On 03/30/2011 04:39 PM, Philippe Nunes wrote:
 ---
  src/stkutil.c |4 ++--
  src/stkutil.h |2 +-
  2 files changed, 3 insertions(+), 3 deletions(-)
 

Patch has been applied, thanks.

Regards,
-Denis
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


Re: [PATCH v2 1/2] stkutil: Complete the TLV parsing/builder to support BIP commands

2011-03-30 Thread Denis Kenzior
Hi Philippe,

On 03/30/2011 04:41 PM, Philippe Nunes wrote:
 ---
  src/stkutil.c |  287 +---
  src/stkutil.h |  132 ++-
  2 files changed, 380 insertions(+), 39 deletions(-)

snip

 
 @@ -1604,16 +1624,48 @@ static gboolean parse_dataobj_esn(struct 
 comprehension_tlv_iter *iter,
  static gboolean parse_dataobj_network_access_name(
   struct comprehension_tlv_iter *iter, void *user)
  {
 - struct stk_network_access_name *nan = user;
 + char **apn = user;
   const unsigned char *data;
   unsigned int len = comprehension_tlv_iter_get_length(iter);
 + unsigned char label_size;
 + unsigned char offset = 0;
 + char decoded_apn[100];
  
 - if (len == 0)
 + if (len == 0 || len  100)
   return FALSE;
  
   data = comprehension_tlv_iter_get_data(iter);
 - nan-len = len;
 - memcpy(nan-name, data, len);
 + /*
 +  * As specified in TS 23 003 Section 9
 +  * The APN consists of one or more labels. Each label is coded as
 +  * a one octet length field followed by that number of octets coded
 +  * as 8 bit ASCII characters
 +  */
 +
 + while (len) {
 + label_size = *data;
 +
 + if (label_size  (len-1))
 + return FALSE;
 +
 + memcpy(decoded_apn + offset, data + 1, label_size);
 +
 + data += label_size + 1;
 + offset += label_size;
 +
 + len -= label_size + 1;

This really belongs with the data/offset increments

 + if (len) {
 + decoded_apn[offset] = '.';
 + offset += 1;

This might be better written as:

if (len  0)
decoded_apn[offset++] = '.';

 + }
 + }
 +
 + *apn = g_try_malloc(offset + 1);
 + if (*apn == NULL)
 + return FALSE;
 +
 + memcpy(*apn, decoded_apn, offset);
 + (*apn)[offset] = '\0';

*apn = g_strdup(decoded_apn);

is really just fine ;)

  
   return TRUE;
  }
 @@ -3274,7 +3326,68 @@ static enum stk_command_parse_result 
 parse_launch_browser(
   STK_DATA_OBJECT_TYPE_INVALID);
  }
  
 -/* TODO: parse_open_channel */
 +static void destroy_open_channel(struct stk_command *command)
 +{
 + g_free(command-open_channel.alpha_id);
 + g_free(command-open_channel.text_usr);
 + g_free(command-open_channel.text_passwd);
 +}

==9744== 40 bytes in 4 blocks are definitely lost in loss record 1,825
of 1,925
==9744==at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==9744==by 0x41B868: parse_dataobj_network_access_name (stkutil.c:1663)
==9744==by 0x41AF95: parse_dataobj (stkutil.c:2415)
==9744==by 0x41CC1B: stk_command_new_from_pdu (stkutil.c:3358)
==9744==by 0x40A953: test_open_channel (test-stkutil.c:17257)
==9744==by 0x4E922E2: g_test_run_suite_internal (gtestutils.c:1138)
==9744==by 0x4E92455: g_test_run_suite_internal (gtestutils.c:1197)
==9744==by 0x4E9273A: g_test_run_suite (gtestutils.c:1246)
==9744==by 0x406C45: main (test-stkutil.c:26130)

snip

 +static gboolean build_receive_data(struct stk_tlv_builder *builder,
 + const struct stk_response *response)
 +{
 + const struct stk_response_receive_data *receive_data =
 + response-receive_data;
 +
 + if (response-result.type == STK_RESULT_TYPE_SUCCESS) {
 + if (receive_data-rx_data.len) {
 + if (build_dataobj(builder, build_dataobj_channel_data,
 + DATAOBJ_FLAG_CR,
 + response-receive_data.rx_data,
 + NULL) != TRUE)
 + return FALSE;
 + }
 +
 + return build_dataobj(builder,
 + build_dataobj_channel_data_length,
 + DATAOBJ_FLAG_CR,
 + response-receive_data.rx_remaining,
 + NULL);
 + }

Avoid nesting whenever possible.  This really might be better written like:

if (response-result.type != STK_RESULT_TYPE_SUCCESS)
return TRUE;

if (...) {
}

return build_dataobj(...)

 +
 + return TRUE;
 +}
 +
 +static gboolean build_send_data(struct stk_tlv_builder *builder,
 + const struct stk_response *response)
 +{
 + if (response-result.type == STK_RESULT_TYPE_SUCCESS) {
 + return build_dataobj(builder,
 + build_dataobj_channel_data_length,
 + DATAOBJ_FLAG_CR,
 + response-send_data.tx_avail,
 + NULL);
 + }
 +

Same comment as above

 + return TRUE;
 +}
 +
  const unsigned char *stk_pdu_from_response(const struct stk_response 
 *response,