2011-02-16 23:07:28

by Claudio Takahasi

[permalink] [raw]
Subject: [PATCH 1/4] Add static Device Appearance Characteristic

Declaration and definition of the Device Appearance Characteristic
defined in the GAP Characteristics for Low Energy section: Bluetooth
Core Specification, Volume 3, Part C, section 12.2.
---
src/attrib-server.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/attrib-server.c b/src/attrib-server.c
index 85b39a8..fe5d68c 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -799,6 +799,7 @@ static void register_core_services(void)
uint8_t atval[256];
uuid_t uuid;
int len;
+ uint16_t appearance = 0x0000;

/* GAP service: primary service definition */
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
@@ -818,8 +819,17 @@ static void register_core_services(void)
attrib_db_add(0x0006, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
(uint8_t *) main_opts.name, len);

- /* TODO: Implement Appearance characteristic. It is mandatory for
- * Peripheral/Central GAP roles. */
+ /* GAP service: device appearance characteristic */
+ sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
+ atval[0] = ATT_CHAR_PROPER_READ;
+ att_put_u16(0x0008, &atval[1]);
+ att_put_u16(GATT_CHARAC_APPEARANCE, &atval[3]);
+ attrib_db_add(0x0007, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
+
+ /* GAP service: device appearance attribute */
+ sdp_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
+ att_put_u16(appearance, &atval[0]);
+ attrib_db_add(0x0008, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);

/* GATT service: primary service definition */
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
--
1.7.4.1



2011-02-17 18:36:59

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH 1/4] Add static Device Appearance Characteristic

Hi Claudio,

On Wed, Feb 16, 2011, Claudio Takahasi wrote:
> Declaration and definition of the Device Appearance Characteristic
> defined in the GAP Characteristics for Low Energy section: Bluetooth
> Core Specification, Volume 3, Part C, section 12.2.
> ---
> src/attrib-server.c | 14 ++++++++++++--
> 1 files changed, 12 insertions(+), 2 deletions(-)

All four patches have been pushed upstream. Thanks.

Johan

2011-02-16 23:07:31

by Claudio Takahasi

[permalink] [raw]
Subject: [PATCH 4/4] Fix Device Name Characteristic

"Name" key value defined in the main.conf file can not be used without
substitution(hostname and adapter id). This patch adds Device Name
Characteristic with length 0 and updates the value when the adapter is
initialized.

Multiple adapters with different settings is not supported at the moment
by the attribute server. GAP characteristics values will be overwritten
if the host has multiple adapters.
---
src/adapter.c | 4 ++++
src/attrib-server.c | 4 +---
2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 2a19ace..dbae219 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2658,6 +2658,10 @@ gboolean adapter_init(struct btd_adapter *adapter)
expand_name(adapter->dev.name, MAX_NAME_LENGTH, main_opts.name,
adapter->dev_id);

+ if (main_opts.attrib_server)
+ attrib_gap_set(GATT_CHARAC_DEVICE_NAME,
+ (const uint8_t *) dev->name, strlen(dev->name));
+
sdp_init_services_list(&adapter->bdaddr);
load_drivers(adapter);
clear_blocked(adapter);
diff --git a/src/attrib-server.c b/src/attrib-server.c
index c1ca5ba..5e00601 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -802,7 +802,6 @@ static void register_core_services(void)
{
uint8_t atval[256];
uuid_t uuid;
- int len;
uint16_t appearance = 0x0000;

/* GAP service: primary service definition */
@@ -820,9 +819,8 @@ static void register_core_services(void)

/* GAP service: device name attribute */
sdp_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
- len = strlen(main_opts.name);
attrib_db_add(name_handle, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
- (uint8_t *) main_opts.name, len);
+ NULL, 0);

/* GAP service: device appearance characteristic */
appearance_handle = 0x0008;
--
1.7.4.1


2011-02-16 23:07:30

by Claudio Takahasi

[permalink] [raw]
Subject: [PATCH 3/4] Update the Device Name characteristic when the local name has changed

---
src/adapter.c | 4 ++++
src/attrib-server.c | 12 +++++++++---
2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index e7b2495..2a19ace 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -892,6 +892,10 @@ void adapter_update_local_name(struct btd_adapter *adapter, const char *name)

strncpy(dev->name, name, MAX_NAME_LENGTH);

+ if (main_opts.attrib_server)
+ attrib_gap_set(GATT_CHARAC_DEVICE_NAME,
+ (const uint8_t *) dev->name, strlen(dev->name));
+
if (!adapter->name_stored) {
char *name_ptr = dev->name;

diff --git a/src/attrib-server.c b/src/attrib-server.c
index b4df137..c1ca5ba 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -72,6 +72,8 @@ static GIOChannel *le_io = NULL;
static GSList *clients = NULL;
static uint32_t sdp_handle = 0;

+/* GAP attribute handles */
+static uint16_t name_handle = 0x0000;
static uint16_t appearance_handle = 0x0000;

static uuid_t prim_uuid = {
@@ -809,16 +811,17 @@ static void register_core_services(void)
attrib_db_add(0x0001, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);

/* GAP service: device name characteristic */
+ name_handle = 0x0006;
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
atval[0] = ATT_CHAR_PROPER_READ;
- att_put_u16(0x0006, &atval[1]);
+ att_put_u16(name_handle, &atval[1]);
att_put_u16(GATT_CHARAC_DEVICE_NAME, &atval[3]);
attrib_db_add(0x0004, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

/* GAP service: device name attribute */
sdp_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
len = strlen(main_opts.name);
- attrib_db_add(0x0006, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
+ attrib_db_add(name_handle, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
(uint8_t *) main_opts.name, len);

/* GAP service: device appearance characteristic */
@@ -1011,11 +1014,14 @@ int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len)
uuid_t u16;
uint16_t handle;

- /* FIXME: Missing Name, Privacy and Reconnection Address */
+ /* FIXME: Missing Privacy and Reconnection Address */

sdp_uuid16_create(&u16, uuid);

switch (uuid) {
+ case GATT_CHARAC_DEVICE_NAME:
+ handle = name_handle;
+ break;
case GATT_CHARAC_APPEARANCE:
handle = appearance_handle;
break;
--
1.7.4.1


2011-02-16 23:07:29

by Claudio Takahasi

[permalink] [raw]
Subject: [PATCH 2/4] Update Device Appearance Characteristic based on device class

Appearance Characteristic value is still under discussion. Temporary
solution which maps directly the device class of device(major and minor)
into Device Characteristic value without shifting the two less significant
bits reserved to Format Type. The second byte of the device class
contains the major class in the 5 less significant bits.
---
src/adapter.c | 7 +++++++
src/attrib-server.c | 28 ++++++++++++++++++++++++++--
src/attrib-server.h | 2 ++
3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index f63d9e4..e7b2495 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -55,6 +55,7 @@
#include "glib-helper.h"
#include "agent.h"
#include "storage.h"
+#include "attrib-server.h"
#include "att.h"

/* Flags Descriptions */
@@ -871,6 +872,12 @@ void btd_adapter_class_changed(struct btd_adapter *adapter, uint32_t new_class)

adapter->dev_class = new_class;

+ if (main_opts.attrib_server) {
+ /* Removes service class */
+ class[1] = class[1] & 0x1f;
+ attrib_gap_set(GATT_CHARAC_APPEARANCE, class, 2);
+ }
+
emit_property_changed(connection, adapter->path,
ADAPTER_INTERFACE, "Class",
DBUS_TYPE_UINT32, &new_class);
diff --git a/src/attrib-server.c b/src/attrib-server.c
index fe5d68c..b4df137 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -72,6 +72,8 @@ static GIOChannel *le_io = NULL;
static GSList *clients = NULL;
static uint32_t sdp_handle = 0;

+static uint16_t appearance_handle = 0x0000;
+
static uuid_t prim_uuid = {
.type = SDP_UUID16,
.value.uuid16 = GATT_PRIM_SVC_UUID
@@ -820,16 +822,18 @@ static void register_core_services(void)
(uint8_t *) main_opts.name, len);

/* GAP service: device appearance characteristic */
+ appearance_handle = 0x0008;
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
atval[0] = ATT_CHAR_PROPER_READ;
- att_put_u16(0x0008, &atval[1]);
+ att_put_u16(appearance_handle, &atval[1]);
att_put_u16(GATT_CHARAC_APPEARANCE, &atval[3]);
attrib_db_add(0x0007, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);

/* GAP service: device appearance attribute */
sdp_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
att_put_u16(appearance, &atval[0]);
- attrib_db_add(0x0008, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
+ attrib_db_add(appearance_handle, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
+ atval, 2);

/* GATT service: primary service definition */
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
@@ -1001,3 +1005,23 @@ int attrib_db_del(uint16_t handle)

return 0;
}
+
+int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len)
+{
+ uuid_t u16;
+ uint16_t handle;
+
+ /* FIXME: Missing Name, Privacy and Reconnection Address */
+
+ sdp_uuid16_create(&u16, uuid);
+
+ switch (uuid) {
+ case GATT_CHARAC_APPEARANCE:
+ handle = appearance_handle;
+ break;
+ default:
+ return -ENOSYS;
+ }
+
+ return attrib_db_update(handle, &u16, value, len);
+}
diff --git a/src/attrib-server.h b/src/attrib-server.h
index ba90ff4..252700f 100644
--- a/src/attrib-server.h
+++ b/src/attrib-server.h
@@ -30,3 +30,5 @@ int attrib_db_add(uint16_t handle, uuid_t *uuid, int read_reqs, int write_reqs,
int attrib_db_update(uint16_t handle, uuid_t *uuid, const uint8_t *value,
int len);
int attrib_db_del(uint16_t handle);
+
+int attrib_gap_set(uint16_t uuid, const uint8_t *value, int len);
--
1.7.4.1