Linux bluetooth development
 help / color / mirror / Atom feed
* 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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox