* Re: [PATCH] core: Add ControllerMode to list of supported options
From: Marcel Holtmann @ 2014-10-21 11:08 UTC (permalink / raw)
To: Jacob Siverskog; +Cc: linux-bluetooth
In-Reply-To: <1413877738-23941-1-git-send-email-jacob@teenageengineering.com>
Hi Jacob,
> Signed-off-by: Jacob Siverskog <jacob@teenageengineering.com>
we do not add signed-off-by for userspace patches. That is only required for kernel patches.
> Prevent warning message 'Unknown key ControllerMode in main.conf'.
> ---
> src/main.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/src/main.c b/src/main.c
> index 191dc11..061060d 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -79,6 +79,7 @@ static const char * const supported_options[] = {
> "ReverseServiceDiscovery",
> "NameResolving",
> "DebugKeys",
> + "ControllerMode",
> };
Good catch. Please resend the patch without signed-off-by line.
Regards
Marcel
^ permalink raw reply
* Re: how to set PSCAN mode in .conf?
From: Marcel Holtmann @ 2014-10-21 11:06 UTC (permalink / raw)
To: Jeff Chua; +Cc: linux-bluetooth
In-Reply-To: <CAAJw_ZshxjeK5N3wcFn5cCUZJ0iKVcpFeDUAoijh7JZiweGjqg@mail.gmail.com>
Hi Jeff,
>> See doc/mgmt-api.txt for the details since btmgmt maps the management interface. In short action 1 means to allow incoming connections.
>
> Got it. I tried "-a 0" and it returned Invalid Parameters. But anyway,
> "1" is the one I needed.
the documentation clearly says that action 0x00 and 0x02 are only valid for LE addresses. Action 0x01 is valid for BR/EDR and LE addresses.
If anyone wants to implement action 0x00 semantics on BR/EDR, then it requires using Periodic Inquiry. It is possible, but it is not a common use case these days.
Regards
Marcel
^ permalink raw reply
* Confused about gatttool in Makefile.tools
From: Qian Lei @ 2014-10-21 10:38 UTC (permalink / raw)
To: linux-bluetooth
Dear all:
I don't understand the log message "build: Only compile actually
selected binaries" in commit ed7989e, which modifies the file
Makefile.tools. Gatttool and some other programs are only compiled and
do not been installed into system any more. I'm confused about it, why
did we do this?
Thanks.
Qian Lei
^ permalink raw reply
* [PATCH] android/pts: Update PTS files for HOGP
From: Sebastian Chlad @ 2014-10-21 9:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sebastian Chlad
PICS and PIXITs updated to PTS 5.3. Regression done for Android
4.4.4.
---
android/pics-hogp.txt | 2 +-
android/pixit-hogp.txt | 2 +-
android/pts-hogp.txt | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/android/pics-hogp.txt b/android/pics-hogp.txt
index d7192bf..61cf56a 100644
--- a/android/pics-hogp.txt
+++ b/android/pics-hogp.txt
@@ -1,6 +1,6 @@
HOGP PICS for the PTS tool.
-PTS version: 5.2
+PTS version: 5.3
* - different than PTS defaults
# - not yet implemented/supported
diff --git a/android/pixit-hogp.txt b/android/pixit-hogp.txt
index 067c280..d32fe69 100644
--- a/android/pixit-hogp.txt
+++ b/android/pixit-hogp.txt
@@ -1,6 +1,6 @@
HOGP PIXIT for the PTS tool.
-PTS version: 5.2
+PTS version: 5.3
* - different than PTS defaults
& - should be set to IUT Bluetooth address
diff --git a/android/pts-hogp.txt b/android/pts-hogp.txt
index 19292d1..d86522d 100644
--- a/android/pts-hogp.txt
+++ b/android/pts-hogp.txt
@@ -1,7 +1,7 @@
PTS test results for HoG
-PTS version: 5.2
-Tested: 22-July-2014
+PTS version: 5.3
+Tested: 21-October-2014
Android version: 4.4.4
Results:
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH] android/pts: Updated SM PICS and PIXITs for PTS 5.3
From: Szymon Janc @ 2014-10-21 9:11 UTC (permalink / raw)
To: Ruslan Mstoi; +Cc: linux-bluetooth
In-Reply-To: <1413814868-20811-1-git-send-email-ruslan.mstoi@linux.intel.com>
Hi Ruslan,
On Monday 20 of October 2014 17:21:08 Ruslan Mstoi wrote:
> ---
> android/pics-sm.txt | 6 +++---
> android/pixit-sm.txt | 2 +-
> android/pts-sm.txt | 12 +++++-------
> 3 files changed, 9 insertions(+), 11 deletions(-)
>
> diff --git a/android/pics-sm.txt b/android/pics-sm.txt
> index dcdfff8..c1bfe0e 100644
> --- a/android/pics-sm.txt
> +++ b/android/pics-sm.txt
> @@ -1,6 +1,6 @@
> SM PICS for the PTS tool.
>
> -PTS version: 5.2
> +PTS version: 5.3
>
> * - different than PTS defaults
>
> @@ -25,7 +25,7 @@ Parameter Name Selected Description
> TSPC_SM_2_1 True Authenticated MITM protection (O)
> TSPC_SM_2_2 True Unauthenticated no MITM protection (C.1)
> TSPC_SM_2_3 True No security requirements (M)
> -TSPC_SM_2_4 False OOB supported (O)
> +TSPC_SM_2_4 False (*) OOB supported (O)
> -------------------------------------------------------------------------------
> C.1: If TSPC_SM_2_1 is supported then Mandatory, else Optional
> -------------------------------------------------------------------------------
> @@ -45,7 +45,7 @@ Parameter Name Selected Description
> -------------------------------------------------------------------------------
> TSPC_SM_4_1 True Just Works (O)
> TSPC_SM_4_2 True Passkey Entry (C.1)
> -TSPC_SM_4_3 False Out of Band (C.1)
> +TSPC_SM_4_3 False (*) Out of Band (C.1)
> -------------------------------------------------------------------------------
> C.1: If TSPC_SM_2_1 is supported, at least one of these features shall be
> supported.
> diff --git a/android/pixit-sm.txt b/android/pixit-sm.txt
> index 2526e29..2d1442b 100644
> --- a/android/pixit-sm.txt
> +++ b/android/pixit-sm.txt
> @@ -1,6 +1,6 @@
> SM PIXIT for the PTS tool.
>
> -PTS version: 5.2
> +PTS version: 5.3
>
> * - different than PTS defaults
> & - should be set to IUT Bluetooth address
> diff --git a/android/pts-sm.txt b/android/pts-sm.txt
> index a5c0aba..8a38d32 100644
> --- a/android/pts-sm.txt
> +++ b/android/pts-sm.txt
> @@ -1,7 +1,7 @@
> PTS test results for SM
>
> -PTS version: 5.2
> -Tested: 25-July-2014
> +PTS version: 5.3
> +Tested: 20-October-2014
> Android version: 4.4.4
> kernel version: 3.17
>
> @@ -66,8 +66,7 @@ TC_OOB_BI_01_C N/A
> TC_OOB_BI_02_C N/A
> TC_EKS_BV_01_C PASS
> TC_EKS_BV_02_C PASS
> -TC_EKS_BI_01_C INC PTS issue #12449
> - btmgmt io-cap 0x03
> +TC_EKS_BI_01_C PASS btmgmt io-cap 0x03
> TC_EKS_BI_02_C PASS
> TC_SIGN_BV_01_C INC PTS issue #12305
> TC_SIGN_BV_03_C PASS haltest
> @@ -79,7 +78,7 @@ TC_KDU_BV_01_C PASS btmgmt pairable on
> TC_KDU_BV_02_C PASS PTS issue #12302
> Note: Can pass it with following instructions:
> btmgmt privacy on
> - btmgmt advetising on
> + btmgmt advertising on
> Check our random address (valid for 15 min)
> Set PIXIT TSPX_bd_addr_iut to random address
> Set PIXIT TSPX_peer_type to 01
> @@ -95,7 +94,6 @@ TC_KDU_BV_05_C PASS PTS issue #12302
> TC_KDU_BV_06_C PASS btmgmt pair -c 0x03 -t 0x01 <addr>
> TC_KDU_BV_07_C PASS btmgmt pairable on
> TC_SIP_BV_01_C PASS btmgmt pair -c 0x03 -t 0x01 <addr>
> -TC_SIP_BV_02_C INC PTS issue #12460
> - l2test -n -J4 -V le_public <addr>
> +TC_SIP_BV_02_C PASS l2test -n -J4 -V le_public <addr>
> TC_SIE_BV_01_C PASS btmgmt pair -c 0x03 -t 0x01 <addr>
> -------------------------------------------------------------------------------
>
Applied, thanks.
--
Best regards,
Szymon Janc
^ permalink raw reply
* Re: [PATCH 1/2] android/bluetooth: Fix Supported feature bitmask for MPMD scenarios
From: Szymon Janc @ 2014-10-21 9:03 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1413812032-26631-1-git-send-email-marcin.kraglak@tieto.com>
Hi Marcin,
On Monday 20 of October 2014 15:33:51 Marcin Kraglak wrote:
> Set A2DP-SRC_AVRCP-TG instead of A2DP-SNK_AVRCP-CT_DUN-DT bit.
> It was affecting TC_SDP_CTH_SD_BV_01_I PTS test case.
> ---
> android/bluetooth.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/android/bluetooth.c b/android/bluetooth.c
> index 827e205..03eb1a1 100644
> --- a/android/bluetooth.c
> +++ b/android/bluetooth.c
> @@ -70,7 +70,7 @@
> */
> #define MPS_DEFAULT_MPMD ((1ULL << 1) | (1ULL << 3) | (1ULL << 5) | \
> (1ULL << 6) | (1ULL << 8) | (1ULL << 10) | \
> - (1ULL << 12) | (1ULL << 15) | (1ULL << 18))
> + (1ULL << 12) | (1ULL << 15) | (1ULL << 17))
>
> /*
> * bits in bitmask as defined in table 6.5 of Multi Profile Specification
>
Both patches applied. Thanks.
--
Best regards,
Szymon Janc
^ permalink raw reply
* Re: [PATCH v3 0/5] android/map-client: Add MAP client daemon implementation
From: Szymon Janc @ 2014-10-21 8:34 UTC (permalink / raw)
To: Grzegorz Kolodziejczyk; +Cc: linux-bluetooth
In-Reply-To: <1413383281-17292-1-git-send-email-grzegorz.kolodziejczyk@tieto.com>
Hi Grzegorz,
On Wednesday 15 of October 2014 16:27:56 Grzegorz Kolodziejczyk wrote:
> v1.
> *Add MAP client daemon implementation (skeleton, body)
> *Add haltest MAP client support
>
> v2.
> *Fix style issue in cmd handler
> *Change if-else to if statements for map client instance create
> *Check if allocation of cb data has failed
> *Set free as destroy callback function for search service
> *Fix status overwrite (add fail label)
>
> v3.
> *Fix protos handling, rfcomm channel check
>
> Grzegorz Kolodziejczyk (5):
> android/map-client: Add initial files
> android/map-client: Add stubs for MAP client commands handlers
> android/map-client: Add support for get remote MAS instances
> android/ipc-tester: Add case for MAP client service opcode boundries
> android/ipc-tester: Add cases for MAP client msg size
>
> android/Android.mk | 1 +
> android/Makefile.am | 1 +
> android/ipc-tester.c | 18 +++++
> android/main.c | 12 +++
> android/map-client.c | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++
> android/map-client.h | 26 +++++++
> 6 files changed, 263 insertions(+)
> create mode 100644 android/map-client.c
> create mode 100644 android/map-client.h
>
I've fixed this double free you mentioned and applied all patches, thanks.
--
Best regards,
Szymon Janc
^ permalink raw reply
* [PATCH] core: Add ControllerMode to list of supported options
From: Jacob Siverskog @ 2014-10-21 7:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jacob Siverskog
Signed-off-by: Jacob Siverskog <jacob@teenageengineering.com>
Prevent warning message 'Unknown key ControllerMode in main.conf'.
---
src/main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main.c b/src/main.c
index 191dc11..061060d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -79,6 +79,7 @@ static const char * const supported_options[] = {
"ReverseServiceDiscovery",
"NameResolving",
"DebugKeys",
+ "ControllerMode",
};
GKeyFile *btd_get_main_conf(void)
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH v2 bluetooth-next 1/4] 6lowpan: remove skb_deliver from IPHC
From: Alexander Aring @ 2014-10-21 7:31 UTC (permalink / raw)
To: Martin Townsend
Cc: Martin Townsend, linux-bluetooth, linux-wpan, marcel,
jukka.rissanen
In-Reply-To: <5445801D.30800@xsilon.com>
Hi Martin,
On Mon, Oct 20, 2014 at 10:35:25PM +0100, Martin Townsend wrote:
> Hi Alex,
>
> On 20/10/14 20:18, Alexander Aring wrote:
> >Hi Martin,
> >
> >On Mon, Oct 20, 2014 at 03:39:48PM +0100, Martin Townsend wrote:
> >>Separating skb delivery from decompression ensures that we can support further
> >>decompression schemes and removes the mixed return value of error codes with
> >>NET_RX_FOO.
> >>
> >>Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
> >>Signed-off-by: Martin Townsend <martin.townsend@xsilon.com>
> >All your patches have two different "Signed-off-by". Please use only one
> >here.
> I think I know how this occurred, 2 difference computers with 2 different
> git configs :) I'll fix this in the next series.
> >>---
> >> include/net/6lowpan.h | 4 +---
> >> net/6lowpan/iphc.c | 32 ++++++--------------------------
> >> net/bluetooth/6lowpan.c | 12 +++++++++++-
> >> net/ieee802154/6lowpan_rtnl.c | 26 ++++++++++++++------------
> >> 4 files changed, 32 insertions(+), 42 deletions(-)
> >>
> >...
> >>diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> >>index 6c5c2ef..03787e0 100644
> >>--- a/net/bluetooth/6lowpan.c
> >>+++ b/net/bluetooth/6lowpan.c
> >>@@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
> >> return lowpan_process_data(skb, netdev,
> >> saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
> >> daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
> >>- iphc0, iphc1, give_skb_to_upper);
> >>+ iphc0, iphc1);
> >> drop:
> >> kfree_skb(skb);
> >>@@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
> >> if (ret != NET_RX_SUCCESS)
> >> goto drop;
> >>+ local_skb->protocol = htons(ETH_P_IPV6);
> >>+ local_skb->pkt_type = PACKET_HOST;
> >>+ local_skb->dev = dev;
> >>+
> >>+ if (give_skb_to_upper(local_skb, dev)
> >>+ != NET_RX_SUCCESS) {
> >There is still a NET_RX_FOO and errno conversion in function
> >"give_skb_to_upper". Please check that, maybe introduce a new patch for
> >this one.
> I thought give_skb_to_upper only returned NET_RX_FOO return values? I'll
> double check and fix.
> >
<qoute>
static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
{
struct sk_buff *skb_cp;
skb_cp = skb_copy(skb, GFP_ATOMIC);
if (!skb_cp)
return -ENOMEM;
Returning errno here.
return netif_rx(skb_cp);
Returning NET_RX_FOO here. Here should be the same behaviour like below.
Only without a loop. Because the skb_share_check and only one lowpan
interface, I think we don't need the skb_copy here. This is out of scope
in this patch.
}
</qoute>
> >>+ kfree_skb(local_skb);
> >>+ goto drop;
> >>+ }
> >>+
> >> dev->stats.rx_bytes += skb->len;
> >> dev->stats.rx_packets++;
> >>diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
> >>index 0c1a49b..898d317 100644
> >>--- a/net/ieee802154/6lowpan_rtnl.c
> >>+++ b/net/ieee802154/6lowpan_rtnl.c
> >>@@ -146,8 +146,9 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
> >> if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
> >> skb_cp = skb_copy(skb, GFP_ATOMIC);
> >> if (!skb_cp) {
> >>- stat = -ENOMEM;
> >>- break;
> >>+ kfree_skb(skb);
> >>+ rcu_read_unlock();
> >>+ return NET_RX_DROP;
> >> }
> >> skb_cp->dev = entry->ldev;
> >>@@ -155,6 +156,11 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
> >> }
> >> rcu_read_unlock();
> >>+ if (stat == NET_RX_SUCCESS)
> >>+ consume_skb(skb);
> >>+ else
> >>+ kfree_skb(skb);
> >>+
> >You will not see it because somebody forgot brackets in the above
> >"list_for_each_entry_rcu" loop. But variable "stat" in this case is only
> >for the last entry of netif_rx call.
> This is a bug that's probably outside the scope of this patch.
> >Also if netif_rx returns NET_RX_DROP, which is the else branch in this
> >case. In case of netif_rx the skb will be freed somewhere else.
> >
> >Calltrace:
> >
> >- netif_rx
> >- netif_rx_internal
> >- enqueue_to_backlog
> > - kfree_skb(skb);
> > - return NET_RX_DROP;
> The copy will be freed not the skb that is passed to the function.
mhh, okay.
> skb_cp = skb_copy(skb, GFP_ATOMIC);
> ....
> stat = netif_rx(skb_cp);
>
> What to do with stat that is set multiple times in a loop. We could call
> skb_consume if stat is always NET_RX_SUCCESS or call skb_consume if stat is
> at least NET_RX_SUCCESS once, or maybe remove the loop further out the call
> chain ... if possible??
>
static int lowpan_give_skb_to_devices(struct sk_buff *skb,
struct net_device *dev)
{
struct lowpan_dev_record *entry;
struct sk_buff *skb_cp;
int stat = NET_RX_SUCCESS;
rcu_read_lock();
list_for_each_entry_rcu(entry, &lowpan_devices, list)
if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
skb_cp = skb_copy(skb, GFP_ATOMIC);
if (!skb_cp) {
kfree_skb(skb);
rcu_read_unlock();
return NET_RX_DROP;
}
skb_cp->dev = entry->ldev;
stat = netif_rx(skb_cp);
if (stat == NET_RX_DROP)
break;
}
rcu_read_unlock();
consume_skb(skb);
return stat;
}
We don't need no explicit run of kfree_skb or consume_skb here. in
this case "skb" should only a skb where we create copies from. After
that we don't dropping the skb. Okay, we only drop it if allocation
failed. I this okay now or I overlooked something here?
- Alex
^ permalink raw reply
* [PATCH v2] obexd/mas: Add Support for MSETime filter
From: Bharat Panda @ 2014-10-21 7:06 UTC (permalink / raw)
To: linux-bluetooth; +Cc: cpgs, Bharat Panda
Changes made to add support for MSE local time and timezone offset
parameter along with GetMessageListing response.
---
obexd/plugins/mas.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/obexd/plugins/mas.c b/obexd/plugins/mas.c
index fb97fe3..5379a01 100644
--- a/obexd/plugins/mas.c
+++ b/obexd/plugins/mas.c
@@ -30,6 +30,7 @@
#include <glib.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <sys/time.h>
#include <gobex/gobex.h>
#include <gobex/gobex-apparam.h>
@@ -228,6 +229,33 @@ static void g_string_append_escaped_printf(GString *string,
va_end(ap);
}
+static gchar *get_mse_timestamp(void)
+{
+ struct timeval time_val;
+ struct tm ltime;
+ gchar *local_ts;
+ char sign;
+
+ gettimeofday(&time_val, NULL);
+
+ if (!localtime_r(&time_val.tv_sec, <ime))
+ return NULL;
+
+ if (difftime(mktime(localtime(&time_val.tv_sec)),
+ mktime(gmtime(&time_val.tv_sec))) < 0)
+ sign = '+';
+ else
+ sign = '-';
+
+ local_ts = g_strdup_printf("%04d%02d%02dT%02d%02d%02d%c%2ld%2ld",
+ ltime.tm_year + 1900, ltime.tm_mon + 1,
+ ltime.tm_mday, ltime.tm_hour,
+ ltime.tm_min, ltime.tm_sec, sign,
+ ltime.tm_gmtoff/3600, (ltime.tm_gmtoff%3600)/60);
+
+ return local_ts;
+}
+
static const char *yesorno(gboolean a)
{
if (a)
@@ -243,6 +271,7 @@ static void get_messages_listing_cb(void *session, int err, uint16_t size,
{
struct mas_session *mas = user_data;
uint16_t max = 1024;
+ gchar *mse_time;
if (err < 0 && err != -EAGAIN) {
obex_object_set_io_flags(mas, G_IO_ERR, err);
@@ -358,6 +387,13 @@ proceed:
mas->outparams = g_obex_apparam_set_uint8(mas->outparams,
MAP_AP_NEWMESSAGE,
newmsg ? 1 : 0);
+ /* Response to report the local time of MSE */
+ mse_time = get_mse_timestamp();
+ if (mse_time) {
+ g_obex_apparam_set_string(mas->outparams,
+ MAP_AP_MSETIME, mse_time);
+ g_free(mse_time);
+ }
}
if (err != -EAGAIN)
--
1.9.1
^ permalink raw reply related
* Re: how to set PSCAN mode in .conf?
From: Jeff Chua @ 2014-10-21 5:53 UTC (permalink / raw)
To: Szymon Janc; +Cc: Marcel Holtmann, linux-bluetooth
In-Reply-To: <5460120.arhYbJZIVa@athlon>
On Tue, Oct 21, 2014 at 2:49 AM, Szymon Janc <szymon.janc@gmail.com> wrote:
> Proper syntax for this would be:
> btmgmt -i hci0 connectable on
Szymon,
Thank you. That works!
Jeff
^ permalink raw reply
* Re: how to set PSCAN mode in .conf?
From: Jeff Chua @ 2014-10-21 5:46 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <07E0A5D2-1E7E-4D89-A8A8-F87E643882A0@holtmann.org>
On Tue, Oct 21, 2014 at 2:03 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
> See doc/mgmt-api.txt for the details since btmgmt maps the management interface. In short action 1 means to allow incoming connections.
Marcel,
Got it. I tried "-a 0" and it returned Invalid Parameters. But anyway,
"1" is the one I needed.
> Mixing btmgmt and hciconfig is not a good idea. hciconfig is for all style APIs and btmgmt is for new mgmt interfaces. For example bluetoothd only uses the mgmt interface. So my advice is to just run bluetoothd and then use the D-Bus command to make it discoverable. That will always work correctly and still is as you have seen by running bluetoothctl.
>
> It is like this kernel -> mgmt -> bluetoothd -> D-Bus -> bluetoothctl. And you can replace bluetoothctl with a Python script or your own code.
Great advice. Thank you for sharing.
Jeff.
^ permalink raw reply
* BlueZ 5: SDP Record & D-Bus APIs
From: Sujay Sarkhel @ 2014-10-21 2:43 UTC (permalink / raw)
To: linux-bluetooth
I'm still getting used to BlueZ 5 D-Bus APIs and I was wondering if
someone can help me with a few queries that I've:
1. BlueZ 4 D-Bus Device API provided a method called
DiscoverServices(string pattern) that could be used to retrieve
service information from the remote device in XML format. I used to
use this XML information to retrieve several meta-data relevant to my
use-case.
For example: for Device ID profile, I would want to retrieve vendor
information (id/vendoridsource, etc), for HDP, the optional text
associated with an MDEP, etc.
>From what I understand, this method does not exist anymore in the
exposed APIs. I was wondering whether there's a workaround? How can I
still look at the meta-data?
2. I was investigating how to work with the BlueZ D-Bus GATT APIs when
it comes to talking to GATT services on remote devices. Is that
possible? If yes, then how do I retrieve the list of object path
corresponding to the available remote services?
I've a Bluetooth LE heart rate watch, to which I can connect and use
gatttool to talk to. I was wondering how to do the same using the
experimental APIs.
I apologize in advance for my ignorance. Still learning about BlueZ,
D-Bus and Bluetooth LE.
Would really appreciate any pointers in this regard. Thanks!
- Sujay
^ permalink raw reply
* BlueZ 5.24: Using the LE Heart Rate Profile
From: Sujay Sarkhel @ 2014-10-21 2:17 UTC (permalink / raw)
To: linux-bluetooth
Hi,
I'm pretty much new to using BlueZ 5 and I've been experimenting with
a Bluetooth LE heart rate watch on a Raspberry Pi. I would really
appreciate if someone can point me to the right direction.
When I run the "test-heartrate" test, I see the following error:
Traceback (most recent call last):
File "./test-heartrate", line 88, in <module>
properties = dev_prop.GetAll(HEARTRATE_INTERFACE)
File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 70, in __call__
return self._proxy_method(*args, **keywords)
File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 145, in __call__
**keywords)
File "/usr/lib/python2.7/dist-packages/dbus/connection.py", line
651, in call_blocking
message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.InvalidArgs:
No such interface 'org.bluez.HeartRate1'
Not sure what I'm doing wrong. Here're some relevant information
BlueZ version installed: 5.24
For installation, I followed the steps listed in:
http://www.linuxfromscratch.org/blfs/view/svn/general/bluez.html (with
one addition: I added --enable-experimental during configuration)
It seems I'm facing the same issue as described at:
http://comments.gmane.org/gmane.linux.bluez.kernel/47931
I've followed the suggestion provided as well as tried passing -E to
bluetoothd while running it but to no avail.
I can successfully run:
test-discovery : To discover devices, including the heart-rate watch
test-device connect <bt_addr>: To connect to this device
But the one that is failing for me is test-heartrate
Even after connecting to the device, when I try to introspect (
dbus-send --system --dest=org.bluez --print-reply [obj_path]
org.freedesktop.DBus.Introspectable.Introspect), I don't see the
"org.bluez.HeartRate1" showing up, with its appropriate methods.
I can post the entire introspection data, along with the device
properties that I get, if that helps.
Would really appreciate any helpful pointer in this regard. Thanks!!
^ permalink raw reply
* Discoverable undirected advertising report event
From: John Tobias @ 2014-10-21 1:05 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
Hi Bluez team,
Is there any existing command to respond to PTS for (discoverable
undirected advertising report event - TC_BROB_BCST_BV_02_C)?.
Regards,
John
^ permalink raw reply
* Re: [PATCH v2 bluetooth-next 1/4] 6lowpan: remove skb_deliver from IPHC
From: Martin Townsend @ 2014-10-20 21:35 UTC (permalink / raw)
To: Alexander Aring, Martin Townsend
Cc: linux-bluetooth, linux-wpan, marcel, jukka.rissanen
In-Reply-To: <20141020191855.GB31180@omega>
Hi Alex,
On 20/10/14 20:18, Alexander Aring wrote:
> Hi Martin,
>
> On Mon, Oct 20, 2014 at 03:39:48PM +0100, Martin Townsend wrote:
>> Separating skb delivery from decompression ensures that we can support further
>> decompression schemes and removes the mixed return value of error codes with
>> NET_RX_FOO.
>>
>> Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
>> Signed-off-by: Martin Townsend <martin.townsend@xsilon.com>
> All your patches have two different "Signed-off-by". Please use only one
> here.
I think I know how this occurred, 2 difference computers with 2
different git configs :) I'll fix this in the next series.
>> ---
>> include/net/6lowpan.h | 4 +---
>> net/6lowpan/iphc.c | 32 ++++++--------------------------
>> net/bluetooth/6lowpan.c | 12 +++++++++++-
>> net/ieee802154/6lowpan_rtnl.c | 26 ++++++++++++++------------
>> 4 files changed, 32 insertions(+), 42 deletions(-)
>>
> ...
>> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
>> index 6c5c2ef..03787e0 100644
>> --- a/net/bluetooth/6lowpan.c
>> +++ b/net/bluetooth/6lowpan.c
>> @@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
>> return lowpan_process_data(skb, netdev,
>> saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
>> daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
>> - iphc0, iphc1, give_skb_to_upper);
>> + iphc0, iphc1);
>>
>> drop:
>> kfree_skb(skb);
>> @@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
>> if (ret != NET_RX_SUCCESS)
>> goto drop;
>>
>> + local_skb->protocol = htons(ETH_P_IPV6);
>> + local_skb->pkt_type = PACKET_HOST;
>> + local_skb->dev = dev;
>> +
>> + if (give_skb_to_upper(local_skb, dev)
>> + != NET_RX_SUCCESS) {
> There is still a NET_RX_FOO and errno conversion in function
> "give_skb_to_upper". Please check that, maybe introduce a new patch for
> this one.
I thought give_skb_to_upper only returned NET_RX_FOO return values? I'll
double check and fix.
>
>> + kfree_skb(local_skb);
>> + goto drop;
>> + }
>> +
>> dev->stats.rx_bytes += skb->len;
>> dev->stats.rx_packets++;
>>
>> diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
>> index 0c1a49b..898d317 100644
>> --- a/net/ieee802154/6lowpan_rtnl.c
>> +++ b/net/ieee802154/6lowpan_rtnl.c
>> @@ -146,8 +146,9 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
>> if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
>> skb_cp = skb_copy(skb, GFP_ATOMIC);
>> if (!skb_cp) {
>> - stat = -ENOMEM;
>> - break;
>> + kfree_skb(skb);
>> + rcu_read_unlock();
>> + return NET_RX_DROP;
>> }
>>
>> skb_cp->dev = entry->ldev;
>> @@ -155,6 +156,11 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
>> }
>> rcu_read_unlock();
>>
>> + if (stat == NET_RX_SUCCESS)
>> + consume_skb(skb);
>> + else
>> + kfree_skb(skb);
>> +
> You will not see it because somebody forgot brackets in the above
> "list_for_each_entry_rcu" loop. But variable "stat" in this case is only
> for the last entry of netif_rx call.
This is a bug that's probably outside the scope of this patch.
> Also if netif_rx returns NET_RX_DROP, which is the else branch in this
> case. In case of netif_rx the skb will be freed somewhere else.
>
> Calltrace:
>
> - netif_rx
> - netif_rx_internal
> - enqueue_to_backlog
> - kfree_skb(skb);
> - return NET_RX_DROP;
The copy will be freed not the skb that is passed to the function.
skb_cp = skb_copy(skb, GFP_ATOMIC);
....
stat = netif_rx(skb_cp);
What to do with stat that is set multiple times in a loop. We could
call skb_consume if stat is always NET_RX_SUCCESS or call skb_consume if
stat is at least NET_RX_SUCCESS once, or maybe remove the loop further
out the call chain ... if possible??
>
> - Alex
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wpan" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
- Martin.
^ permalink raw reply
* [PATCH BlueZ 8/8] TODO: Update shared/gatt-server items.
From: Arman Uguray @ 2014-10-20 21:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
In-Reply-To: <1413838861-29956-1-git-send-email-armansito@chromium.org>
shared/gatt-server has been introduced, so removed that item. Added new
items for remaining tasks.
---
TODO | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/TODO b/TODO
index efaec11..b09b047 100644
--- a/TODO
+++ b/TODO
@@ -149,12 +149,43 @@ ATT/GATT (new shared stack)
Priority: Medium
Complexity: C2
-- Introduce shared/gatt-server, which combined with shared/gatt-db, can be used
- as a GATT server implementation.
+- Implement GATT read and write procedures for shared/gatt-server. These map to
+ the following ATT protocol operations:
+
+ Read Request
+ Read Blob Request
+ Write Command
+ Write Request
+ Prepare Write Request
+ Execute Write Request
+
+ Priority: Medium
+ Complexity: C2
+
+- Implement server-initiated ATT protocol operations for shared/gatt-server:
+
+ Handle Value Notification
+ Handle Value Indication
Priority: Medium
Complexity: C2
+- Provide a tool for shared/gatt-server. This tool should demonstrate how a
+ shared/gatt-db can be used together with a shared/gatt-server to implement the
+ GATT server role. This should be written in a way so that it can be easily
+ used in conjunction with a remote instance of tools/btgatt-client (i.e. it
+ should listen for incoming connections, have similar verbose output, etc.)
+
+ Priority: Medium
+ Complexity: C2
+
+- Implement other low-priority ATT protocol operations for shared/gatt-server:
+
+ Read Multiple Request
+
+ Priority: Low
+ Complexity: C1
+
- Implement the server portion of doc/gatt-api.txt using shared/gatt-server once
it exists.
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related
* [PATCH BlueZ 7/8] shared/gatt-server: Implement "Find Information" request.
From: Arman Uguray @ 2014-10-20 21:01 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
In-Reply-To: <1413838861-29956-1-git-send-email-armansito@chromium.org>
This patch implements the "Find Information" request for the GATT
server role.
---
src/shared/gatt-server.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 153 insertions(+), 1 deletion(-)
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 6c5ea2b..1388db7 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -57,6 +57,7 @@ struct bt_gatt_server {
unsigned int mtu_id;
unsigned int read_by_grp_type_id;
unsigned int read_by_type_id;
+ unsigned int find_info_id;
struct async_read_op *pending_read_op;
@@ -73,11 +74,12 @@ static void bt_gatt_server_free(struct bt_gatt_server *server)
bt_att_unregister(server->att, server->mtu_id);
bt_att_unregister(server->att, server->read_by_grp_type_id);
bt_att_unregister(server->att, server->read_by_type_id);
- bt_att_unref(server->att);
+ bt_att_unregister(server->att, server->find_info_id);
if (server->pending_read_op)
server->pending_read_op->server = NULL;
+ bt_att_unref(server->att);
free(server);
}
@@ -494,6 +496,148 @@ error:
NULL, NULL, NULL);
}
+static void put_uuid_le(const bt_uuid_t *src, void *dst)
+{
+ bt_uuid_t uuid;
+
+ switch (src->type) {
+ case BT_UUID16:
+ put_le16(src->value.u16, dst);
+ break;
+ case BT_UUID128:
+ bswap_128(&src->value.u128, dst);
+ break;
+ case BT_UUID32:
+ bt_uuid_to_uuid128(src, &uuid);
+ bswap_128(&uuid.value.u128, dst);
+ break;
+ default:
+ break;
+ }
+}
+
+static bool encode_find_info_rsp(struct gatt_db *db, struct queue *q,
+ uint16_t mtu,
+ uint8_t *pdu, uint16_t *len)
+{
+ uint16_t handle;
+ const bt_uuid_t *type;
+ int uuid_len, cur_uuid_len;
+ int iter = 0;
+
+ *len = 0;
+
+ while (queue_peek_head(q)) {
+ handle = PTR_TO_UINT(queue_pop_head(q));
+ type = gatt_db_get_attribute_type(db, handle);
+ if (!type)
+ return false;
+
+ cur_uuid_len = bt_uuid_len(type);
+
+ if (iter == 0) {
+ switch (cur_uuid_len) {
+ case 2:
+ uuid_len = 2;
+ pdu[0] = 0x01;
+ break;
+ case 4:
+ case 16:
+ uuid_len = 16;
+ pdu[0] = 0x02;
+ break;
+ default:
+ return false;
+ }
+
+ iter++;
+ } else if (cur_uuid_len != uuid_len)
+ break;
+
+ if (iter + uuid_len + 2 > mtu - 1)
+ break;
+
+ put_le16(handle, pdu + iter);
+ put_uuid_le(type, pdu + iter + 2);
+
+ iter += uuid_len + 2;
+ }
+
+ *len = iter;
+
+ return true;
+}
+
+static void find_info_cb(uint8_t opcode, const void *pdu,
+ uint16_t length, void *user_data)
+{
+ struct bt_gatt_server *server = user_data;
+ uint16_t start, end;
+ uint16_t mtu = bt_att_get_mtu(server->att);
+ uint8_t rsp_pdu[mtu];
+ uint16_t rsp_len;
+ uint8_t rsp_opcode;
+ uint8_t ecode = 0;
+ uint16_t ehandle = 0;
+ struct queue *q = NULL;
+
+ if (length != 4) {
+ ecode = BT_ATT_ERROR_INVALID_PDU;
+ goto error;
+ }
+
+ q = queue_new();
+ if (!q) {
+ ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
+ goto error;
+ }
+
+ start = get_le16(pdu);
+ end = get_le16(pdu + 2);
+
+ util_debug(server->debug_callback, server->debug_data,
+ "Find Info - start: 0x%04x end: 0x%04x",
+ start, end);
+
+ if (!start || !end) {
+ ecode = BT_ATT_ERROR_INVALID_HANDLE;
+ goto error;
+ }
+
+ ehandle = start;
+
+ if (start > end) {
+ ecode = BT_ATT_ERROR_INVALID_HANDLE;
+ goto error;
+ }
+
+ gatt_db_find_information(server->db, start, end, q);
+
+ if (queue_isempty(q)) {
+ ecode = BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND;
+ goto error;
+ }
+
+ if (!encode_find_info_rsp(server->db, q, mtu, rsp_pdu, &rsp_len)) {
+ ecode = BT_ATT_ERROR_UNLIKELY;
+ goto error;
+ }
+
+ rsp_opcode = BT_ATT_OP_FIND_INFO_RSP;
+
+ goto done;
+
+error:
+ rsp_opcode = BT_ATT_OP_ERROR_RSP;
+ rsp_len = 4;
+ encode_error_rsp(opcode, ehandle, ecode, rsp_pdu);
+
+done:
+ queue_destroy(q, NULL);
+ bt_att_send(server->att, rsp_opcode, rsp_pdu, rsp_len,
+ NULL, NULL, NULL);
+}
+
static void exchange_mtu_cb(uint8_t opcode, const void *pdu,
uint16_t length, void *user_data)
{
@@ -550,6 +694,14 @@ static bool gatt_server_register_att_handlers(struct bt_gatt_server *server)
if (!server->read_by_type_id)
return false;
+ /* Find Information */
+ server->find_info_id = bt_att_register(server->att,
+ BT_ATT_OP_FIND_INFO_REQ,
+ find_info_cb,
+ server, NULL);
+ if (!server->find_info_id)
+ return false;
+
return true;
}
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related
* [PATCH BlueZ 6/8] shared/gatt-server: Implement "Read By Type" request.
From: Arman Uguray @ 2014-10-20 21:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
In-Reply-To: <1413838861-29956-1-git-send-email-armansito@chromium.org>
This patch implements the ATT protocol "Read By Type" request for
shared/gatt-server. Logic is implemented that allows asynchronous
reading of non-standard attribute values via the registered read and
read completion callbacks.
---
src/shared/gatt-server.c | 273 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 270 insertions(+), 3 deletions(-)
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 3233b21..6c5ea2b 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -38,6 +38,16 @@
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
+struct async_read_op {
+ struct bt_gatt_server *server;
+ uint8_t opcode;
+ bool done;
+ uint8_t *pdu;
+ size_t pdu_len;
+ int value_len;
+ struct queue *db_data;
+};
+
struct bt_gatt_server {
struct gatt_db *db;
struct bt_att *att;
@@ -46,6 +56,9 @@ struct bt_gatt_server {
unsigned int mtu_id;
unsigned int read_by_grp_type_id;
+ unsigned int read_by_type_id;
+
+ struct async_read_op *pending_read_op;
bt_gatt_server_debug_func_t debug_callback;
bt_gatt_server_destroy_func_t debug_destroy;
@@ -59,8 +72,12 @@ static void bt_gatt_server_free(struct bt_gatt_server *server)
bt_att_unregister(server->att, server->mtu_id);
bt_att_unregister(server->att, server->read_by_grp_type_id);
+ bt_att_unregister(server->att, server->read_by_type_id);
bt_att_unref(server->att);
+ if (server->pending_read_op)
+ server->pending_read_op->server = NULL;
+
free(server);
}
@@ -124,21 +141,21 @@ static bool encode_read_by_grp_type_rsp(struct gatt_db *db, struct queue *q,
* value is seen.
*/
if (iter == 0) {
- data_val_len = value_len;
+ data_val_len = MIN(MIN(mtu - 6, 251), value_len);
pdu[0] = data_val_len + 4;
iter++;
} else if (value_len != data_val_len)
break;
/* Stop if this unit would surpass the MTU */
- if (iter + data_val_len + 4 > mtu)
+ if (iter + data_val_len + 4 > mtu - 1)
break;
end_handle = gatt_db_get_end_handle(db, start_handle);
put_le16(start_handle, pdu + iter);
put_le16(end_handle, pdu + iter + 2);
- memcpy(pdu + iter + 4, value, value_len);
+ memcpy(pdu + iter + 4, value, data_val_len);
iter += data_val_len + 4;
}
@@ -235,6 +252,248 @@ done:
NULL, NULL, NULL);
}
+static void async_read_op_destroy(struct async_read_op *op)
+{
+ if (op->server)
+ op->server->pending_read_op = NULL;
+
+ queue_destroy(op->db_data, NULL);
+ free(op->pdu);
+ free(op);
+}
+
+static void process_read_by_type(struct async_read_op *op);
+
+static void read_by_type_read_complete_cb(uint16_t handle, uint16_t att_ecode,
+ const uint8_t *value, size_t len,
+ void *complete_data)
+{
+ struct async_read_op *op = complete_data;
+ struct bt_gatt_server *server = op->server;
+ uint16_t mtu;
+
+ if (!server) {
+ async_read_op_destroy(op);
+ return;
+ }
+
+ mtu = bt_att_get_mtu(server->att);
+
+ /* Terminate the operation if there was an error */
+ if (att_ecode) {
+ uint8_t pdu[4];
+
+ encode_error_rsp(BT_ATT_OP_READ_BY_TYPE_REQ, handle, att_ecode,
+ pdu);
+ bt_att_send(server->att, BT_ATT_OP_ERROR_RSP, pdu, 4, NULL,
+ NULL, NULL);
+ async_read_op_destroy(op);
+ return;
+ }
+
+ if (op->pdu_len == 0) {
+ op->value_len = MIN(MIN(mtu - 4, 253), len);
+ op->pdu[0] = op->value_len + 2;
+ op->pdu_len++;
+ } else if (len != op->value_len) {
+ op->done = true;
+ goto done;
+ }
+
+ /* Stop if this would surpass the MTU */
+ if (op->pdu_len + op->value_len + 2 > mtu - 1) {
+ op->done = true;
+ goto done;
+ }
+
+ /* Encode the current value */
+ put_le16(handle, op->pdu + op->pdu_len);
+ memcpy(op->pdu + op->pdu_len + 2, value, op->value_len);
+
+ op->pdu_len += op->value_len + 2;
+
+ if (op->pdu_len == mtu - 1)
+ op->done = true;
+
+done:
+ process_read_by_type(op);
+}
+
+static void process_read_by_type(struct async_read_op *op)
+{
+ struct bt_gatt_server *server = op->server;
+ uint16_t mtu = bt_att_get_mtu(server->att);
+ uint8_t rsp_opcode;
+ uint8_t rsp_len;
+ uint8_t ecode;
+ uint16_t ehandle;
+ uint16_t start_handle;
+ uint8_t *value;
+ int value_len;
+ uint32_t perm;
+
+ if (op->done) {
+ rsp_opcode = BT_ATT_OP_READ_BY_TYPE_RSP;
+ rsp_len = op->pdu_len;
+ goto done;
+ }
+
+ while (queue_peek_head(op->db_data)) {
+ start_handle = PTR_TO_UINT(queue_pop_head(op->db_data));
+ value = NULL;
+ value_len = 0;
+
+ if (!gatt_db_get_attribute_permissions(server->db, start_handle,
+ &perm)) {
+ ecode = BT_ATT_ERROR_UNLIKELY;
+ goto error;
+ }
+
+ /*
+ * Check for the READ access permission. Encryption,
+ * authentication, and authorization permissions need to be
+ * checked by the read handler, since bt_att is agnostic to
+ * connection type and doesn't have security information on it.
+ */
+ if (perm && !(perm & BT_ATT_PERM_READ)) {
+ ecode = BT_ATT_ERROR_READ_NOT_PERMITTED;
+ goto error;
+ }
+
+ if (!gatt_db_read(server->db, start_handle, 0, op->opcode, NULL,
+ &value, &value_len,
+ read_by_type_read_complete_cb, op)) {
+ ecode = BT_ATT_ERROR_UNLIKELY;
+ goto error;
+ }
+
+ /* The read has been deferred to the upper layer if |value_len|
+ * is less than 0.
+ */
+ if (value_len < 0)
+ return;
+
+ if (op->pdu_len == 0) {
+ op->value_len = MIN(MIN(mtu - 4, 253), value_len);
+ op->pdu[0] = op->value_len + 2;
+ op->pdu_len++;
+ } else if (value_len != op->value_len)
+ break;
+
+ /* Stop if this would surpass the MTU */
+ if (op->pdu_len + op->value_len + 2 > mtu - 1)
+ break;
+
+ /* Encode the current value */
+ put_le16(start_handle, op->pdu + op->pdu_len);
+ memcpy(op->pdu + op->pdu_len + 2, value, op->value_len);
+
+ op->pdu_len += op->value_len + 2;
+
+ if (op->pdu_len == mtu - 1)
+ break;
+ }
+
+ rsp_opcode = BT_ATT_OP_READ_BY_TYPE_RSP;
+ rsp_len = op->pdu_len;
+
+ goto done;
+
+error:
+ rsp_opcode = BT_ATT_OP_ERROR_RSP;
+ rsp_len = 4;
+ encode_error_rsp(BT_ATT_OP_READ_BY_TYPE_REQ, ehandle, ecode, op->pdu);
+
+done:
+ bt_att_send(server->att, rsp_opcode, op->pdu, rsp_len, NULL,
+ NULL, NULL);
+ async_read_op_destroy(op);
+}
+
+static void read_by_type_cb(uint8_t opcode, const void *pdu,
+ uint16_t length, void *user_data)
+{
+ struct bt_gatt_server *server = user_data;
+ uint16_t start, end;
+ bt_uuid_t type;
+ uint8_t rsp_pdu[4];
+ uint16_t ehandle = 0;
+ uint8_t ecode;
+ struct queue *q = NULL;
+ struct async_read_op *op;
+
+ if (length != 6 && length != 20) {
+ ecode = BT_ATT_ERROR_INVALID_PDU;
+ goto error;
+ }
+
+ q = queue_new();
+ if (!q) {
+ ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
+ goto error;
+ }
+
+ start = get_le16(pdu);
+ end = get_le16(pdu + 2);
+ get_uuid_le(pdu + 4, length - 4, &type);
+
+ util_debug(server->debug_callback, server->debug_data,
+ "Read By Type - start: 0x%04x end: 0x%04x",
+ start, end);
+
+ if (!start || !end) {
+ ecode = BT_ATT_ERROR_INVALID_HANDLE;
+ goto error;
+ }
+
+ ehandle = start;
+
+ if (start > end) {
+ ecode = BT_ATT_ERROR_INVALID_HANDLE;
+ goto error;
+ }
+
+ gatt_db_read_by_type(server->db, start, end, type, q);
+
+ if (queue_isempty(q)) {
+ ecode = BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND;
+ goto error;
+ }
+
+ if (server->pending_read_op) {
+ ecode = BT_ATT_ERROR_UNLIKELY;
+ goto error;
+ }
+
+ op = new0(struct async_read_op, 1);
+ if (!op) {
+ ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
+ goto error;
+ }
+
+ op->pdu = malloc(bt_att_get_mtu(server->att));
+ if (!op->pdu) {
+ free(op);
+ ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
+ goto error;
+ }
+
+ op->opcode = opcode;
+ op->server = server;
+ op->db_data = q;
+ server->pending_read_op = op;
+
+ process_read_by_type(op);
+
+ return;
+
+error:
+ encode_error_rsp(opcode, ehandle, ecode, rsp_pdu);
+ queue_destroy(q, NULL);
+ bt_att_send(server->att, BT_ATT_OP_ERROR_RSP, rsp_pdu, 4,
+ NULL, NULL, NULL);
+}
+
static void exchange_mtu_cb(uint8_t opcode, const void *pdu,
uint16_t length, void *user_data)
{
@@ -283,6 +542,14 @@ static bool gatt_server_register_att_handlers(struct bt_gatt_server *server)
if (!server->read_by_grp_type_id)
return false;
+ /* Read By Type */
+ server->read_by_type_id = bt_att_register(server->att,
+ BT_ATT_OP_READ_BY_TYPE_REQ,
+ read_by_type_cb,
+ server, NULL);
+ if (!server->read_by_type_id)
+ return false;
+
return true;
}
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related
* [PATCH BlueZ 5/8] shared/att-types: Add attribute permission bitfield definitions.
From: Arman Uguray @ 2014-10-20 21:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
In-Reply-To: <1413838861-29956-1-git-send-email-armansito@chromium.org>
GATT doesn't have a standard way of representing attribute permissions
but coming up with values that can be used consistently among code that
uses shared/att is valuable. This patch introduces macros to represent
attribute permissions in a bitfield, with specific bits assigned to
read and write access, encryption, authentication, and authorization
permissions.
---
src/shared/att-types.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/shared/att-types.h b/src/shared/att-types.h
index b57a5f3..a6b23e4 100644
--- a/src/shared/att-types.h
+++ b/src/shared/att-types.h
@@ -74,6 +74,18 @@
#define BT_ATT_ERROR_UNSUPPORTED_GROUP_TYPE 0x10
#define BT_ATT_ERROR_INSUFFICIENT_RESOURCES 0x11
+/*
+ * ATT attribute permission bitfield values. Permissions are grouped as
+ * "Access", "Encryption", "Authentication", and "Authorization". A bitmask of
+ * permissions is a byte that encodes a combination of these.
+ */
+#define BT_ATT_PERM_READ 0x01
+#define BT_ATT_PERM_WRITE 0x02
+#define BT_ATT_PERM_ENCRYPT 0x04
+#define BT_ATT_PERM_AUTHEN 0x08
+#define BT_ATT_PERM_AUTHOR 0x10
+#define BT_ATT_PERM_NONE 0x20
+
/* GATT Characteristic Properties Bitfield values */
#define BT_GATT_CHRC_PROP_BROADCAST 0x01
#define BT_GATT_CHRC_PROP_READ 0x02
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related
* [PATCH BlueZ 4/8] shared/att-types: Move GATT characteristic property defines to att-types.
From: Arman Uguray @ 2014-10-20 21:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
In-Reply-To: <1413838861-29956-1-git-send-email-armansito@chromium.org>
This patch moves GATT characteristic property macros from gatt-client to
att-types. att-types is a logical place for these since gatt-server will
make use of them as well.
---
src/shared/att-types.h | 14 ++++++++++++++
src/shared/gatt-client.h | 9 ---------
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/src/shared/att-types.h b/src/shared/att-types.h
index b85c969..b57a5f3 100644
--- a/src/shared/att-types.h
+++ b/src/shared/att-types.h
@@ -73,3 +73,17 @@
#define BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION 0x0F
#define BT_ATT_ERROR_UNSUPPORTED_GROUP_TYPE 0x10
#define BT_ATT_ERROR_INSUFFICIENT_RESOURCES 0x11
+
+/* GATT Characteristic Properties Bitfield values */
+#define BT_GATT_CHRC_PROP_BROADCAST 0x01
+#define BT_GATT_CHRC_PROP_READ 0x02
+#define BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP 0x04
+#define BT_GATT_CHRC_PROP_WRITE 0x08
+#define BT_GATT_CHRC_PROP_NOTIFY 0x10
+#define BT_GATT_CHRC_PROP_INDICATE 0x20
+#define BT_GATT_CHRC_PROP_AUTH 0x40
+#define BT_GATT_CHRC_PROP_EXT_PROP 0x80
+
+/* GATT Characteristic Extended Properties Bitfield values */
+#define BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE 0x01
+#define BT_GATT_CHRC_EXT_PROP_WRITABLE_AUX 0x02
diff --git a/src/shared/gatt-client.h b/src/shared/gatt-client.h
index 6807f6b..6b8719f 100644
--- a/src/shared/gatt-client.h
+++ b/src/shared/gatt-client.h
@@ -27,15 +27,6 @@
#define BT_GATT_UUID_SIZE 16
-#define BT_GATT_CHRC_PROP_BROADCAST 0x01
-#define BT_GATT_CHRC_PROP_READ 0x02
-#define BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP 0x04
-#define BT_GATT_CHRC_PROP_WRITE 0x08
-#define BT_GATT_CHRC_PROP_NOTIFY 0x10
-#define BT_GATT_CHRC_PROP_INDICATE 0x20
-#define BT_GATT_CHRC_PROP_AUTH 0x40
-#define BT_GATT_CHRC_PROP_EXT_PROP 0x80
-
struct bt_gatt_client;
struct bt_gatt_client *bt_gatt_client_new(struct bt_att *att, uint16_t mtu);
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related
* [PATCH BlueZ 3/8] shared/gatt-db: Add complete callback to gatt_db_write.
From: Arman Uguray @ 2014-10-20 21:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
In-Reply-To: <1413838861-29956-1-git-send-email-armansito@chromium.org>
This patch introduces a completion callback parameter to gatt_db_write,
which is meant to be used by a gatt_db_write_t implementation to signal
the end of an asynchronous read operation performed in the upper layer.
---
android/gatt.c | 21 +++++++++++++--------
src/shared/gatt-db.c | 7 +++++--
src/shared/gatt-db.h | 8 +++++++-
3 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/android/gatt.c b/android/gatt.c
index e2aa686..80ba728 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -4799,6 +4799,8 @@ failed:
static void write_cb(uint16_t handle, uint16_t offset,
const uint8_t *value, size_t len,
uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_write_complete_t complete_func,
+ void *complete_data,
void *user_data)
{
uint8_t buf[IPC_MTU];
@@ -5880,7 +5882,8 @@ static void write_cmd_request(const uint8_t *cmd, uint16_t cmd_len,
if (check_device_permissions(dev, cmd[0], permissions))
return;
- gatt_db_write(gatt_db, handle, 0, value, vlen, cmd[0], &dev->bdaddr);
+ gatt_db_write(gatt_db, handle, 0, value, vlen, cmd[0], &dev->bdaddr,
+ NULL, NULL);
}
static void write_signed_cmd_request(const uint8_t *cmd, uint16_t cmd_len,
@@ -5948,7 +5951,7 @@ static void write_signed_cmd_request(const uint8_t *cmd, uint16_t cmd_len,
/* Signature OK, proceed with write */
bt_update_sign_counter(&dev->bdaddr, REMOTE_CSRK, r_sign_cnt);
gatt_db_write(gatt_db, handle, 0, value, vlen, cmd[0],
- &dev->bdaddr);
+ &dev->bdaddr, NULL, NULL);
}
}
@@ -5990,7 +5993,7 @@ static uint8_t write_req_request(const uint8_t *cmd, uint16_t cmd_len,
}
if (!gatt_db_write(gatt_db, handle, 0, value, vlen, cmd[0],
- &dev->bdaddr)) {
+ &dev->bdaddr, NULL, NULL)) {
queue_remove(dev->pending_requests, data);
free(data);
return ATT_ECODE_UNLIKELY;
@@ -6042,7 +6045,7 @@ static uint8_t write_prep_request(const uint8_t *cmd, uint16_t cmd_len,
}
if (!gatt_db_write(gatt_db, handle, offset, value, vlen, cmd[0],
- &dev->bdaddr))
+ &dev->bdaddr, NULL, NULL))
return ATT_ECODE_UNLIKELY;
return 0;
@@ -6583,10 +6586,12 @@ static void register_device_info_service(void)
}
static void gatt_srvc_change_write_cb(uint16_t handle, uint16_t offset,
- const uint8_t *val, size_t len,
- uint8_t att_opcode,
- bdaddr_t *bdaddr,
- void *user_data)
+ const uint8_t *val, size_t len,
+ uint8_t att_opcode,
+ bdaddr_t *bdaddr,
+ gatt_db_write_complete_t complete_func,
+ void *complete_data,
+ void *user_data)
{
struct pending_request *entry;
struct gatt_device *dev;
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index c342e32..afb0c75 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -682,7 +682,9 @@ bool gatt_db_read(struct gatt_db *db, uint16_t handle, uint16_t offset,
bool gatt_db_write(struct gatt_db *db, uint16_t handle, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t att_opcode, bdaddr_t *bdaddr)
+ uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_write_complete_t complete_func,
+ void *complete_data)
{
struct gatt_db_service *service;
uint16_t service_handle;
@@ -700,7 +702,8 @@ bool gatt_db_write(struct gatt_db *db, uint16_t handle, uint16_t offset,
return false;
a->write_func(handle, offset, value, len, att_opcode, bdaddr,
- a->user_data);
+ complete_func, complete_data,
+ a->user_data);
return true;
}
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index 1c8739e..c940b71 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -39,9 +39,13 @@ typedef void (*gatt_db_read_t) (uint16_t handle, uint16_t offset,
void *complete_data,
void *user_data);
+typedef void (*gatt_db_write_complete_t)(uint16_t handle, uint16_t att_ecode,
+ void *complete_data);
typedef void (*gatt_db_write_t) (uint16_t handle, uint16_t offset,
const uint8_t *value, size_t len,
uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_write_complete_t complete_func,
+ void *complete_data,
void *user_data);
uint16_t gatt_db_add_characteristic(struct gatt_db *db, uint16_t handle,
@@ -92,7 +96,9 @@ bool gatt_db_read(struct gatt_db *db, uint16_t handle, uint16_t offset,
bool gatt_db_write(struct gatt_db *db, uint16_t handle, uint16_t offset,
const uint8_t *value, size_t len,
- uint8_t att_opcode, bdaddr_t *bdaddr);
+ uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_write_complete_t complete_func,
+ void *complete_data);
const bt_uuid_t *gatt_db_get_attribute_type(struct gatt_db *db,
uint16_t handle);
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related
* [PATCH BlueZ 2/8] shared/gatt-db: Add complete callback to gatt_db_read.
From: Arman Uguray @ 2014-10-20 21:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
In-Reply-To: <1413838861-29956-1-git-send-email-armansito@chromium.org>
This patch introduces a completion callback parameter to gatt_db_read,
which is meant to be used by a gatt_db_read_t implementation to signal
the end of an asynchronous read operation performed in the upper layer.
---
android/gatt.c | 21 ++++++++++++++++++---
src/shared/gatt-db.c | 7 +++++--
src/shared/gatt-db.h | 9 ++++++++-
src/shared/gatt-server.c | 4 ++--
4 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/android/gatt.c b/android/gatt.c
index ea20941..e2aa686 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -4694,7 +4694,8 @@ static void read_requested_attributes(void *data, void *user_data)
resp_data->offset,
process_data->opcode,
&process_data->device->bdaddr,
- &value, &value_len))
+ &value, &value_len,
+ NULL, NULL))
error = ATT_ECODE_UNLIKELY;
/* We have value here already if no callback will be called */
@@ -4744,7 +4745,10 @@ static struct pending_trans_data *conn_add_transact(struct app_connection *conn,
}
static void read_cb(uint16_t handle, uint16_t offset, uint8_t att_opcode,
- bdaddr_t *bdaddr, void *user_data)
+ bdaddr_t *bdaddr,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data,
+ void *user_data)
{
struct pending_trans_data *transaction;
struct hal_ev_gatt_server_request_read ev;
@@ -6266,7 +6270,10 @@ static struct gap_srvc_handles gap_srvc_data;
#define PERIPHERAL_PRIVACY_DISABLE 0x00
static void gap_read_cb(uint16_t handle, uint16_t offset, uint8_t att_opcode,
- bdaddr_t *bdaddr, void *user_data)
+ bdaddr_t *bdaddr,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data,
+ void *user_data)
{
struct pending_request *entry;
struct gatt_device *dev;
@@ -6373,6 +6380,8 @@ static void register_gap_service(void)
static void device_info_read_cb(uint16_t handle, uint16_t offset,
uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data,
void *user_data)
{
struct pending_request *entry;
@@ -6406,6 +6415,8 @@ done:
static void device_info_read_system_id_cb(uint16_t handle, uint16_t offset,
uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data,
void *user_data)
{
struct pending_request *entry;
@@ -6438,6 +6449,8 @@ done:
static void device_info_read_pnp_id_cb(uint16_t handle, uint16_t offset,
uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data,
void *user_data)
{
struct pending_request *entry;
@@ -6602,6 +6615,8 @@ static void gatt_srvc_change_write_cb(uint16_t handle, uint16_t offset,
static void gatt_srvc_change_read_cb(uint16_t handle, uint16_t offset,
uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data,
void *user_data)
{
struct pending_request *entry;
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index b3f95d2..c342e32 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -638,7 +638,9 @@ static bool find_service_for_handle(const void *data, const void *user_data)
bool gatt_db_read(struct gatt_db *db, uint16_t handle, uint16_t offset,
uint8_t att_opcode, bdaddr_t *bdaddr,
- uint8_t **value, int *length)
+ uint8_t **value, int *length,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data)
{
struct gatt_db_service *service;
uint16_t service_handle;
@@ -665,7 +667,8 @@ bool gatt_db_read(struct gatt_db *db, uint16_t handle, uint16_t offset,
if (a->read_func) {
*value = NULL;
*length = -1;
- a->read_func(handle, offset, att_opcode, bdaddr, a->user_data);
+ a->read_func(handle, offset, att_opcode, bdaddr, complete_func,
+ complete_data, a->user_data);
} else {
if (offset > a->value_len)
return false;
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index 8d18434..1c8739e 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -30,8 +30,13 @@ uint16_t gatt_db_add_service(struct gatt_db *db, const bt_uuid_t *uuid,
bool primary, uint16_t num_handles);
bool gatt_db_remove_service(struct gatt_db *db, uint16_t handle);
+typedef void (*gatt_db_read_complete_t)(uint16_t handle, uint16_t att_ecode,
+ const uint8_t *value, size_t len,
+ void *complete_data);
typedef void (*gatt_db_read_t) (uint16_t handle, uint16_t offset,
uint8_t att_opcode, bdaddr_t *bdaddr,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data,
void *user_data);
typedef void (*gatt_db_write_t) (uint16_t handle, uint16_t offset,
@@ -81,7 +86,9 @@ void gatt_db_find_information(struct gatt_db *db, uint16_t start_handle,
bool gatt_db_read(struct gatt_db *db, uint16_t handle, uint16_t offset,
uint8_t att_opcode, bdaddr_t *bdaddr,
- uint8_t **value, int *length);
+ uint8_t **value, int *length,
+ gatt_db_read_complete_t complete_func,
+ void *complete_data);
bool gatt_db_write(struct gatt_db *db, uint16_t handle, uint16_t offset,
const uint8_t *value, size_t len,
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 657b564..3233b21 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -114,8 +114,8 @@ static bool encode_read_by_grp_type_rsp(struct gatt_db *db, struct queue *q,
*/
if (!gatt_db_read(db, start_handle, 0,
BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
- NULL, &value,
- &value_len) || value_len < 0)
+ NULL, &value, &value_len,
+ NULL, NULL) || value_len < 0)
return false;
/*
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related
* [PATCH BlueZ 1/8] shared/att: bt_att_cancel should not cancel pending requests/indications.
From: Arman Uguray @ 2014-10-20 21:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
In-Reply-To: <1413838861-29956-1-git-send-email-armansito@chromium.org>
bt_att_cancel and bt_att_cancel_all no longer destroy any pending
request or indication, since this would cause a later bt_att_send to
erroneously send out a request or indication before a
response/confirmation for a pending one is received. Instead, they now
keep the pending operations but clear their response and destroy
callbacks since the upper layer is no longer interested in them.
---
src/shared/att.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/src/shared/att.c b/src/shared/att.c
index 503e06c..c70d396 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -1029,15 +1029,17 @@ bool bt_att_cancel(struct bt_att *att, unsigned int id)
return false;
if (att->pending_req && att->pending_req->id == id) {
- op = att->pending_req;
- att->pending_req = NULL;
- goto done;
+ /* Don't cancel the pending request; remove it's handlers */
+ att->pending_req->callback = NULL;
+ att->pending_req->destroy = NULL;
+ return true;
}
if (att->pending_ind && att->pending_ind->id == id) {
- op = att->pending_ind;
- att->pending_ind = NULL;
- goto done;
+ /* Don't cancel the pending indication; remove it's handlers */
+ att->pending_ind->callback = NULL;
+ att->pending_ind->destroy = NULL;
+ return true;
}
op = queue_remove_if(att->req_queue, match_op_id, UINT_TO_PTR(id));
@@ -1073,13 +1075,15 @@ bool bt_att_cancel_all(struct bt_att *att)
queue_remove_all(att->write_queue, NULL, NULL, destroy_att_send_op);
if (att->pending_req) {
- destroy_att_send_op(att->pending_req);
- att->pending_req = NULL;
+ /* Don't cancel the pending request; remove it's handlers */
+ att->pending_req->callback = NULL;
+ att->pending_req->destroy = NULL;
}
if (att->pending_ind) {
- destroy_att_send_op(att->pending_ind);
- att->pending_ind = NULL;
+ /* Don't cancel the pending indication; remove it's handlers */
+ att->pending_ind->callback = NULL;
+ att->pending_ind->destroy = NULL;
}
return true;
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related
* [PATCH BlueZ 0/8] shared/gatt-server: Implement discovery operations.
From: Arman Uguray @ 2014-10-20 21:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Arman Uguray
This patch set implements the server side of GATT discovery procedures. With
this, characteristic, descriptor, and include declaration discovery can be
performed on a device running shared/gatt-server.
Also included are modifications to shared/gatt-db's external read/write handlers
and minor fixes to shared/att.
The TODO has also been updated to reflect the remaining core shared/gatt-server
features. I've already started with most of them but I'm including them there to
track the progress.
Arman Uguray (8):
shared/att: bt_att_cancel should not cancel pending
requests/indications.
shared/gatt-db: Add complete callback to gatt_db_read.
shared/gatt-db: Add complete callback to gatt_db_write.
shared/att-types: Move GATT characteristic property defines to
att-types.
shared/att-types: Add attribute permission bitfield definitions.
shared/gatt-server: Implement "Read By Type" request.
shared/gatt-server: Implement "Find Information" request.
TODO: Update shared/gatt-server items.
TODO | 35 +++-
android/gatt.c | 42 +++--
src/shared/att-types.h | 26 +++
src/shared/att.c | 24 +--
src/shared/gatt-client.h | 9 -
src/shared/gatt-db.c | 14 +-
src/shared/gatt-db.h | 17 +-
src/shared/gatt-server.c | 431 ++++++++++++++++++++++++++++++++++++++++++++++-
8 files changed, 554 insertions(+), 44 deletions(-)
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply
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