* Re: [PATCHv1 3/3] Bluetooth: btmrvl: Fix skb buffer overflow
From: Gustavo Padovan @ 2012-09-27 20:51 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1348732308-29348-3-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
* Andrei Emeltchenko <Andrei.Emeltchenko.news@gmail.com> [2012-09-27 10:51:48 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Add extra check to avoid skb buffer overflow. Fixes crash below:
>
> [ 101.030427] ------------[ cut here ]------------
> [ 101.030459] kernel BUG at net/core/skbuff.c:127!
> [ 101.030486] invalid opcode: 0000 [#1] SMP
> ...
> [ 101.030806] Pid: 2010, comm: btmrvl_main_ser Not tainted 3.5.0+ #80 Laptop
> [ 101.030859] EIP: 0060:[<c14f2ba9>] EFLAGS: 00010282 CPU: 0
> [ 101.030894] EIP is at skb_put+0x99/0xa0
> [ 101.030919] EAX: 00000080 EBX: f129380b ECX: ef923540 EDX: 00000001
> [ 101.030956] ESI: f00a4000 EDI: 00001003 EBP: ed4a5efc ESP: ed4a5ecc
> [ 101.030992] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
> [ 101.031024] CR0: 8005003b CR2: 08fca014 CR3: 30960000 CR4: 000407f0
> [ 101.031062] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
> [ 101.031100] DR6: ffff0ff0 DR7: 00000400
> [ 101.031125] Process btmrvl_main_ser (pid: 2010, ti=ed4a4000 task=ef923540 task.ti=ed4a4000)
> [ 101.031174] Stack:
> [ 101.031188] c18126f8 c1651938 f853f8d2 00001003 00001003 f1292800 f1292808 f129380b
> [ 101.031250] f1292940 f00a4000 eddb1280 efc0f9c0 ed4a5f44 f853f8d2 00000040 00000000
> [ 101.031312] ef923540 c15ee096 ef923540 eddb12d4 00000004 f00a4000 00000040 00000000
> [ 101.031376] Call Trace:
> [ 101.031396] [<f853f8d2>] ? btmrvl_sdio_process_int_status+0x272/0x3d0 [btmrvl_sdio]
> [ 101.031444] [<f853f8d2>] btmrvl_sdio_process_int_status+0x272/0x3d0 [btmrvl_sdio]
> [ 101.031488] [<c15ee096>] ? _raw_spin_unlock_irqrestore+0x36/0x70
> [ 101.031526] [<f85a46e4>] btmrvl_service_main_thread+0x244/0x300 [btmrvl]
> [ 101.031568] [<f853fb50>] ? btmrvl_sdio_poll_card_status.isra.6.constprop.7+0x90/0x90 [btmrvl_sdio]
> [ 101.031619] [<c107eda0>] ? try_to_wake_up+0x270/0x270
> [ 101.031648] [<f85a44a0>] ? btmrvl_process_event+0x3b0/0x3b0 [btmrvl]
> [ 101.031686] [<c106d19d>] kthread+0x7d/0x90
> [ 101.031713] [<c106d120>] ? flush_kthread_work+0x150/0x150
> [ 101.031745] [<c15f5a82>] kernel_thread_helper+0x6/0x10
> ...
> [ 101.032008] EIP: [<c14f2ba9>] skb_put+0x99/0xa0 SS:ESP 0068:ed4a5ecc
> [ 101.056125] ---[ end trace a0bd01d1a9a796c8 ]---
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
> drivers/bluetooth/btmrvl_sdio.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
> index 1457f25..b3b3680 100644
> --- a/drivers/bluetooth/btmrvl_sdio.c
> +++ b/drivers/bluetooth/btmrvl_sdio.c
> @@ -554,7 +554,16 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
> */
>
> buf_len = payload[0];
> - buf_len |= (u16) payload[1] << 8;
> + buf_len |= payload[1] << 8;
> + buf_len |= payload[2] << 16;
> +
> + if (buf_len > blksz * num_blocks) {
> + BT_ERR("Skip incorrect packet: hdrlen %d buffer %d",
> + buf_len, blksz * num_blocks);
> + ret = -EIO;
> + goto exit;
> + }
> +
> type = payload[3];
>
> BT_DBG("%s len %zu type %d", hdev->name, buf_len, type);
All three patches doesn't apply. Please check them.
Gustavo
^ permalink raw reply
* Re: [PATCHv1 1/3] Bluetooth: btmrvl: Correct num_block name
From: Gustavo Padovan @ 2012-09-27 20:48 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1348732308-29348-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
* Andrei Emeltchenko <Andrei.Emeltchenko.news@gmail.com> [2012-09-27 10:51:46 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Make code readable by correcting name from buf_block_len to num_blocks
> since it represent number of blocks; NOT a length of a block buffer.
>
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> ---
> drivers/bluetooth/btmrvl_sdio.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
> index da4df9c..25dc53b 100644
> --- a/drivers/bluetooth/btmrvl_sdio.c
> +++ b/drivers/bluetooth/btmrvl_sdio.c
> @@ -492,7 +492,7 @@ done:
> static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
> {
> u16 buf_len = 0;
> - int ret, buf_block_len, blksz;
> + int ret, num_blocks, blksz;
> struct sk_buff *skb = NULL;
> u32 type;
> u8 *payload = NULL;
> @@ -516,18 +516,17 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
> BT_DBG("%s buf_len %zu", hdev->name, buf_len);
>
> blksz = SDIO_BLOCK_SIZE;
> - buf_block_len = (buf_len + blksz - 1) / blksz;
> + num_blocks = (buf_len + blksz - 1) / blksz;
>
> if (buf_len <= SDIO_HEADER_LEN
> - || (buf_block_len * blksz) > ALLOC_BUF_SIZE) {
> + || (num_blocks * blksz) > ALLOC_BUF_SIZE) {
> BT_ERR("invalid packet length: %d", buf_len);
> ret = -EINVAL;
> goto exit;
> }
>
> /* Allocate buffer */
> - skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN,
> - GFP_ATOMIC);
> + skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC);
> if (skb == NULL) {
> BT_ERR("No free skb");
> goto exit;
> @@ -543,7 +542,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
> payload = skb->data;
>
> ret = sdio_readsb(card->func, payload, card->ioport,
> - buf_block_len * blksz);
> + num_blocks * blksz);
> if (ret < 0) {
> BT_ERR("readsb failed: %d", ret);
> ret = -EIO;
> @@ -594,7 +593,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
> default:
> BT_ERR("Unknown packet type:%d", type);
> print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload,
> - blksz * buf_block_len);
> + blksz * num_blocks);
>
> kfree_skb(skb);
> skb = NULL;
By some reason this patch fails to apply:
Applying: Bluetooth: btmrvl: Correct num_block name
fatal: sha1 information is lacking or useless
(drivers/bluetooth/btmrvl_sdio.c).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 Bluetooth: btmrvl: Correct num_block name
Gustavo
^ permalink raw reply
* Re: [PATCHv7 00/19] Bluetooth: Create AMP physical link
From: Gustavo Padovan @ 2012-09-27 20:44 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth, mathewm
In-Reply-To: <1348755984-6403-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
* Andrei Emeltchenko <Andrei.Emeltchenko.news@gmail.com> [2012-09-27 17:26:05 +0300]:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> This set of patches enhances A2MP protocol and creates physical
> link between AMP controllers. This is further iteration towards
> Bluetooth High Speed.
>
> Changes:
> * p7: Fix ctrl_lookup, add phylink accept functions.
> * p6: Refactoring: moving code from pal.[ch] to amp.[ch]
> * p5: Fix issues reported by Mat in mailing list review
> * p4: Rebased against recent bluetooth-next, minor fixes
> * p3: Use hci_conn for representing physical link(type AMP_LINK) instead of
> struct phy_link, refactoring.
> * p2: Remove HCI callbacks and use amp_mgr global list, refactor code.
> * p1: Fixed locking issues, added basic logical link preparation.
> * v3: Remove workqueue from callback processing; change callback functions
> names according to reviewers recommendations; create global amp_mgr_list to
> have lookup to amp manager, physical and logical links so for those HCI events
> which might be identified by __handler__ we have lookup; remove extensive
> hexdump from gen_amp_key.
> * v2: Fix typos and bugs, add functionality: now physical connection
> might be established.
> * v1: Fix typos, change debug prints, refactor code for better
> splitting functionality.
>
> Andrei Emeltchenko (18):
> Bluetooth: Add HCI logical link cmds definitions
> Bluetooth: A2MP: Create amp_mgr global list
> Bluetooth: AMP: Use HCI cmd to Read AMP Info
> Bluetooth: AMP: Use HCI cmd to Read Loc AMP Assoc
> Bluetooth: A2MP: Process Discover Response
> Bluetooth: AMP: Physical link struct and heplers
> Bluetooth: AMP: Remote AMP ctrl definitions
> Bluetooth: AMP: Handle create / disc phylink req
> Bluetooth: A2MP: Process A2MP Getinfo Rsp
> Bluetooth: A2MP: Process A2MP Get AMP Assoc Rsp
> Bluetooth: Choose connection based on capabilities
> Bluetooth: AMP: Add AMP key calculation
> Bluetooth: AMP: Create Physical Link
> Bluetooth: AMP: Write remote AMP Assoc
> Bluetooth: A2MP: Add fallback to normal l2cap init sequence
> Bluetooth: AMP: Process Chan Selected event
> Bluetooth: AMP: Accept Physical Link
> Bluetooth: AMP: Handle Accept phylink command status evt
>
> Dmitry Kasatkin (1):
> Bluetooth: Add function to derive AMP key using hmac
All 19 patches were applied to bluetooth-next. Thanks.
Gustavo
^ permalink raw reply
* Re: [PATCH 0/5] mSBC tests
From: Siarhei Siamashka @ 2012-09-27 20:34 UTC (permalink / raw)
To: Frédéric Dalleau; +Cc: linux-bluetooth
In-Reply-To: <1348757068-31048-1-git-send-email-frederic.dalleau@linux.intel.com>
On Thu, 27 Sep 2012 16:44:23 +0200
Frédéric Dalleau <frederic.dalleau@linux.intel.com> wrote:
> Hi folks,
>
> I wanted to know more about mSBC and I look into the spec and saw it
> was just a set of settings for SBC. So I tried to exercise them using
> sbcenc and sbcdec and found it wasn't possible, I ended modifying SBC
> library and now it should be possible to use mSBC settings.
> Using 15 block doesn't work using SIMD processing because of data
> reordering so I recalled some legacy C code from an older release
> (sbc_analyse_eight) and put in a separate primitives file.
Hi,
I wonder why they decided to go with the odd sided blocks? Anyway,
I guess there is no other way but to adapt to this extended spec.
Thanks for taking a look at this stuff.
Have you tried to tweak the SIMD code to make it process one
block at a time instead of batches of 4?
I suspect that we might only need to track the state and flip between
"even" and "odd" constant tables for every other processed block in
"sbc_analyze_4b_4s_simd" and "sbc_analyze_4b_8s_simd" replacement
functions. The functions "sbc_encoder_process_input_s4_internal"
and "sbc_encoder_process_input_s8_internal" also need to be
updated to handle arbitrary number of blocks and not just
multiples of 4. Though I haven't been working with sbc code lately
and may be mistaken.
Using the old tables "_sbc_proto_fixed8" and "_sbc_proto_fixed4" has
a disadvantage of not having the tweaks from:
http://git.kernel.org/?p=bluetooth/sbc.git;a=commit;h=bec3d3989ba2
They haven't been in use for ages and just remained in the sources by.
If we just could make SIMD code work, that would be the best option in
my opinion.
> Work done from the spec, not tested with any reference encoder.
Does a reference mSBC encoder exist somewhere? Or any ideas how to test
the new code with something other than bluez just to be sure that it's
correct?
> How to use:
> sample.au should be an .au audio file 16000hz 16bits 1 channel pcm.
> $ src/sbcenc -m -b26 -B16 -s8 sample.au > sample.au.msbc
> $ src/sbcinfo sample.au.msbc
> $ src/sbcdec -m -f sample.au.msbc.au sample.au.msbc
> $ mplayer sample.au.msbc.au
>
> Note sure there is any application yet but I thought I should share.
Thanks for sharing this information and patches. I would love to try
experimenting with mSBC code myself (mostly curious to check whether
SIMD has any chance to remain useful), but don't have much time right
now and will be away from my primary computer for the whole next week.
--
Best regards,
Siarhei Siamashka
^ permalink raw reply
* Re: [PATCH BlueZ v7 5/9] core: Queue discovery if scanning is active
From: Joao Paulo Rechi Vita @ 2012-09-27 20:34 UTC (permalink / raw)
To: Vinicius Costa Gomes; +Cc: linux-bluetooth, Claudio Takahasi
In-Reply-To: <20120927031616.GA7630@echo>
On Thu, Sep 27, 2012 at 12:16 AM, Vinicius Costa Gomes
<vinicius.gomes@openbossa.org> wrote:
> Hi João, Claudio,
>
> On 14:38 Tue 25 Sep, João Paulo Rechi Vita wrote:
>> From: Claudio Takahasi <claudio.takahasi@openbossa.org>
>>
>> This patch manages BR/EDR inquiry and BLE scanning discovery sessions.
>> A scanning session is added in the discovery session list when there is
>> a bonded device which requires re-connection.
>>
>> bluetoothd decides if interleaved or scanning needs to be executed based
>> on the queued discovery sessions. Interleaved discovery has higher
>> priority, scanning only is executed when there is only a scanning
>> session active.
>> ---
>> src/adapter.c | 65 ++++++++++++++++++++++++++++++++++++++++++-----------------
>> 1 file changed, 46 insertions(+), 19 deletions(-)
>>
>> diff --git a/src/adapter.c b/src/adapter.c
>> index 201e6a0..0a0ac8f 100644
>> --- a/src/adapter.c
>> +++ b/src/adapter.c
>> @@ -132,6 +132,7 @@ struct btd_adapter {
>> GSList *devices; /* Devices structure pointers */
>> GSList *mode_sessions; /* Request Mode sessions */
>> GSList *disc_sessions; /* Discovery sessions */
>> + struct session_req *scanning_session;
>> GSList *connect_list; /* Devices to connect when found */
>> guint discov_id; /* Discovery timer */
>> gboolean discovering; /* Discovery active */
>> @@ -221,17 +222,18 @@ static struct session_req *create_session(struct btd_adapter *adapter,
>> DBusMessage *msg, uint8_t mode,
>> GDBusWatchFunction cb)
>> {
>> - const char *sender = dbus_message_get_sender(msg);
>> + const char *sender;
>> struct session_req *req;
>>
>> req = g_new0(struct session_req, 1);
>> req->adapter = adapter;
>> - req->msg = dbus_message_ref(msg);
>> req->mode = mode;
>>
>> - if (cb == NULL)
>> + if (cb == NULL || msg == NULL)
>> return session_ref(req);
>
> Sorry for taking so long to notice this, but there is a problem here.
> 'req->msg' is needed in 'set_mode_complete()' (around adapter.c:2329) even
> when 'cb' is NULL: when setting the "Powered" or "Discoverable" property,
> the session created doesn't have a 'cb' but it has a 'msg'.
>
Good catch, Vinicius. Thanks!
--
João Paulo Rechi Vita
Openbossa Labs - INdT
^ permalink raw reply
* Re: [PATCH BlueZ v7 1/9] core: Mutually exclude concurrent connections
From: Joao Paulo Rechi Vita @ 2012-09-27 20:31 UTC (permalink / raw)
To: Johan Hedberg, linux-bluetooth
In-Reply-To: <20120927074206.GB9610@x220>
Hello Johan,
On Thu, Sep 27, 2012 at 4:42 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi,
>
> On Tue, Sep 25, 2012, João Paulo Rechi Vita wrote:
>> Since controllers don't support more than one ongoing connection
>> procedure at the same time, new connection attempts needs to yield if
>> there is an ongoing connection procedure already.
>
> Simply based on this description the first question that comes to mind
> is wouldn't this be better handled on the kernel side? After all other
> processes besides bluetoothd (like obexd) are also capable of initiating
> connections and we can't control that within bluetoothd.
>
This whole series implements the General Connection Establishment
Procedure (GCEP), as described in the core spec. According to this
procedure, when a new connection to a remote device is requested, a
scan is initiated and only when an advertise from this device is seen
the connect command is sent to the controller.
We could implement the whole procedure inside the kernel, but on the
discussions we (me, André, Vinicius and Claudio) had, it seems that
some changes on the socket api (related to the l2cap socket timeout)
will be needed to accommodate that. Also, it is still an open
question if we can make use of the controller white-list to improve LE
connections management, and in this case it wouldn't make sense to
have the GCEP in the kernel.
And more important, having the GCEP in userspace is a big improvement
over what we have now. Current upstream code doesn't handle LE
re-connections at all, so if a remote device disconnects to save power
(which all HoG devices we have do), we're starting the GCEP to
re-connect to it. We can discuss a way to better support multiple
processes opening LE sockets, but I don't think having this code
upstream will hurt right now.
--
João Paulo Rechi Vita
Openbossa Labs - INdT
^ permalink raw reply
* [PATCH v2 BlueZ 27/27] alert: Add org.bluez.AlertAgent to D-Bus policy file
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 26fde34..8b656f3 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"/>
</policy>
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 BlueZ 26/27] alert: Implement Release() agent method
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 c631e0d..4b00ae3 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 v2 BlueZ 25/27] alert: Add support for unread alert notification
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 560765b..c631e0d 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;
@@ -645,8 +646,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,
@@ -890,8 +894,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 v2 BlueZ 24/27] alert: Add support for new alert notification
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index e4ad7e2..560765b 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,11 @@ 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 +876,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 v2 BlueZ 23/27] alert: Add support for alert status notification
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 6fc6384..e4ad7e2 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 v2 BlueZ 22/27] alert: Add support for ringer setting notification
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 bde9056..6fc6384 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 v2 BlueZ 21/27] alert: Update Alert Status and Ringer Setting characteristic values
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 3b74ad8..bde9056 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 v2 BlueZ 20/27] alert: Add test-alert script
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 | 3 +-
test/test-alert | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 175 insertions(+), 1 deletion(-)
create mode 100755 test/test-alert
diff --git a/Makefile.tools b/Makefile.tools
index 15fe4e2..b803af5 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -212,4 +212,5 @@ EXTRA_DIST += test/sap_client.py test/hsplay test/hsmicro \
test/test-proximity test/test-thermometer test/test-profile \
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/service-ftp.xml test/simple-player test/test-nap \
+ 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 v2 BlueZ 19/27] alert: Add support for calling SetRinger()
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 feac7c8..3b74ad8 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 v2 BlueZ 18/27] alert: Add support for calling MuteOnce()
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 64458f4..feac7c8 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 v2 BlueZ 17/27] alert: Implement MuteOnce command
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 e025cb2..64458f4 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 v2 BlueZ 16/27] alert: Update unread alert characteristic value
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 49cf530..e025cb2 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 v2 BlueZ 15/27] alert: Update new alert characteristic value
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 f38761b..49cf530 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 v2 BlueZ 14/27] alert: Update Supported New/Unread Category characteristic values
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 9288ffe..f38761b 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 v2 BlueZ 13/27] alert: Add per adapter attribute handle information
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 465496c..9288ffe 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 *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 v2 BlueZ 12/27] alert: Automatically unregister alert when agent leaves D-Bus
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 e7eb38f..465496c 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 v2 BlueZ 11/27] alert: Add initial support for UnreadAlert D-Bus method
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348770996-12236-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 ce8404c..e7eb38f 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 v2 BlueZ 10/27] alert: Add initial support for NewAlert D-Bus method
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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 2c7373c..ce8404c 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 v2 BlueZ 09/27] alert: Implement category registration in RegisterAlert()
From: Anderson Lizardo @ 2012-09-27 18:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348770996-12236-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..2c7373c 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 *anp_categories[] = {
+ "simple",
+ "email",
+ "news",
+ "call",
+ "missed_call",
+ "sms_mms",
+ "voice_mail",
+ "schedule",
+ "high_priority",
+ "instant_message",
+};
+
+static const char *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
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