This abstraction layer makes the GATT Time profile implementation
consistent with other profiles. It is the first step before implementing
the adapter driver for the Time server implementation.
---
Makefile.am | 1 +
time/main.c | 6 +++---
time/manager.c | 40 ++++++++++++++++++++++++++++++++++++++++
time/manager.h | 26 ++++++++++++++++++++++++++
4 files changed, 70 insertions(+), 3 deletions(-)
create mode 100644 time/manager.c
create mode 100644 time/manager.h
diff --git a/Makefile.am b/Makefile.am
index 1c214c6..b606b9c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -226,6 +226,7 @@ builtin_sources += thermometer/main.c \
thermometer/thermometer.h thermometer/thermometer.c \
alert/main.c alert/server.h alert/server.c \
time/main.c time/server.h time/server.c \
+ time/manager.h time/manager.c \
plugins/gatt-example.c \
proximity/main.c proximity/manager.h proximity/manager.c \
proximity/monitor.h proximity/monitor.c \
diff --git a/time/main.c b/time/main.c
index d876725..9ef5bf1 100644
--- a/time/main.c
+++ b/time/main.c
@@ -33,7 +33,7 @@
#include "plugin.h"
#include "hcid.h"
#include "log.h"
-#include "server.h"
+#include "manager.h"
static int time_init(void)
{
@@ -42,7 +42,7 @@ static int time_init(void)
return -ENOTSUP;
}
- return time_server_init();
+ return time_manager_init();
}
static void time_exit(void)
@@ -50,7 +50,7 @@ static void time_exit(void)
if (!main_opts.gatt_enabled)
return;
- time_server_exit();
+ time_manager_exit();
}
BLUETOOTH_PLUGIN_DEFINE(time, VERSION,
diff --git a/time/manager.c b/time/manager.c
new file mode 100644
index 0000000..5bda1a3
--- /dev/null
+++ b/time/manager.c
@@ -0,0 +1,40 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Nokia Corporation
+ * Copyright (C) 2012 Marcel Holtmann <[email protected]>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "manager.h"
+#include "server.h"
+
+int time_manager_init(void)
+{
+ return time_server_init();
+}
+
+void time_manager_exit(void)
+{
+ time_server_exit();
+}
diff --git a/time/manager.h b/time/manager.h
new file mode 100644
index 0000000..74641d6
--- /dev/null
+++ b/time/manager.h
@@ -0,0 +1,26 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Nokia Corporation
+ * Copyright (C) 2012 Marcel Holtmann <[email protected]>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+int time_manager_init(void);
+void time_manager_exit(void);
--
1.7.9.5
Add support for the Reference Time Update Service (RTUS). From the spec:
"This service defines how a client can request an update from a
reference time source from a time server using the Generic Attribute
Profile (GATT)."
This a initial dummy implementation, which always reports success (for
testing purposes).
---
time/server.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
time/server.h | 19 +++++++++++++++
2 files changed, 90 insertions(+)
diff --git a/time/server.c b/time/server.c
index 52bd778..be6e196 100644
--- a/time/server.c
+++ b/time/server.c
@@ -42,8 +42,11 @@
#include "server.h"
#define CURRENT_TIME_SVC_UUID 0x1805
+#define REF_TIME_UPDATE_SVC_UUID 0x1806
#define LOCAL_TIME_INFO_CHR_UUID 0x2A0F
+#define TIME_UPDATE_CTRL_CHR_UUID 0x2A16
+#define TIME_UPDATE_STAT_CHR_UUID 0x2A17
#define CT_TIME_CHR_UUID 0x2A2B
static int encode_current_time(uint8_t value[10])
@@ -141,6 +144,69 @@ static gboolean register_current_time_service(struct btd_adapter *adapter)
GATT_OPT_INVALID);
}
+static uint8_t time_update_control(struct attribute *a,
+ struct btd_device *device,
+ gpointer user_data)
+{
+ DBG("handle 0x%04x", a->handle);
+
+ if (a->len != 1)
+ DBG("Invalid control point value size: %d", a->len);
+
+ switch (a->data[0]) {
+ case GET_REFERENCE_UPDATE:
+ DBG("Get Reference Update");
+ break;
+ case CANCEL_REFERENCE_UPDATE:
+ DBG("Cancel Reference Update");
+ break;
+ default:
+ DBG("Unknown command: 0x%02x", a->data[0]);
+ }
+
+ return 0;
+}
+
+static uint8_t time_update_status(struct attribute *a,
+ struct btd_device *device,
+ gpointer user_data)
+{
+ struct btd_adapter *adapter = user_data;
+ uint8_t value[2];
+
+ DBG("handle 0x%04x", a->handle);
+
+ value[0] = UPDATE_STATE_IDLE;
+ value[1] = UPDATE_RESULT_SUCCESSFUL;
+ attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
+
+ return 0;
+}
+
+static gboolean register_ref_time_update_service(struct btd_adapter *adapter)
+{
+ bt_uuid_t uuid;
+
+ bt_uuid16_create(&uuid, REF_TIME_UPDATE_SVC_UUID);
+
+ /* Reference Time Update service */
+ return gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
+ /* Time Update control point */
+ GATT_OPT_CHR_UUID, TIME_UPDATE_CTRL_CHR_UUID,
+ GATT_OPT_CHR_PROPS,
+ ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE,
+ time_update_control, adapter,
+
+ /* Time Update status */
+ GATT_OPT_CHR_UUID, TIME_UPDATE_STAT_CHR_UUID,
+ GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
+ GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
+ time_update_status, adapter,
+
+ GATT_OPT_INVALID);
+}
+
int time_server_init(struct btd_adapter *adapter)
{
const char *path = adapter_get_path(adapter);
@@ -152,6 +218,11 @@ int time_server_init(struct btd_adapter *adapter)
return -EIO;
}
+ if (!register_ref_time_update_service(adapter)) {
+ error("Reference Time Update Service could not be registered");
+ return -EIO;
+ }
+
return 0;
}
diff --git a/time/server.h b/time/server.h
index 69cf114..c7b997d 100644
--- a/time/server.h
+++ b/time/server.h
@@ -22,5 +22,24 @@
*
*/
+enum {
+ UPDATE_RESULT_SUCCESSFUL = 0,
+ UPDATE_RESULT_CANCELED = 1,
+ UPDATE_RESULT_NO_CONN = 2,
+ UPDATE_RESULT_ERROR = 3,
+ UPDATE_RESULT_TIMEOUT = 4,
+ UPDATE_RESULT_NOT_ATTEMPTED = 5,
+};
+
+enum {
+ UPDATE_STATE_IDLE = 0,
+ UPDATE_STATE_PENDING = 1,
+};
+
+enum {
+ GET_REFERENCE_UPDATE = 1,
+ CANCEL_REFERENCE_UPDATE = 2,
+};
+
int time_server_init(struct btd_adapter *adapter);
void time_server_exit(struct btd_adapter *adapter);
--
1.7.9.5
Following changes to the GATT service registration API, services should
now be registered per adapter.
---
time/manager.c | 13 +++++++++++--
time/server.c | 33 +++++++++++++++++++++------------
time/server.h | 4 ++--
3 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/time/manager.c b/time/manager.c
index 5bda1a3..285c7b1 100644
--- a/time/manager.c
+++ b/time/manager.c
@@ -26,15 +26,24 @@
#include <config.h>
#endif
+#include "adapter.h"
#include "manager.h"
#include "server.h"
+struct btd_adapter_driver time_server_driver = {
+ .name = "gatt-time-server",
+ .probe = time_server_init,
+ .remove = time_server_exit,
+};
+
int time_manager_init(void)
{
- return time_server_init();
+ btd_register_adapter_driver(&time_server_driver);
+
+ return 0;
}
void time_manager_exit(void)
{
- time_server_exit();
+ btd_unregister_adapter_driver(&time_server_driver);
}
diff --git a/time/server.c b/time/server.c
index 13a7bbe..52bd778 100644
--- a/time/server.c
+++ b/time/server.c
@@ -83,13 +83,13 @@ static int encode_current_time(uint8_t value[10])
static uint8_t current_time_read(struct attribute *a,
struct btd_device *device, gpointer user_data)
{
+ struct btd_adapter *adapter = user_data;
uint8_t value[10];
if (encode_current_time(value) < 0)
return ATT_ECODE_IO;
- /* FIXME: Provide the adapter in next function */
- attrib_db_update(NULL, a->handle, NULL, value, sizeof(value), NULL);
+ attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
return 0;
}
@@ -97,6 +97,7 @@ static uint8_t current_time_read(struct attribute *a,
static uint8_t local_time_info_read(struct attribute *a,
struct btd_device *device, gpointer user_data)
{
+ struct btd_adapter *adapter = user_data;
uint8_t value[2];
DBG("a=%p", a);
@@ -111,44 +112,52 @@ static uint8_t local_time_info_read(struct attribute *a,
* format (offset from UTC in number of 15 minutes increments). */
value[1] = (uint8_t) (-1 * timezone / (60 * 15));
- /* FIXME: Provide the adapter in next function */
- attrib_db_update(NULL, a->handle, NULL, value, sizeof(value), NULL);
+ attrib_db_update(adapter, a->handle, NULL, value, sizeof(value), NULL);
return 0;
}
-static void register_current_time_service(void)
+static gboolean register_current_time_service(struct btd_adapter *adapter)
{
bt_uuid_t uuid;
bt_uuid16_create(&uuid, CURRENT_TIME_SVC_UUID);
/* Current Time service */
- /* FIXME: Provide the adapter in next function */
- gatt_service_add(NULL, GATT_PRIM_SVC_UUID, &uuid,
+ return gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid,
/* CT Time characteristic */
GATT_OPT_CHR_UUID, CT_TIME_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ |
ATT_CHAR_PROPER_NOTIFY,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
- current_time_read, NULL,
+ current_time_read, adapter,
/* Local Time Information characteristic */
GATT_OPT_CHR_UUID, LOCAL_TIME_INFO_CHR_UUID,
GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
- local_time_info_read, NULL,
+ local_time_info_read, adapter,
GATT_OPT_INVALID);
}
-int time_server_init(void)
+int time_server_init(struct btd_adapter *adapter)
{
- register_current_time_service();
+ const char *path = adapter_get_path(adapter);
+
+ DBG("path %s", path);
+
+ if (!register_current_time_service(adapter)) {
+ error("Current Time Service could not be registered");
+ return -EIO;
+ }
return 0;
}
-void time_server_exit(void)
+void time_server_exit(struct btd_adapter *adapter)
{
+ const char *path = adapter_get_path(adapter);
+
+ DBG("path %s", path);
}
diff --git a/time/server.h b/time/server.h
index 621bf2b..69cf114 100644
--- a/time/server.h
+++ b/time/server.h
@@ -22,5 +22,5 @@
*
*/
-int time_server_init(void);
-void time_server_exit(void);
+int time_server_init(struct btd_adapter *adapter);
+void time_server_exit(struct btd_adapter *adapter);
--
1.7.9.5
Hi Lizardo,
On Wed, Jul 04, 2012, Anderson Lizardo wrote:
> On Wed, Jun 20, 2012 at 3:14 PM, Anderson Lizardo
> <[email protected]> wrote:
> > This abstraction layer makes the GATT Time profile implementation
> > consistent with other profiles. It is the first step before implementing
> > the adapter driver for the Time server implementation.
> > ---
>
> ping.
Sorry, I must have missed these. All three patches have now been
applied.
Johan
On Wed, Jul 4, 2012 at 3:12 PM, Anderson Lizardo
<[email protected]> wrote:
> On Wed, Jun 20, 2012 at 3:14 PM, Anderson Lizardo
> <[email protected]> wrote:
>> This abstraction layer makes the GATT Time profile implementation
>> consistent with other profiles. It is the first step before implementing
>> the adapter driver for the Time server implementation.
>> ---
>
> ping.
>
FWIW, this series fixes the Time Profile on the tests I've been making
recently (its broken without it).
I also have another small fix to the timezone data to go on top of that.
--
João Paulo Rechi Vita
Openbossa Labs - INdT
On Wed, Jun 20, 2012 at 3:14 PM, Anderson Lizardo
<[email protected]> wrote:
> This abstraction layer makes the GATT Time profile implementation
> consistent with other profiles. It is the first step before implementing
> the adapter driver for the Time server implementation.
> ---
ping.
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil