[PATCH BlueZ RESEND] profiles/battery: handle reversed ordering of CCC and value

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Order of batt_io_value_cb() and batt_io_ccc_written_cb() may be reverse.
This causes device to appear with 0% or missing battery percentage,
because batt->percentage is set on the ignored update so the initial
update is lost.

Fix by saving new initial value, if battery is not registered.  Also
downgrade warning to debug message.

Also check data length before parsing it.

Log (Sony Linkbuds S):

src/shared/att.c:can_read_data() (chan 0x7c31eea05c50) ATT PDU received: 0x1b
profiles/battery/battery.c:parse_battery_level() Battery Level updated: 87%
profiles/battery/battery.c:parse_battery_level() Trying to update an unregistered battery
src/battery.c:btd_battery_register() path = /org/bluez/hci1/dev_CF_D2_4D_EE_A2_1A
src/battery.c:btd_battery_register() registered Battery object: /org/bluez/hci1/dev_CF_D2_4D_EE_A2_1A
profiles/battery/battery.c:batt_io_ccc_written_cb() Battery Level: notification enabled
---
 profiles/battery/battery.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/profiles/battery/battery.c b/profiles/battery/battery.c
index 5be78ab14..2f5be48e9 100644
--- a/profiles/battery/battery.c
+++ b/profiles/battery/battery.c
@@ -91,16 +91,19 @@ static void batt_reset(struct batt *batt)
 static void parse_battery_level(struct batt *batt,
 				const uint8_t *value)
 {
-	uint8_t percentage;
+	uint8_t percentage = value[0];
+
+	DBG("Battery Level updated: %d%%", percentage);
+
+	if (!batt->battery) {
+		free(batt->initial_value);
+		batt->initial_value = util_memdup(value, 1);
+		DBG("Battery not yet registered");
+		return;
+	}
 
-	percentage = value[0];
 	if (batt->percentage != percentage) {
 		batt->percentage = percentage;
-		DBG("Battery Level updated: %d%%", percentage);
-		if (!batt->battery) {
-			warn("Trying to update an unregistered battery");
-			return;
-		}
 		btd_battery_update(batt->battery, batt->percentage);
 	}
 }
@@ -111,6 +114,8 @@ static void batt_io_value_cb(uint16_t value_handle, const uint8_t *value,
 	struct batt *batt = user_data;
 
 	if (value_handle == batt->batt_level_io_handle) {
+		if (!length)
+			return;
 		parse_battery_level(batt, value);
 	} else {
 		g_assert_not_reached();
-- 
2.50.1





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux