oFono release plan?

2010-12-17 Thread Sjur BRENDELAND
Hi Denis and Marcel.

Do you have a release plan defined for oFono? 
When will you release oFono 1.0?

Thanks,

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


ConnectionContext creation for LTE PDN Connection.

2010-11-29 Thread Sjur BRENDELAND
Hi all,

We have started to investigate LTE impact on oFono, 
specifically how to integrate LTE and initial PDN connection,
and we have some questions regarding this.

This raises some questions about the handling of
ConnectionContexts.

When a terminal attach to LTE network it would
normally do an implicit context activation request
associated to attach request (+CGATT=1).
When the context activation is completed this will
result in an event notifying about the activated PDN
connection according to
27.007 10.1.19 Packet Domain event reporting +CGEREP.

+CGEV: ME PDN ACT cid

At this point we have a connection context in the modem.

The question is then, how should we model this in oFono?
Should we assume/require that a Connection Context
already is created by ConnMan and pre-exists in 
oFono (possibly with a flag indicating that this
represents the initial PDN, or perhaps just taking
the internet ConnectionContext)?
Or should oFono automatically create a Connection Context?

Furthermore, should oFono automatically proceed and
set Active=true, bind the connection to a network interface
and set network interface in state UP, or should the
ConnectionContext initially set Active=false, 
waiting for ConnMan to activate it?


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


RE: [PATCH v4 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.

2010-11-12 Thread Sjur BRENDELAND
Hi Marcel.

 Does anything cleans up the channel when oFono unexpectedly crashes?

No not yet. I suppose the interface will continue up until someone
destroys it. Should we simply destroy all CAIF interfaces
if oFono crashes? I think this would be the simplest approach.

BTW, how does connman behave in this case? Will it do any attempt
to clean up IP interfaces when it notices that oFono APIs has gone missing?
And what about modem state, is it taken back to flight-mode (AT+CFUN=0) in
order to reset everything?

If you don't mind, I would prefer to do restart handling as the next step.
It would be nice to finish this patch review first, what do you think?

 
 I think you can just use a stack buffer when you actually send the
 message. This is damn ugly and from a security point it actually scares
 me.
 
 Please only keep the seqnum in here. Since that is the only thing you
 need to find that pending request. Just get rid of everything that you
 don't need for the callback.

Yes, done.

  I have squashed this into parse_rtnl_message, as you suggested.
  I'm not really convinced this was any cleaner though..?
  I end up with duplicating the code in the two if statements.
 
 We will see. I might have been wrong, but in my mind it just locked
 fine. I will take a second look when you send the updated patch.

OK, tell me what you think about the next patch then.

  I think that the kernel implementation of rtnl will guarantee the
  requests to be processed in order. rtnetlink_rcv in
 ..net/core/rtnetlink.c
  takes the rtnl_lock before processing the netlink messages.
  I believe this will guarantee that the NEWLINK responses will be
 received
  in the same order as they are sent.
 
 it might be keeping the order, but I wouldn't count on it. And just
 using your find request function would make this code simpler.

The seqnr is not present in the message header of this response message,
so this will not be possible. I would prefer to stick with the current
implementation. Or do you see another way forward?
 
+   req = find_request(hdr-nlmsg_seq);
+   if (req == NULL)
+   break;
+
+   DBG(nlmsg error req);
+   rtnl_client_response(req, -1);
+   return;
+   }
  
   If I understand this right, then you can always find the pending
   request
   and remove it here. No need for rtnl_client_response at all.
 
  Yes, I guess you are right. I can remove this callback.
  Currently I am only actually interested in the result when
  the interface is created successfully. Nothing particularly
  is done in gprs-context.c if it fails.
 
 That is not what I meant. We should find that request and call the
 callback, but I think this can be done a more generic way.
 
 So whatever message you get, find the request that it belongs to. You
 need that request struct anyway. And then just reply here.

OK, I think I have done so. Have a look when I send the next patch.

  Actually I think io_channel_read is just fine here. I think connman
 is doing
  the same thing for rtnl. It is the sending part which is problematic.
 
 We should not be using that in ConnMan either actually. The _read is
 fine, but deprecated. The new _read_chars is doing buffering and a bit
 nasty in that area. So really just use recv() here.

OK, I've changed it to recv.

   So if we split out creating the NLMSG header into one helper
 functions,
   then you can easily prep the RTNL newlink message here inside the
   function.
 
  Even with creating this helper function you suggested
  the prep_rtnl_newlink_req is on 45 lines. I think it makes sense
  still keep then separate. It is no big deal for me, but I would
 prefer
  to avoid such a large functions,
 
 As I said above, it looked good in my head. Maybe I was wrong, but in
 general this is pretty simple sequential stuff. So it can be in one
 function and still be easy readable. Lets have a look on how it looks
 and then decide.

OK, I've squashed the two functions. 

 
   This will also allow you to remove req-loop_enabled variables
 since I
   don't see need for storing them.
 
  You are right, the loop_enabled variable is not currently needed.
  However for various testing purposes we frequently want to run the
 CAIF Interface
  in loopback mode (e.g. testing loopback to the modem). loopback_mode
 will make the
  interface swap src and destination ip addresses so we actually can do
 ping etc.
  If you are OK with this, I would prefer to keep this in order to make
 testing easier.
  But again, I'm easy...
 
 Having loopback mode is fine. I just meant that you don't have to store
 the variable in the request struct since you build the request already.
 
 Please store only things in your request struct that you do need later
 on.

OK, done. This struct is much smaller now.

 
diff --git a/drivers/stemodem/caif_rtnl.h
  ...
+typedef void (*caif_rtnl_create_cb_t) 

RE: [PATCH v4 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.

2010-11-11 Thread Sjur BRENDELAND
Hi Marcel.

 what happens for network triggered deactivation. Some networks here
 disconnect the GPRS context used MMS. Has some funny behavior that need
 to be taken into account.

Good question! When code reading with this in mind I realize that
we missed to mark the conn_info-interface as available by setting
cid = 0. This is bug, thank you for leading me to it.


FYI this is how CAIF and AT works together:
In order to have payload over CAIF there need to be
both a CAIF channel connected and a context activated with AT*EPPSD.
When Channel-ID configured for CAIF IP Interface and the Channel-Id given
in AT*EPPSD matches, the modem side will connect the CAIF Channel to
the Network Signaling Stack in the modem.

With this new patch CAIF channels are created statically from probe.
Activation and deactivation is controlled by AT*EPPSD, or notified by
+CGEV which will result in a CGACT status query.

If the network disconnects GPRS we should receive a
+CGEV: NW DEACT, subsequent CGACT status query.
Here the connection (and CAIF Network Interface) should be
marked as unused by setting cid to zero.

  +#define NLMSG_TAIL(nmsg) \
  +   ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-
 nlmsg_len)))

 We have no global define this? You wanted to look into that. What was
 the outcome of it?

I did mention this before - I have looked around, but he did not find
any relevant macro for this unfortunately.


  +struct iplink_req {
  +   struct nlmsghdr n;
  +   struct ifinfomsg i;
  +   char pad[1024];

 What is this huge pad for? It looks totally fishy to me.

The pad is there to hold the remaining of the rtnl attributes.
I'm working on restructuring this so that I can separate the
buffer holding the rtnl_message and the iplink_req.
I just have to make it work...


  +static guint  rtnl_watch;

 Get rid of the double spaces for rtnl_watch.

  +static GIOChannel *channel;

 If we follow your convention here and not to overload variables this
 might be better named rtnl_channel.

 And yes, I am fine with keeping it since there is no way to connect a
 netlink socket properly to just use send(). You will require to use
 sendto for everything.


OK, Done.


  +static void store_newlink_param(struct iplink_req *req, unsigned
 short type,
  +   int index, unsigned flags,
  +   unsigned change, struct ifinfomsg *msg,
  +   int bytes)
  +{
  +   const char *ifname = NULL;
  +
  +   get_ifname(msg, bytes, ifname);
  +   strncpy(req-ifname, ifname,
  +   sizeof(req-ifname));
  +   req-ifname[sizeof(req-ifname)-1] = '\0';
  +   req-ifindex = index;
  +}

 So I think that store_newlink_... and get_ifname can be nicely combined
 into one helper function. And using extract_parameters() function name
 is a bit better.

 And please only add parameters to that function that you really need in
 there. And the iplink_req should be last parameter.

 As one general is to have input parameters first and then the output
 parameters last. So read this something like extract values from this
 structure to this structure.


Yes, I agree. I have squashed the two functions together and cleaned up the 
parameters.
This is much nicer, thank you.


  +static int send_rtnl_req(struct iplink_req *req)
  +{
  +   struct sockaddr_nl addr;
  +   int sk = g_io_channel_unix_get_fd(channel);
  +
  +   memset(addr, 0, sizeof(addr));
  +   addr.nl_family = AF_NETLINK;
  +
  +   return sendto(sk, req, req-n.nlmsg_len, 0,
  +   (struct sockaddr *) addr, sizeof(addr));
  +}

 I don't think this should be a separate function. You use it only twice
 and having it close to the code using it would be better.

OK, good I have squashed these to functions as well.


  +static struct iplink_req *find_request(guint32 seq)
  +{
  +   GSList *list;
  +
  +   for (list = pending_requests; list; list = list-next) {
  +   struct iplink_req *req = list-data;
  +
  +   if (req-n.nlmsg_seq == seq)
  +   return req;
  +   }
  +
  +   return NULL;
  +}

 I would move this function up in this file at the top. It should go
 close to the variable declaration for pending_request.

OK, done.


  +static void rtnl_client_response(struct iplink_req *req, int result)
  +{
  +
  +   if (req-callback  req-n.nlmsg_type == RTM_NEWLINK)
  +   req-callback(result, req-user_data,
  +   req-ifname, req-ifindex);
  +
  +   pending_requests = g_slist_remove(pending_requests, req);
  +   g_free(req);
  +}

 I don't like this split out. You already checked the nlmsg_type and
 here
 you keep checking it again just to reuse some code. This looks like
 waste to me.

I have squashed this into parse_rtnl_message, as you suggested.
I'm not really convinced this was any cleaner though..?
I end up with duplicating the code in the two if statements.


  +static void parse_rtnl_message(void *buf, size_t len)
  

RE: [RFC] plugin/ste: Use D-Bus API from Modem Init Daemon for autoconfig.

2010-11-05 Thread Sjur BRENDELAND
Hi Marcel,

  This patch introduces auto discovery of ST-Ericsson modems.
  ST-Ericsson modems are managed by a Modem Init Daemon which
  is responsible for start/stop/restart flashing etc. The
  STE plugin monitors the modem state exposed from the
  Modem Init Damon Dbus API. When the modem is in state on
  the STE modem is created and registered.
 
  The reason for not using the standard udev paradigm is that
  the CAIF device is up before the modem is ready to setup AT channels.
  For flashless modems CAIF is used as part of the boot. The Modem Init
  Daemon is managing the flashless boot procedure and sets the State to
  on when the modem is available.
 
 so I don't like this at all. This looks pretty nasty and like an ugly
 hack to get something working.
 
 Please show us what Modem Init Daemon is actually doing.

As mentioned above the Modem Init Daemon is responsible for:
- Toggling the different GPIOs, powering the modem on/off.
- Boot the modem and upload the firmware in several stages. 
  a) Initial Z-Protocol, for handshaking the modem
  b) PROTROM boot protocol to upload modem firmware.
  c) CAIF Remote File System protocol for further
 firmware loading (modules)
  d) CAIF Remote File System protocol for serving modem file system.
- Monitoring the GPIOs for modem restart and act upon this.
- Enabling/Disabling the CAIF Link Layer Interface according to
  the modem state (GPIO).
- Monitoring Thermal and Battery Warnings URC over AT 
  and acting upon this.
- In case of modem crash, the crash-dump from the modem
  must be downloaded to host. This needs to be synchronized
  so that the reboot of the modem is not started before
  the dump is complete.
- Modem Init daemon has to expose an API in for:
o triggering restart
o signal modem status
o initiate upgrade

The Modem Init Daemon will be available in product quality under Apache License,
and will be in use for several platforms (not just MeeGo) and modem versions.

The issue we have is that when the CAIF Link Layer Interface is up
it does not necessarily mean that the Modem is fully started.
So we need to have a way to synchronize other services and modem clients
when the modem is ready. The other services that needs this ready notification
are: oFono, Remote File Manager, Logging Daemon. On other platforms than MeeGo
there are AT based clients such as Audio, AGPS, RIL as well.

We definitely need a synchronization mechanism between Modem Init Daemon
and the other services, so we decided to use a D-Bus API for the 
Modem Init Daemon to expose the modem state and an API for initiating
power-off, upgrade and reboot. 

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


RE: [PATCHv2 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.

2010-11-03 Thread Sjur BRENDELAND
Hi Marcel.

  +static GSList *pending_requests;
  +static GIOChannel *channel;
  +static guint32 rtnl_seqnr;
  +static guint  rtnl_watch;
 
 To be fair, you don't need both, the GIOChannel and the watch. You can
 just add the watch and then unref the GIOChannel and set it to close on
 unref. That way when the watch gets removed or you remove it, the
 GIOChannel and the underlaying socket will be automatically closed as
 well.

 As described above. Just unref the GIOChannel and forget about it. And
 then you can make the GIOChannel a local variable.

I think I have to keep the channel, because I do need the
file descriptor derived from the channel when doing sendto.

   You don't really have to play this append/remove game. You can just
   append it after send_rtnl_req succeed. The read goes via the
 mainloop
   anyway and we are a single threaded program. So the order is
   guaranteed.
...
 You don't need to append it first, send the message, check error and in
 case of an error remove it again.

OK, thanks - now I get what your after. I completely misunderstood your 
previous comment, my bad.

 And while we are at it. Essentially you also need to use asynchronous
 and non-blocking watch driven sending of your message in the first
 place. I did forget to check if you open the RTNL socket non-blocking,
 but you should be doing that.

So I'll add something like this then:
fl = fcntl(sk, F_GETFL);
fcntl(sk, F_SETFL, fl | O_NONBLOCK);


  +   }
  +
  +   g_slist_free(pending_requests);
  +   pending_requests = NULL;
 
 No need to set pending_requests to NULL here.

But I will have to move this to the caif_rtnl_init function then,
I think pending_requests needs to be NULL before using it.

   I am not really sold on this param stuct thingy btw. Why do you
 need
   them? Just proper input params and output params for the callback
   handler would do them same. Won't they?
 
  Yes, I could do that. But in that case I would prefer to typedef the
  response function to simplify create function's signature. Otherwise
  I think the create function's signature gets too complex.
 
 typedef for function callbacks are just fine. I have no problem with
 that at all.

I got rid of the structs and typedef'ed response function - I agree this better.

snip
typedef void (*rtnl_create_cb_t) (int result, gpointer user_data,
char *ifname, int ifindex);

extern int caif_rtnl_create_interface(gpointer user_data, int type, int connid,
gboolean loop, rtnl_create_cb_t cb);


Hoping to get the next patch out later today.

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


RE: [PATCHv2 1/2] stemodem: Add RTNL functionality managing CAIF Network Interfaces.

2010-11-01 Thread Sjur BRENDELAND
 From: Marcel Holtmann [mailto:mar...@holtmann.org]
 
 just to be clear. You want to name it like this? I am just asking here
 since I made a few proposals.

No worries :-)
The file is called caif_rtnl and exported functions are prefixed caif_rtnl,
I think that makes a lot of sense.

 
  +#define NLMSG_TAIL(nmsg) \
  +   ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-
 nlmsg_len)))
 
 We don't have this one as part of some kernel includes?

I'll check what I can find ;-)

 
  +static gboolean get_ifname(struct ifinfomsg *msg, int bytes,
  +   const char **ifname)
  +{
  +   struct rtattr *attr;
  +
  +   for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
  +   attr = RTA_NEXT(attr, bytes))
  +
  +   if (attr-rta_type == IFLA_IFNAME 
  +   ifname != NULL) {
  +   *ifname = RTA_DATA(attr);
  +   return TRUE;
  +   }
  +
  +   return FALSE;
  +}
 
 After I stared long enough at it, I realized that the code is fine, but
 that was not obvious to me. In this case please use for () { } with the
 curly braces around it. It improves readability.
 
 And I know that other times we don't do { } for single statements, but
 here is does helps my poor human brain ;)

Sure I'll add the braces ;-)

 You don't really have to play this append/remove game. You can just
 append it after send_rtnl_req succeed. The read goes via the mainloop
 anyway and we are a single threaded program. So the order is
 guaranteed.

I'm not sure about this. I need to keep track of what
connection-id I assign to the CAIF Interface in the request and what 
interface name and interface index I get for that connection id
in the RTNL response.
This mapping between network interface and connection id is used 
when PDP Contexts are activated. The append/remove game provides me
with the request-response mapping. 


 And here you should add an extra empty line.

Sorry, I don't know why I keep doing that...

  +struct rtnl_rsp_param {
  +   int result;
  +   gpointer user_data;
  +   char ifname[IF_NAMESIZE];
  +   int  ifindex;
  +};
  +
  +struct rtnl_req_param {
  +   void (*callback)(struct rtnl_rsp_param *param);
  +   gpointer user_data;
  +   int type;
  +   int conn_id;
  +   gboolean loop_enabled;
  +};
  +
  +extern int caif_rtnl_create_interface(struct rtnl_req_param *req);
  +extern int caif_rtnl_delete_interface(int ifid);
 
 I am not really sold on this param stuct thingy btw. Why do you need
 them? Just proper input params and output params for the callback
 handler would do them same. Won't they?

Yes, I could do that. But in that case I would prefer to typedef the 
response function to simplify create function's signature. Otherwise
I think the create function's signature gets too complex.

...
 I do need another look at the RTNL magic and casting. That always
 drives
 my crazy when I look at that. In the meantime, please address these
 details first.

Sure, and thanks for reviewing.

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


RE: [RFC] AGPS Support

2010-10-22 Thread Sjur BRENDELAND
Hi Bastian,

 Bastian, Waldo wrote:
 
 Please find attached a proposal for both a DBUS and Modem API for AGPS 
 support. There are some minor changes compared to the proposal from 
 May 14, 2010.
 
...
                void SendLCSFrame(string frametype, string framedata)
 
                        Send a LCS position protocol frame to the Mobile
                        Network. The LCS frame typically represents a
                        Position Response.
 
                        Valid frametypes are:
                                rrlp_measure_position_response
                                rrc_measurement_report
 
                        The raw frame data is formatted as the concatenated
                        sequence of the two digit hexadecimal representation
                        of each of its octets. Example: 00FC2345

 struct ofono_lcs_frame {
        enum ofono_lcs_frame_type lcs_frame_type;
        int frame_length;       /* size of raw_frame in bytes */
        unsigned char* raw_frame;
 };



The 27.007 Spec specifies positioning request/responses for AT where
Positioning data are coded in XML data structures.

I think the oFono interface should not use binary data, but rather be aligned 
with 27.007
and present decoded data as DBUS typed signals and methods with the same 
information 
content as specified in the XML data for AT+CPOS, AT+CPOSR.

In this way the vanilla AT driver could handle the CPOS, CPOR AT-commands
and code/decode between XML and explicit data structures, which in turn
oFono Core could code/decode as DBUS data types.

Regards,
Sjur Brændeland
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


RE: oFono v0.22 test report

2010-06-10 Thread Sjur BRENDELAND
Hi Li,

Li, Zhigang wrote:
 The test will do full light functional validation, mainly focus on
 checking implemented functionality of ofono v0.22 
...
Executed total 276 test cases during this round of testing, and among them: 
Pass: 266
Fail: 10

Are these all manual tests or are you using any automated test suite?

Regards
Sjur Brændeland


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


RE: RTNL sync or async when creating GPRS Context for STE modem.

2010-05-31 Thread Sjur BRENDELAND
Rémi Denis-Courmont wrote:
  I have started out by doing the RTNL handling async,
  i.e. registering the RTNL socket with g_io_add_watch etc.
  But I'm not really happy with the code as it feels
  unnecessary complex, introduces new states in gprs-context.c. etc.
 
 Using an event loop makes sense if, and only if, the process blocks as
 far as poll() is concerned. If your ioctl() calls or Netlink requests 
 do not enter the kernel scheduler at any point, then the glib main
 loop will just slows things down - more code, more context switches.

Thanks Denis,
I think a synchronous implementation should be find then.

If I understand RT-Netlink correctly, creating a CAIF Network Interface should
not enter the poll() or wait in recvmsg. When sending RTNL newlink message,
the whole newlink operation should execute in the senders thread, and 
response messages be ready in the rtnl sockets receive queue when the send
operation completes. Hence read/poll should not block the thread.

Regards
/Sjur



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


RTNL sync or async when creating GPRS Context for STE modem.

2010-05-30 Thread Sjur BRENDELAND
Hi Marcel.

I have finally got around to do some coding in oFono again,
and have started to look into creating CAIF Network Interface 
using RTNL, instead using socket ioctls.
 
I have started out by doing the RTNL handling async, 
i.e. registering the RTNL socket with g_io_add_watch etc.
But I'm not really happy with the code as it feels
unnecessary complex, introduces new states in gprs-context.c. etc.

So I would like to do the RTNL handling synchronous instead,
as this would reduce complexity. But I just wanted your opinion
on this before I start refactoring my code.

Do you see any issues with doing RTNL request synchronous
i.e. sending out RTM_NEWLINK request and a waiting for 
RTM_NEWLINK response followed by NLMSG_ERROR,
(or just NLMSG_ERROR if unsuccessful)?


Regards
Sjur

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