From: Anderson Lizardo <anderson.lizardo@openbossa.org>
To: linux-bluetooth@vger.kernel.org
Cc: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Subject: [PATCH RFC BlueZ 4/5] Add support for sending notifications for current time
Date: Fri, 2 Dec 2011 14:34:09 -0400 [thread overview]
Message-ID: <1322850850-18019-5-git-send-email-anderson.lizardo@openbossa.org> (raw)
In-Reply-To: <1322850850-18019-1-git-send-email-anderson.lizardo@openbossa.org>
From: Vinicius Costa Gomes <vinicius.gomes@openbossa.org>
Now, we are able to send notifications when the time gets updated,
this should occur when, for example, the user changes the system's
timezone.
---
time/server.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
time/server.h | 2 +
2 files changed, 118 insertions(+), 1 deletions(-)
diff --git a/time/server.c b/time/server.c
index 56eecb1..df70d2f 100644
--- a/time/server.c
+++ b/time/server.c
@@ -29,10 +29,17 @@
#include <glib.h>
#include <time.h>
#include <errno.h>
+#include <stdlib.h>
#include <bluetooth/uuid.h>
+#include "adapter.h"
+#include "manager.h"
+
#include "att.h"
#include "gattrib.h"
+#include "attio.h"
+#include "textfile.h"
+#include "storage.h"
#include "attrib-server.h"
#include "gatt-service.h"
#include "log.h"
@@ -46,6 +53,21 @@
#define TIME_UPDATE_STAT_CHR_UUID 0x2A17
#define CT_TIME_CHR_UUID 0x2A2B
+struct adapter_ccc {
+ struct btd_adapter *adapter;
+ uint16_t handle;
+};
+
+struct notify_callback {
+ struct btd_device *device;
+ guint id;
+};
+
+static GSList *devices_notify;
+
+static uint16_t current_time_ccc_handle;
+static uint16_t current_time_value_handle;
+
static int encode_current_time(uint8_t value[10])
{
struct timespec tp;
@@ -92,6 +114,94 @@ static uint8_t current_time_read(struct attribute *a, gpointer user_data)
return 0;
}
+static void filter_devices_notify(char *key, char *value, void *user_data)
+{
+ struct adapter_ccc *ccc = user_data;
+ struct btd_adapter *adapter = ccc->adapter;
+ struct btd_device *device;
+ char addr[18];
+ uint16_t handle, ccc_val;
+
+ sscanf(key, "%17s#%04hX", addr, &handle);
+
+ if (ccc->handle != handle)
+ return;
+
+ ccc_val = strtol(value, NULL, 16);
+ if (!(ccc_val & 0x0001))
+ return;
+
+ device = adapter_find_device(adapter, addr);
+ if (device == NULL)
+ return;
+
+ if (g_slist_find(devices_notify, device))
+ return;
+
+ devices_notify = g_slist_append(devices_notify, device);
+}
+
+static GSList *devices_to_notify(struct btd_adapter *adapter, uint16_t ccc_hnd)
+{
+ struct adapter_ccc ccc_list = { adapter, ccc_hnd };
+ char filename[PATH_MAX + 1];
+ char srcaddr[18];
+ bdaddr_t src;
+
+ adapter_get_address(adapter, &src);
+ ba2str(&src, srcaddr);
+
+ create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "ccc");
+
+ textfile_foreach(filename, filter_devices_notify, &ccc_list);
+
+ return devices_notify;
+}
+
+static void send_notification(GAttrib *attrib, gpointer user_data)
+{
+ struct notify_callback *callback = user_data;
+ uint8_t value[10], pdu[ATT_MAX_MTU];
+ int err, len;
+
+ err = encode_current_time(value);
+ if (err)
+ goto done;
+
+ len = enc_notification(current_time_value_handle, value, sizeof(value),
+ pdu, sizeof(pdu));
+ g_attrib_send(attrib, 0, ATT_OP_HANDLE_NOTIFY, pdu, len,
+ NULL, NULL, NULL);
+
+done:
+ btd_device_remove_attio_callback(callback->device, callback->id);
+ devices_notify = g_slist_remove(devices_notify, callback->device);
+ g_free(callback);
+}
+
+void current_time_updated(void)
+{
+ struct btd_adapter *adapter;
+ GSList *devices, *l;
+
+ adapter = manager_get_default_adapter();
+ if (adapter == NULL)
+ return;
+
+ devices = devices_to_notify(adapter, current_time_ccc_handle);
+
+ for (l = devices; l; l = l->next) {
+ struct btd_device *device = l->data;
+ struct notify_callback *callback;
+
+ callback = g_new0(struct notify_callback, 1);
+ callback->device = device;
+
+ callback->id = btd_device_add_attio_callback(device,
+ send_notification, NULL, callback);
+ }
+}
+
static uint8_t local_time_info_read(struct attribute *a, gpointer user_data)
{
uint8_t value[2];
@@ -123,7 +233,10 @@ static void register_current_time_service(void)
ATT_CHAR_PROPER_NOTIFY,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
current_time_read,
-
+ GATT_OPT_CCC_GET_HANDLE,
+ ¤t_time_ccc_handle,
+ GATT_OPT_CHR_VALUE_GET_HANDLE,
+ ¤t_time_value_handle,
/* Local Time Information characteristic */
GATT_OPT_CHR_UUID, LOCAL_TIME_INFO_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
@@ -193,4 +306,6 @@ int time_server_init(void)
void time_server_exit(void)
{
time_provider_exit();
+
+ g_slist_free(devices_notify);
}
diff --git a/time/server.h b/time/server.h
index 0e1f858..91be6e8 100644
--- a/time/server.h
+++ b/time/server.h
@@ -51,3 +51,5 @@ void time_provider_exit(void);
/* Time provider control and status routines. Implemented by provider-*.c */
void time_provider_status(uint8_t *state, uint8_t *result);
uint8_t time_provider_control(int op);
+
+void current_time_updated(void);
--
1.7.0.4
next prev parent reply other threads:[~2011-12-02 18:34 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-02 18:34 [PATCH RFC BlueZ 0/5] Time Profile (server) improvements Anderson Lizardo
2011-12-02 18:34 ` [PATCH RFC BlueZ 1/5] Time Profile: add Reference Time Update Service Anderson Lizardo
2011-12-02 18:34 ` [PATCH RFC BlueZ 2/5] Time Profile: implement generic "time provider" interface Anderson Lizardo
2011-12-02 18:34 ` [PATCH RFC BlueZ 3/5] Time Profile: Add "timed" time provider Anderson Lizardo
2011-12-02 18:34 ` Anderson Lizardo [this message]
2011-12-02 18:34 ` [PATCH RFC BlueZ 5/5] Add testing API to dummy Time Server provider Anderson Lizardo
2012-02-01 22:48 ` [PATCH RFC BlueZ 0/5] Time Profile (server) improvements Arik Nemtsov
2012-02-01 23:12 ` Anderson Lizardo
2012-02-02 12:19 ` Arik Nemtsov
2012-02-02 13:07 ` Anderson Lizardo
2012-02-02 13:32 ` Arik Nemtsov
2012-02-02 14:06 ` Anderson Lizardo
2012-05-16 11:40 ` Arun K. Singh
2012-05-17 14:50 ` Anderson Lizardo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1322850850-18019-5-git-send-email-anderson.lizardo@openbossa.org \
--to=anderson.lizardo@openbossa.org \
--cc=linux-bluetooth@vger.kernel.org \
--cc=vinicius.gomes@openbossa.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).