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 =