Merge lp:~cyphermox/powerd/wifi-powersave into lp:powerd

Proposed by Mathieu Trudel-Lapierre
Status: Rejected
Rejected by: Mathieu Trudel-Lapierre
Proposed branch: lp:~cyphermox/powerd/wifi-powersave
Merge into: lp:powerd
Diff against target: 445 lines (+372/-0)
4 files modified
CMakeLists.txt (+5/-0)
src/powerd-netlink.c (+281/-0)
src/powerd-netlink.h (+77/-0)
src/powerd.cpp (+9/-0)
To merge this branch: bzr merge lp:~cyphermox/powerd/wifi-powersave
Reviewer Review Type Date Requested Status
Mathieu Trudel-Lapierre Disapprove
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+239403@code.launchpad.net

Commit message

Use netlink to set up powersave for wireless devices on startup.

Description of the change

Investigating the use of netlink to set up powersave for wireless devices.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

Abandoning; this code would not support the module removal and readding that happens when flight mode is toggled.

review: Disapprove

Unmerged revisions

145. By Mathieu Trudel-Lapierre

Implement setting powersave via netlink on startup

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-09-30 20:52:33 +0000
+++ CMakeLists.txt 2014-10-23 16:07:31 +0000
@@ -26,6 +26,7 @@
26pkg_check_modules(GIO-UNIX gio-unix-2.0)26pkg_check_modules(GIO-UNIX gio-unix-2.0)
27pkg_check_modules(UPOWER_GLIB upower-glib)27pkg_check_modules(UPOWER_GLIB upower-glib)
28pkg_check_modules(UUID uuid)28pkg_check_modules(UUID uuid)
29pkg_check_modules(LIBNL3 libnl-3.0 libnl-genl-3.0)
2930
30set(POWERD_GENERATED_SOURCES31set(POWERD_GENERATED_SOURCES
31 ${GDBUS_NAME}.c32 ${GDBUS_NAME}.c
@@ -50,6 +51,7 @@
50 src/log.c51 src/log.c
51 src/power-request.c52 src/power-request.c
52 src/power-source.c53 src/power-source.c
54 src/powerd-netlink.c
53 src/powerd-client.c55 src/powerd-client.c
54 src/powerd-object.c56 src/powerd-object.c
55 src/powerd-sensors.cpp57 src/powerd-sensors.cpp
@@ -67,6 +69,7 @@
67 ${GIO-UNIX_LIBRARY_DIRS}69 ${GIO-UNIX_LIBRARY_DIRS}
68 ${UPOWER_GLIB_LIBRARY_DIRS}70 ${UPOWER_GLIB_LIBRARY_DIRS}
69 ${UUID_LIBRARY_DIRS}71 ${UUID_LIBRARY_DIRS}
72 ${LIBNL3_LIBRARY_DIRS}
70)73)
7174
72include_directories(75include_directories(
@@ -76,6 +79,7 @@
76 ${GIO-UNIX_INCLUDE_DIRS}79 ${GIO-UNIX_INCLUDE_DIRS}
77 ${UPOWER_GLIB_INCLUDE_DIRS}80 ${UPOWER_GLIB_INCLUDE_DIRS}
78 ${UUID_INCLUDE_DIRS}81 ${UUID_INCLUDE_DIRS}
82 ${LIBNL3_INCLUDE_DIRS}
79 ${PROJECT_SOURCE_DIR}/libsuspend83 ${PROJECT_SOURCE_DIR}/libsuspend
80 ${CMAKE_CURRENT_BINARY_DIR}/src84 ${CMAKE_CURRENT_BINARY_DIR}/src
81)85)
@@ -111,6 +115,7 @@
111 "-lhardware"115 "-lhardware"
112 ${UPOWER_GLIB_LIBRARIES}116 ${UPOWER_GLIB_LIBRARIES}
113 ${UUID_LIBRARIES}117 ${UUID_LIBRARIES}
118 ${LIBNL3_LIBRARIES}
114)119)
115120
116install(121install(
117122
=== added file 'src/powerd-netlink.c'
--- src/powerd-netlink.c 1970-01-01 00:00:00 +0000
+++ src/powerd-netlink.c 2014-10-23 16:07:31 +0000
@@ -0,0 +1,281 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of powerd.
5 *
6 * powerd is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * powerd is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <glib.h>
20#include <glib-object.h>
21#include <gio/gio.h>
22#include <inttypes.h>
23#include <string.h>
24#include <stdio.h>
25#include <errno.h>
26#include <sys/types.h>
27#include <sys/ioctl.h>
28
29#include <ifaddrs.h>
30#include <net/if.h>
31#include <linux/nl80211.h>
32#include <wireless.h>
33
34#include <netlink/netlink.h>
35#include <netlink/genl/genl.h>
36#include <netlink/genl/family.h>
37#include <netlink/genl/ctrl.h>
38#include <netlink/msg.h>
39#include <netlink/attr.h>
40
41#include "powerd-netlink.h"
42
43struct _PowerdNetlinkPrivate {
44 struct nl_sock *socket;
45 struct nl_cb *cb;
46 gboolean is_generic;
47 char *type;
48 int type_id;
49 gboolean valid;
50};
51
52static void powerd_netlink_class_init (PowerdNetlinkClass * klass);
53static void powerd_netlink_init (PowerdNetlink * self);
54static void powerd_netlink_dispose (GObject * object);
55static void powerd_netlink_finalize (GObject * object);
56
57G_DEFINE_TYPE (PowerdNetlink, powerd_netlink, G_TYPE_OBJECT);
58
59#define POWERD_NETLINK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POWERD_TYPE_NETLINK, PowerdNetlinkPrivate))
60
61static struct nl_cb *
62set_socket_cb (struct nl_sock *sock, int cb_level)
63{
64 struct nl_cb *cb;
65
66 cb = nl_cb_alloc(cb_level);
67 nl_socket_set_cb(sock, cb);
68
69 return cb;
70}
71
72static struct nl_sock *
73allocate_netlink_socket()
74{
75 struct nl_sock *sock;
76
77 sock = nl_socket_alloc();
78 if (!sock) {
79 g_warning ("Failed to allocate netlink socket");
80 return NULL;
81 }
82
83 nl_socket_set_buffer_size(sock, 8192, 8192);
84
85 return sock;
86}
87
88static gboolean
89get_generic_netlink(PowerdNetlink *self)
90{
91 PowerdNetlinkPrivate *priv = POWERD_NETLINK_GET_PRIVATE(self);
92
93 g_return_val_if_fail (priv->socket != NULL, FALSE);
94
95 if (genl_connect(priv->socket) < 0) {
96 g_warning ("Could not make netlink socket generic");
97 return FALSE;
98 }
99
100 return TRUE;
101}
102
103/* Instance */
104static void
105powerd_netlink_init (PowerdNetlink *self)
106{
107 self->priv = POWERD_NETLINK_GET_PRIVATE(self);
108 self->priv->socket = allocate_netlink_socket();
109 self->priv->is_generic = FALSE;
110 self->priv->type = NULL;
111 self->priv->valid = self->priv->socket != NULL;
112
113 return;
114}
115
116/* Class Init */
117static void
118powerd_netlink_class_init (PowerdNetlinkClass *self)
119{
120 GObjectClass *object_class = G_OBJECT_CLASS (self);
121
122 g_type_class_add_private (self, sizeof (PowerdNetlinkPrivate));
123 object_class->dispose = powerd_netlink_dispose;
124 object_class->finalize = powerd_netlink_finalize;
125
126 return;
127}
128
129/* Clean up references */
130static void
131powerd_netlink_dispose (GObject *object)
132{
133 PowerdNetlink * self = POWERD_NETLINK(object);
134 PowerdNetlinkPrivate *priv = POWERD_NETLINK_GET_PRIVATE (self);
135
136 if (priv->type) {
137 g_free (priv->type);
138 priv->type = NULL;
139 }
140
141 nl_cb_put(priv->cb);
142 nl_socket_free(priv->socket);
143
144 priv->valid = FALSE;
145
146 return;
147}
148
149static void
150powerd_netlink_finalize (GObject *object)
151{
152 return;
153}
154
155static int
156get_powersave_val (gboolean powersave)
157{
158 if (powersave)
159 return NL80211_PS_ENABLED;
160 else
161 return NL80211_PS_DISABLED;
162}
163
164void
165powerd_netlink_set_cb (PowerdNetlink *self, int cb)
166{
167 PowerdNetlinkPrivate *priv = POWERD_NETLINK_GET_PRIVATE (self);
168
169 g_return_val_if_fail (priv->valid, FALSE);
170
171 set_socket_cb (priv->socket, cb);
172}
173
174void
175powerd_netlink_make_generic (PowerdNetlink *self)
176{
177 PowerdNetlinkPrivate *priv = POWERD_NETLINK_GET_PRIVATE (self);
178
179 g_return_val_if_fail (!priv->is_generic, TRUE);
180 g_return_val_if_fail (priv->valid, FALSE);
181
182 priv->valid = get_generic_netlink (self);
183 if (priv->valid)
184 priv->is_generic = TRUE;
185}
186
187gboolean
188powerd_netlink_set_type (PowerdNetlink *self, char *type)
189{
190 PowerdNetlinkPrivate *priv = POWERD_NETLINK_GET_PRIVATE (self);
191
192 g_return_val_if_fail (priv->is_generic, FALSE);
193 g_return_val_if_fail (priv->valid, FALSE);
194
195 priv->type = g_strdup (type);
196 priv->type_id = genl_ctrl_resolve(priv->socket, type);
197
198 return priv->type_id >= 0;
199}
200
201gboolean
202powerd_netlink_set_device_powersave(PowerdNetlink *self, char *devname, gboolean powersave)
203{
204 PowerdNetlinkPrivate *priv = POWERD_NETLINK_GET_PRIVATE (self);
205 struct nl_msg *msg;
206 int devidx;
207 gboolean result = FALSE;
208 int iferr = 0;
209
210 /* Fail now if we're not dealing with a valid nl80211 netlink */
211 g_return_val_if_fail (priv->valid, FALSE);
212 g_return_val_if_fail (!g_strcmp0 (priv->type, "nl80211"), FALSE);
213
214 devidx = if_nametoindex(devname);
215
216 msg = nlmsg_alloc();
217 genlmsg_put(msg, 0, 0, priv->type_id, 0, 0, NL80211_CMD_SET_POWER_SAVE, 0);
218
219 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx);
220 NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, get_powersave_val(powersave));
221
222 iferr = nl_send_auto_complete(priv->socket, msg);
223 if (iferr >= 0)
224 result = TRUE;
225
226 nlmsg_free(msg);
227
228nla_put_failure:
229 return result;
230}
231
232gboolean
233powerd_netlink_set_wifi_powersave(PowerdNetlink *self, gboolean powersave)
234{
235 PowerdNetlinkPrivate *priv = POWERD_NETLINK_GET_PRIVATE (self);
236 struct ifaddrs *ifa, *ifaddr;
237 gboolean result = FALSE;
238 int skfd;
239 int n, errcnt = 0;
240
241 /* Fail now if we're not dealing with a valid nl80211 netlink */
242 g_return_val_if_fail (priv->valid, FALSE);
243 g_return_val_if_fail (!g_strcmp0 (priv->type, "nl80211"), FALSE);
244
245 skfd = socket(AF_INET, SOCK_DGRAM, 0);
246 if (getifaddrs(&ifaddr) < 0) {
247 g_warning ("Could not get network interfaces");
248 goto out;
249 }
250
251 for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
252 struct ifreq pwrq;
253
254 if (ifa->ifa_addr == NULL)
255 continue;
256
257 if (ifa->ifa_addr->sa_family != AF_INET)
258 continue;
259
260 strncpy(pwrq.ifr_name, ifa->ifa_name, IFNAMSIZ);
261 if (ioctl(skfd, SIOCGIWNAME, &pwrq) < 0) {
262 /* We can't set wifi powersave if the device isn't
263 * wifi...
264 */
265 continue;
266 }
267
268 if (!powerd_netlink_set_device_powersave (self,
269 ifa->ifa_name,
270 powersave))
271 errcnt++;
272 }
273
274 if (errcnt == 0)
275 result = TRUE;
276
277out:
278 freeifaddrs(ifaddr);
279 return result;
280}
281
0282
=== added file 'src/powerd-netlink.h'
--- src/powerd-netlink.h 1970-01-01 00:00:00 +0000
+++ src/powerd-netlink.h 2014-10-23 16:07:31 +0000
@@ -0,0 +1,77 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of powerd.
5 *
6 * powerd is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * powerd is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __POWERD_NETLINK_H__
20#define __POWERD_NETLINK_H__
21
22#include <netlink/netlink.h>
23
24#include <glib.h>
25#include <glib-object.h>
26#include <gio/gio.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32G_BEGIN_DECLS
33
34#define POWERD_TYPE_NETLINK (powerd_netlink_get_type ())
35#define POWERD_NETLINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POWERD_TYPE_NETLINK, PowerdNetlink))
36#define POWERD_IS_NETLINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POWERD_TYPE_NETLINK))
37#define POWERD_NETLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), POWERD_TYPE_NETLINK, PowerdNetlinkClass))
38#define POWERD_IS_NETLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), POWERD_TYPE_NETLINK))
39#define POWERD_NETLINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), POWERD_TYPE_NETLINK, PowerdNetlinkClass))
40
41struct _PowerdNetlinkPrivate;
42
43typedef struct _PowerdNetlink PowerdNetlink;
44typedef struct _PowerdNetlinkClass PowerdNetlinkClass;
45typedef struct _PowerdNetlinkPrivate PowerdNetlinkPrivate;
46
47struct _PowerdNetlinkClass {
48 GObjectClass parent_class;
49};
50
51struct _PowerdNetlink {
52 GObject parent;
53 PowerdNetlinkPrivate * priv;
54};
55
56GType powerd_netlink_get_type (void);
57
58void powerd_netlink_set_cb (PowerdNetlink *self, int cb);
59
60void powerd_netlink_make_generic (PowerdNetlink *self);
61
62gboolean powerd_netlink_set_type (PowerdNetlink *self, char *type);
63
64gboolean powerd_netlink_set_device_powersave (PowerdNetlink *self,
65 char *devname,
66 gboolean powersave);
67
68gboolean powerd_netlink_set_wifi_powersave (PowerdNetlink *self,
69 gboolean powersave);
70
71G_END_DECLS
72
73#ifdef __cplusplus
74}
75#endif
76
77#endif
078
=== modified file 'src/powerd.cpp'
--- src/powerd.cpp 2014-09-30 14:50:08 +0000
+++ src/powerd.cpp 2014-10-23 16:07:31 +0000
@@ -38,6 +38,7 @@
38#include <gio/gio.h>38#include <gio/gio.h>
39#include "powerd-internal.h"39#include "powerd-internal.h"
40#include "powerd-object.h"40#include "powerd-object.h"
41#include "powerd-netlink.h"
41#include "powerd-dbus.h"42#include "powerd-dbus.h"
42#include "powerd-sensors.h"43#include "powerd-sensors.h"
43#include "device-config.h"44#include "device-config.h"
@@ -95,6 +96,8 @@
95static GDBusProxy *g_ofono_proxy;96static GDBusProxy *g_ofono_proxy;
96static GDBusProxy *g_unity_proxy;97static GDBusProxy *g_unity_proxy;
9798
99static PowerdNetlink *powerd_netlink;
100
98static struct power_module* _power_module;101static struct power_module* _power_module;
99102
100static void103static void
@@ -402,6 +405,12 @@
402 /* Init this first, data is used by other inits */405 /* Init this first, data is used by other inits */
403 device_config_init();406 device_config_init();
404407
408 powerd_netlink = POWERD_NETLINK (g_object_new (POWERD_TYPE_NETLINK, NULL));
409 powerd_netlink_set_cb (powerd_netlink, 0);
410 powerd_netlink_make_generic (powerd_netlink);
411 powerd_netlink_set_type (powerd_netlink, "nl80211");
412 powerd_netlink_set_wifi_powersave (powerd_netlink, TRUE);
413
405 libsuspend_init(0);414 libsuspend_init(0);
406 powerd_info("libsuspend: detect module: %s.", libsuspend_getname());415 powerd_info("libsuspend: detect module: %s.", libsuspend_getname());
407 powerd_stats_init();416 powerd_stats_init();

Subscribers

People subscribed via source and target branches