Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp1572799pxb; Fri, 20 Nov 2020 12:58:31 -0800 (PST) X-Google-Smtp-Source: ABdhPJz5hmWih9bpA+p8zTV2l6Gp4d0H+gnG+2Q+piaPQ1cWDMPV84AgvjWkLDEQHqRqAoQnZzGZ X-Received: by 2002:a17:906:3782:: with SMTP id n2mr35592570ejc.493.1605905911421; Fri, 20 Nov 2020 12:58:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605905911; cv=none; d=google.com; s=arc-20160816; b=xok483XpfrmhzvalTJeaY6wfDZG9Y/kIv198lGntvGkC7unp1XS9w0ZrV0ZfnORji2 VnbFw1SYwRkOrYXiEt7gaT7x22mpSGLTFGrV9q02uVLKzjQ6IrbRjctfa4Q+w86V0eYx PnXfWQI8j8bPthQR7xcRLSHTwUYT/DUfXjibBAZ8DXqPWNC1ZPt1LVYvVayxicR29iy6 Xydg1qEFxJdXHIaY9k1IiIW4IEV6ZMRJSdIhl6fnocp2r6g3UlxJkfjX+QZ3apRtEthS /Xs/Kt+p3th/i6E+/FGG20Dhh0mb+mQfQY1LbHhP5ENfIX5DPRuDycDND+Evx78B47um 2cEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=4lpY+Sh0Q2EQRKqw0QFdfTD5oYIKy1v6u1iamItNIGQ=; b=Dj+bAMHnOpQE/qPWxEmFYj3HVX3ML+YUYSnUVgIjr83aNmJLVwobwNUenHpC1rZyfA G8FGKrK2NseRkNWrX6VeKHPtzhGrmEwQLNr2tnG09QiacLXeQF5ETj838CrnVK1wdDiv 92Gad10c4TnX9uacnuvKB5YDBG96xFa6B1ODU3q9a1t0Od7aQymIOmzpKreJrW1qrUmF hlnusdMqPGGvOgur6BsqK3wvVM0aJ1Fq5TOZuN6X0Ztf60fwtyv5TyGxID/Ck0TUMesG 2Zr+x4uMZ/CMDlcUyDATlNWKODOjnZ6BXddqb+Sb5poX6qyGoyVUy5saz+ByEas7Vnqr 3lkw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=J8eDGlvV; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id i23si2426077edg.60.2020.11.20.12.57.56; Fri, 20 Nov 2020 12:58:31 -0800 (PST) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=J8eDGlvV; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730134AbgKTU5v (ORCPT + 99 others); Fri, 20 Nov 2020 15:57:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729547AbgKTU5v (ORCPT ); Fri, 20 Nov 2020 15:57:51 -0500 Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F010C0613CF for ; Fri, 20 Nov 2020 12:57:51 -0800 (PST) Received: by mail-pf1-x443.google.com with SMTP id b63so9015696pfg.12 for ; Fri, 20 Nov 2020 12:57:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=4lpY+Sh0Q2EQRKqw0QFdfTD5oYIKy1v6u1iamItNIGQ=; b=J8eDGlvV1Uknvl5cHKI6I4EIfzziSZpd6TqPCk1d3XMw8fe7xASjNW1VrqKJt1Q0eY m9PzDk0wPl56g/T3xnKznIHNtFMCxbT4Tx+pkY9dgt5sf9wvwFkmvYgTNz0nCVu+Hk6w nD/cd2ZRN4VY43kaIL9pVafonoJIuRzN01piE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=4lpY+Sh0Q2EQRKqw0QFdfTD5oYIKy1v6u1iamItNIGQ=; b=RrQTBdW/u0cMA/8NT+G2yXdOno1B64pQth0eR0ZKELhjuX8TuvwxoQoVa+LoXfeusY nEVAk9ASPXgc9QCbSu70P+u4H67zlLAM0mDpimLLJe1YlDaJKL4O1ezP6KhEu0AvtO3w x6JYw/kX2tERmp352piMhssE9eAqo2wjnT7eBG0f/uYypoa2UIGnX32NDg74QB1JrscL b3F/keVKulXSrta5UqsvZlMqhlmBpeu8S2I6xQtQkJg9WfU6KuH1kA0DhJF7HqRs2boa g0M4Di6oQuYYV8b3KtE1n0LbHoMEmH77kIP0fhN2LDjWHvXnDtZLau6G6PxI4mzuqFhJ lkPw== X-Gm-Message-State: AOAM530rqZeQKeqFyhex7bfeDCJrjxeDwZ6199quCvyB2FhvIBXpxHVC o4cQK3O/lvRTb6sD63ZySVnmpBHjor1zJg== X-Received: by 2002:a17:90a:1902:: with SMTP id 2mr12356899pjg.177.1605905870360; Fri, 20 Nov 2020 12:57:50 -0800 (PST) Received: from sonnysasaka-chrome.mtv.corp.google.com ([2620:15c:202:201:4a0f:cfff:fe66:e60c]) by smtp.gmail.com with ESMTPSA id a67sm3232080pfa.77.2020.11.20.12.57.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 20 Nov 2020 12:57:49 -0800 (PST) From: Sonny Sasaka To: linux-bluetooth@vger.kernel.org Cc: Sonny Sasaka , Daniel Winkler Subject: [PATCH BlueZ v3 1/7] battery: Add the internal Battery API Date: Fri, 20 Nov 2020 12:57:22 -0800 Message-Id: <20201120205728.339325-1-sonnysasaka@chromium.org> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org This patch adds an API for internal BlueZ code to expose battery information to org.bluez.Battery1 interface. The motivation behind this is that there is going to be other places than GATT BAS handler that exposes battery information, for example internal plugins and the BatteryProvider1 D-Bus API for external clients. Reviewed-by: Daniel Winkler --- Makefile.am | 3 +- src/battery.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/battery.h | 15 ++++ 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 src/battery.c create mode 100644 src/battery.h diff --git a/Makefile.am b/Makefile.am index 69b95828f..95917f695 100644 --- a/Makefile.am +++ b/Makefile.am @@ -294,7 +294,8 @@ src_bluetoothd_SOURCES = $(builtin_sources) \ src/device.h src/device.c \ src/dbus-common.c src/dbus-common.h \ src/eir.h src/eir.c \ - src/adv_monitor.h src/adv_monitor.c + src/adv_monitor.h src/adv_monitor.c \ + src/battery.h src/battery.c src_bluetoothd_LDADD = lib/libbluetooth-internal.la \ gdbus/libgdbus-internal.la \ src/libshared-glib.la \ diff --git a/src/battery.c b/src/battery.c new file mode 100644 index 000000000..87a6b91fb --- /dev/null +++ b/src/battery.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2020 Google LLC + * + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include + +#include "gdbus/gdbus.h" +#include "lib/bluetooth.h" +#include "src/shared/queue.h" +#include "src/shared/util.h" +#include "battery.h" +#include "dbus-common.h" +#include "adapter.h" +#include "log.h" + +#define BATTERY_INTERFACE "org.bluez.Battery1" + +#define BATTERY_MAX_PERCENTAGE 100 + +struct btd_battery { + char *path; /* D-Bus object path, owns pointer */ + uint8_t percentage; /* valid between 0 to 100 inclusively */ +}; + +static struct queue *batteries = NULL; + +static void battery_add(struct btd_battery *battery) +{ + if (!batteries) + batteries = queue_new(); + + queue_push_head(batteries, battery); +} + +static void battery_remove(struct btd_battery *battery) +{ + queue_remove(batteries, battery); + if (queue_isempty(batteries)) { + queue_destroy(batteries, NULL); + batteries = NULL; + } +} + +static bool match_path(const void *data, const void *user_data) +{ + const struct btd_battery *battery = data; + const char *path = user_data; + + return g_strcmp0(battery->path, path) == 0; +} + +static struct btd_battery *battery_new(const char *path) +{ + struct btd_battery *battery; + + battery = new0(struct btd_battery, 1); + battery->path = g_strdup(path); + battery->percentage = UINT8_MAX; + + return battery; +} + +static void battery_free(struct btd_battery *battery) +{ + if (battery->path) + g_free(battery->path); + + free(battery); +} + +static gboolean property_percentage_get(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct btd_battery *battery = data; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, + &battery->percentage); + + return TRUE; +} + +static gboolean property_percentage_exists(const GDBusPropertyTable *property, + void *data) +{ + struct btd_battery *battery = data; + + return battery->percentage <= BATTERY_MAX_PERCENTAGE; +} + +static const GDBusPropertyTable battery_properties[] = { + { "Percentage", "y", property_percentage_get, NULL, + property_percentage_exists }, + {} +}; + +struct btd_battery *btd_battery_register(const char *path) +{ + struct btd_battery *battery; + + DBG("path = %s", path); + + if (queue_find(batteries, match_path, path)) { + error("error registering battery: path exists"); + return NULL; + } + + if (!g_str_has_prefix(path, "/")) { + error("error registering battery: invalid D-Bus object path"); + return NULL; + } + + battery = battery_new(path); + battery_add(battery); + + if (!g_dbus_register_interface(btd_get_dbus_connection(), battery->path, + BATTERY_INTERFACE, NULL, NULL, + battery_properties, battery, NULL)) { + error("error registering D-Bus interface for %s", + battery->path); + + battery_remove(battery); + battery_free(battery); + + return NULL; + } + + DBG("registered Battery object: %s", battery->path); + + return battery; +} + +bool btd_battery_unregister(struct btd_battery *battery) +{ + DBG("path = %s", battery->path); + + if (!queue_find(batteries, NULL, battery)) { + error("error unregistering battery: " + "battery %s is not registered", + battery->path); + return false; + } + + if (!g_dbus_unregister_interface(btd_get_dbus_connection(), + battery->path, BATTERY_INTERFACE)) { + error("error unregistering battery %s from D-Bus interface", + battery->path); + return false; + } + + battery_remove(battery); + battery_free(battery); + + return true; +} + +bool btd_battery_update(struct btd_battery *battery, uint8_t percentage) +{ + DBG("path = %s", battery->path); + + if (!queue_find(batteries, NULL, battery)) { + error("error updating battery: battery is not registered"); + return false; + } + + if (percentage > BATTERY_MAX_PERCENTAGE) { + error("error updating battery: percentage is not valid"); + return false; + } + + if (battery->percentage == percentage) + return true; + + battery->percentage = percentage; + g_dbus_emit_property_changed(btd_get_dbus_connection(), battery->path, + BATTERY_INTERFACE, "Percentage"); + + return true; +} diff --git a/src/battery.h b/src/battery.h new file mode 100644 index 000000000..9c69b7afa --- /dev/null +++ b/src/battery.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2020 Google LLC + * + * + */ + +struct btd_battery; + +struct btd_battery *btd_battery_register(const char *path); +bool btd_battery_unregister(struct btd_battery *battery); +bool btd_battery_update(struct btd_battery *battery, uint8_t percentage); -- 2.26.2