]>
Commit | Line | Data |
---|---|---|
7c4fe1b5 AM |
1 | commit 232d70155c45d24afabe47ed37954cc000678295 |
2 | Author: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
3 | Date: Wed Mar 20 17:51:14 2013 +0100 | |
4 | ||
5 | Find hidraw devices correctly with systemd udev >= v196. | |
6 | ||
7 | udev v196 libraries changed behaviour of g_udev_device_get_sysfs_attr() | |
8 | by stopping following symlinks for "device" attribute [1]. That change | |
9 | broke hiddev finding for unifying devices. Fix that by getting sysfs | |
10 | path from parent hiddev device. | |
11 | ||
12 | 1. http://cgit.freedesktop.org/systemd/systemd/commit/?id=5ae18ddc0d86673520c0dd6b59ccac8afc8aa605 | |
13 | ||
14 | Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
15 | Signed-off-by: Richard Hughes <richard@hughsie.com> | |
16 | ||
17 | diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c | |
18 | index c7f0103..4b659c3 100644 | |
19 | --- a/src/linux/up-device-unifying.c | |
20 | +++ b/src/linux/up-device-unifying.c | |
21 | @@ -165,7 +165,7 @@ up_device_unifying_coldplug (UpDevice *device) | |
ac33aa7d AM |
22 | hidraw_list = g_udev_client_query_by_subsystem (client, "hidraw"); |
23 | for (l = hidraw_list; l != NULL; l = l->next) { | |
24 | if (g_strcmp0 (g_udev_device_get_sysfs_path (parent), | |
25 | - g_udev_device_get_sysfs_attr (l->data, "device")) == 0) { | |
26 | + g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) == 0) { | |
27 | receiver = g_object_ref (l->data); | |
28 | break; | |
29 | } | |
7c4fe1b5 AM |
30 | |
31 | commit 28f396496a90705b0d8823707396731fe60d85bc | |
32 | Author: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
33 | Date: Wed Mar 20 22:22:54 2013 +0100 | |
34 | ||
35 | Detection of version 1 hid++ is not returned to the caller | |
36 | ||
37 | HID++ version 1 was properly detected but that information wasn't | |
38 | reaching caller. | |
39 | ||
40 | Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
41 | Signed-off-by: Richard Hughes <richard@hughsie.com> | |
42 | ||
43 | diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c | |
44 | index 0a27dbf..1bcefab 100644 | |
45 | --- a/src/linux/hidpp-device.c | |
46 | +++ b/src/linux/hidpp-device.c | |
47 | @@ -314,9 +314,9 @@ hidpp_device_cmd (HidppDevice *device, | |
48 | buf[2] == HIDPP_ERR_INVALID_SUBID && | |
49 | buf[3] == 0x00 && | |
50 | buf[4] == HIDPP_FEATURE_ROOT_FN_PING) { | |
51 | - /* HID++ 1.0 ping reply, so fake success */ | |
52 | + /* HID++ 1.0 ping reply, so fake success with version 1 */ | |
53 | if (buf[5] == HIDPP_ERROR_CODE_UNKNOWN) { | |
54 | - buf[0] = 1; | |
55 | + response_data[0] = 1; | |
56 | goto out; | |
57 | } | |
58 | if (buf[5] == HIDPP_ERROR_CODE_UNSUPPORTED) { | |
59 | ||
60 | commit 972acff14532aa1a495b2ee20f24505cb581291a | |
61 | Author: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
62 | Date: Wed Mar 20 22:28:11 2013 +0100 | |
63 | ||
64 | Buffer for HIDPP_REFRESH_FLAGS_KIND not big enough | |
65 | ||
66 | HIDPP_REFRESH_FLAGS_KIND action puts result into 7 bytes buffer and | |
67 | later tries to access 8th element (with index 7). Make buffer bigger, | |
68 | so 8th element will fit. | |
69 | ||
70 | Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
71 | Signed-off-by: Richard Hughes <richard@hughsie.com> | |
72 | ||
73 | diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c | |
74 | index 1bcefab..58c6e6d 100644 | |
75 | --- a/src/linux/hidpp-device.c | |
76 | +++ b/src/linux/hidpp-device.c | |
77 | @@ -560,7 +560,7 @@ hidpp_device_refresh (HidppDevice *device, | |
78 | HIDPP_READ_LONG_REGISTER, | |
79 | 0xb5, | |
80 | buf, 3, | |
81 | - buf, 7, | |
82 | + buf, 8, | |
83 | error); | |
84 | if (!ret) | |
85 | goto out; | |
86 | ||
87 | commit af24f55c7925c8ea990cb36078b63c17cd671a95 | |
88 | Author: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
89 | Date: Wed Mar 20 22:35:59 2013 +0100 | |
90 | ||
91 | Invalid request/response for HIDPP_REFRESH_FLAGS_BATTERY in hid++1 | |
92 | ||
93 | Version 1 hid++ HIDPP_REFRESH_FLAGS_BATTERY packets were incorrect. | |
94 | ||
95 | Response packets were incorrectly thrown away as invalid. These | |
96 | packets have HIDPP_HEADER_REQUEST (and not HIDPP_HEADER_RESPONSE as code | |
97 | expexted). Fix that by allowing both types. | |
98 | ||
99 | Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
100 | Signed-off-by: Richard Hughes <richard@hughsie.com> | |
101 | ||
102 | diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c | |
103 | index 58c6e6d..8e861c5 100644 | |
104 | --- a/src/linux/hidpp-device.c | |
105 | +++ b/src/linux/hidpp-device.c | |
106 | @@ -327,7 +327,7 @@ hidpp_device_cmd (HidppDevice *device, | |
107 | goto out; | |
108 | } | |
109 | } | |
110 | - if (buf[0] != HIDPP_HEADER_RESPONSE || | |
111 | + if ((buf[0] != HIDPP_HEADER_REQUEST && buf[0] != HIDPP_HEADER_RESPONSE) || | |
112 | buf[1] != device_idx || | |
113 | buf[2] != feature_idx || | |
114 | buf[3] != function_idx) { | |
115 | @@ -662,16 +662,14 @@ hidpp_device_refresh (HidppDevice *device, | |
116 | /* get battery status */ | |
117 | if ((refresh_flags & HIDPP_REFRESH_FLAGS_BATTERY) > 0) { | |
118 | if (priv->version == 1) { | |
119 | - buf[0] = HIDPP_READ_SHORT_REGISTER; | |
120 | - buf[1] = HIDPP_READ_SHORT_REGISTER_BATTERY; | |
121 | + buf[0] = 0x00; | |
122 | + buf[1] = 0x00; | |
123 | buf[2] = 0x00; | |
124 | - buf[3] = 0x00; | |
125 | - buf[4] = 0x00; | |
126 | ret = hidpp_device_cmd (device, | |
127 | priv->device_idx, | |
128 | - HIDPP_FEATURE_ROOT_INDEX, | |
129 | - HIDPP_FEATURE_ROOT_FN_PING, | |
130 | - buf, 5, | |
131 | + HIDPP_READ_SHORT_REGISTER, | |
132 | + HIDPP_READ_SHORT_REGISTER_BATTERY, | |
133 | + buf, 3, | |
134 | buf, 1, | |
135 | error); | |
136 | if (!ret) | |
137 | ||
138 | commit e571f840e9fd945c94bc1c5fa494fde9d23fa2ad | |
139 | Author: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
140 | Date: Thu Mar 21 19:57:26 2013 +0100 | |
141 | ||
142 | Add support for HIDPP_REFRESH_FLAGS_MODEL in hid++ v1 | |
143 | ||
144 | Add support for checking device model name for hid++ v1 protocol | |
145 | version. | |
146 | ||
147 | Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
148 | Signed-off-by: Richard Hughes <richard@hughsie.com> | |
149 | ||
150 | diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c | |
151 | index 8e861c5..bfc1b5c 100644 | |
152 | --- a/src/linux/hidpp-device.c | |
153 | +++ b/src/linux/hidpp-device.c | |
154 | @@ -624,39 +624,60 @@ hidpp_device_refresh (HidppDevice *device, | |
155 | ||
156 | /* get device model string */ | |
157 | if ((refresh_flags & HIDPP_REFRESH_FLAGS_MODEL) > 0) { | |
158 | - buf[0] = 0x00; | |
159 | - buf[1] = 0x00; | |
160 | - buf[2] = 0x00; | |
161 | - map = hidpp_device_map_get_by_feature (device, HIDPP_FEATURE_GET_DEVICE_NAME_TYPE); | |
162 | - if (map != NULL) { | |
163 | + if (priv->version == 1) { | |
164 | + buf[0] = 0x40 | (priv->device_idx - 1); | |
165 | + buf[1] = 0x00; | |
166 | + buf[2] = 0x00; | |
167 | + | |
168 | ret = hidpp_device_cmd (device, | |
169 | + HIDPP_RECEIVER_ADDRESS, | |
170 | + HIDPP_READ_LONG_REGISTER, | |
171 | + 0xb5, | |
172 | + buf, 3, | |
173 | + buf, HIDPP_RESPONSE_LONG_LENGTH, | |
174 | + error); | |
175 | + if (!ret) | |
176 | + goto out; | |
177 | + | |
178 | + len = buf[1]; | |
179 | + name = g_string_new (""); | |
180 | + g_string_append_len (name, (gchar *) buf+2, len); | |
181 | + priv->model = g_strdup (name->str); | |
182 | + } else if (priv->version == 2) { | |
183 | + buf[0] = 0x00; | |
184 | + buf[1] = 0x00; | |
185 | + buf[2] = 0x00; | |
186 | + map = hidpp_device_map_get_by_feature (device, HIDPP_FEATURE_GET_DEVICE_NAME_TYPE); | |
187 | + if (map != NULL) { | |
188 | + ret = hidpp_device_cmd (device, | |
189 | priv->device_idx, | |
190 | map->idx, | |
191 | HIDPP_FEATURE_GET_DEVICE_NAME_TYPE_FN_GET_COUNT, | |
192 | buf, 3, | |
193 | buf, 1, | |
194 | error); | |
195 | - if (!ret) | |
196 | - goto out; | |
197 | - } | |
198 | - len = buf[0]; | |
199 | - name = g_string_new (""); | |
200 | - for (i = 0; i < len; i +=4 ) { | |
201 | - buf[0] = i; | |
202 | - buf[1] = 0x00; | |
203 | - buf[2] = 0x00; | |
204 | - ret = hidpp_device_cmd (device, | |
205 | + if (!ret) | |
206 | + goto out; | |
207 | + } | |
208 | + len = buf[0]; | |
209 | + name = g_string_new (""); | |
210 | + for (i = 0; i < len; i +=4 ) { | |
211 | + buf[0] = i; | |
212 | + buf[1] = 0x00; | |
213 | + buf[2] = 0x00; | |
214 | + ret = hidpp_device_cmd (device, | |
215 | priv->device_idx, | |
216 | map->idx, | |
217 | HIDPP_FEATURE_GET_DEVICE_NAME_TYPE_FN_GET_NAME, | |
218 | buf, 3, | |
219 | buf, 4, | |
220 | error); | |
221 | - if (!ret) | |
222 | - goto out; | |
223 | - g_string_append_len (name, (gchar *) &buf[0], 4); | |
224 | + if (!ret) | |
225 | + goto out; | |
226 | + g_string_append_len (name, (gchar *) &buf[0], 4); | |
227 | + } | |
228 | + priv->model = g_strdup (name->str); | |
229 | } | |
230 | - priv->model = g_strdup (name->str); | |
231 | } | |
232 | ||
233 | /* get battery status */ | |
234 | ||
235 | commit fd0286e871bcf67d29aa622b66ecf362fe2d6ec0 | |
236 | Author: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
237 | Date: Thu Mar 21 20:40:26 2013 +0100 | |
238 | ||
239 | Repair vendor handling for Logitech Unifying devices | |
240 | ||
241 | Set proper vendor via udev rules for unifying devices and handle | |
242 | that in code. | |
243 | ||
244 | Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
245 | Signed-off-by: Richard Hughes <richard@hughsie.com> | |
246 | ||
247 | diff --git a/rules/95-upower-csr.rules b/rules/95-upower-csr.rules | |
248 | index bd171b2..b8d92fe 100644 | |
249 | --- a/rules/95-upower-csr.rules | |
250 | +++ b/rules/95-upower-csr.rules | |
251 | @@ -22,6 +22,7 @@ LABEL="up_csr_end" | |
252 | ||
253 | # Unifying HID++ devices | |
254 | SUBSYSTEM!="hid", GOTO="up_unifying_end" | |
255 | +ATTRS{idVendor}=="046d", ENV{UPOWER_VENDOR}="Logitech, Inc." | |
256 | ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying" | |
257 | ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c532", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying" | |
258 | LABEL="up_unifying_end" | |
259 | diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c | |
260 | index 4b659c3..633909f 100644 | |
261 | --- a/src/linux/up-device-unifying.c | |
262 | +++ b/src/linux/up-device-unifying.c | |
263 | @@ -123,6 +123,7 @@ up_device_unifying_coldplug (UpDevice *device) | |
264 | const gchar *bus_address; | |
265 | const gchar *device_file; | |
266 | const gchar *type; | |
267 | + const gchar *vendor; | |
268 | gboolean ret = FALSE; | |
269 | gchar *endptr = NULL; | |
270 | gchar *tmp; | |
271 | @@ -198,9 +199,13 @@ up_device_unifying_coldplug (UpDevice *device) | |
272 | goto out; | |
273 | } | |
274 | ||
275 | + vendor = g_udev_device_get_property (native, "UPOWER_VENDOR"); | |
276 | + if (vendor == NULL) | |
277 | + vendor = g_udev_device_get_property (native, "ID_VENDOR"); | |
278 | + | |
279 | /* set some default values */ | |
280 | g_object_set (device, | |
281 | - "vendor", g_udev_device_get_property (native, "ID_VENDOR"), | |
282 | + "vendor", vendor, | |
283 | "type", up_device_unifying_get_device_kind (unifying), | |
284 | "model", hidpp_device_get_model (unifying->priv->hidpp_device), | |
285 | "has-history", TRUE, | |
286 | ||
287 | commit 32daed2dfa22196bd4c51fdabad3d333d4839903 | |
288 | Author: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
289 | Date: Fri Mar 22 15:28:11 2013 +0100 | |
290 | ||
291 | Add support for Logitech Wireless (NonUnifying) devices | |
292 | ||
293 | There are Logitech Wireless devices similar to Unifying ones with the | |
294 | difference that device is paired with single dongle and dongle doesn't | |
295 | support pairing multiple devices. | |
296 | ||
297 | Add support for these. Tested with Wireless Mouse M187 and M185/M225. | |
298 | ||
299 | Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
300 | Signed-off-by: Richard Hughes <richard@hughsie.com> | |
301 | ||
302 | diff --git a/rules/95-upower-csr.rules b/rules/95-upower-csr.rules | |
303 | index b8d92fe..b476660 100644 | |
304 | --- a/rules/95-upower-csr.rules | |
305 | +++ b/rules/95-upower-csr.rules | |
306 | @@ -25,4 +25,5 @@ SUBSYSTEM!="hid", GOTO="up_unifying_end" | |
307 | ATTRS{idVendor}=="046d", ENV{UPOWER_VENDOR}="Logitech, Inc." | |
308 | ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying" | |
309 | ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c532", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying" | |
310 | +ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52f", ENV{UPOWER_BATTERY_TYPE}="lg-wireless" | |
311 | LABEL="up_unifying_end" | |
312 | diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c | |
313 | index 633909f..f6636e6 100644 | |
314 | --- a/src/linux/up-device-unifying.c | |
315 | +++ b/src/linux/up-device-unifying.c | |
316 | @@ -142,7 +142,7 @@ up_device_unifying_coldplug (UpDevice *device) | |
317 | type = g_udev_device_get_property (native, "UPOWER_BATTERY_TYPE"); | |
318 | if (type == NULL) | |
319 | goto out; | |
320 | - if (g_strcmp0 (type, "unifying") != 0) | |
321 | + if ((g_strcmp0 (type, "unifying") != 0) && (g_strcmp0 (type, "lg-wireless") != 0)) | |
322 | goto out; | |
323 | ||
324 | /* get the device index */ | |
325 | @@ -153,23 +153,37 @@ up_device_unifying_coldplug (UpDevice *device) | |
326 | g_debug ("Could not get physical device index"); | |
327 | goto out; | |
328 | } | |
329 | - hidpp_device_set_index (unifying->priv->hidpp_device, | |
330 | + | |
331 | + if (g_strcmp0 (type, "lg-wireless") == 0) | |
332 | + hidpp_device_set_index (unifying->priv->hidpp_device, 1); | |
333 | + else { | |
334 | + hidpp_device_set_index (unifying->priv->hidpp_device, | |
335 | g_ascii_strtoull (tmp + 1, &endptr, 10)); | |
336 | - if (endptr != NULL && endptr[0] != '\0') { | |
337 | - g_debug ("HID_PHYS malformed: '%s'", bus_address); | |
338 | - goto out; | |
339 | + if (endptr != NULL && endptr[0] != '\0') { | |
340 | + g_debug ("HID_PHYS malformed: '%s'", bus_address); | |
341 | + goto out; | |
342 | + } | |
343 | } | |
344 | ||
345 | - /* find the hidraw device that matches the parent */ | |
346 | + /* find the hidraw device that matches */ | |
347 | parent = g_udev_device_get_parent (native); | |
348 | client = g_udev_client_new (NULL); | |
349 | hidraw_list = g_udev_client_query_by_subsystem (client, "hidraw"); | |
350 | for (l = hidraw_list; l != NULL; l = l->next) { | |
351 | - if (g_strcmp0 (g_udev_device_get_sysfs_path (parent), | |
352 | - g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) == 0) { | |
353 | - receiver = g_object_ref (l->data); | |
354 | - break; | |
355 | + if (g_strcmp0 (type, "lg-wireless") == 0) { | |
356 | + if (g_strcmp0 (g_udev_device_get_sysfs_path (native), | |
357 | + g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) != 0) | |
358 | + continue; | |
359 | + // Ugly way to distinguish receiver itself from mouse/keyboard etc for non-unifying dongles | |
360 | + if (g_strcmp0(g_udev_device_get_property(g_udev_device_get_parent (native), "INTERFACE"), "3/0/0") != 0) | |
361 | + continue; | |
362 | + } else { | |
363 | + if (g_strcmp0 (g_udev_device_get_sysfs_path (parent), | |
364 | + g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) != 0) | |
365 | + continue; | |
366 | } | |
367 | + receiver = g_object_ref (l->data); | |
368 | + break; | |
369 | } | |
370 | if (receiver == NULL) { | |
371 | g_debug ("Unable to find an hidraw device for Unifying receiver"); | |
372 | ||
373 | commit fadca8ad7706c15b5fabee2f7be599961fe33240 | |
374 | Author: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
375 | Date: Fri Mar 22 19:46:47 2013 +0100 | |
376 | ||
377 | Better method of figuring out v1 vs v2 protocol version. | |
378 | ||
379 | Protocol version detection isn't very reliable (especially for | |
380 | hid++ v1). | |
381 | ||
382 | Version 1 checking was potentially happening in every hidpp_device_cmd() | |
383 | call and not only when requested. Improve that to do version checking | |
384 | and priv->version manipulation only when requested by using | |
385 | HIDPP_REFRESH_FLAGS_VERSION. | |
386 | ||
387 | When doing version checking first try v2 protocol command and if it | |
388 | succeeds assume version 2 device. Otherwise try v1 protocol query | |
389 | and if that successds assume version 1 device. | |
390 | ||
391 | v2 devices in unreachable/sleep mode seem to do not respond to v2 | |
392 | queries but they respond to v1 queries! Still we want best protocol | |
393 | possible. To do that we are rechecking version when current protocol | |
394 | version is below 2 and we are doing up_device_unifying_refresh() and if | |
395 | recheck succeeds we upgrade protocol to v2. | |
396 | ||
397 | Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl> | |
398 | Signed-off-by: Richard Hughes <richard@hughsie.com> | |
399 | ||
400 | diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c | |
401 | index bfc1b5c..5398a38 100644 | |
402 | --- a/src/linux/hidpp-device.c | |
403 | +++ b/src/linux/hidpp-device.c | |
404 | @@ -46,6 +46,7 @@ | |
405 | /* HID++ 1.0 */ | |
406 | #define HIDPP_READ_SHORT_REGISTER 0x81 | |
407 | #define HIDPP_READ_SHORT_REGISTER_BATTERY 0x0d | |
408 | +#define HIDPP_READ_SHORT_REGISTER_CONNECTION_STATE 0x02 | |
409 | ||
410 | #define HIDPP_READ_LONG_REGISTER 0x83 | |
411 | #define HIDPP_READ_LONG_REGISTER_DEVICE_TYPE 11 | |
412 | @@ -314,11 +315,6 @@ hidpp_device_cmd (HidppDevice *device, | |
413 | buf[2] == HIDPP_ERR_INVALID_SUBID && | |
414 | buf[3] == 0x00 && | |
415 | buf[4] == HIDPP_FEATURE_ROOT_FN_PING) { | |
416 | - /* HID++ 1.0 ping reply, so fake success with version 1 */ | |
417 | - if (buf[5] == HIDPP_ERROR_CODE_UNKNOWN) { | |
418 | - response_data[0] = 1; | |
419 | - goto out; | |
420 | - } | |
421 | if (buf[5] == HIDPP_ERROR_CODE_UNSUPPORTED) { | |
422 | /* device offline / unreachable */ | |
423 | g_set_error_literal (error, 1, 0, | |
424 | @@ -533,6 +529,7 @@ hidpp_device_refresh (HidppDevice *device, | |
425 | ||
426 | /* get version */ | |
427 | if ((refresh_flags & HIDPP_REFRESH_FLAGS_VERSION) > 0) { | |
428 | + /* first try v2 packet */ | |
429 | buf[0] = 0x00; | |
430 | buf[1] = 0x00; | |
431 | buf[2] = HIDPP_PING_DATA; | |
432 | @@ -543,9 +540,32 @@ hidpp_device_refresh (HidppDevice *device, | |
433 | buf, 3, | |
434 | buf, 4, | |
435 | error); | |
436 | - if (!ret) | |
437 | - goto out; | |
438 | - priv->version = buf[0]; | |
439 | + if (ret) | |
440 | + priv->version = buf[0]; | |
441 | + /* then try v1 packet */ | |
442 | + else { | |
443 | + /* discard potential v1 error */ | |
444 | + g_clear_error (error); | |
445 | + | |
446 | + /* checking hid++ v1 packet */ | |
447 | + buf[0] = 0x00; | |
448 | + buf[1] = 0x00; | |
449 | + buf[2] = 0x00; | |
450 | + | |
451 | + ret = hidpp_device_cmd (device, | |
452 | + HIDPP_RECEIVER_ADDRESS, | |
453 | + HIDPP_READ_SHORT_REGISTER, | |
454 | + HIDPP_READ_SHORT_REGISTER_CONNECTION_STATE, | |
455 | + buf, 3, | |
456 | + buf, 2, | |
457 | + error); | |
458 | + | |
459 | + if (!ret) | |
460 | + goto out; | |
461 | + | |
462 | + priv->version = 1; | |
463 | + } | |
464 | + | |
465 | } | |
466 | ||
467 | /* get device kind */ | |
468 | diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c | |
469 | index f6636e6..ea8b0b3 100644 | |
470 | --- a/src/linux/up-device-unifying.c | |
471 | +++ b/src/linux/up-device-unifying.c | |
472 | @@ -52,13 +52,25 @@ up_device_unifying_refresh (UpDevice *device) | |
473 | gboolean ret; | |
474 | GError *error = NULL; | |
475 | GTimeVal timeval; | |
476 | + HidppRefreshFlags refresh_flags; | |
477 | UpDeviceState state = UP_DEVICE_STATE_UNKNOWN; | |
478 | UpDeviceUnifying *unifying = UP_DEVICE_UNIFYING (device); | |
479 | UpDeviceUnifyingPrivate *priv = unifying->priv; | |
480 | ||
481 | - /* refresh just the battery stats */ | |
482 | + /* refresh the battery stats */ | |
483 | + refresh_flags = HIDPP_REFRESH_FLAGS_BATTERY; | |
484 | + | |
485 | + /* | |
486 | + * Device hid++ v2 when in unreachable mode seems to be able | |
487 | + * to respond to hid++ v1 queries (but fails to respond to v2 | |
488 | + * queries). When it gets waken up it starts responding | |
489 | + * to v2 queries, so always try to upgrade protocol to v2 | |
490 | + */ | |
491 | + if (hidpp_device_get_version (priv->hidpp_device) < 2) | |
492 | + refresh_flags |= HIDPP_REFRESH_FLAGS_VERSION; | |
493 | + | |
494 | ret = hidpp_device_refresh (priv->hidpp_device, | |
495 | - HIDPP_REFRESH_FLAGS_BATTERY, | |
496 | + refresh_flags, | |
497 | &error); | |
498 | if (!ret) { | |
499 | g_warning ("failed to coldplug unifying device: %s", | |
f310ec08 AM |
500 | diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c |
501 | index 5398a38..1ce48b7 100644 | |
502 | --- a/src/linux/hidpp-device.c | |
503 | +++ b/src/linux/hidpp-device.c | |
504 | @@ -46,7 +46,6 @@ | |
505 | /* HID++ 1.0 */ | |
506 | #define HIDPP_READ_SHORT_REGISTER 0x81 | |
507 | #define HIDPP_READ_SHORT_REGISTER_BATTERY 0x0d | |
508 | -#define HIDPP_READ_SHORT_REGISTER_CONNECTION_STATE 0x02 | |
509 | ||
510 | #define HIDPP_READ_LONG_REGISTER 0x83 | |
511 | #define HIDPP_READ_LONG_REGISTER_DEVICE_TYPE 11 | |
512 | @@ -315,11 +314,10 @@ hidpp_device_cmd (HidppDevice *device, | |
513 | buf[2] == HIDPP_ERR_INVALID_SUBID && | |
514 | buf[3] == 0x00 && | |
515 | buf[4] == HIDPP_FEATURE_ROOT_FN_PING) { | |
516 | - if (buf[5] == HIDPP_ERROR_CODE_UNSUPPORTED) { | |
517 | - /* device offline / unreachable */ | |
518 | - g_set_error_literal (error, 1, 0, | |
519 | - "device is unreachable"); | |
520 | - ret = FALSE; | |
521 | + /* HID++ 1.0 ping reply, so fake success with version 1 */ | |
522 | + if (priv->version < 2 && (buf[5] == HIDPP_ERROR_CODE_UNKNOWN | |
523 | + || buf[5] == HIDPP_ERROR_CODE_UNSUPPORTED)) { | |
524 | + response_data[0] = 1; | |
525 | goto out; | |
526 | } | |
527 | } | |
528 | @@ -504,32 +502,12 @@ hidpp_device_refresh (HidppDevice *device, | |
529 | ret = FALSE; | |
530 | goto out; | |
531 | } | |
532 | - | |
533 | - /* add features we are going to use */ | |
534 | -// hidpp_device_map_add (device, | |
535 | -// HIDPP_FEATURE_I_FEATURE_SET, | |
536 | -// "IFeatureSet"); | |
537 | -// hidpp_device_map_add (device, | |
538 | -// HIDPP_FEATURE_I_FIRMWARE_INFO, | |
539 | -// "IFirmwareInfo"); | |
540 | - hidpp_device_map_add (device, | |
541 | - HIDPP_FEATURE_GET_DEVICE_NAME_TYPE, | |
542 | - "GetDeviceNameType"); | |
543 | - hidpp_device_map_add (device, | |
544 | - HIDPP_FEATURE_BATTERY_LEVEL_STATUS, | |
545 | - "BatteryLevelStatus"); | |
546 | -// hidpp_device_map_add (device, | |
547 | -// HIDPP_FEATURE_WIRELESS_DEVICE_STATUS, | |
548 | -// "WirelessDeviceStatus"); | |
549 | - hidpp_device_map_add (device, | |
550 | - HIDPP_FEATURE_SOLAR_DASHBOARD, | |
551 | - "SolarDashboard"); | |
552 | - hidpp_device_map_print (device); | |
553 | } | |
554 | ||
555 | /* get version */ | |
556 | if ((refresh_flags & HIDPP_REFRESH_FLAGS_VERSION) > 0) { | |
557 | - /* first try v2 packet */ | |
558 | + guint version_old = priv->version; | |
559 | + | |
560 | buf[0] = 0x00; | |
561 | buf[1] = 0x00; | |
562 | buf[2] = HIDPP_PING_DATA; | |
563 | @@ -540,34 +518,43 @@ hidpp_device_refresh (HidppDevice *device, | |
564 | buf, 3, | |
565 | buf, 4, | |
566 | error); | |
567 | - if (ret) | |
568 | - priv->version = buf[0]; | |
569 | - /* then try v1 packet */ | |
570 | - else { | |
571 | - /* discard potential v1 error */ | |
572 | - g_clear_error (error); | |
573 | - | |
574 | - /* checking hid++ v1 packet */ | |
575 | - buf[0] = 0x00; | |
576 | - buf[1] = 0x00; | |
577 | - buf[2] = 0x00; | |
578 | + if (!ret) | |
579 | + goto out; | |
580 | ||
581 | - ret = hidpp_device_cmd (device, | |
582 | - HIDPP_RECEIVER_ADDRESS, | |
583 | - HIDPP_READ_SHORT_REGISTER, | |
584 | - HIDPP_READ_SHORT_REGISTER_CONNECTION_STATE, | |
585 | - buf, 3, | |
586 | - buf, 2, | |
587 | - error); | |
588 | + priv->version = buf[0]; | |
589 | ||
590 | - if (!ret) | |
591 | - goto out; | |
592 | + if (version_old != priv->version) | |
593 | + g_debug("protocol for hid++ device changed from v%d to v%d", | |
594 | + version_old, priv->version); | |
595 | ||
596 | - priv->version = 1; | |
597 | - } | |
598 | + if (version_old < 2 && priv->version >= 2) | |
599 | + refresh_flags |= HIDPP_REFRESH_FLAGS_FEATURES; | |
600 | ||
601 | } | |
602 | ||
603 | + if ((refresh_flags & HIDPP_REFRESH_FLAGS_FEATURES) > 0) { | |
604 | + /* add features we are going to use */ | |
605 | +// hidpp_device_map_add (device, | |
606 | +// HIDPP_FEATURE_I_FEATURE_SET, | |
607 | +// "IFeatureSet"); | |
608 | +// hidpp_device_map_add (device, | |
609 | +// HIDPP_FEATURE_I_FIRMWARE_INFO, | |
610 | +// "IFirmwareInfo"); | |
611 | + hidpp_device_map_add (device, | |
612 | + HIDPP_FEATURE_GET_DEVICE_NAME_TYPE, | |
613 | + "GetDeviceNameType"); | |
614 | + hidpp_device_map_add (device, | |
615 | + HIDPP_FEATURE_BATTERY_LEVEL_STATUS, | |
616 | + "BatteryLevelStatus"); | |
617 | +// hidpp_device_map_add (device, | |
618 | +// HIDPP_FEATURE_WIRELESS_DEVICE_STATUS, | |
619 | +// "WirelessDeviceStatus"); | |
620 | + hidpp_device_map_add (device, | |
621 | + HIDPP_FEATURE_SOLAR_DASHBOARD, | |
622 | + "SolarDashboard"); | |
623 | + hidpp_device_map_print (device); | |
624 | + } | |
625 | + | |
626 | /* get device kind */ | |
627 | if ((refresh_flags & HIDPP_REFRESH_FLAGS_KIND) > 0) { | |
628 | ||
629 | diff --git a/src/linux/hidpp-device.h b/src/linux/hidpp-device.h | |
630 | index 935cd07..3f249a8 100644 | |
631 | --- a/src/linux/hidpp-device.h | |
632 | +++ b/src/linux/hidpp-device.h | |
633 | @@ -68,7 +68,8 @@ typedef enum { | |
634 | HIDPP_REFRESH_FLAGS_VERSION = 1, | |
635 | HIDPP_REFRESH_FLAGS_KIND = 2, | |
636 | HIDPP_REFRESH_FLAGS_BATTERY = 4, | |
637 | - HIDPP_REFRESH_FLAGS_MODEL = 8 | |
638 | + HIDPP_REFRESH_FLAGS_MODEL = 8, | |
639 | + HIDPP_REFRESH_FLAGS_FEATURES = 16 | |
640 | } HidppRefreshFlags; | |
641 | ||
642 | GType hidpp_device_get_type (void); | |
643 | ||
8103521f AM |
644 | diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c |
645 | index ea8b0b3..9023ac2 100644 | |
646 | --- a/src/linux/up-device-unifying.c | |
647 | +++ b/src/linux/up-device-unifying.c | |
648 | @@ -183,11 +188,32 @@ up_device_unifying_coldplug (UpDevice *device) | |
649 | hidraw_list = g_udev_client_query_by_subsystem (client, "hidraw"); | |
650 | for (l = hidraw_list; l != NULL; l = l->next) { | |
651 | if (g_strcmp0 (type, "lg-wireless") == 0) { | |
652 | + gboolean receiver_found = FALSE; | |
653 | + const gchar *filename; | |
654 | + GDir* dir; | |
655 | + | |
656 | if (g_strcmp0 (g_udev_device_get_sysfs_path (native), | |
657 | g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) != 0) | |
658 | continue; | |
659 | - // Ugly way to distinguish receiver itself from mouse/keyboard etc for non-unifying dongles | |
660 | - if (g_strcmp0(g_udev_device_get_property(g_udev_device_get_parent (native), "INTERFACE"), "3/0/0") != 0) | |
661 | + | |
662 | + /* hidraw device which exposes hiddev interface is our receiver */ | |
663 | + tmp = g_build_filename(g_udev_device_get_sysfs_path (g_udev_device_get_parent(native)), | |
664 | + "usbmisc", NULL); | |
665 | + dir = g_dir_open (tmp, 0, &error); | |
666 | + g_free(tmp); | |
667 | + if (error) { | |
668 | + g_clear_error(&error); | |
669 | + continue; | |
670 | + } | |
671 | + while ( (filename = g_dir_read_name(dir)) ) { | |
672 | + if (g_ascii_strncasecmp(filename, "hiddev", 6) == 0) { | |
673 | + receiver_found = TRUE; | |
674 | + break; | |
675 | + } | |
676 | + } | |
677 | + g_dir_close(dir); | |
678 | + | |
679 | + if (!receiver_found) | |
680 | continue; | |
681 | } else { | |
682 | if (g_strcmp0 (g_udev_device_get_sysfs_path (parent), | |
683 | ||
684 | diff --git a/rules/95-upower-csr.rules b/rules/95-upower-csr.rules | |
685 | index b476660..ffd55b2 100644 | |
686 | --- a/rules/95-upower-csr.rules | |
687 | +++ b/rules/95-upower-csr.rules | |
688 | @@ -25,5 +25,6 @@ SUBSYSTEM!="hid", GOTO="up_unifying_end" | |
689 | ATTRS{idVendor}=="046d", ENV{UPOWER_VENDOR}="Logitech, Inc." | |
690 | ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying" | |
691 | ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c532", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying" | |
692 | +ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52e", ENV{UPOWER_BATTERY_TYPE}="lg-wireless" | |
693 | ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52f", ENV{UPOWER_BATTERY_TYPE}="lg-wireless" | |
694 | LABEL="up_unifying_end" | |
38a4c250 AM |
695 | commit 181e7fa573bf6ba442ffd29d845c8fd10b62b3fe |
696 | Author: Richard Hughes <richard@hughsie.com> | |
697 | Date: Wed Apr 24 08:04:31 2013 +0100 | |
698 | ||
699 | Allow clients to call org.freedesktop.DBus.Peer | |
700 | ||
701 | This fixes Ping() and GetMachineId() which is needed by systemd. | |
702 | ||
703 | diff --git a/src/org.freedesktop.UPower.conf.in b/src/org.freedesktop.UPower.conf.in | |
704 | index a15ce93..fc2b604 100644 | |
705 | --- a/src/org.freedesktop.UPower.conf.in | |
706 | +++ b/src/org.freedesktop.UPower.conf.in | |
707 | @@ -14,6 +14,8 @@ | |
708 | send_interface="org.freedesktop.DBus.Introspectable"/> | |
709 | ||
710 | <allow send_destination="org.freedesktop.UPower" | |
711 | + send_interface="org.freedesktop.DBus.Peer"/> | |
712 | + <allow send_destination="org.freedesktop.UPower" | |
713 | send_interface="org.freedesktop.DBus.Properties"/> | |
714 | <allow send_destination="org.freedesktop.UPower.Device" | |
715 | send_interface="org.freedesktop.DBus.Properties"/> |