* [RFC] Add new method to DBus API: DiscoverServiceByUUID @ 2015-05-28 20:44 Jakub Pawlowski 2015-05-28 21:32 ` Luiz Augusto von Dentz 0 siblings, 1 reply; 10+ messages in thread From: Jakub Pawlowski @ 2015-05-28 20:44 UTC (permalink / raw) To: BlueZ development Currently, calling org.bluez.Device1.Connect() on a new, never connected before device, would cause automatic discovery of all services. This is bad in some cases, because discovering all available services might take a long time. Additionally some devices, i.e. iPhone have built-in 0.5s delay between each "Find Information Response" packet, which make discovery even longer. I would like to propose following change: 1. Calling org.bluez.Device1.Connect() would work just like now, except no "Find Information Request" would be issued (that means no call to "device_browse_gatt"). 2. Add two new methods: org.bluez.Device1.DiscoverServices(), and org.bluez.Device1.DiscoverServiceByUUID(uuid). First one would just call device_browse_gatt and make "Find Information Request" , the second one would issue "Find By Type Value Request" to find just one service. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-05-28 20:44 [RFC] Add new method to DBus API: DiscoverServiceByUUID Jakub Pawlowski @ 2015-05-28 21:32 ` Luiz Augusto von Dentz 2015-05-28 22:25 ` Jakub Pawlowski 0 siblings, 1 reply; 10+ messages in thread From: Luiz Augusto von Dentz @ 2015-05-28 21:32 UTC (permalink / raw) To: Jakub Pawlowski; +Cc: BlueZ development Hi Jakub, On Thu, May 28, 2015 at 11:44 PM, Jakub Pawlowski <jpawlowski@google.com> wrote: > Currently, calling org.bluez.Device1.Connect() on a new, never > connected before device, would cause automatic discovery of all > services. > > This is bad in some cases, because discovering all available services > might take a long time. Additionally some devices, i.e. iPhone have > built-in 0.5s delay between each "Find Information Response" packet, > which make discovery even longer. > > > I would like to propose following change: > > 1. Calling org.bluez.Device1.Connect() would work just like now, > except no "Find Information Request" would be issued (that means no > call to "device_browse_gatt"). > > 2. Add two new methods: org.bluez.Device1.DiscoverServices(), and > org.bluez.Device1.DiscoverServiceByUUID(uuid). First one would just > call device_browse_gatt and make "Find Information Request" , the > second one would issue "Find By Type Value Request" to find just one > service. You are just changing one problem to another, or actually many other problems: 1. Instead of just 1 method there is at least 2, but Connect depends on what has been discovered first so you are adding a D-Bus round trips. 2. DiscoverServiceByUUID can only discover primary services if I remember correct, what about included? And if an application, or many, decide to discovery one by one every single UUID defined in the spec, how many more request that would be compared to Read by Group Type Request? 3. We can't take advance of Service Changed Characteristic if DiscoverServiceByUUID, so at that point one would have to start polling if the remote server has capability to change its database. I guess the problem number 3 is actually what you did not consider, the whole point is that we discover only once and then let the server tell us what has changed, so reconnection should happens very fast because we already have the device database in cache. -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-05-28 21:32 ` Luiz Augusto von Dentz @ 2015-05-28 22:25 ` Jakub Pawlowski 2015-05-29 8:35 ` Luiz Augusto von Dentz 2015-05-31 2:55 ` Johan Hedberg 0 siblings, 2 replies; 10+ messages in thread From: Jakub Pawlowski @ 2015-05-28 22:25 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: BlueZ development Hi Luiz, On Thu, May 28, 2015 at 2:32 PM, Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > Hi Jakub, > > On Thu, May 28, 2015 at 11:44 PM, Jakub Pawlowski <jpawlowski@google.com> wrote: >> Currently, calling org.bluez.Device1.Connect() on a new, never >> connected before device, would cause automatic discovery of all >> services. >> >> This is bad in some cases, because discovering all available services >> might take a long time. Additionally some devices, i.e. iPhone have >> built-in 0.5s delay between each "Find Information Response" packet, >> which make discovery even longer. >> >> >> I would like to propose following change: >> >> 1. Calling org.bluez.Device1.Connect() would work just like now, >> except no "Find Information Request" would be issued (that means no >> call to "device_browse_gatt"). >> >> 2. Add two new methods: org.bluez.Device1.DiscoverServices(), and >> org.bluez.Device1.DiscoverServiceByUUID(uuid). First one would just >> call device_browse_gatt and make "Find Information Request" , the >> second one would issue "Find By Type Value Request" to find just one >> service. > > You are just changing one problem to another, or actually many other problems: > Example use case to make things clearer: there's device advertising it contains service with UUID "abcd", and my app wants to use only this one. It connects to device, and asks only for this service. If it's not there I disconnect. If it's there, it read/writes and disconnect. Everything took ~1.5 second. If I can't do "Find By Type Value Request" I'm stuck discovering services for 6, or 10, or more seconds, depending of number of services on device. > 1. Instead of just 1 method there is at least 2, but Connect depends > on what has been discovered first so you are adding a D-Bus round > trips. Yes, I'm probably adding one round trip. It might hovewer be avoided. To avoid additional roundtrip there should be two methods: Connect() that just works right now, and ConnectToUUID(uuid) that would connect, and then do "Find By Type Value Request". I think that this solution wouldn't be that clean, and would be problematic to discover rest of services. One round trip per connection isn't that bad issue, is it ? > 2. DiscoverServiceByUUID can only discover primary services if I > remember correct, what about included? And if an application, or many, It can discovery Primary or Secondary services, but it is used for Primary only right now as far as I know. > decide to discovery one by one every single UUID defined in the spec, > how many more request that would be compared to Read by Group Type > Request? If application want to use only one service, and it cares about speed it should use this new method (I think that's the reason Bluetooth have "Find By Type Value Request"). If application doesn't know what it wants, it should find all services for sure. If application want more than one service, or included service, it should probably discover all at once. If application wants to discover included service, it can do Read by Group Type with handle range that's included in "included service" attribute (would need new API method if we want that, or use discover all service). > 3. We can't take advance of Service Changed Characteristic if > DiscoverServiceByUUID, so at that point one would have to start > polling if the remote server has capability to change its database. > > I guess the problem number 3 is actually what you did not consider, > the whole point is that we discover only once and then let the server > tell us what has changed, so reconnection should happens very fast > because we already have the device database in cache. Right, I haven't conseidered number 3, but: - app might decide to later discover rest of services, or - just service I discovered might be still cached, or - service I need might be re-discovered because it's only one and it's fast in comparison to discovering all - maybe if device get paired, full service discovery will be required ? otherwise it'll change MAC in 15 minutes and be forgotten anyway. I'll figure out how to deal nicely with cache. I think that discovering one service should be a option in modern BLE API (and I know few projects that need it). Please note that i.e. MAC API have that. For other reasons why that's good idea see "Explore a Peripheral’s Data Wisely" at https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/BestPracticesForInteractingWithARemotePeripheralDevice/BestPracticesForInteractingWithARemotePeripheralDevice.html#//apple_ref/doc/uid/TP40013257-CH6-SW6 I think it's more "how to do it right" than "whether to do it". Thanks, Jakub. > > > -- > Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-05-28 22:25 ` Jakub Pawlowski @ 2015-05-29 8:35 ` Luiz Augusto von Dentz 2015-05-31 2:55 ` Johan Hedberg 1 sibling, 0 replies; 10+ messages in thread From: Luiz Augusto von Dentz @ 2015-05-29 8:35 UTC (permalink / raw) To: Jakub Pawlowski; +Cc: BlueZ development Hi Jakub, On Fri, May 29, 2015 at 1:25 AM, Jakub Pawlowski <jpawlowski@google.com> wrote: > Hi Luiz, > > On Thu, May 28, 2015 at 2:32 PM, Luiz Augusto von Dentz > <luiz.dentz@gmail.com> wrote: >> Hi Jakub, >> >> On Thu, May 28, 2015 at 11:44 PM, Jakub Pawlowski <jpawlowski@google.com> wrote: >>> Currently, calling org.bluez.Device1.Connect() on a new, never >>> connected before device, would cause automatic discovery of all >>> services. >>> >>> This is bad in some cases, because discovering all available services >>> might take a long time. Additionally some devices, i.e. iPhone have >>> built-in 0.5s delay between each "Find Information Response" packet, >>> which make discovery even longer. >>> >>> >>> I would like to propose following change: >>> >>> 1. Calling org.bluez.Device1.Connect() would work just like now, >>> except no "Find Information Request" would be issued (that means no >>> call to "device_browse_gatt"). >>> >>> 2. Add two new methods: org.bluez.Device1.DiscoverServices(), and >>> org.bluez.Device1.DiscoverServiceByUUID(uuid). First one would just >>> call device_browse_gatt and make "Find Information Request" , the >>> second one would issue "Find By Type Value Request" to find just one >>> service. >> >> You are just changing one problem to another, or actually many other problems: >> > > Example use case to make things clearer: > there's device advertising it contains service with UUID "abcd", and > my app wants to use only this one. It connects to device, and asks > only for this service. If it's not there I disconnect. If it's there, > it read/writes and disconnect. > Everything took ~1.5 second. > > If I can't do "Find By Type Value Request" I'm stuck discovering > services for 6, or 10, or more seconds, depending of number of > services on device. > > >> 1. Instead of just 1 method there is at least 2, but Connect depends >> on what has been discovered first so you are adding a D-Bus round >> trips. > > Yes, I'm probably adding one round trip. It might hovewer be avoided. > To avoid additional roundtrip there should be two methods: > Connect() that just works right now, and ConnectToUUID(uuid) that > would connect, and then do "Find By Type Value Request". I think that > this solution wouldn't be that clean, and would be problematic to > discover rest of services. > > One round trip per connection isn't that bad issue, is it ? > >> 2. DiscoverServiceByUUID can only discover primary services if I >> remember correct, what about included? And if an application, or many, > > It can discovery Primary or Secondary services, but it is used for > Primary only right now as far as I know. > >> decide to discovery one by one every single UUID defined in the spec, >> how many more request that would be compared to Read by Group Type >> Request? > > If application want to use only one service, and it cares about speed > it should use this new method (I think that's the reason Bluetooth > have "Find By Type Value Request"). > If application doesn't know what it wants, it should find all services for sure. > If application want more than one service, or included service, it > should probably discover all at once. > If application wants to discover included service, it can do Read by > Group Type with handle range that's included in "included service" > attribute (would need new API method if we want that, or use discover > all service). > > >> 3. We can't take advance of Service Changed Characteristic if >> DiscoverServiceByUUID, so at that point one would have to start >> polling if the remote server has capability to change its database. >> >> I guess the problem number 3 is actually what you did not consider, >> the whole point is that we discover only once and then let the server >> tell us what has changed, so reconnection should happens very fast >> because we already have the device database in cache. > > Right, I haven't conseidered number 3, but: > - app might decide to later discover rest of services, or > - just service I discovered might be still cached, or > - service I need might be re-discovered because it's only one and > it's fast in comparison to discovering all > - maybe if device get paired, full service discovery will be required > ? otherwise it'll change MAC in 15 minutes and be forgotten anyway. > > I'll figure out how to deal nicely with cache. > > I think that discovering one service should be a option in modern BLE > API (and I know few projects that need it). > Please note that i.e. MAC API have that. For other reasons why that's > good idea see "Explore a Peripheral’s Data Wisely" at > https://developer.apple.com/library/mac/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/BestPracticesForInteractingWithARemotePeripheralDevice/BestPracticesForInteractingWithARemotePeripheralDevice.html#//apple_ref/doc/uid/TP40013257-CH6-SW6 > > I think it's more "how to do it right" than "whether to do it". I realize you probably don't know how we discover the attributes, the process is like this: 1. Read by Group Type Request: First we discover primary/secondary range, the number of attempts depend in the MTU so this may actually return all services in one operation: > ACL Data RX: Handle 3585 flags 0x02 dlen 11 ATT: Read By Group Type Request (0x10) len 6 Handle range: 0x0001-0xffff Attribute group type: Primary Service (0x2800) < ACL Data TX: Handle 3585 flags 0x00 dlen 24 ATT: Read By Group Type Response (0x11) len 19 Attribute data length: 6 Attribute group list: 3 entries Handle range: 0x0001-0x0005 UUID: Generic Access Profile (0x1800) Handle range: 0x0006-0x000d UUID: Heart Rate (0x180d) Handle range: 0x000e-0x0011 UUID: Battery Service (0x180f) 2. Read By Type Request: Then we discover the characteristics within each service, again this request can pack more than one entry: > ACL Data RX: Handle 3585 flags 0x02 dlen 11 ATT: Read By Type Request (0x08) len 6 Handle range: 0x0001-0x0005 Attribute type: Characteristic (0x2803) < ACL Data TX: Handle 3585 flags 0x00 dlen 13 ATT: Read By Type Response (0x09) len 8 Attribute data length: 7 Attribute data list: 1 entry Handle: 0x0004 Value: 020500012a 3. Find Information Request: Last we discover the descriptors in the characteristic range: > ACL Data RX: Handle 3585 flags 0x02 dlen 9 ATT: Find Information Request (0x04) len 4 Handle range: 0x0009-0x0009 < ACL Data TX: Handle 3585 flags 0x00 dlen 10 ATT: Find Information Response (0x05) len 5 Format: UUID-16 (0x01) Handle: 0x0009 UUID: Client Characteristic Configuration (0x2902) Note that 2 and 3 are valid with Find by Type request, which btw is documented in the core spec (see 4.4 PRIMARY SERVICE DISCOVERY), so if we talk about efficiency we should compare Find by Type vs Read by Group Type, the former can only group services of the same type, so if you have a n number of UUID you will have to do n number of requests which in practice means that once you have n > 1 Read by Group Type will probably start to be more efficient. Given the fact that we want to discover GAP, GATT and DIS normally, or at least GAP and GATT Services, I think Read by Group Type will usually outperform Find by Type in terms of speed in with that setup, with the only exception being if the database is really huge or/and the MTU is small. We could in theory optimize the process after 1 to only discovery characteristics for the services which have a driver or a external client registered, but this would mean splinting the ready logic bt_gatt_client has so we are able to detect what drivers would be probed and then continue from there, or provide the UUID list upfront to bt_gatt_client do the filtering. Personally I don't think it is worth changing this logic because the database are normally quite small with just a few services, but if you find real case where this is not true then we may have discuss this again. -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-05-28 22:25 ` Jakub Pawlowski 2015-05-29 8:35 ` Luiz Augusto von Dentz @ 2015-05-31 2:55 ` Johan Hedberg 2015-06-01 17:25 ` Jakub Pawlowski 1 sibling, 1 reply; 10+ messages in thread From: Johan Hedberg @ 2015-05-31 2:55 UTC (permalink / raw) To: Jakub Pawlowski; +Cc: Luiz Augusto von Dentz, BlueZ development Hi Jakub, On Thu, May 28, 2015, Jakub Pawlowski wrote: > > 1. Instead of just 1 method there is at least 2, but Connect depends > > on what has been discovered first so you are adding a D-Bus round > > trips. > > Yes, I'm probably adding one round trip. It might hovewer be avoided. > To avoid additional roundtrip there should be two methods: > Connect() that just works right now, and ConnectToUUID(uuid) that > would connect, and then do "Find By Type Value Request". I think that > this solution wouldn't be that clean, and would be problematic to > discover rest of services. We already have this "ConnectToUUID" method in the form of Device1.ConnectProfile, don't we? It was originally designed for BR/EDR, but seems to have at least some code for LE as well. If it's not working as desired for LE it's probably something worth fixing. Johan ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-05-31 2:55 ` Johan Hedberg @ 2015-06-01 17:25 ` Jakub Pawlowski 2015-06-01 18:22 ` Luiz Augusto von Dentz 0 siblings, 1 reply; 10+ messages in thread From: Jakub Pawlowski @ 2015-06-01 17:25 UTC (permalink / raw) To: Jakub Pawlowski, Luiz Augusto von Dentz, BlueZ development Hi Johan, Luiz On Sat, May 30, 2015 at 7:55 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote: > Hi Jakub, > > On Thu, May 28, 2015, Jakub Pawlowski wrote: >> > 1. Instead of just 1 method there is at least 2, but Connect depends >> > on what has been discovered first so you are adding a D-Bus round >> > trips. >> >> Yes, I'm probably adding one round trip. It might hovewer be avoided. >> To avoid additional roundtrip there should be two methods: >> Connect() that just works right now, and ConnectToUUID(uuid) that >> would connect, and then do "Find By Type Value Request". I think that >> this solution wouldn't be that clean, and would be problematic to >> discover rest of services. > > We already have this "ConnectToUUID" method in the form of > Device1.ConnectProfile, don't we? It was originally designed for BR/EDR, > but seems to have at least some code for LE as well. If it's not working > as desired for LE it's probably something worth fixing. > "ConnectToUUID" method is what I was looking for. It doesn't work for LE devices as far as I tested, so I'll fix it. It creates connection, but then stops (no MTU exchange, or service discovery). Here's merged (to show time order) output of btmon and bluetoothd together when calling ConnectToUUID right now: http://pastebin.com/s76bT3jx When I looked into source, it looks like it still want to do full service discvery, not just one service. Can I modify it to do ""Find By Type Value Request" for LE devices ? I modified bluez a little bit to test timing, and show why I want to have "Find By Type Value Request": Right after connecting and negotiating MTU, instead of doing Primary and Secondary Service Discovery, I made BlueZ do "Find By Type Value Request" for service with UUID "babe", and then auto discover it's included services, characteristics, descriptors. First I tested against Android phone with three Primary Services (GATT, GAP, and one with UUID "babe"), and total of 4 characteristic, one in "babe" service. MTU=517. Doing regular discovery took 2.38s from "Read By Group Type Request" to last request, http://pastebin.com/pgrfAJM9 Doing just one service discovery took 0,84s from "Find By Type Value Request" to last request, http://pastebin.com/V1WZERfw Then I tested against iPhone with 5 services and total of 12 characteristics (one with UUID "babe", having one characteristic). MTU=158. Sample iPhone app I used for tests started automatically discovering services on the laptop, which also impacted discovery time. Doing regular discovery took 9.7s from "Read By Group Type Request" to last request, http://pastebin.com/aycMWZ4w Doing just one service discovery took 2s from "Find By Type Value Request" to last request, http://pastebin.com/C9Jp28WM My use case is to quickly connect, and use one service, then disconnect. 2.3s vs 0.8s is big gain for me, not talking about 9.7 vs 2s. Some controllers designed for coin-battery scenarios have MTU fixed on 23, which should also make all service discovery slow, and yield big difference. > Johan ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-06-01 17:25 ` Jakub Pawlowski @ 2015-06-01 18:22 ` Luiz Augusto von Dentz 2015-06-01 21:42 ` Arman Uguray 0 siblings, 1 reply; 10+ messages in thread From: Luiz Augusto von Dentz @ 2015-06-01 18:22 UTC (permalink / raw) To: Jakub Pawlowski; +Cc: BlueZ development Hi Jakub, On Mon, Jun 1, 2015 at 8:25 PM, Jakub Pawlowski <jpawlowski@google.com> wrote: > Hi Johan, Luiz > > On Sat, May 30, 2015 at 7:55 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote: >> Hi Jakub, >> >> On Thu, May 28, 2015, Jakub Pawlowski wrote: >>> > 1. Instead of just 1 method there is at least 2, but Connect depends >>> > on what has been discovered first so you are adding a D-Bus round >>> > trips. >>> >>> Yes, I'm probably adding one round trip. It might hovewer be avoided. >>> To avoid additional roundtrip there should be two methods: >>> Connect() that just works right now, and ConnectToUUID(uuid) that >>> would connect, and then do "Find By Type Value Request". I think that >>> this solution wouldn't be that clean, and would be problematic to >>> discover rest of services. >> >> We already have this "ConnectToUUID" method in the form of >> Device1.ConnectProfile, don't we? It was originally designed for BR/EDR, >> but seems to have at least some code for LE as well. If it's not working >> as desired for LE it's probably something worth fixing. >> > > "ConnectToUUID" method is what I was looking for. It doesn't work for > LE devices as far as I tested, so I'll fix it. It creates connection, > but then stops (no MTU exchange, or service discovery). > > Here's merged (to show time order) output of btmon and bluetoothd > together when calling ConnectToUUID right now: > http://pastebin.com/s76bT3jx > > When I looked into source, it looks like it still want to do full > service discvery, not just one service. Can I modify it to do ""Find > By Type Value Request" for LE devices ? > > > I modified bluez a little bit to test timing, and show why I want to > have "Find By Type Value Request": > > Right after connecting and negotiating MTU, instead of doing Primary > and Secondary Service Discovery, I made BlueZ do "Find By Type Value > Request" for service with UUID "babe", and then auto discover it's > included services, characteristics, descriptors. > > First I tested against Android phone with three Primary Services > (GATT, GAP, and one with UUID "babe"), and total of 4 characteristic, > one in "babe" service. MTU=517. > Doing regular discovery took 2.38s from "Read By Group Type Request" > to last request, http://pastebin.com/pgrfAJM9 > Doing just one service discovery took 0,84s from "Find By Type Value > Request" to last request, http://pastebin.com/V1WZERfw They are not doing the same thing, you are not looking for GAP, GATT and DIS services for example, so the device will not have any of these discovered, so no long names, no appearance, no service changed and no device information. Also Im not sure you got my point about the ConnectUUID, let say it is just discover the UUID requested, you will have to do it every single time you connnect because it cannot be cached without service changed, also this is per UUID, if the peripheral just have one being advertised that might work in favor of this but there could be many as well then doing ConnectUUID separately don't make any sense. > Then I tested against iPhone with 5 services and total of 12 > characteristics (one with UUID "babe", having one characteristic). > MTU=158. Sample iPhone app I used for tests started automatically > discovering services on the laptop, which also impacted discovery > time. > Doing regular discovery took 9.7s from "Read By Group Type Request" to > last request, http://pastebin.com/aycMWZ4w > Doing just one service discovery took 2s from "Find By Type Value > Request" to last request, http://pastebin.com/C9Jp28WM > > My use case is to quickly connect, and use one service, then > disconnect. 2.3s vs 0.8s is big gain for me, not talking about 9.7 vs > 2s. Some controllers designed for coin-battery scenarios have MTU > fixed on 23, which should also make all service discovery slow, and > yield big difference. Service changed, the lower is your requirement to reconnect the more it will be required, but you got to pair to make it persistent across reconnections but the first time you connect is always going to be time consuming since you got to discover so it does not matter much if the first time takes 9.7s to discover all services since the next time it would not spend any time doing it again, that is the only reason HoG can reconnect very fast. -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-06-01 18:22 ` Luiz Augusto von Dentz @ 2015-06-01 21:42 ` Arman Uguray 2015-06-02 14:51 ` Luiz Augusto von Dentz 0 siblings, 1 reply; 10+ messages in thread From: Arman Uguray @ 2015-06-01 21:42 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: Jakub Pawlowski, BlueZ development Hi, > On Mon, Jun 1, 2015 at 11:22 AM, Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > Hi Jakub, > > On Mon, Jun 1, 2015 at 8:25 PM, Jakub Pawlowski <jpawlowski@google.com> wrote: >> Hi Johan, Luiz >> >> On Sat, May 30, 2015 at 7:55 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote: >>> Hi Jakub, >>> >>> On Thu, May 28, 2015, Jakub Pawlowski wrote: >>>> > 1. Instead of just 1 method there is at least 2, but Connect depends >>>> > on what has been discovered first so you are adding a D-Bus round >>>> > trips. >>>> >>>> Yes, I'm probably adding one round trip. It might hovewer be avoided. >>>> To avoid additional roundtrip there should be two methods: >>>> Connect() that just works right now, and ConnectToUUID(uuid) that >>>> would connect, and then do "Find By Type Value Request". I think that >>>> this solution wouldn't be that clean, and would be problematic to >>>> discover rest of services. >>> >>> We already have this "ConnectToUUID" method in the form of >>> Device1.ConnectProfile, don't we? It was originally designed for BR/EDR, >>> but seems to have at least some code for LE as well. If it's not working >>> as desired for LE it's probably something worth fixing. >>> >> >> "ConnectToUUID" method is what I was looking for. It doesn't work for >> LE devices as far as I tested, so I'll fix it. It creates connection, >> but then stops (no MTU exchange, or service discovery). >> >> Here's merged (to show time order) output of btmon and bluetoothd >> together when calling ConnectToUUID right now: >> http://pastebin.com/s76bT3jx >> >> When I looked into source, it looks like it still want to do full >> service discvery, not just one service. Can I modify it to do ""Find >> By Type Value Request" for LE devices ? >> >> >> I modified bluez a little bit to test timing, and show why I want to >> have "Find By Type Value Request": >> >> Right after connecting and negotiating MTU, instead of doing Primary >> and Secondary Service Discovery, I made BlueZ do "Find By Type Value >> Request" for service with UUID "babe", and then auto discover it's >> included services, characteristics, descriptors. >> >> First I tested against Android phone with three Primary Services >> (GATT, GAP, and one with UUID "babe"), and total of 4 characteristic, >> one in "babe" service. MTU=517. >> Doing regular discovery took 2.38s from "Read By Group Type Request" >> to last request, http://pastebin.com/pgrfAJM9 >> Doing just one service discovery took 0,84s from "Find By Type Value >> Request" to last request, http://pastebin.com/V1WZERfw > > They are not doing the same thing, you are not looking for GAP, GATT > and DIS services for example, so the device will not have any of these > discovered, so no long names, no appearance, no service changed and no > device information. Also Im not sure you got my point about the > ConnectUUID, let say it is just discover the UUID requested, you will > have to do it every single time you connnect because it cannot be > cached without service changed, also this is per UUID, if the > peripheral just have one being advertised that might work in favor of > this but there could be many as well then doing ConnectUUID separately > don't make any sense. > >> Then I tested against iPhone with 5 services and total of 12 >> characteristics (one with UUID "babe", having one characteristic). >> MTU=158. Sample iPhone app I used for tests started automatically >> discovering services on the laptop, which also impacted discovery >> time. >> Doing regular discovery took 9.7s from "Read By Group Type Request" to >> last request, http://pastebin.com/aycMWZ4w >> Doing just one service discovery took 2s from "Find By Type Value >> Request" to last request, http://pastebin.com/C9Jp28WM >> >> My use case is to quickly connect, and use one service, then >> disconnect. 2.3s vs 0.8s is big gain for me, not talking about 9.7 vs >> 2s. Some controllers designed for coin-battery scenarios have MTU >> fixed on 23, which should also make all service discovery slow, and >> yield big difference. > > Service changed, the lower is your requirement to reconnect the more > it will be required, but you got to pair to make it persistent across > reconnections but the first time you connect is always going to be > time consuming since you got to discover so it does not matter much if > the first time takes 9.7s to discover all services since the next time > it would not spend any time doing it again, that is the only reason > HoG can reconnect very fast. > > -- > Luiz Augusto von Dentz > -- > To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html I'm late to the discussion, but wasn't this kind of functionality the whole point behind adding the org.bluez.GattProfile1 interface defined in doc/gatt-api.txt? Can't we do this through that? -Arman ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-06-01 21:42 ` Arman Uguray @ 2015-06-02 14:51 ` Luiz Augusto von Dentz 2015-06-09 10:48 ` Luiz Augusto von Dentz 0 siblings, 1 reply; 10+ messages in thread From: Luiz Augusto von Dentz @ 2015-06-02 14:51 UTC (permalink / raw) To: Arman Uguray; +Cc: Jakub Pawlowski, BlueZ development Hi Arman, On Tue, Jun 2, 2015 at 12:42 AM, Arman Uguray <armansito@chromium.org> wrote: >> Service changed, the lower is your requirement to reconnect the more >> it will be required, but you got to pair to make it persistent across >> reconnections but the first time you connect is always going to be >> time consuming since you got to discover so it does not matter much if >> the first time takes 9.7s to discover all services since the next time >> it would not spend any time doing it again, that is the only reason >> HoG can reconnect very fast. >> >> -- >> Luiz Augusto von Dentz >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > I'm late to the discussion, but wasn't this kind of functionality the > whole point behind adding the org.bluez.GattProfile1 interface defined > in doc/gatt-api.txt? Can't we do this through that? Yes, that was my suggestion to give a list of UUID of interested so bt_gatt_client instance can skip discovery of characteristics and descriptor not in the list, but it is not so simple when this is dynamic as it is applications may come and go so we would have to cache not only the database but also what was discovered which complicate things. Btw, the spec says the following about the service changed: C1: Mandatory if service definitions on the server can be added, changed or removed; otherwise optional So the following code should be optimized to return without clearing the database if service changed is not supported. if (device->le_state.bonded) return; gatt_db_clear(device->db); device->gatt_cache_used = false; Futhermore Im not sure we need to clear the database like that, we could check if the service range match that probably means the service has not changed since the last connection as is very unlikely that service characteristics and descriptors would change even if the service was removed and added again in the exact same place. -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC] Add new method to DBus API: DiscoverServiceByUUID 2015-06-02 14:51 ` Luiz Augusto von Dentz @ 2015-06-09 10:48 ` Luiz Augusto von Dentz 0 siblings, 0 replies; 10+ messages in thread From: Luiz Augusto von Dentz @ 2015-06-09 10:48 UTC (permalink / raw) To: Arman Uguray; +Cc: Jakub Pawlowski, BlueZ development Hi Arman, Jakub, On Tue, Jun 2, 2015 at 5:51 PM, Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > Hi Arman, > > On Tue, Jun 2, 2015 at 12:42 AM, Arman Uguray <armansito@chromium.org> wrote: >>> Service changed, the lower is your requirement to reconnect the more >>> it will be required, but you got to pair to make it persistent across >>> reconnections but the first time you connect is always going to be >>> time consuming since you got to discover so it does not matter much if >>> the first time takes 9.7s to discover all services since the next time >>> it would not spend any time doing it again, that is the only reason >>> HoG can reconnect very fast. >>> >>> -- >>> Luiz Augusto von Dentz >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in >>> the body of a message to majordomo@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >> >> I'm late to the discussion, but wasn't this kind of functionality the >> whole point behind adding the org.bluez.GattProfile1 interface defined >> in doc/gatt-api.txt? Can't we do this through that? > > Yes, that was my suggestion to give a list of UUID of interested so > bt_gatt_client instance can skip discovery of characteristics and > descriptor not in the list, but it is not so simple when this is > dynamic as it is applications may come and go so we would have to > cache not only the database but also what was discovered which > complicate things. > > Btw, the spec says the following about the service changed: > > C1: Mandatory if service definitions on the server can be added, > changed or removed; > otherwise optional > > So the following code should be optimized to return without clearing > the database if service changed is not supported. > > if (device->le_state.bonded) > return; > > gatt_db_clear(device->db); > device->gatt_cache_used = false; > > Futhermore Im not sure we need to clear the database like that, we > could check if the service range match that probably means the service > has not changed since the last connection as is very unlikely that > service characteristics and descriptors would change even if the > service was removed and added again in the exact same place. Any chance that you guys give some feedback to the patch-set Ive sent yesterday? Im assuming it does take care of connecting to a single UUID since in most cases only Read by Group Type is necessary. -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2015-06-09 10:48 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-05-28 20:44 [RFC] Add new method to DBus API: DiscoverServiceByUUID Jakub Pawlowski 2015-05-28 21:32 ` Luiz Augusto von Dentz 2015-05-28 22:25 ` Jakub Pawlowski 2015-05-29 8:35 ` Luiz Augusto von Dentz 2015-05-31 2:55 ` Johan Hedberg 2015-06-01 17:25 ` Jakub Pawlowski 2015-06-01 18:22 ` Luiz Augusto von Dentz 2015-06-01 21:42 ` Arman Uguray 2015-06-02 14:51 ` Luiz Augusto von Dentz 2015-06-09 10:48 ` Luiz Augusto von Dentz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox