linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).