* RE: Wireshark
From: Michal.Labedzki @ 2012-10-03 7:17 UTC (permalink / raw)
To: linux-bluetooth; +Cc: johan.hedberg, andrei.emeltchenko.news
In-Reply-To: <20120928135747.GD8184@aemeltch-MOBL1>
Hello,
> HCI also does not have full support for AMP HCI commands. I can send that
> log.
All logs are welcome. Andrei, please send it.
> but it can't do any kind of
> high-level decoding (e.g. profiles). It'd be interesting to know if it
> could be easily supported in wireshark since right now there doesn't
> seem to be a viable way of porting decoders from hcidump to btmon due to
> their very different ways of handling buffers etc.
Johan, I guess Wireshark support decoding what do you need (expect ongoing tasks). If you have another idea how do decoding, please share it. Power of Wireshark is:
1. Decoding all fields in protocols (+ user friendly describes and visualization bit/byte position in the frame)
2. Colors per protocol/profile to improve readability;
3. Possibility to display specified field as column (like Protocol, Length, Info; for example I display btl2cap.cid, btrfcomm.channel) [by the way, I have configured Wireshark to display column "Time" as "Absolute date and time" and additional "Delta" as "Delta time" - nice combination to working on timings]
4. Filtering logs, in Filter field you can but "btavrcp" and you see only AVRCP; or something like "btbnep.bnep_type == 0x01 || bthci_evt" - so you can display only HCI Events and BNEP packet where BNEP Type is equal 0x01.
5. (Menu) Statistics -> IO Graph, then "Y Axis -> Unit -> Bytes per Tick" and using filters - you can analyse throughput (for example: OPP, A2DP)
6. pcap file format can contain "Comments" - so everyone can share some useful additional information (per frame)
Example logs:
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=9186
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=9187
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=9139
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=9111
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=9112
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=9023
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=9024
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=9025
https://bugs.wireshark.org/bugzilla/attachment.cgi?id=7686
You can obtain Wireshark from SVN or GIT:
svn co http://anonsvn.wireshark.org/wireshark/trunk/ wireshark
git clone http://code.wireshark.org/git/wireshark (I use only this one, but please note sometimes this way may not working...)
Installation:
not required: ./autogen.sh && ./configure && make -j 16 && ./wireshark
Regards / Pozdrawiam
-------------------------------------------------------------------------------------------------------------
Michał Łabędzki
ASCII: Michal Labedzki
e-mail: michal.labedzki@tieto.com
location: Poland, Wrocław, Legnicka 55F
---
Tieto Corporation / Tieto Poland
http://www.tieto.com / http://www.tieto.pl
---
Tieto Poland spółka z ograniczoną odpowiedzialnością z siedzibą w Szczecinie, ul. Malczewskiego 26. Zarejestrowana w Sądzie Rejonowym Szczecin-Centrum w Szczecinie, XIII Wydział Gospodarczy Krajowego Rejestru Sądowego pod numerem 0000124858. NIP: 8542085557. REGON: 812023656. Kapitał zakładowy: 4 271500 PLN
^ permalink raw reply
* [PATCH v3 BlueZ 27/27] alert: Add org.bluez.AlertAgent to D-Bus policy file
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
This allows BlueZ to call the methods on the org.bluez.AlertAgent
interface.
---
src/bluetooth.conf | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index 602c8af..2db43d9 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -16,6 +16,7 @@
<allow send_interface="org.bluez.MediaPlayer"/>
<allow send_interface="org.bluez.Watcher"/>
<allow send_interface="org.bluez.ThermometerWatcher"/>
+ <allow send_interface="org.bluez.AlertAgent"/>
<allow send_interface="org.bluez.Profile"/>
<allow send_interface="org.bluez.HeartRateWatcher"/>
</policy>
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 26/27] alert: Implement Release() agent method
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
This method allows BlueZ to notify the agent that it will not be used
anymore, and can thus cleanup itself (e.g. deallocate D-Bus object, or
exit).
---
profiles/alert/server.c | 18 +++++++++++++++++-
test/test-alert | 11 +++++++++--
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 0ed8bb1..37fd125 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -179,9 +179,25 @@ static void alert_data_destroy(gpointer user_data)
g_free(alert);
}
+static void alert_release(gpointer user_data)
+{
+ struct alert_data *alert = user_data;
+ DBusMessage *msg;
+
+ msg = dbus_message_new_method_call(alert->srv, alert->path,
+ ALERT_AGENT_INTERFACE,
+ "Release");
+ if (msg)
+ g_dbus_send_message(btd_get_dbus_connection(), msg);
+
+ alert_data_destroy(alert);
+}
+
static void alert_destroy(gpointer user_data)
{
- g_slist_free_full(registered_alerts, alert_data_destroy);
+ DBG("");
+
+ g_slist_free_full(registered_alerts, alert_release);
registered_alerts = NULL;
}
diff --git a/test/test-alert b/test/test-alert
index c92a719..1e241a3 100755
--- a/test/test-alert
+++ b/test/test-alert
@@ -15,9 +15,10 @@ BLUEZ_OBJECT_PATH = '/org/bluez'
TEST_OBJECT_PATH = '/org/bluez/test'
class AlertAgent(dbus.service.Object):
- def __init__(self, bus, object_path, alert):
+ def __init__(self, bus, object_path, alert, mainloop):
dbus.service.Object.__init__(self, bus, object_path)
self.alert = alert
+ self.mainloop = mainloop
@dbus.service.method(ALERT_AGENT_INTERFACE, in_signature='',
out_signature='')
@@ -31,6 +32,12 @@ class AlertAgent(dbus.service.Object):
print('method SetRinger(%s) was called' % mode)
self.alert.NewAlert('ringer', 1, mode)
+ @dbus.service.method(ALERT_AGENT_INTERFACE, in_signature='',
+ out_signature='')
+ def Release(self):
+ print('method Release() was called')
+ self.mainloop.quit()
+
def print_command_line(options):
if not options.verbose:
return False
@@ -145,7 +152,7 @@ bus = dbus.SystemBus()
mainloop = gobject.MainLoop()
alert = dbus.Interface(bus.get_object(BUS_NAME, BLUEZ_OBJECT_PATH),
ALERT_INTERFACE)
-alert_agent = AlertAgent(bus, TEST_OBJECT_PATH, alert)
+alert_agent = AlertAgent(bus, TEST_OBJECT_PATH, alert, mainloop)
print_command_line(options)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 25/27] alert: Add support for unread alert notification
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
When UnreadAlert D-Bus method is called for a registered category
from Alert Notification Profile, The unread alert characteristic value
is notified.
---
profiles/alert/server.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 166f905..0ed8bb1 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -96,6 +96,7 @@ enum notify_type {
NOTIFY_RINGER_SETTING = 0,
NOTIFY_ALERT_STATUS,
NOTIFY_NEW_ALERT,
+ NOTIFY_UNREAD_ALERT,
NOTIFY_SIZE,
};
@@ -110,7 +111,6 @@ struct alert_adapter {
struct btd_adapter *adapter;
uint16_t supp_new_alert_cat_handle;
uint16_t supp_unread_alert_cat_handle;
- uint16_t unread_alert_handle;
uint16_t hnd_ccc[NOTIFY_SIZE];
uint16_t hnd_value[NOTIFY_SIZE];
};
@@ -352,6 +352,7 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
pdu, sizeof(pdu));
break;
case NOTIFY_NEW_ALERT:
+ case NOTIFY_UNREAD_ALERT:
len = enc_notification(al_adapter->hnd_value[type],
nd->value, nd->len, pdu, sizeof(pdu));
break;
@@ -644,8 +645,11 @@ static void update_unread_alert(gpointer data, gpointer user_data)
struct btd_adapter *adapter = al_adapter->adapter;
uint8_t *value = user_data;
- attrib_db_update(adapter, al_adapter->unread_alert_handle, NULL, value,
- 2, NULL);
+ attrib_db_update(adapter,
+ al_adapter->hnd_value[NOTIFY_UNREAD_ALERT], NULL, value,
+ 2, NULL);
+
+ notify_devices(al_adapter, NOTIFY_UNREAD_ALERT, value, 2);
}
static DBusMessage *unread_alert(DBusConnection *conn, DBusMessage *msg,
@@ -889,8 +893,10 @@ static void register_alert_notif_service(struct alert_adapter *al_adapter)
/* Unread Alert Status */
GATT_OPT_CHR_UUID, UNREAD_ALERT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
+ GATT_OPT_CCC_GET_HANDLE,
+ &al_adapter->hnd_ccc[NOTIFY_UNREAD_ALERT],
GATT_OPT_CHR_VALUE_GET_HANDLE,
- &al_adapter->unread_alert_handle,
+ &al_adapter->hnd_value[NOTIFY_UNREAD_ALERT],
/* Alert Notification Control Point */
GATT_OPT_CHR_UUID, ALERT_NOTIF_CP_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 24/27] alert: Add support for new alert notification
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
When NewAlert D-Bus method is called for one category from Alert
Notification Profile, the new alert characteristic value is notified.
---
profiles/alert/server.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 5414d74..166f905 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -95,6 +95,7 @@ enum {
enum notify_type {
NOTIFY_RINGER_SETTING = 0,
NOTIFY_ALERT_STATUS,
+ NOTIFY_NEW_ALERT,
NOTIFY_SIZE,
};
@@ -109,7 +110,6 @@ struct alert_adapter {
struct btd_adapter *adapter;
uint16_t supp_new_alert_cat_handle;
uint16_t supp_unread_alert_cat_handle;
- uint16_t new_alert_handle;
uint16_t unread_alert_handle;
uint16_t hnd_ccc[NOTIFY_SIZE];
uint16_t hnd_value[NOTIFY_SIZE];
@@ -351,6 +351,10 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
&alert_status, sizeof(alert_status),
pdu, sizeof(pdu));
break;
+ case NOTIFY_NEW_ALERT:
+ len = enc_notification(al_adapter->hnd_value[type],
+ nd->value, nd->len, pdu, sizeof(pdu));
+ break;
default:
DBG("Unknown type, could not send notification");
goto end;
@@ -483,8 +487,10 @@ static void update_new_alert(gpointer data, gpointer user_data)
struct btd_adapter *adapter = al_adapter->adapter;
uint8_t *value = user_data;
- attrib_db_update(adapter, al_adapter->new_alert_handle, NULL, &value[1],
- value[0], NULL);
+ attrib_db_update(adapter, al_adapter->hnd_value[NOTIFY_NEW_ALERT], NULL,
+ &value[1], value[0], NULL);
+
+ notify_devices(al_adapter, NOTIFY_NEW_ALERT, &value[1], value[0]);
}
static void update_phone_alerts(const char *category, const char *description)
@@ -869,8 +875,10 @@ static void register_alert_notif_service(struct alert_adapter *al_adapter)
/* New Alert */
GATT_OPT_CHR_UUID, NEW_ALERT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
+ GATT_OPT_CCC_GET_HANDLE,
+ &al_adapter->hnd_ccc[NOTIFY_NEW_ALERT],
GATT_OPT_CHR_VALUE_GET_HANDLE,
- &al_adapter->new_alert_handle,
+ &al_adapter->hnd_value[NOTIFY_NEW_ALERT],
/* Supported Unread Alert Category */
GATT_OPT_CHR_UUID, SUPP_UNREAD_ALERT_CAT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 23/27] alert: Add support for alert status notification
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
The notification is sent (to peer devices that have it enabled on the
CCC descriptor) every time the alert status characteristic value
changes.
---
profiles/alert/server.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 10c4160..5414d74 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -94,6 +94,7 @@ enum {
enum notify_type {
NOTIFY_RINGER_SETTING = 0,
+ NOTIFY_ALERT_STATUS,
NOTIFY_SIZE,
};
@@ -345,6 +346,11 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
&ringer_setting, sizeof(ringer_setting),
pdu, sizeof(pdu));
break;
+ case NOTIFY_ALERT_STATUS:
+ len = enc_notification(al_adapter->hnd_value[type],
+ &alert_status, sizeof(alert_status),
+ pdu, sizeof(pdu));
+ break;
default:
DBG("Unknown type, could not send notification");
goto end;
@@ -499,10 +505,14 @@ static void update_phone_alerts(const char *category, const char *description)
for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
if (g_str_equal(pasp_categories[i], category)) {
- if (g_str_equal(description, "active"))
+ if (g_str_equal(description, "active")) {
alert_status |= (1 << i);
- else if (g_str_equal(description, "not active"))
+ pasp_notification(NOTIFY_ALERT_STATUS);
+ } else if (g_str_equal(description, "not active")) {
alert_status &= ~(1 << i);
+ pasp_notification(NOTIFY_ALERT_STATUS);
+ }
+ break;
}
}
}
@@ -755,6 +765,10 @@ static void register_phone_alert_service(struct alert_adapter *al_adapter)
ATT_CHAR_PROPER_NOTIFY,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
alert_status_read, al_adapter->adapter,
+ GATT_OPT_CCC_GET_HANDLE,
+ &al_adapter->hnd_ccc[NOTIFY_ALERT_STATUS],
+ GATT_OPT_CHR_VALUE_GET_HANDLE,
+ &al_adapter->hnd_value[NOTIFY_ALERT_STATUS],
/* Ringer Control Point characteristic */
GATT_OPT_CHR_UUID, RINGER_CP_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 22/27] alert: Add support for ringer setting notification
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
When the agent reports a ringer setting change, a ringer setting
notification is sent to the peer device (if notification is enabled).
---
profiles/alert/server.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 154 insertions(+), 2 deletions(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 95dee04..10c4160 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -31,6 +31,7 @@
#include <gdbus.h>
#include <glib.h>
#include <bluetooth/uuid.h>
+#include <stdlib.h>
#include "dbus-common.h"
#include "att.h"
@@ -45,6 +46,8 @@
#include "server.h"
#include "profile.h"
#include "error.h"
+#include "textfile.h"
+#include "attio.h"
#define PHONE_ALERT_STATUS_SVC_UUID 0x180E
#define ALERT_NOTIF_SVC_UUID 0x1811
@@ -89,6 +92,11 @@ enum {
RINGER_NORMAL,
};
+enum notify_type {
+ NOTIFY_RINGER_SETTING = 0,
+ NOTIFY_SIZE,
+};
+
struct alert_data {
const char *category;
char *srv;
@@ -102,6 +110,21 @@ struct alert_adapter {
uint16_t supp_unread_alert_cat_handle;
uint16_t new_alert_handle;
uint16_t unread_alert_handle;
+ uint16_t hnd_ccc[NOTIFY_SIZE];
+ uint16_t hnd_value[NOTIFY_SIZE];
+};
+
+struct notify_data {
+ struct alert_adapter *al_adapter;
+ enum notify_type type;
+ uint8_t *value;
+ size_t len;
+};
+
+struct notify_callback {
+ struct notify_data *notify_data;
+ struct btd_device *device;
+ guint id;
};
static GSList *registered_alerts = NULL;
@@ -282,6 +305,125 @@ static void watcher_disconnect(DBusConnection *conn, void *user_data)
g_slist_foreach(alert_adapters, update_supported_categories, NULL);
}
+static struct btd_device *get_notifiable_device(struct btd_adapter *adapter,
+ char *key, char *value,
+ uint16_t ccc)
+{
+ struct btd_device *device;
+ char addr[18];
+ uint16_t hnd, val;
+ uint8_t bdaddr_type;
+
+ sscanf(key, "%17s#%hhu#%04hX", addr, &bdaddr_type, &hnd);
+
+ if (hnd != ccc)
+ return NULL;
+
+ val = strtol(value, NULL, 16);
+ if (!(val & 0x0001))
+ return NULL;
+
+ device = adapter_find_device(adapter, addr);
+ if (device == NULL)
+ return NULL;
+
+ return btd_device_ref(device);
+}
+
+static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
+{
+ struct notify_callback *cb = user_data;
+ struct notify_data *nd = cb->notify_data;
+ enum notify_type type = nd->type;
+ struct alert_adapter *al_adapter = nd->al_adapter;
+ uint8_t pdu[ATT_MAX_MTU];
+ size_t len = 0;
+
+ switch (type) {
+ case NOTIFY_RINGER_SETTING:
+ len = enc_notification(al_adapter->hnd_value[type],
+ &ringer_setting, sizeof(ringer_setting),
+ pdu, sizeof(pdu));
+ break;
+ default:
+ DBG("Unknown type, could not send notification");
+ goto end;
+ }
+
+ DBG("Send notification for handle: 0x%04x, ccc: 0x%04x",
+ al_adapter->hnd_value[type],
+ al_adapter->hnd_ccc[type]);
+
+ g_attrib_send(attrib, 0, ATT_OP_HANDLE_NOTIFY, pdu, len,
+ NULL, NULL, NULL);
+
+end:
+ btd_device_remove_attio_callback(cb->device, cb->id);
+ btd_device_unref(cb->device);
+ g_free(cb->notify_data->value);
+ g_free(cb->notify_data);
+ g_free(cb);
+}
+
+static void filter_devices_notify(char *key, char *value, void *user_data)
+{
+ struct notify_data *notify_data = user_data;
+ struct alert_adapter *al_adapter = notify_data->al_adapter;
+ enum notify_type type = notify_data->type;
+ struct btd_device *device;
+ struct notify_callback *cb;
+
+ device = get_notifiable_device(al_adapter->adapter, key, value,
+ al_adapter->hnd_ccc[type]);
+ if (device == NULL)
+ return;
+
+ cb = g_new0(struct notify_callback, 1);
+ cb->notify_data = notify_data;
+ cb->device = device;
+ cb->id = btd_device_add_attio_callback(device,
+ attio_connected_cb, NULL, cb);
+}
+
+static void create_filename(char *filename, struct btd_adapter *adapter)
+{
+ char srcaddr[18];
+ bdaddr_t src;
+
+ adapter_get_address(adapter, &src);
+ ba2str(&src, srcaddr);
+
+ create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "ccc");
+}
+
+static void notify_devices(struct alert_adapter *al_adapter,
+ enum notify_type type, uint8_t *value, size_t len)
+{
+ struct notify_data *notify_data;
+ char filename[PATH_MAX + 1];
+
+ notify_data = g_new0(struct notify_data, 1);
+ notify_data->al_adapter = al_adapter;
+ notify_data->type = type;
+ notify_data->value = g_memdup(value, len);
+ notify_data->len = len;
+
+ create_filename(filename, al_adapter->adapter);
+ textfile_foreach(filename, filter_devices_notify, notify_data);
+}
+
+static void pasp_notification(enum notify_type type)
+{
+ GSList *it;
+ struct alert_adapter *al_adapter;
+
+ for (it = alert_adapters; it; it = g_slist_next(it)) {
+ al_adapter = it->data;
+
+ notify_devices(al_adapter, type, NULL, 0);
+ }
+}
+
static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -344,10 +486,15 @@ static void update_phone_alerts(const char *category, const char *description)
unsigned int i;
if (g_str_equal(category, "ringer")) {
- if (g_str_equal(description, "enabled"))
+ if (g_str_equal(description, "enabled")) {
ringer_setting = RINGER_NORMAL;
- else if (g_str_equal(description, "disabled"))
+ pasp_notification(NOTIFY_RINGER_SETTING);
+ return;
+ } else if (g_str_equal(description, "disabled")) {
ringer_setting = RINGER_SILENT;
+ pasp_notification(NOTIFY_RINGER_SETTING);
+ return;
+ }
}
for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
@@ -619,6 +766,10 @@ static void register_phone_alert_service(struct alert_adapter *al_adapter)
ATT_CHAR_PROPER_NOTIFY,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
ringer_setting_read, al_adapter->adapter,
+ GATT_OPT_CCC_GET_HANDLE,
+ &al_adapter->hnd_ccc[NOTIFY_RINGER_SETTING],
+ GATT_OPT_CHR_VALUE_GET_HANDLE,
+ &al_adapter->hnd_value[NOTIFY_RINGER_SETTING],
GATT_OPT_INVALID);
}
@@ -753,6 +904,7 @@ static void alert_server_remove(struct btd_profile *p,
alert_adapters = g_slist_remove(alert_adapters, al_adapter);
btd_adapter_unref(al_adapter->adapter);
+
g_free(al_adapter);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 21/27] alert: Update Alert Status and Ringer Setting characteristic values
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
Now these characteristic values are updated when the agent changes any
PASP alert state or setting.
---
profiles/alert/server.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 6592913..95dee04 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -339,6 +339,27 @@ static void update_new_alert(gpointer data, gpointer user_data)
value[0], NULL);
}
+static void update_phone_alerts(const char *category, const char *description)
+{
+ unsigned int i;
+
+ if (g_str_equal(category, "ringer")) {
+ if (g_str_equal(description, "enabled"))
+ ringer_setting = RINGER_NORMAL;
+ else if (g_str_equal(description, "disabled"))
+ ringer_setting = RINGER_SILENT;
+ }
+
+ for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
+ if (g_str_equal(pasp_categories[i], category)) {
+ if (g_str_equal(description, "active"))
+ alert_status |= (1 << i);
+ else if (g_str_equal(description, "not active"))
+ alert_status &= ~(1 << i);
+ }
+ }
+}
+
static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -399,6 +420,9 @@ static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
}
}
+ if (pasp_category(category))
+ update_phone_alerts(category, description);
+
DBG("NewAlert(\"%s\", %d, \"%s\")", category, count, description);
return dbus_message_new_method_return(msg);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 20/27] alert: Add test-alert script
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
This script is useful for testing the Alert API and testing the
implementation with PTS.
---
Makefile.tools | 2 +-
test/test-alert | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 174 insertions(+), 1 deletion(-)
create mode 100755 test/test-alert
diff --git a/Makefile.tools b/Makefile.tools
index 9637a9f..a83ed3f 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -213,4 +213,4 @@ EXTRA_DIST += test/sap_client.py test/hsplay test/hsmicro \
test/test-health test/test-health-sink test/service-record.dtd \
test/service-did.xml test/service-spp.xml test/service-opp.xml \
test/service-ftp.xml test/simple-player test/test-nap \
- test/test-heartrate
+ test/test-heartrate test/test-alert
diff --git a/test/test-alert b/test/test-alert
new file mode 100755
index 0000000..c92a719
--- /dev/null
+++ b/test/test-alert
@@ -0,0 +1,173 @@
+#!/usr/bin/python
+from __future__ import absolute_import, print_function, unicode_literals
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+import gobject
+import optparse
+import sys
+import os
+
+BUS_NAME = 'org.bluez'
+ALERT_INTERFACE = 'org.bluez.Alert'
+ALERT_AGENT_INTERFACE = 'org.bluez.AlertAgent'
+BLUEZ_OBJECT_PATH = '/org/bluez'
+TEST_OBJECT_PATH = '/org/bluez/test'
+
+class AlertAgent(dbus.service.Object):
+ def __init__(self, bus, object_path, alert):
+ dbus.service.Object.__init__(self, bus, object_path)
+ self.alert = alert
+
+ @dbus.service.method(ALERT_AGENT_INTERFACE, in_signature='',
+ out_signature='')
+ def MuteOnce(self):
+ print('method MuteOnce() was called')
+ self.alert.NewAlert('ringer', 1, 'not active')
+
+ @dbus.service.method(ALERT_AGENT_INTERFACE, in_signature='s',
+ out_signature='')
+ def SetRinger(self, mode):
+ print('method SetRinger(%s) was called' % mode)
+ self.alert.NewAlert('ringer', 1, mode)
+
+def print_command_line(options):
+ if not options.verbose:
+ return False
+
+ print('-w: ' + str(options.wait))
+
+ if options.times:
+ print('-t: ' + str(options.times))
+
+ if options.register:
+ print('-r: ' + options.register)
+ else:
+ print('-r: ' + str(None))
+
+ if options.new_alert:
+ print('-n:')
+ for i in options.new_alert:
+ print(' ' + i[0] + ', ' + i[1] + ', ' + i[2])
+ else:
+ print('-n: ' + str(None))
+
+ if options.unread_alert:
+ print('-u:')
+ for i in options.unread_alert:
+ print(' ' + i[0] + ', ' + i[1])
+ else:
+ print('-u: ' + str(None))
+
+ print()
+
+ return True
+
+def read_count(param):
+ try:
+ return int(param)
+ except ValueError:
+ print('<count> must be integer, not \"%s\"' % param)
+ sys.exit(1)
+
+def new_alert(alert, params):
+ if not params:
+ return False
+
+ for param in params:
+ category = param[0]
+ count = read_count(param[1])
+ description = param[2]
+
+ alert.NewAlert(category, count, description)
+
+def unread_alert(alert, params):
+ if not params:
+ return False
+
+ for param in params:
+ category = param[0]
+ count = read_count(param[1])
+
+ alert.UnreadAlert(category, count)
+
+option_list = [
+ optparse.make_option('-v', None,
+ action = 'store_true',
+ default = False,
+ dest = 'verbose',
+ help = 'verbose'),
+
+ optparse.make_option('-w', None,
+ action = 'store_true',
+ default = False,
+ dest = 'wait',
+ help = 'wait for dbus events'),
+
+ optparse.make_option('-t', None,
+ action = 'store',
+ default = 1,
+ type = "int",
+ dest = 'times',
+ help = 'repeat UnreadAlert/NewAlert <times> times',
+ metavar = '<times>'),
+
+ optparse.make_option('-r', None,
+ action = 'store',
+ dest = 'register',
+ type = 'string',
+ metavar = '<category>',
+ help = 'register alert'),
+
+ optparse.make_option('-n', None,
+ action = 'append',
+ dest = 'new_alert',
+ type = 'string',
+ nargs = 3,
+ metavar = '<category> <count> <description>',
+ help = 'send new alert'),
+
+ optparse.make_option('-u', None,
+ action = 'append',
+ dest = 'unread_alert',
+ type = 'string',
+ nargs = 2,
+ metavar = '<category> <count>',
+ help = 'send unread alert'),
+]
+
+parser = optparse.OptionParser(option_list=option_list)
+parser.disable_interspersed_args()
+(options, args) = parser.parse_args()
+
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+bus = dbus.SystemBus()
+mainloop = gobject.MainLoop()
+alert = dbus.Interface(bus.get_object(BUS_NAME, BLUEZ_OBJECT_PATH),
+ ALERT_INTERFACE)
+alert_agent = AlertAgent(bus, TEST_OBJECT_PATH, alert)
+
+print_command_line(options)
+
+if not (options.register or options.new_alert or options.unread_alert or
+ options.wait):
+ parser.print_usage()
+ sys.exit(1)
+
+if options.register:
+ alert.RegisterAlert(options.register, TEST_OBJECT_PATH)
+
+times = 0
+while times < options.times:
+ times += 1
+
+ new_alert(alert, options.new_alert)
+ unread_alert(alert, options.unread_alert)
+
+if not options.wait:
+ sys.exit(0)
+
+try:
+ mainloop.run()
+except:
+ pass
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 19/27] alert: Add support for calling SetRinger()
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
When BlueZ wants to call SetRinger() method from org.bluez.AlertAgent
interface for a registered agent, the function agent_ringer_set_ringer()
must be called.
---
profiles/alert/server.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index d18140f..6592913 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -426,6 +426,31 @@ static int agent_ringer_mute_once(void)
return 0;
}
+static int agent_ringer_set_ringer(const char *mode)
+{
+ struct alert_data *alert;
+ DBusMessage *msg;
+
+ alert = get_alert_data_by_category("ringer");
+ if (!alert) {
+ DBG("Category ringer is not registered");
+ return -EINVAL;
+ }
+
+ msg = dbus_message_new_method_call(alert->srv, alert->path,
+ ALERT_AGENT_INTERFACE, "SetRinger");
+ if (!msg)
+ return -ENOMEM;
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &mode,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+ g_dbus_send_message(btd_get_dbus_connection(), msg);
+
+ return 0;
+}
+
static void update_unread_alert(gpointer data, gpointer user_data)
{
struct alert_adapter *al_adapter = data;
@@ -498,6 +523,7 @@ static uint8_t ringer_cp_write(struct attribute *a,
switch (a->data[0]) {
case RINGER_SILENT_MODE:
DBG("Silent Mode");
+ agent_ringer_set_ringer("disabled");
break;
case RINGER_MUTE_ONCE:
DBG("Mute Once");
@@ -505,6 +531,7 @@ static uint8_t ringer_cp_write(struct attribute *a,
break;
case RINGER_CANCEL_SILENT_MODE:
DBG("Cancel Silent Mode");
+ agent_ringer_set_ringer("enabled");
break;
default:
DBG("Invalid command (0x%02x)", a->data[0]);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 18/27] alert: Add support for calling MuteOnce()
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
When BlueZ wants to call MuteOnce() method from org.bluez.AlertAgent
interface for a registered agent, the function agent_ringer_mute_once()
must be called.
---
profiles/alert/server.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index f021c07..d18140f 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -61,6 +61,7 @@
#define ALERT_OBJECT_PATH "/org/bluez"
#define ALERT_INTERFACE "org.bluez.Alert"
+#define ALERT_AGENT_INTERFACE "org.bluez.AlertAgent"
/* Maximum length for "Text String Information" */
#define NEW_ALERT_MAX_INFO_SIZE 18
@@ -403,6 +404,28 @@ static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}
+static int agent_ringer_mute_once(void)
+{
+ struct alert_data *alert;
+ DBusMessage *msg;
+
+ alert = get_alert_data_by_category("ringer");
+ if (!alert) {
+ DBG("Category ringer is not registered");
+ return -EINVAL;
+ }
+
+ msg = dbus_message_new_method_call(alert->srv, alert->path,
+ ALERT_AGENT_INTERFACE, "MuteOnce");
+ if (!msg)
+ return -ENOMEM;
+
+ dbus_message_set_no_reply(msg, TRUE);
+ g_dbus_send_message(btd_get_dbus_connection(), msg);
+
+ return 0;
+}
+
static void update_unread_alert(gpointer data, gpointer user_data)
{
struct alert_adapter *al_adapter = data;
@@ -478,6 +501,7 @@ static uint8_t ringer_cp_write(struct attribute *a,
break;
case RINGER_MUTE_ONCE:
DBG("Mute Once");
+ agent_ringer_mute_once();
break;
case RINGER_CANCEL_SILENT_MODE:
DBG("Cancel Silent Mode");
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 17/27] alert: Implement MuteOnce command
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
MuteOnce() is called by BlueZ to instruct the agent to mute the ringer
during a incoming call.
---
profiles/alert/server.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index e289dfc..f021c07 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -76,6 +76,12 @@ enum {
NOTIFY_UNREAD_CAT,
};
+enum {
+ RINGER_SILENT_MODE = 1,
+ RINGER_MUTE_ONCE,
+ RINGER_CANCEL_SILENT_MODE,
+};
+
/* Ringer Setting characteristic values */
enum {
RINGER_SILENT,
@@ -461,6 +467,25 @@ static uint8_t ringer_cp_write(struct attribute *a,
{
DBG("a = %p", a);
+ if (a->len > 1) {
+ DBG("Invalid command size (%zu)", a->len);
+ return 0;
+ }
+
+ switch (a->data[0]) {
+ case RINGER_SILENT_MODE:
+ DBG("Silent Mode");
+ break;
+ case RINGER_MUTE_ONCE:
+ DBG("Mute Once");
+ break;
+ case RINGER_CANCEL_SILENT_MODE:
+ DBG("Cancel Silent Mode");
+ break;
+ default:
+ DBG("Invalid command (0x%02x)", a->data[0]);
+ }
+
return 0;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 16/27] alert: Update unread alert characteristic value
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
Update the attribute value when the unread alert count is changed.
---
profiles/alert/server.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 73da8b8..e289dfc 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -94,6 +94,7 @@ struct alert_adapter {
uint16_t supp_new_alert_cat_handle;
uint16_t supp_unread_alert_cat_handle;
uint16_t new_alert_handle;
+ uint16_t unread_alert_handle;
};
static GSList *registered_alerts = NULL;
@@ -396,12 +397,23 @@ static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}
+static void update_unread_alert(gpointer data, gpointer user_data)
+{
+ struct alert_adapter *al_adapter = data;
+ struct btd_adapter *adapter = al_adapter->adapter;
+ uint8_t *value = user_data;
+
+ attrib_db_update(adapter, al_adapter->unread_alert_handle, NULL, value,
+ 2, NULL);
+}
+
static DBusMessage *unread_alert(DBusConnection *conn, DBusMessage *msg,
void *data)
{
const char *sender = dbus_message_get_sender(msg);
struct alert_data *alert;
const char *category;
+ unsigned int i;
uint16_t count;
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &category,
@@ -415,12 +427,29 @@ static DBusMessage *unread_alert(DBusConnection *conn, DBusMessage *msg,
return btd_error_invalid_args(msg);
}
+ if (!valid_count(category, count)) {
+ DBG("Count %d is invalid for %s category", count, category);
+ return btd_error_invalid_args(msg);
+ }
+
if (!g_str_equal(alert->srv, sender)) {
DBG("Sender %s is not registered in category %s", sender,
category);
return btd_error_invalid_args(msg);
}
+ for (i = 0; i < G_N_ELEMENTS(anp_categories); i++) {
+ if (g_str_equal(anp_categories[i], category)) {
+ uint8_t value[2];
+
+ value[0] = i; /* Category ID */
+ value[1] = count; /* Unread count */
+
+ g_slist_foreach(alert_adapters, update_unread_alert,
+ value);
+ }
+ }
+
DBG("category %s, count %d", category, count);
return dbus_message_new_method_return(msg);
@@ -587,6 +616,8 @@ static void register_alert_notif_service(struct alert_adapter *al_adapter)
/* Unread Alert Status */
GATT_OPT_CHR_UUID, UNREAD_ALERT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
+ GATT_OPT_CHR_VALUE_GET_HANDLE,
+ &al_adapter->unread_alert_handle,
/* Alert Notification Control Point */
GATT_OPT_CHR_UUID, ALERT_NOTIF_CP_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 15/27] alert: Update new alert characteristic value
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
Update the attribute value when a new alert is reported to BlueZ.
---
profiles/alert/server.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 8d0635a..73da8b8 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -64,6 +64,8 @@
/* Maximum length for "Text String Information" */
#define NEW_ALERT_MAX_INFO_SIZE 18
+/* Maximum length for New Alert Characteristic Value */
+#define NEW_ALERT_CHR_MAX_VALUE_SIZE (NEW_ALERT_MAX_INFO_SIZE + 2)
enum {
ENABLE_NEW_INCOMING,
@@ -91,6 +93,7 @@ struct alert_adapter {
struct btd_adapter *adapter;
uint16_t supp_new_alert_cat_handle;
uint16_t supp_unread_alert_cat_handle;
+ uint16_t new_alert_handle;
};
static GSList *registered_alerts = NULL;
@@ -318,6 +321,16 @@ static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}
+static void update_new_alert(gpointer data, gpointer user_data)
+{
+ struct alert_adapter *al_adapter = data;
+ struct btd_adapter *adapter = al_adapter->adapter;
+ uint8_t *value = user_data;
+
+ attrib_db_update(adapter, al_adapter->new_alert_handle, NULL, &value[1],
+ value[0], NULL);
+}
+
static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -325,6 +338,7 @@ static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
const char *category, *description;
struct alert_data *alert;
uint16_t count;
+ unsigned int i;
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &category,
DBUS_TYPE_UINT16, &count, DBUS_TYPE_STRING,
@@ -354,6 +368,29 @@ static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
return btd_error_invalid_args(msg);
}
+ for (i = 0; i < G_N_ELEMENTS(anp_categories); i++) {
+ if (g_str_equal(anp_categories[i], category)) {
+ uint8_t value[NEW_ALERT_CHR_MAX_VALUE_SIZE + 1];
+ size_t dlen = strlen(description);
+ uint8_t *ptr = value;
+
+ memset(value, 0, sizeof(value));
+
+ *ptr++ = 2; /* Attribute value size */
+ *ptr++ = i; /* Category ID (mandatory) */
+ *ptr++ = count; /* Number of New Alert (mandatory) */
+ /* Text String Information (optional) */
+ strncpy((char *) ptr, description,
+ NEW_ALERT_MAX_INFO_SIZE - 1);
+
+ if (dlen > 0)
+ *value += dlen + 1;
+
+ g_slist_foreach(alert_adapters, update_new_alert,
+ value);
+ }
+ }
+
DBG("NewAlert(\"%s\", %d, \"%s\")", category, count, description);
return dbus_message_new_method_return(msg);
@@ -538,6 +575,8 @@ static void register_alert_notif_service(struct alert_adapter *al_adapter)
/* New Alert */
GATT_OPT_CHR_UUID, NEW_ALERT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
+ GATT_OPT_CHR_VALUE_GET_HANDLE,
+ &al_adapter->new_alert_handle,
/* Supported Unread Alert Category */
GATT_OPT_CHR_UUID, SUPP_UNREAD_ALERT_CAT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 14/27] alert: Update Supported New/Unread Category characteristic values
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
The value is now kept up-to-date when new/unread alerts arrive. This
value is not notified yet.
---
profiles/alert/server.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 6f59f59..8d0635a 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -89,7 +89,8 @@ struct alert_data {
struct alert_adapter {
struct btd_adapter *adapter;
- /* TODO: store characteristic value handles */
+ uint16_t supp_new_alert_cat_handle;
+ uint16_t supp_unread_alert_cat_handle;
};
static GSList *registered_alerts = NULL;
@@ -235,6 +236,29 @@ static gboolean valid_count(const char *category, uint16_t count)
return FALSE;
}
+static void update_supported_categories(gpointer data, gpointer user_data)
+{
+ struct alert_adapter *al_adapter = data;
+ struct btd_adapter *adapter = al_adapter->adapter;
+ uint8_t value[2];
+ unsigned int i;
+
+ memset(value, 0, sizeof(value));
+
+ for (i = 0; i < G_N_ELEMENTS(anp_categories); i++) {
+ if (registered_category(anp_categories[i]))
+ hci_set_bit(i, value);
+ }
+
+ attrib_db_update(adapter, al_adapter->supp_new_alert_cat_handle, NULL,
+ value, sizeof(value), NULL);
+
+ /* FIXME: For now report all registered categories as supporting unread
+ * status, until it is known which ones should be supported */
+ attrib_db_update(adapter, al_adapter->supp_unread_alert_cat_handle,
+ NULL, value, sizeof(value), NULL);
+}
+
static void watcher_disconnect(DBusConnection *conn, void *user_data)
{
struct alert_data *alert = user_data;
@@ -243,6 +267,8 @@ static void watcher_disconnect(DBusConnection *conn, void *user_data)
registered_alerts = g_slist_remove(registered_alerts, alert);
alert_data_destroy(alert);
+
+ g_slist_foreach(alert_adapters, update_supported_categories, NULL);
}
static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
@@ -285,6 +311,8 @@ static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
registered_alerts = g_slist_append(registered_alerts, alert);
+ g_slist_foreach(alert_adapters, update_supported_categories, NULL);
+
DBG("RegisterAlert(\"%s\", \"%s\")", alert->category, alert->path);
return dbus_message_new_method_return(msg);
@@ -505,6 +533,8 @@ static void register_alert_notif_service(struct alert_adapter *al_adapter)
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
supp_new_alert_cat_read, al_adapter->adapter,
+ GATT_OPT_CHR_VALUE_GET_HANDLE,
+ &al_adapter->supp_new_alert_cat_handle,
/* New Alert */
GATT_OPT_CHR_UUID, NEW_ALERT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
@@ -513,6 +543,8 @@ static void register_alert_notif_service(struct alert_adapter *al_adapter)
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
supp_unread_alert_cat_read, al_adapter->adapter,
+ GATT_OPT_CHR_VALUE_GET_HANDLE,
+ &al_adapter->supp_unread_alert_cat_handle,
/* Unread Alert Status */
GATT_OPT_CHR_UUID, UNREAD_ALERT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 13/27] alert: Add per adapter attribute handle information
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
Each adapter may have different GATT services running, therefore any
attribute handles (e.g. for updating characteristic values) need to be
saved per adapter.
---
profiles/alert/server.c | 57 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 47 insertions(+), 10 deletions(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 7622da0..6f59f59 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -87,7 +87,13 @@ struct alert_data {
guint watcher;
};
+struct alert_adapter {
+ struct btd_adapter *adapter;
+ /* TODO: store characteristic value handles */
+};
+
static GSList *registered_alerts = NULL;
+static GSList *alert_adapters = NULL;
static uint8_t ringer_setting = RINGER_NORMAL;
static uint8_t alert_status = 0;
@@ -110,6 +116,21 @@ static const char * const pasp_categories[] = {
"display",
};
+static int adapter_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct alert_adapter *al_adapter = a;
+ const struct btd_adapter *adapter = b;
+
+ return al_adapter->adapter == adapter ? 0 : -1;
+}
+
+static struct alert_adapter *find_alert_adapter(struct btd_adapter *adapter)
+{
+ GSList *l = g_slist_find_custom(alert_adapters, adapter, adapter_cmp);
+
+ return l ? l->data : NULL;
+}
+
static void alert_data_destroy(gpointer user_data)
{
struct alert_data *alert = user_data;
@@ -379,20 +400,20 @@ static uint8_t ringer_setting_read(struct attribute *a,
return 0;
}
-static void register_phone_alert_service(struct btd_adapter *adapter)
+static void register_phone_alert_service(struct alert_adapter *al_adapter)
{
bt_uuid_t uuid;
bt_uuid16_create(&uuid, PHONE_ALERT_STATUS_SVC_UUID);
/* Phone Alert Status Service */
- gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+ gatt_service_add(al_adapter->adapter, GATT_PRIM_SVC_UUID, &uuid,
/* Alert Status characteristic */
GATT_OPT_CHR_UUID, ALERT_STATUS_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
ATT_CHAR_PROPER_NOTIFY,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
- alert_status_read, adapter,
+ alert_status_read, al_adapter->adapter,
/* Ringer Control Point characteristic */
GATT_OPT_CHR_UUID, RINGER_CP_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
@@ -403,7 +424,7 @@ static void register_phone_alert_service(struct btd_adapter *adapter)
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
ATT_CHAR_PROPER_NOTIFY,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
- ringer_setting_read, adapter,
+ ringer_setting_read, al_adapter->adapter,
GATT_OPT_INVALID);
}
@@ -471,19 +492,19 @@ static uint8_t alert_notif_cp_write(struct attribute *a,
return 0;
}
-static void register_alert_notif_service(struct btd_adapter *adapter)
+static void register_alert_notif_service(struct alert_adapter *al_adapter)
{
bt_uuid_t uuid;
bt_uuid16_create(&uuid, ALERT_NOTIF_SVC_UUID);
/* Alert Notification Service */
- gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+ gatt_service_add(al_adapter->adapter, GATT_PRIM_SVC_UUID, &uuid,
/* Supported New Alert Category */
GATT_OPT_CHR_UUID, SUPP_NEW_ALERT_CAT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
- supp_new_alert_cat_read, adapter,
+ supp_new_alert_cat_read, al_adapter->adapter,
/* New Alert */
GATT_OPT_CHR_UUID, NEW_ALERT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
@@ -491,7 +512,7 @@ static void register_alert_notif_service(struct btd_adapter *adapter)
GATT_OPT_CHR_UUID, SUPP_UNREAD_ALERT_CAT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
- supp_unread_alert_cat_read, adapter,
+ supp_unread_alert_cat_read, al_adapter->adapter,
/* Unread Alert Status */
GATT_OPT_CHR_UUID, UNREAD_ALERT_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
@@ -506,8 +527,15 @@ static void register_alert_notif_service(struct btd_adapter *adapter)
static int alert_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
- register_phone_alert_service(adapter);
- register_alert_notif_service(adapter);
+ struct alert_adapter *al_adapter;
+
+ al_adapter = g_new0(struct alert_adapter, 1);
+ al_adapter->adapter = btd_adapter_ref(adapter);
+
+ alert_adapters = g_slist_append(alert_adapters, al_adapter);
+
+ register_phone_alert_service(al_adapter);
+ register_alert_notif_service(al_adapter);
return 0;
}
@@ -515,6 +543,15 @@ static int alert_server_probe(struct btd_profile *p,
static void alert_server_remove(struct btd_profile *p,
struct btd_adapter *adapter)
{
+ struct alert_adapter *al_adapter;
+
+ al_adapter = find_alert_adapter(adapter);
+ if (!al_adapter)
+ return;
+
+ alert_adapters = g_slist_remove(alert_adapters, al_adapter);
+ btd_adapter_unref(al_adapter->adapter);
+ g_free(al_adapter);
}
static struct btd_profile alert_profile = {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 12/27] alert: Automatically unregister alert when agent leaves D-Bus
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
---
profiles/alert/server.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 2dbc3b7..7622da0 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -84,6 +84,7 @@ struct alert_data {
const char *category;
char *srv;
char *path;
+ guint watcher;
};
static GSList *registered_alerts = NULL;
@@ -113,6 +114,9 @@ static void alert_data_destroy(gpointer user_data)
{
struct alert_data *alert = user_data;
+ if (alert->watcher)
+ g_dbus_remove_watch(btd_get_dbus_connection(), alert->watcher);
+
g_free(alert->srv);
g_free(alert->path);
g_free(alert);
@@ -210,6 +214,16 @@ static gboolean valid_count(const char *category, uint16_t count)
return FALSE;
}
+static void watcher_disconnect(DBusConnection *conn, void *user_data)
+{
+ struct alert_data *alert = user_data;
+
+ DBG("Category %s was disconnected", alert->category);
+
+ registered_alerts = g_slist_remove(registered_alerts, alert);
+ alert_data_destroy(alert);
+}
+
static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -238,6 +252,15 @@ static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
alert->srv = g_strdup(sender);
alert->path = g_strdup(path);
alert->category = category;
+ alert->watcher = g_dbus_add_disconnect_watch(conn, alert->srv,
+ watcher_disconnect, alert, NULL);
+
+ if (alert->watcher == 0) {
+ alert_data_destroy(alert);
+ DBG("Could not register disconnect watcher");
+ return btd_error_failed(msg,
+ "Could not register disconnect watcher");
+ }
registered_alerts = g_slist_append(registered_alerts, alert);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 11/27] alert: Add initial support for UnreadAlert D-Bus method
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
This method is used for updating the "unread" counter for categories
that support it.
---
profiles/alert/server.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 06370e4..2dbc3b7 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -287,6 +287,36 @@ static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}
+static DBusMessage *unread_alert(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ const char *sender = dbus_message_get_sender(msg);
+ struct alert_data *alert;
+ const char *category;
+ uint16_t count;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &category,
+ DBUS_TYPE_UINT16, &count,
+ DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
+
+ alert = get_alert_data_by_category(category);
+ if (!alert) {
+ DBG("Category %s not registered", category);
+ return btd_error_invalid_args(msg);
+ }
+
+ if (!g_str_equal(alert->srv, sender)) {
+ DBG("Sender %s is not registered in category %s", sender,
+ category);
+ return btd_error_invalid_args(msg);
+ }
+
+ DBG("category %s, count %d", category, count);
+
+ return dbus_message_new_method_return(msg);
+}
+
static uint8_t ringer_cp_write(struct attribute *a,
struct btd_device *device,
gpointer user_data)
@@ -480,6 +510,9 @@ static const GDBusMethodTable alert_methods[] = {
{ "count", "q" },
{ "description", "s" }), NULL,
new_alert) },
+ { GDBUS_METHOD("UnreadAlert",
+ GDBUS_ARGS({ "category", "s" }, { "count", "q" }), NULL,
+ unread_alert) },
{ }
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 10/27] alert: Add initial support for NewAlert D-Bus method
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
NewAlert() is used for notifying BlueZ of new alert(s) for the given
category.
---
profiles/alert/server.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 105 insertions(+), 1 deletion(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 77fd40b..06370e4 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -62,6 +62,9 @@
#define ALERT_OBJECT_PATH "/org/bluez"
#define ALERT_INTERFACE "org.bluez.Alert"
+/* Maximum length for "Text String Information" */
+#define NEW_ALERT_MAX_INFO_SIZE 18
+
enum {
ENABLE_NEW_INCOMING,
ENABLE_UNREAD_CAT,
@@ -138,7 +141,7 @@ static const char *valid_category(const char *category)
return NULL;
}
-static gboolean registered_category(const char *category)
+static struct alert_data *get_alert_data_by_category(const char *category)
{
GSList *l;
struct alert_data *alert;
@@ -146,9 +149,64 @@ static gboolean registered_category(const char *category)
for (l = registered_alerts; l; l = g_slist_next(l)) {
alert = l->data;
if (g_str_equal(alert->category, category))
+ return alert;
+ }
+
+ return NULL;
+}
+
+static gboolean registered_category(const char *category)
+{
+ struct alert_data *alert;
+
+ alert = get_alert_data_by_category(category);
+ if (alert)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean pasp_category(const char *category)
+{
+ unsigned i;
+
+ for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++)
+ if (g_str_equal(category, pasp_categories[i]))
return TRUE;
+
+ return FALSE;
+}
+
+static gboolean valid_description(const char *category,
+ const char *description)
+{
+ if (!pasp_category(category)) {
+ if (strlen(description) >= NEW_ALERT_MAX_INFO_SIZE)
+ return FALSE;
+
+ return TRUE;
}
+ if (g_str_equal(description, "active") ||
+ g_str_equal(description, "not active"))
+ return TRUE;
+
+ if (g_str_equal(category, "ringer"))
+ if (g_str_equal(description, "enabled") ||
+ g_str_equal(description, "disabled"))
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean valid_count(const char *category, uint16_t count)
+{
+ if (!pasp_category(category) && count > 0 && count <= 255)
+ return TRUE;
+
+ if (pasp_category(category) && count == 1)
+ return TRUE;
+
return FALSE;
}
@@ -188,6 +246,47 @@ static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}
+static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ const char *sender = dbus_message_get_sender(msg);
+ const char *category, *description;
+ struct alert_data *alert;
+ uint16_t count;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &category,
+ DBUS_TYPE_UINT16, &count, DBUS_TYPE_STRING,
+ &description, DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
+
+ alert = get_alert_data_by_category(category);
+ if (!alert) {
+ DBG("Category %s not registered", category);
+ return btd_error_invalid_args(msg);
+ }
+
+ if (!g_str_equal(alert->srv, sender)) {
+ DBG("Sender %s is not registered in category %s", sender,
+ category);
+ return btd_error_invalid_args(msg);
+ }
+
+ if (!valid_description(category, description)) {
+ DBG("Description %s is invalid for %s category",
+ description, category);
+ return btd_error_invalid_args(msg);
+ }
+
+ if (!valid_count(category, count)) {
+ DBG("Count %d is invalid for %s category", count, category);
+ return btd_error_invalid_args(msg);
+ }
+
+ DBG("NewAlert(\"%s\", %d, \"%s\")", category, count, description);
+
+ return dbus_message_new_method_return(msg);
+}
+
static uint8_t ringer_cp_write(struct attribute *a,
struct btd_device *device,
gpointer user_data)
@@ -376,6 +475,11 @@ static const GDBusMethodTable alert_methods[] = {
GDBUS_ARGS({ "category", "s" },
{ "agent", "o" }), NULL,
register_alert) },
+ { GDBUS_METHOD("NewAlert",
+ GDBUS_ARGS({ "category", "s" },
+ { "count", "q" },
+ { "description", "s" }), NULL,
+ new_alert) },
{ }
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 09/27] alert: Implement category registration in RegisterAlert()
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Eder Ruiz Maria <eder.ruiz@openbossa.org>
The given alert category is now validated and registered.
---
profiles/alert/server.c | 102 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 98 insertions(+), 4 deletions(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index c0434a4..77fd40b 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -77,19 +77,113 @@ enum {
RINGER_NORMAL,
};
+struct alert_data {
+ const char *category;
+ char *srv;
+ char *path;
+};
+
+static GSList *registered_alerts = NULL;
static uint8_t ringer_setting = RINGER_NORMAL;
static uint8_t alert_status = 0;
+static const char * const anp_categories[] = {
+ "simple",
+ "email",
+ "news",
+ "call",
+ "missed_call",
+ "sms_mms",
+ "voice_mail",
+ "schedule",
+ "high_priority",
+ "instant_message",
+};
+
+static const char * const pasp_categories[] = {
+ "ringer",
+ "vibrate",
+ "display",
+};
+
+static void alert_data_destroy(gpointer user_data)
+{
+ struct alert_data *alert = user_data;
+
+ g_free(alert->srv);
+ g_free(alert->path);
+ g_free(alert);
+}
+
+static void alert_destroy(gpointer user_data)
+{
+ g_slist_free_full(registered_alerts, alert_data_destroy);
+ registered_alerts = NULL;
+}
+
+static const char *valid_category(const char *category)
+{
+ unsigned i;
+
+ for (i = 0; i < G_N_ELEMENTS(anp_categories); i++) {
+ if (g_str_equal(anp_categories[i], category))
+ return anp_categories[i];
+ }
+
+ for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
+ if (g_str_equal(pasp_categories[i], category))
+ return pasp_categories[i];
+ }
+
+ return NULL;
+}
+
+static gboolean registered_category(const char *category)
+{
+ GSList *l;
+ struct alert_data *alert;
+
+ for (l = registered_alerts; l; l = g_slist_next(l)) {
+ alert = l->data;
+ if (g_str_equal(alert->category, category))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
void *data)
{
+ const char *sender = dbus_message_get_sender(msg);
+ char *path;
const char *category;
+ const char *c;
+ struct alert_data *alert;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &c,
+ DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
- if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &category,
- DBUS_TYPE_INVALID))
+ category = valid_category(c);
+ if (!category) {
+ DBG("Invalid category: %s", c);
return btd_error_invalid_args(msg);
+ }
+
+ if (registered_category(category)) {
+ DBG("Category %s already registered", category);
+ return dbus_message_new_method_return(msg);
+ }
+
+ alert = g_new0(struct alert_data, 1);
+ alert->srv = g_strdup(sender);
+ alert->path = g_strdup(path);
+ alert->category = category;
+
+ registered_alerts = g_slist_append(registered_alerts, alert);
- DBG("RegisterAlert: %s", category);
+ DBG("RegisterAlert(\"%s\", \"%s\")", alert->category, alert->path);
return dbus_message_new_method_return(msg);
}
@@ -290,7 +384,7 @@ int alert_server_init(void)
if (!g_dbus_register_interface(btd_get_dbus_connection(),
ALERT_OBJECT_PATH, ALERT_INTERFACE,
alert_methods, NULL, NULL, NULL,
- NULL)) {
+ alert_destroy)) {
error("D-Bus failed to register %s interface",
ALERT_INTERFACE);
return -EIO;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 08/27] alert: Initial Alert Notification
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
Initial implementation for Alert Notification Profile (ANP).
---
profiles/alert/server.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 154 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 90536d5..c0434a4 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -27,9 +27,12 @@
#endif
#include <stdbool.h>
+#include <errno.h>
+#include <gdbus.h>
#include <glib.h>
#include <bluetooth/uuid.h>
+#include "dbus-common.h"
#include "att.h"
#include "adapter.h"
#include "device.h"
@@ -41,13 +44,33 @@
#include "gatt.h"
#include "server.h"
#include "profile.h"
+#include "error.h"
#define PHONE_ALERT_STATUS_SVC_UUID 0x180E
+#define ALERT_NOTIF_SVC_UUID 0x1811
#define ALERT_STATUS_CHR_UUID 0x2A3F
#define RINGER_CP_CHR_UUID 0x2A40
#define RINGER_SETTING_CHR_UUID 0x2A41
+#define ALERT_NOTIF_CP_CHR_UUID 0x2A44
+#define UNREAD_ALERT_CHR_UUID 0x2A45
+#define NEW_ALERT_CHR_UUID 0x2A46
+#define SUPP_NEW_ALERT_CAT_CHR_UUID 0x2A47
+#define SUPP_UNREAD_ALERT_CAT_CHR_UUID 0x2A48
+
+#define ALERT_OBJECT_PATH "/org/bluez"
+#define ALERT_INTERFACE "org.bluez.Alert"
+
+enum {
+ ENABLE_NEW_INCOMING,
+ ENABLE_UNREAD_CAT,
+ DISABLE_NEW_INCOMING,
+ DISABLE_UNREAD_CAT,
+ NOTIFY_NEW_INCOMING,
+ NOTIFY_UNREAD_CAT,
+};
+
/* Ringer Setting characteristic values */
enum {
RINGER_SILENT,
@@ -57,6 +80,20 @@ enum {
static uint8_t ringer_setting = RINGER_NORMAL;
static uint8_t alert_status = 0;
+static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ const char *category;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &category,
+ DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
+
+ DBG("RegisterAlert: %s", category);
+
+ return dbus_message_new_method_return(msg);
+}
+
static uint8_t ringer_cp_write(struct attribute *a,
struct btd_device *device,
gpointer user_data)
@@ -124,10 +161,107 @@ static void register_phone_alert_service(struct btd_adapter *adapter)
GATT_OPT_INVALID);
}
+static uint8_t supp_new_alert_cat_read(struct attribute *a,
+ struct btd_device *device,
+ gpointer user_data)
+{
+ struct btd_adapter *adapter = user_data;
+ uint8_t value[] = {0x00, 0x00};
+
+ DBG("a = %p", a);
+
+ if (a->data == NULL)
+ attrib_db_update(adapter, a->handle, NULL, value, sizeof(value),
+ NULL);
+
+ return 0;
+}
+
+static uint8_t supp_unread_alert_cat_read(struct attribute *a,
+ struct btd_device *device,
+ gpointer user_data)
+{
+ struct btd_adapter *adapter = user_data;
+ uint8_t value[] = {0x00, 0x00};
+
+ DBG("a = %p", a);
+
+ if (a->data == NULL)
+ attrib_db_update(adapter, a->handle, NULL, value, sizeof(value),
+ NULL);
+
+ return 0;
+}
+
+static uint8_t alert_notif_cp_write(struct attribute *a,
+ struct btd_device *device,
+ gpointer user_data)
+{
+ DBG("a = %p", a);
+
+ switch (a->data[0]) {
+ case ENABLE_NEW_INCOMING:
+ DBG("ENABLE_NEW_INCOMING: 0x%02x", a->data[1]);
+ break;
+ case ENABLE_UNREAD_CAT:
+ DBG("ENABLE_UNREAD_CAT: 0x%02x", a->data[1]);
+ break;
+ case DISABLE_NEW_INCOMING:
+ DBG("DISABLE_NEW_INCOMING: 0x%02x", a->data[1]);
+ break;
+ case DISABLE_UNREAD_CAT:
+ DBG("DISABLE_UNREAD_CAT: 0x%02x", a->data[1]);
+ break;
+ case NOTIFY_NEW_INCOMING:
+ DBG("NOTIFY_NEW_INCOMING: 0x%02x", a->data[1]);
+ break;
+ case NOTIFY_UNREAD_CAT:
+ DBG("NOTIFY_UNREAD_CAT: 0x%02x", a->data[1]);
+ break;
+ default:
+ DBG("0x%02x 0x%02x", a->data[0], a->data[1]);
+ }
+
+ return 0;
+}
+
+static void register_alert_notif_service(struct btd_adapter *adapter)
+{
+ bt_uuid_t uuid;
+
+ bt_uuid16_create(&uuid, ALERT_NOTIF_SVC_UUID);
+
+ /* Alert Notification Service */
+ gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+ /* Supported New Alert Category */
+ GATT_OPT_CHR_UUID, SUPP_NEW_ALERT_CAT_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+ supp_new_alert_cat_read, adapter,
+ /* New Alert */
+ GATT_OPT_CHR_UUID, NEW_ALERT_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
+ /* Supported Unread Alert Category */
+ GATT_OPT_CHR_UUID, SUPP_UNREAD_ALERT_CAT_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+ supp_unread_alert_cat_read, adapter,
+ /* Unread Alert Status */
+ GATT_OPT_CHR_UUID, UNREAD_ALERT_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
+ /* Alert Notification Control Point */
+ GATT_OPT_CHR_UUID, ALERT_NOTIF_CP_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
+ alert_notif_cp_write, NULL,
+ GATT_OPT_INVALID);
+}
+
static int alert_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
register_phone_alert_service(adapter);
+ register_alert_notif_service(adapter);
return 0;
}
@@ -143,8 +277,25 @@ static struct btd_profile alert_profile = {
.adapter_remove = alert_server_remove,
};
+static const GDBusMethodTable alert_methods[] = {
+ { GDBUS_METHOD("RegisterAlert",
+ GDBUS_ARGS({ "category", "s" },
+ { "agent", "o" }), NULL,
+ register_alert) },
+ { }
+};
+
int alert_server_init(void)
{
+ if (!g_dbus_register_interface(btd_get_dbus_connection(),
+ ALERT_OBJECT_PATH, ALERT_INTERFACE,
+ alert_methods, NULL, NULL, NULL,
+ NULL)) {
+ error("D-Bus failed to register %s interface",
+ ALERT_INTERFACE);
+ return -EIO;
+ }
+
btd_profile_register(&alert_profile);
return 0;
@@ -153,4 +304,7 @@ int alert_server_init(void)
void alert_server_exit(void)
{
btd_profile_unregister(&alert_profile);
+
+ g_dbus_unregister_interface(btd_get_dbus_connection(),
+ ALERT_OBJECT_PATH, ALERT_INTERFACE);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 07/27] alert: Add Alert Status characteristic
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Bruna Moreira <bruna.moreira@openbossa.org>
This characteristic allows to read/notify the status of the ringer,
display and vibration motor.
---
profiles/alert/server.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 59e6fdc..90536d5 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -43,6 +43,8 @@
#include "profile.h"
#define PHONE_ALERT_STATUS_SVC_UUID 0x180E
+
+#define ALERT_STATUS_CHR_UUID 0x2A3F
#define RINGER_CP_CHR_UUID 0x2A40
#define RINGER_SETTING_CHR_UUID 0x2A41
@@ -53,6 +55,7 @@ enum {
};
static uint8_t ringer_setting = RINGER_NORMAL;
+static uint8_t alert_status = 0;
static uint8_t ringer_cp_write(struct attribute *a,
struct btd_device *device,
@@ -63,6 +66,21 @@ static uint8_t ringer_cp_write(struct attribute *a,
return 0;
}
+static uint8_t alert_status_read(struct attribute *a,
+ struct btd_device *device,
+ gpointer user_data)
+{
+ struct btd_adapter *adapter = user_data;
+
+ DBG("a = %p", a);
+
+ if (a->data == NULL || a->data[0] != alert_status)
+ attrib_db_update(adapter, a->handle, NULL, &alert_status,
+ sizeof(alert_status), NULL);
+
+ return 0;
+}
+
static uint8_t ringer_setting_read(struct attribute *a,
struct btd_device *device,
gpointer user_data)
@@ -86,6 +104,12 @@ static void register_phone_alert_service(struct btd_adapter *adapter)
/* Phone Alert Status Service */
gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+ /* Alert Status characteristic */
+ GATT_OPT_CHR_UUID, ALERT_STATUS_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
+ ATT_CHAR_PROPER_NOTIFY,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+ alert_status_read, adapter,
/* Ringer Control Point characteristic */
GATT_OPT_CHR_UUID, RINGER_CP_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 06/27] alert: Add Ringer Setting characteristic
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Bruna Moreira <bruna.moreira@openbossa.org>
This characteristic allows to read or notify the ringer mode (silent or
normal).
---
profiles/alert/server.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 8337c38..59e6fdc 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -37,12 +37,22 @@
#include "log.h"
#include "gatt-service.h"
#include "gattrib.h"
+#include "attrib-server.h"
#include "gatt.h"
#include "server.h"
#include "profile.h"
#define PHONE_ALERT_STATUS_SVC_UUID 0x180E
#define RINGER_CP_CHR_UUID 0x2A40
+#define RINGER_SETTING_CHR_UUID 0x2A41
+
+/* Ringer Setting characteristic values */
+enum {
+ RINGER_SILENT,
+ RINGER_NORMAL,
+};
+
+static uint8_t ringer_setting = RINGER_NORMAL;
static uint8_t ringer_cp_write(struct attribute *a,
struct btd_device *device,
@@ -53,6 +63,21 @@ static uint8_t ringer_cp_write(struct attribute *a,
return 0;
}
+static uint8_t ringer_setting_read(struct attribute *a,
+ struct btd_device *device,
+ gpointer user_data)
+{
+ struct btd_adapter *adapter = user_data;
+
+ DBG("a = %p", a);
+
+ if (a->data == NULL || a->data[0] != ringer_setting)
+ attrib_db_update(adapter, a->handle, NULL, &ringer_setting,
+ sizeof(ringer_setting), NULL);
+
+ return 0;
+}
+
static void register_phone_alert_service(struct btd_adapter *adapter)
{
bt_uuid_t uuid;
@@ -66,6 +91,12 @@ static void register_phone_alert_service(struct btd_adapter *adapter)
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
ringer_cp_write, NULL,
+ /* Ringer Setting characteristic */
+ GATT_OPT_CHR_UUID, RINGER_SETTING_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
+ ATT_CHAR_PROPER_NOTIFY,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+ ringer_setting_read, adapter,
GATT_OPT_INVALID);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 05/27] alert: Add Ringer Control Point characteristic
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Bruna Moreira <bruna.moreira@openbossa.org>
Ringer CP characteristic is used for configuring "silent mode" or muting
the ringer once.
---
profiles/alert/server.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index b39ef8a..8337c38 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -32,6 +32,9 @@
#include "att.h"
#include "adapter.h"
+#include "device.h"
+#include "att-database.h"
+#include "log.h"
#include "gatt-service.h"
#include "gattrib.h"
#include "gatt.h"
@@ -39,6 +42,16 @@
#include "profile.h"
#define PHONE_ALERT_STATUS_SVC_UUID 0x180E
+#define RINGER_CP_CHR_UUID 0x2A40
+
+static uint8_t ringer_cp_write(struct attribute *a,
+ struct btd_device *device,
+ gpointer user_data)
+{
+ DBG("a = %p", a);
+
+ return 0;
+}
static void register_phone_alert_service(struct btd_adapter *adapter)
{
@@ -48,6 +61,11 @@ static void register_phone_alert_service(struct btd_adapter *adapter)
/* Phone Alert Status Service */
gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+ /* Ringer Control Point characteristic */
+ GATT_OPT_CHR_UUID, RINGER_CP_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
+ ringer_cp_write, NULL,
GATT_OPT_INVALID);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 BlueZ 04/27] alert: Add Phone Alert Status Service
From: Anderson Lizardo @ 2012-10-02 20:24 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1349209490-31830-1-git-send-email-anderson.lizardo@openbossa.org>
From: Bruna Moreira <bruna.moreira@openbossa.org>
Add Phone Alert Status service for PASP.
---
profiles/alert/server.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index dc844d3..b39ef8a 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -27,14 +27,35 @@
#endif
#include <stdbool.h>
+#include <glib.h>
+#include <bluetooth/uuid.h>
+#include "att.h"
#include "adapter.h"
+#include "gatt-service.h"
+#include "gattrib.h"
+#include "gatt.h"
#include "server.h"
#include "profile.h"
+#define PHONE_ALERT_STATUS_SVC_UUID 0x180E
+
+static void register_phone_alert_service(struct btd_adapter *adapter)
+{
+ bt_uuid_t uuid;
+
+ bt_uuid16_create(&uuid, PHONE_ALERT_STATUS_SVC_UUID);
+
+ /* Phone Alert Status Service */
+ gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+ GATT_OPT_INVALID);
+}
+
static int alert_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
+ register_phone_alert_service(adapter);
+
return 0;
}
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox