[PATCH v5] stemodem: Add RTNL functionality managing CAIF Network Interfaces.

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

---
 Makefile.am  |2 +
 drivers/stemodem/caif_rtnl.c |  340 ++
 drivers/stemodem/caif_rtnl.h |   29 
 3 files changed, 371 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 05082de..f163b0a 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..4ce2401
--- /dev/null
+++ b/drivers/stemodem/caif_rtnl.c
@@ -0,0 +1,340 @@
+/*
+ *
+ *  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)))
+
+#define RTNL_MSG_SIZE 4096
+
+struct rtnl_msg {
+   struct nlmsghdr n;
+   struct ifinfomsg i;
+   char data[RTNL_MSG_SIZE];
+};
+
+struct iplink_req {
+   guint32 rtnlmsg_seqnr;
+   gpointer user_data;
+   caif_rtnl_create_cb_t callback;
+};
+
+static GSList *pending_requests;
+static guint32 rtnl_seqnr;
+static guint rtnl_watch;
+static GIOChannel *rtnl_channel;
+
+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-rtnlmsg_seqnr == seq)
+   return req;
+   }
+
+   return NULL;
+}
+
+static void parse_newlink_param(struct ifinfomsg *msg, int size,
+   int *ifindex, char *ifname)
+{
+   struct rtattr *attr;
+
+   for (attr = IFLA_RTA(msg); RTA_OK(attr, size);
+   attr = RTA_NEXT(attr, size)) {
+
+   if (attr-rta_type == IFLA_IFNAME 
+   ifname != NULL) {
+
+   strncpy(ifname, RTA_DATA(attr), IF_NAMESIZE);
+   ifname[IF_NAMESIZE-1] = '\0';
+   break;
+   }
+   }
+
+   *ifindex = msg-ifi_index;
+}
+
+static void parse_rtnl_message(const void *buf, size_t len)
+{
+   struct ifinfomsg *msg;
+   struct iplink_req *req = NULL;
+   char ifname[IF_NAMESIZE];
+   int ifindex;
+
+   while (len  0) {
+   const struct nlmsghdr *hdr = buf;
+
+   if (!NLMSG_OK(hdr, len))
+   break;
+
+   switch (hdr-nlmsg_type) {
+   case RTM_NEWLINK:
+   req = g_slist_nth_data(pending_requests, 0);
+   if (req == NULL)
+   break;
+
+   msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
+   parse_newlink_param(msg, IFA_PAYLOAD(hdr),
+   ifindex, ifname);
+
+   if (req-callback)
+   req-callback(ifindex, ifname, req-user_data);
+   break;
+
+   case NLMSG_ERROR:
+   req = find_request(hdr-nlmsg_seq);
+   if (req == NULL)
+   break;
+
+   DBG(nlmsg error req);
+   if (req-callback)
+   req-callback(-1, ifname, req-user_data);
+   break;
+   default:
+  

Re: [PATCH v5] stemodem: Add RTNL functionality managing CAIF Network Interfaces.

2010-11-12 Thread Marcel Holtmann
Hi Sjur,

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

I applied this patch now, but I had to fix this up a bit. You have to
send a patch that updates this one.

 +#define RTNL_MSG_SIZE 4096
 +
 +struct rtnl_msg {
 + struct nlmsghdr n;
 + struct ifinfomsg i;
 + char data[RTNL_MSG_SIZE];
 +};

Is this not a bit big?

 +struct iplink_req {
 + guint32 rtnlmsg_seqnr;

Use the proper nlmsg_seqnr type that you get from RTNL.

 + gpointer user_data;

Use void * here since your callback does as well.

 + caif_rtnl_create_cb_t callback;
 +};
 +
 +static GSList *pending_requests;
 +static guint32 rtnl_seqnr;
 +static guint rtnl_watch;
 +static GIOChannel *rtnl_channel;
 +
 +static struct iplink_req *find_request(guint32 seq)
 +{

seq should match RTNL given type.

 + GSList *list;
 +
 + for (list = pending_requests; list; list = list-next) {
 + struct iplink_req *req = list-data;
 +
 + if (req-rtnlmsg_seqnr == seq)
 + return req;
 + }
 +
 + return NULL;
 +}
 +
 +static void parse_newlink_param(struct ifinfomsg *msg, int size,
 + int *ifindex, char *ifname)
 +{
 + struct rtattr *attr;
 +
 + for (attr = IFLA_RTA(msg); RTA_OK(attr, size);
 + attr = RTA_NEXT(attr, size)) {
 +
 + if (attr-rta_type == IFLA_IFNAME 
 + ifname != NULL) {
 +
 + strncpy(ifname, RTA_DATA(attr), IF_NAMESIZE);
 + ifname[IF_NAMESIZE-1] = '\0';
 + break;
 + }
 + }
 +
 + *ifindex = msg-ifi_index;
 +}
 +
 +static void parse_rtnl_message(const void *buf, size_t len)
 +{
 + struct ifinfomsg *msg;
 + struct iplink_req *req = NULL;

This is bad. Please only do assignment if there is no other way around
it. I fixed this for you.

Regards

Marcel


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