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

2010-11-04 Thread Sjur Brændeland
Hi Marcel.

 +int caif_rtnl_init(void)
 +{
 +       struct sockaddr_nl addr;
 +       int sk, err;
 +       GError *gerr = NULL;
 +
 +       sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
 +       if (sk  0)
 +               return sk;
 +
 +       memset(addr, 0, sizeof(addr));
 +       addr.nl_family = AF_NETLINK;
 +       addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE;
 +
 +       err = bind(sk, (struct sockaddr *) addr, sizeof(addr));
 +       if (err  0) {
 +               close(sk);
 +               return err;
 +       }
 +
 +       channel = g_io_channel_unix_new(sk);
 +       g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, gerr);
 +       g_io_channel_set_encoding(channel, NULL, gerr);
 +       g_io_channel_set_buffered(channel, TRUE);
 +       g_io_channel_set_close_on_unref(channel, TRUE);
 +
 +       rtnl_watch = g_io_add_watch(channel,
 +                               G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
 +                               netlink_event, NULL);
 +       pending_requests = NULL;
 +
 +       return 0;
 +}

Sigh, I realize I have a potential leak on gerr above. I'll wait for
more review comments from you,
and resubmit later.

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


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

2010-11-03 Thread Sjur Brændeland
From: Sjur Brændeland sjur.brandel...@stericsson.com

---
Hi Marcel.
I hope I have closed most of your review comments so far.
I had a go at using g_io_chanel_write_chars, but couldn't make it work,
and I (stubbornly ;-) do g_caif_devices = NULL, just in case someone choose
to call caif_rtnl_init more than once.

 Makefile.am  |2 +
 drivers/stemodem/caif_rtnl.c |  382 ++
 drivers/stemodem/caif_rtnl.h |   29 
 3 files changed, 413 insertions(+), 0 deletions(-)
 create mode 100644 drivers/stemodem/caif_rtnl.c
 create mode 100644 drivers/stemodem/caif_rtnl.h

diff --git a/Makefile.am b/Makefile.am
index cd17fa2..aea91ce 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -226,6 +226,8 @@ builtin_sources += drivers/atmodem/atutil.h \
drivers/stemodem/stemodem.c \
drivers/stemodem/voicecall.c \
drivers/stemodem/radio-settings.c \
+   drivers/stemodem/caif_rtnl.c \
+   drivers/stemodem/caif_rtnl.h \
drivers/stemodem/gprs-context.c \
drivers/stemodem/caif_socket.h \
drivers/stemodem/if_caif.h
diff --git a/drivers/stemodem/caif_rtnl.c b/drivers/stemodem/caif_rtnl.c
new file mode 100644
index 000..82740ba
--- /dev/null
+++ b/drivers/stemodem/caif_rtnl.c
@@ -0,0 +1,382 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2010 ST-Ericsson AB.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include config.h
+#endif
+
+#include string.h
+#include unistd.h
+#include errno.h
+#include net/if.h
+#include net/if_arp.h
+#include fcntl.h
+#include linux/rtnetlink.h
+
+#include glib.h
+
+#include ofono/log.h
+
+#include if_caif.h
+#include caif_rtnl.h
+
+#define NLMSG_TAIL(nmsg) \
+   ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)-nlmsg_len)))
+
+struct iplink_req {
+   struct nlmsghdr n;
+   struct ifinfomsg i;
+   char pad[1024];
+
+   int request_id;
+   int type;
+   int conn_id;
+   gpointer user_data;
+   gboolean loop_enabled;
+
+   char ifname[IF_NAMESIZE];
+   int  ifindex;
+   caif_rtnl_create_cb_t callback;
+};
+
+static GSList *pending_requests;
+static guint32 rtnl_seqnr;
+static guint  rtnl_watch;
+static GIOChannel *channel;
+
+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;
+}
+
+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;
+}
+
+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));
+}
+
+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;
+}
+
+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 =