From: Chen Ganir <chen.ganir@ti.com>
To: Joao Paulo Rechi Vita <jprvita@openbossa.org>
Cc: <linux-bluetooth@vger.kernel.org>
Subject: Re: [PATCH 02/10] battery: Implement Generic device battery
Date: Wed, 12 Sep 2012 07:48:22 +0300 [thread overview]
Message-ID: <50501416.90408@ti.com> (raw)
In-Reply-To: <CAAngNMbUQzxAdwo2JUjzrqkLGXFhpyRVqtz03u+3t3nfXcyxpg@mail.gmail.com>
Joao,
On 09/11/2012 09:27 PM, Joao Paulo Rechi Vita wrote:
> On Tue, Sep 11, 2012 at 4:38 AM, <chen.ganir@ti.com> wrote:
>> From: Chen Ganir <chen.ganir@ti.com>
>>
>> Add implementation for the generic battery in bluetooth device.
>> This patch adds new D-Bus interface for adding/removing/changing
>> peer device battery status, allowing management of remote device
>> batteries.
>> ---
>> src/device.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> src/device.h | 15 +++++
>> test/test-device | 13 ++++
>> 3 files changed, 212 insertions(+)
>>
>> diff --git a/src/device.c b/src/device.c
>> index 02ef35e..ce4d467 100644
>> --- a/src/device.c
>> +++ b/src/device.c
>> @@ -166,6 +166,7 @@ struct btd_device {
>>
>> gboolean authorizing;
>> gint ref;
>> + GSList *batteries;
>>
>> GIOChannel *att_io;
>> guint cleanup_id;
>> @@ -180,6 +181,26 @@ static uint16_t uuid_list[] = {
>> 0
>> };
>>
>> +struct device_battery {
>> + DBusConnection *conn;
>> + uint16_t level;
>> + char *path;
>> + struct btd_device *device;
>> + RefreshBattFunc refresh_func;
>> +};
>> +
>> +static void battery_free(gpointer user_data)
>> +{
>> + struct device_battery *b = user_data;
>> +
>> + g_dbus_unregister_interface(b->conn, b->path, BATTERY_INTERFACE);
>> + dbus_connection_unref(b->conn);
>> + btd_device_unref(b->device);
>> + g_free(b->path);
>> + g_free(b);
>> +
>> +}
>> +
>> static void browse_request_free(struct browse_req *req)
>> {
>> if (req->listener_id)
>> @@ -259,6 +280,7 @@ static void device_free(gpointer user_data)
>> g_slist_free_full(device->primaries, g_free);
>> g_slist_free_full(device->attios, g_free);
>> g_slist_free_full(device->attios_offline, g_free);
>> + g_slist_free_full(device->batteries, battery_free);
>>
>> attio_cleanup(device);
>>
>> @@ -433,6 +455,15 @@ static DBusMessage *get_properties(DBusConnection *conn,
>> ptr = adapter_get_path(adapter);
>> dict_append_entry(&dict, "Adapter", DBUS_TYPE_OBJECT_PATH, &ptr);
>>
>> + /* Batteries */
>> + str = g_new0(char *, g_slist_length(device->batteries) + 1);
>> + for (i = 0, l = device->batteries; l; l = l->next, i++) {
>> + struct device_battery *b = l->data;
>> + str[i] = b->path;
>> + }
>> + dict_append_array(&dict, "Batteries", DBUS_TYPE_OBJECT_PATH, &str, i);
>> + g_free(str);
>> +
>> dbus_message_iter_close_container(&iter, &dict);
>>
>> return reply;
>> @@ -3263,3 +3294,156 @@ void btd_profile_disconnected(struct btd_profile *profile,
>> {
>> device->conns = g_slist_remove(device->conns, profile);
>> }
>> +
>> +static void batteries_changed(struct btd_device *device)
>> +{
>> + DBusConnection *conn = get_dbus_connection();
>> + char **batteries;
>> + GSList *l;
>> + int i;
>> +
>> + batteries = g_new0(char *, g_slist_length(device->batteries) + 1);
>> + for (i = 0, l = device->batteries; l; l = l->next, i++) {
>> + struct device_battery *batt = l->data;
>> + batteries[i] = batt->path;
>> + }
>> +
>> + emit_array_property_changed(conn, device->path, DEVICE_INTERFACE,
>> + "Batteries", DBUS_TYPE_OBJECT_PATH,
>> + &batteries, i);
>> +
>> + g_free(batteries);
>> +}
>> +
>> +static DBusMessage *refresh_batt_level(DBusConnection *conn,
>> + DBusMessage *msg, void *data)
>> +{
>> + struct device_battery *b = data;
>> +
>> + if (!b->refresh_func)
>> + return btd_error_not_supported(msg);
>> +
>> + b->refresh_func(b);
>> +
>> + return dbus_message_new_method_return(msg);
>> +}
>> +
>> +static DBusMessage *get_batt_properties(DBusConnection *conn,
>> + DBusMessage *msg, void *data)
>> +{
>> + struct device_battery *b = data;
>> + DBusMessageIter iter;
>> + DBusMessageIter dict;
>> + DBusMessage *reply;
>> +
>> + reply = dbus_message_new_method_return(msg);
>> + if (reply == NULL)
>> + return NULL;
>> +
>> + dbus_message_iter_init_append(reply, &iter);
>> +
>> + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
>> + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
>> + DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
>> + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
>> +
>> + dict_append_entry(&dict, "Level", DBUS_TYPE_UINT16, &b->level);
>> +
>> + dbus_message_iter_close_container(&iter, &dict);
>> +
>> + return reply;
>> +}
>> +
>> +static GDBusMethodTable battery_methods[] = {
>> + { GDBUS_METHOD("GetProperties",
>> + NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
>> + get_batt_properties) },
>> + { GDBUS_METHOD("Refresh",
>> + NULL, NULL,
>> + refresh_batt_level) },
>> + { }
>> +};
>> +
>> +static GDBusSignalTable battery_signals[] = {
>> + { GDBUS_SIGNAL("PropertyChanged",
>> + GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
>> + { }
>> +};
>> +
>> +struct device_battery *btd_device_add_battery(struct btd_device *device)
>> +{
>> + struct device_battery *batt;
>> + DBusConnection *conn = get_dbus_connection();
>> +
>> + batt = g_new0(struct device_battery, 1);
>> + batt->path = g_strdup_printf("%s/BATT%04X", device->path,
>> + g_slist_length(device->batteries));
>> + batt->conn = dbus_connection_ref(conn);
>> +
>> + if (!g_dbus_register_interface(batt->conn, batt->path,
>> + BATTERY_INTERFACE, battery_methods, battery_signals,
>> + NULL, batt, NULL)) {
>> + error("D-Bus register interface %s failed", BATTERY_INTERFACE);
>> + dbus_connection_unref(batt->conn);
>> + g_free(batt->path);
>> + g_free(batt);
>> + return NULL;
>> + }
>> +
>> + batt->device = btd_device_ref(device);
>> + device->batteries = g_slist_append(device->batteries, batt);
>> + batteries_changed(device);
>> +
>> + return batt;
>> +}
>> +
>> +void btd_device_remove_battery(struct device_battery *batt)
>> +{
>> + struct btd_device *dev = batt->device;
>> +
>> + dev->batteries = g_slist_remove(dev->batteries, batt);
>> +
>> + battery_free(batt);
>> +
>> + batteries_changed(dev);
>> +}
>> +
>> +gboolean btd_device_set_battery_opt(struct device_battery *batt,
>> + BatteryOption opt1, ...)
>> +{
>> + va_list args;
>> + BatteryOption opt = opt1;
>> + int level;
>> +
>> + if (!batt)
>> + return FALSE;
>> +
>> + va_start(args, opt1);
>> +
>> + while (opt != BATTERY_OPT_INVALID) {
>> + switch (opt) {
>> + case BATTERY_OPT_LEVEL:
>> + level = va_arg(args, int);
>> + if (level != batt->level) {
>> + batt->level = level;
>> + emit_property_changed(batt->conn, batt->path,
>> + BATTERY_INTERFACE, "Level",
>> + DBUS_TYPE_UINT16, &level);
>> + }
>> + break;
>> + case BATTERY_OPT_REFRESH_FUNC:
>> + batt->refresh_func = va_arg(args, RefreshBattFunc);
>> + break;
>> + default:
>> + error("Unknown option %d", opt);
>> + return FALSE;
>> + }
>> +
>> + opt = va_arg(args, int);
>> + }
>> +
>> + va_end(args);
>> +
>> + return TRUE;
>> +
>> +}
>
> Please remove this empty line also.
>
Thanks, missed that as well.
>> diff --git a/src/device.h b/src/device.h
>> index f1d95c6..66eb5e8 100644
>> --- a/src/device.h
>> +++ b/src/device.h
>> @@ -23,8 +23,10 @@
>> */
>>
>> #define DEVICE_INTERFACE "org.bluez.Device"
>> +#define BATTERY_INTERFACE "org.bluez.Battery"
>>
>> struct btd_device;
>> +struct device_battery;
>
> Since this symbol is being exported, shouldn't it be prefixed with btd_ as well?
>
I will rename it to struct btd_battery. Is that ok ?
>>
>> typedef enum {
>> AUTH_TYPE_PINCODE,
>> @@ -54,6 +56,14 @@ struct btd_profile {
>> void (*adapter_remove) (struct btd_adapter *adapter);
>> };
>>
>> +typedef void (*RefreshBattFunc) (struct device_battery *batt);
>
> I don't think we use CamelCase for anything other than D-Bus method names.
>
We use it in gattrib.h for function pointers. What is the correct
convention for function pointers ? same as in adapter_ops ?
>> +
>> +typedef enum {
>> + BATTERY_OPT_INVALID = 0,
>> + BATTERY_OPT_LEVEL,
>> + BATTERY_OPT_REFRESH_FUNC,
>> +} BatteryOption;
>
> Fix CamelCase usage here and on uses of this type as well.
>
btio.h also uses this convention. What should be the correct convention ?
>> +
>> void btd_profile_foreach(void (*func)(struct btd_profile *p, void *data),
>> void *data);
>>
>> @@ -158,3 +168,8 @@ int device_unblock(DBusConnection *conn, struct btd_device *device,
>> void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
>> uint16_t vendor_id, uint16_t product_id,
>> uint16_t product_ver);
>> +
>> +struct device_battery *btd_device_add_battery(struct btd_device *device);
>> +void btd_device_remove_battery(struct device_battery *batt);
>> +gboolean btd_device_set_battery_opt(struct device_battery *batt,
>> + BatteryOption opt1, ...);
>> diff --git a/test/test-device b/test/test-device
>> index 63a96d3..7edb7b8 100755
>> --- a/test/test-device
>> +++ b/test/test-device
>> @@ -37,6 +37,7 @@ if (len(args) < 1):
>> print("")
>> print(" list")
>> print(" services <address>")
>> + print(" batteries <address>")
>> print(" create <address>")
>> print(" remove <address|path>")
>> print(" disconnect <address>")
>> @@ -205,5 +206,17 @@ if (args[0] == "services"):
>> print(path)
>> sys.exit(0)
>>
>> +if (args[0] == "batteries"):
>> + if (len(args) < 2):
>> + print("Need address parameter")
>> + else:
>> + path = adapter.FindDevice(args[1])
>> + device = dbus.Interface(bus.get_object("org.bluez", path),
>> + "org.bluez.Device")
>> + properties = device.GetProperties()
>> + for path in properties["Batteries"]:
>> + print(path)
>> + sys.exit(0)
>> +
>> print("Unknown command")
>> sys.exit(1)
>> --
>> 1.7.9.5
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>
Thanks,
--
BR,
Chen Ganir
next prev parent reply other threads:[~2012-09-12 4:48 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-11 7:38 [PATCH 00/10] Implement Generic battery and LE Battery client chen.ganir
2012-09-11 7:38 ` [PATCH 01/10] battery: Add generic device battery documentation chen.ganir
2012-09-11 15:34 ` Joao Paulo Rechi Vita
2012-09-12 4:45 ` Chen Ganir
2012-09-11 7:38 ` [PATCH 02/10] battery: Implement Generic device battery chen.ganir
2012-09-11 18:27 ` Joao Paulo Rechi Vita
2012-09-12 4:48 ` Chen Ganir [this message]
2012-09-12 8:45 ` Johan Hedberg
2012-09-12 10:30 ` Chen Ganir
2012-09-12 10:57 ` Anderson Lizardo
2012-09-13 11:32 ` Chen Ganir
2012-09-11 7:38 ` [PATCH 03/10] battery: Add GATT Battery Client Service skeleton chen.ganir
2012-09-11 7:38 ` [PATCH 04/10] battery: Add client connection logic chen.ganir
2012-09-11 7:38 ` [PATCH 05/10] battery: Discover Characteristic Descriptors chen.ganir
2012-09-11 20:52 ` Joao Paulo Rechi Vita
2012-09-12 4:49 ` Chen Ganir
2012-09-11 7:38 ` [PATCH 06/10] battery: Get Battery ID chen.ganir
2012-09-11 7:38 ` [PATCH 07/10] battery: Add Battery to device chen.ganir
2012-09-11 21:40 ` Joao Paulo Rechi Vita
2012-09-12 4:54 ` Chen Ganir
2012-09-11 7:38 ` [PATCH 08/10] battery: Read Battery level characteristic chen.ganir
2012-09-11 21:50 ` Joao Paulo Rechi Vita
2012-09-12 4:55 ` Chen Ganir
2012-09-11 7:38 ` [PATCH 09/10] battery: Add support for notifications chen.ganir
2012-09-11 22:08 ` Joao Paulo Rechi Vita
2012-09-12 4:58 ` Chen Ganir
2012-09-13 11:27 ` Chen Ganir
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50501416.90408@ti.com \
--to=chen.ganir@ti.com \
--cc=jprvita@openbossa.org \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.