2012-03-26 15:25:03

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v2 0/5] Add DeviceInformationService plugin

From: Chen Ganir <[email protected]>

Add Device Information Service GATT Client for reading peer
device PNP_ID and store it.

This is v2 of the patch set, removing some unused code to
eliminate compilation warnings.

Chen Ganir (5):
Add DeviceInformation GATT Client
DeviceInfo: Add connection logic
DeviceInfo: Discover Characteristics
Fix device version in GetProperties
DeviceInfo: Read PNP ID

Makefile.am | 9 ++-
deviceinfo/deviceinfo.c | 205 +++++++++++++++++++++++++++++++++++++++++++++++
deviceinfo/deviceinfo.h | 24 ++++++
deviceinfo/main.c | 55 +++++++++++++
deviceinfo/manager.c | 82 +++++++++++++++++++
deviceinfo/manager.h | 24 ++++++
src/device.c | 35 ++++++++-
src/device.h | 3 +
8 files changed, 433 insertions(+), 4 deletions(-)
create mode 100644 deviceinfo/deviceinfo.c
create mode 100644 deviceinfo/deviceinfo.h
create mode 100644 deviceinfo/main.c
create mode 100644 deviceinfo/manager.c
create mode 100644 deviceinfo/manager.h

--
1.7.4.1



2012-03-27 10:42:20

by Ganir, Chen

[permalink] [raw]
Subject: RE: [PATCH v2 5/5] DeviceInfo: Read PNP ID

Lizardo,

> -----Original Message-----
> From: Anderson Lizardo [mailto:[email protected]]
> Sent: Tuesday, March 27, 2012 12:39 PM
> To: Ganir, Chen
> Cc: [email protected]
> Subject: Re: [PATCH v2 5/5] DeviceInfo: Read PNP ID
>
> Hi Chen,
>
> 2012/3/27 Ganir, Chen <[email protected]>:
> >> > + ? ? ? /* Vendor Source*/
> >> > + ? ? ? if (device->vendor_src)
> >> > + ? ? ? ? ? ? ? dict_append_entry(&dict, "VendorSource",
> >> DBUS_TYPE_UINT16,
> >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &device-
> >> >vendor_src);
> >> > +
> >>
> >> * How does this work for BR/EDR devices (without GATT)? Is zero a
> >> valid value for these devices?
> >
> > For BR/EDR, you may have either DID or DIS. None of the specs define
> what is the relationship between those on BR/EDR (since in theory you
> may have both at the same time), so no special code was added to handle
> such a situation. As far as I can see, in a GATT capable device, the
> DIS should replace the DID since it extends its capabilities, but this
> is totally vendor dependant.
> >
> > Regarding default values, the spec does not specify valid range for
> product id and product version. Both for DID in BR/EDR and DIS in LE,
> those values are totally dependent on vendor implementation and have no
> limits.
> >
> > For the Vendor ID Source, 0x0000 is a reserved for future use, and
> currently should not be used.
> > A default value for nonexistent VID according to the DID spec is
> 0xFFF (the DIS spec does not define such a value).
> >
> > The current device.c implementation was not changed, meaning that for
> the D-BUS interface, having a 0 value will remove the property from the
> dbus dictionary.
> >
> > Do we want to change this behavior ? Maybe add a short bitmask field
> for existing fields ? What do you think ?
>
> I was more worried about what happens on BR/EDR case (with GATT
> disabled), but with your explanation, I believe there is no issue on
> this part.
>
> Regarding DID vs. DIS, I think at least the information needs to be
> stored/managed on a single place. It is very unlikely that some vendor
> will use conflicting information on these services.
>
This will not happen, since I'm using the same mechanism for storing the PNP_ID data both for DID and DIS (in btd_device and in the persistent storage) using the existing API's. I also added a new API specific for DIS, which uses the existing DID API internally.


> Regards,
> --
> Anderson Lizardo
> Instituto Nokia de Tecnologia - INdT
> Manaus - Brazil



Thanks,
Chen Ganir


2012-03-27 10:39:17

by Anderson Lizardo

[permalink] [raw]
Subject: Re: [PATCH v2 5/5] DeviceInfo: Read PNP ID

Hi Chen,

2012/3/27 Ganir, Chen <[email protected]>:
>> > + ? ? ? /* Vendor Source*/
>> > + ? ? ? if (device->vendor_src)
>> > + ? ? ? ? ? ? ? dict_append_entry(&dict, "VendorSource",
>> DBUS_TYPE_UINT16,
>> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &device-
>> >vendor_src);
>> > +
>>
>> * How does this work for BR/EDR devices (without GATT)? Is zero a
>> valid value for these devices?
>
> For BR/EDR, you may have either DID or DIS. None of the specs define what is the relationship between those on BR/EDR (since in theory you may have both at the same time), so no special code was added to handle such a situation. As far as I can see, in a GATT capable device, the DIS should replace the DID since it extends its capabilities, but this is totally vendor dependant.
>
> Regarding default values, the spec does not specify valid range for product id and product version. Both for DID in BR/EDR and DIS in LE, those values are totally dependent on vendor implementation and have no limits.
>
> For the Vendor ID Source, 0x0000 is a reserved for future use, and currently should not be used.
> A default value for nonexistent VID according to the DID spec is 0xFFF (the DIS spec does not define such a value).
>
> The current device.c implementation was not changed, meaning that for the D-BUS interface, having a 0 value will remove the property from the dbus dictionary.
>
> Do we want to change this behavior ? Maybe add a short bitmask field for existing fields ? What do you think ?

I was more worried about what happens on BR/EDR case (with GATT
disabled), but with your explanation, I believe there is no issue on
this part.

Regarding DID vs. DIS, I think at least the information needs to be
stored/managed on a single place. It is very unlikely that some vendor
will use conflicting information on these services.

Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

2012-03-27 07:30:01

by Ganir, Chen

[permalink] [raw]
Subject: RE: [PATCH v2 0/5] Add DeviceInformationService plugin

Q2xhdWRpbw0KDQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IENsYXVkaW8g
VGFrYWhhc2kgW21haWx0bzpjbGF1ZGlvLnRha2FoYXNpQG9wZW5ib3NzYS5vcmddDQo+IFNlbnQ6
IE1vbmRheSwgTWFyY2ggMjYsIDIwMTIgMTA6MzEgUE0NCj4gVG86IEdhbmlyLCBDaGVuDQo+IENj
OiBsaW51eC1ibHVldG9vdGhAdmdlci5rZXJuZWwub3JnDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0gg
djIgMC81XSBBZGQgRGV2aWNlSW5mb3JtYXRpb25TZXJ2aWNlIHBsdWdpbg0KPiANCj4gSGkgQ2hl
biBHYW5pcjoNCj4gDQo+IE9uIE1vbiwgTWFyIDI2LCAyMDEyIGF0IDEyOjI1IFBNLCAgPGNoZW4u
Z2FuaXJAdGkuY29tPiB3cm90ZToNCj4gPiBGcm9tOiBDaGVuIEdhbmlyIDxjaGVuLmdhbmlyQHRp
LmNvbT4NCj4gPg0KPiA+IEFkZCBEZXZpY2UgSW5mb3JtYXRpb24gU2VydmljZSBHQVRUIENsaWVu
dCBmb3IgcmVhZGluZyBwZWVyDQo+ID4gZGV2aWNlIFBOUF9JRCBhbmQgc3RvcmUgaXQuDQo+ID4N
Cj4gPiBUaGlzIGlzIHYyIG9mIHRoZSBwYXRjaCBzZXQsIHJlbW92aW5nIHNvbWUgdW51c2VkIGNv
ZGUgdG8NCj4gPiBlbGltaW5hdGUgY29tcGlsYXRpb24gd2FybmluZ3MuDQo+IA0KPiBJIGFtIGFm
cmFpZCBvZiByYWNlIGNvbmRpdGlvbnMgYmV0d2VlbiBIb0cgYW5kIERJUyBzZXJ2aWNlcy4NCj4g
DQo+IEFUVCBpcyBhICJzZXJpYWwiIHByb3RvY29sLCBob3dldmVyIHRoZXJlIGlzIG5vIGd1YXJh
bnRlZSB0aGF0IFBOUCBJRA0KPiBjaGFyYWN0ZXJpc3RpYyB2YWx1ZSB3aWxsIGJlIGF2YWlsYWJs
ZSBiZWZvcmUgY3JlYXRpbmcgdWhpZCBkZXZpY2UuIEl0DQo+IGRlcGVuZHMgb24gdGhlIHByb2Jp
bmcgb3JkZXIgQU5EIHdoZW4gdGhlIGNvbW1hbmRzIGFyZSBhZGRlZCBpbiB0aGUNCj4gR0F0dHJp
YiBxdWV1ZS4NCj4gDQoNCkN1cnJlbnRseSwgRElEIGlzIHJlYWQgZHVyaW5nIHRoZSBDcmVhdGVE
ZXZpY2UgKEJSL0VEUiBvdmVyIFNEUCB3aGVuIGRldmljZSBpcyBjcmVhdGVkKS4gSW4gYWRkaXRp
b24sIHdoZW4gd2UgY3JlYXRlIGEgZGV2aWNlLCB3ZSBpbW1lZGlhdGVseSBwcm9iZSB0aGUgRElT
IHBsdWctaW4gd2hpY2ggaW1tZWRpYXRlbHkgc3RhcnRzIGV4cGxvcmluZyB0aGUgcmVtb3RlIERJ
UyBzZXJ2ZXIsIGV2ZW4gYmVmb3JlIHVoaWQgaXMgY3JlYXRlZC4gQSAvZGV2L3VoaWQgZGV2aWNl
IHdpbGwgYmUgb3BlbmVkIG9ubHkgYWZ0ZXIgYSBkZXZpY2UgaGFzIGJlZW4gY3JlYXRlZCwgYW5k
IGEgdXNlciBhY3Rpb24gd2FzIHBlcmZvcm1lZCB0byBjb25uZWN0IHRoZSBpbnB1dCBkZXZpY2Ug
KG9yZy5ibHVlei5JbnB1dC5Db25uZWN0IHdpbGwgYmUgY2FsbGVkIG9ubHkgYWZ0ZXIgeW91IGdl
dCB0aGUgRGV2aWNlQ3JlYXRlZCBldmVudCwgd2hpY2ggbWVhbnMgdGhhdCBhbGwgZGF0YSBoYXMg
YmVlbiByZWFkKSAsIHNvIHdlIGRvIG5vdCBuZWVkIHRvIHdvcnJ5IGFib3V0IHN1Y2ggYSBzY2Vu
YXJpbyBhdCB0aGlzIHN0YWdlLg0KDQpIb3dldmVyLCBJIGRvIHRoaW5rIHdlIG5lZWQgdG8gZGVz
aWduIGEgbWVjaGFuaXNtIGZvciBzeW5jaHJvbml6aW5nIGJldHdlZW4gcGx1Zy1pbnMsIGJ1dCBJ
J20gbm90IHN1cmUgaXQgc2hvdWxkIGJlIGEgZ2VuZXJpYyBwbHVnLWluIHN5bmMgbWVjaGFuaXNt
LCBzaW5jZSBub3QgYWxsIHBsdWctaW5zIHJlcXVpcmUgdGhpcy4gDQoNCj4gSU1PLCB0aGUgYWx0
ZXJuYXRpdmVzIGFyZToNCj4gMS4gbW92ZSB0aGUgRElTL1BuUCBkaXNjb3ZlcnkgdG8gdGhlIGNy
ZWF0ZSBkZXZpY2UgInByb2NlZHVyZSINCkl0IGlzIGFscmVhZHkgZG9uZSB0aGlzIHdheS4gQ3Jl
YXRlRGV2aWNlIGZvciBMRSBkZXZpY2UgY2FsbHMgdGhlIGRpc2NvdmVyX3ByaW1hcmllcywgYW5k
IHRoZW4gcHJvYmVzIGFsbCBkcml2ZXJzLiBUaGUgRElTIHBsdWctaW4gd2lsbCBiZSBpbml0aWFs
aXplZCwgYW5kIHJlYWQgdGhlIHZhbHVlcyBmcm9tIHRoZSBwZWVyIGRldmljZSwgYW5kIHN0b3Jl
IHRoZW0gaW4gcGVyc2lzdGVudCBzdG9yYWdlLg0KDQo+IDIuIGNyZWF0ZSBwbHVnaW4gc3RhdGVz
IGFuZCBkZXBlbmRlbmN5IGJlZm9yZSBwcm9iaW5nDQpXZSBkbyBub3QgaGF2ZSB0byBwcm90ZWN0
IHRoZSBwcm9iaW5nIGhlcmUuIFdlIGRvIG5lZWQgdG8gcHJvdGVjdCB0aGUgL2Rldi91aGlkIGNy
ZWF0aW9uIGFuZCBjb25maWd1cmF0aW9uLiBBIC9kZXYvdWhpZCB3aWxsIGJlIGNyZWF0ZWQgb24g
cHJvYmluZyBvbmx5IGFmdGVyIHRoZSB1c2VyIGhhcyBwcmV2aW91c2x5IHNlbGVjdGVkIHRoZSBy
ZW1vdGUgZGV2aWNlIGZvciBjb25uZWN0aW9uLCBhbmQgdGhpcyB3aWxsIGhhcHBlbiBvbmx5IGFm
dGVyIHdlIGhhdmUgYSB2YWxpZCBQTlAgaWQgYWxyZWFkeSBzdG9yZWQuDQoNCj4gMy4gdXVpZCAi
bm90aWZpY2F0aW9uIiBtZWNoYW5pc20iOiBjYWxsYmFjayBnZXRzIGNhbGxlZCB3aGVuIGEgbmV3
DQo+IHZhbHVlIGlzIGF2YWlsYWJsZSBmb3IgYSBnaXZlbiBjaGFyYWN0ZXJpc3RpYw0KQSBjYWxs
YmFjayBpcyBwYXJ0IG9mIHRoZSBzb2x1dGlvbiwgYW5kIG5lZWRzIHRvIGJlIGFjY29tcGFuaWVk
IGJ5IGEgd2F5IHRvIHF1ZXJ5IHRoZSBwbHVnaW4gZm9yIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmlj
IGNoYXJhY3RlcmlzdGljIGJ5IHV1aWQuIEhvd2V2ZXIsIHRoaXMgbWF5IG5vdCBiZSBlYXN5LiBG
b3IgZXhhbXBsZSwgeW91IG1heSBoYXZlIG1vcmUgdGhhbiBvbmUgYmF0dGVyeSBzZXJ2aWNlcywg
d2l0aCBiYXR0ZXJ5IGxldmVsIGNoYXJhY3RlcmlzdGljcyAod2l0aCB0aGUgc2FtZSBVVUlEKS4g
SG93IGRvIHlvdSBsaW5rIGJldHdlZW4gYSBzcGVjaWZpYyBiYXR0ZXJ5IGFuZCBpdHMgdmFsdWU/
IA0KDQpJIGRvIG5vdCB0aGluayBhIGdlbmVyaWMgc29sdXRpb24gaXMgdGhlIGJlc3Qgc29sdXRp
b24gaGVyZS4gUGVyaGFwcyB3ZSBuZWVkIHRvIGNvbWJpbmUgdGhpcyB3aXRoIHRoZSBidGRfZGV2
aWNlLCBhbmQgbWFrZSBzdXJlIGJ0ZF9kZXZpY2UgaXMgdGhlIGNlbnRyYWwgbG9jYXRpb24gZm9y
IGdldHRpbmcgdmFsdWVzIGFuZCBub3RpZmljYXRpb25zLiBDdXJyZW50bHkgd2UgaGF2ZSB0aGUg
YnRkX2RldmljZV9nZXRfdmVuZG9yX3NyYywgYnRkX2RldmljZV9nZXRfdmVuZG9yIGFuZCBvdGhl
cnMgd2hpY2ggY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBwcmVzZW50LiBPciBu
b3QuIFRoZSBzaW1wbGVzdCBzb2x1dGlvbiB3b3VsZCBiZSBjaGVja2luZyB0aGlzIGluZm9ybWF0
aW9uIHBlcmlvZGljYWxseSBmcm9tIHRoZSBISUQgc2VydmljZSBwbHVnaW4sIG9yIGFkZCBhIHBy
b3BlcnR5X2NoYW5nZWQgY2FsbGJhY2sgc2ltaWxhciB0byB0aGUgRC1CVVMgbWVjaGFuaXNtIHRo
YXQgd291bGQgaGF2ZSBhIHZhcmlhYmxlIHNpemVkIGRhdGEgcGF5bG9hZCwgZGVwZW5kaW5nIG9u
IHRoZSBwcm9wZXJ0eSBpZCB3ZSB1c2UuIEFuIGV4YW1wbGUgd291bGQgYmUgOg0KDQp0eXBlZGVm
IHZvaWQgKCpwcm9wZXJ0eV9jaGFuZ2VkX2NiKSAodWludDE2X3QgcHJvcGVydHlfaWQsIHVpbnQ4
X3QgKnByb3BlcnR5X2RhdGEsIHVpbnQxNl90IGRhdGFfbGVuZ3RoKQ0KDQojZGVmaW5lIFBST1BF
UlRZX0NIQU5HRURfVkVORE9SX0lEIDB4MTANCnR5cGVkZWYgc3RydWN0IHZpZF9jaGFuZ2VkIHsN
Cgl1aW50MTZfdCB2aWQ7DQp9DQoNCiNkZWZpbmUgUFJPUEVSVFlfQ0hBTkdFRF9WRU5ET1JfSURf
U1JDIDB4MTENCnR5cGVkZWYgc3RydWN0IHZpZF9zcmNfY2hhbmdlZCB7DQoJdWludDE2X3Qgdmlk
X3NyYzsNCn0NCg0KI2RlZmluZSBQUk9QRVJUWV9DSEFOR0VEX0JBVFRFUllfTEVWRUwgMHgxMg0K
dHlwZWRlZiBzdHJ1Y3QgYmF0dF9sZXZlbF9jaGFuZ2VkIHsNCgl1aW50OF90ICBuYW1lc3BhY2U7
DQoJdWludDE2X3QgZGVzY3JpcHRpb247DQoJdWludDhfdCAgdmFsdWU7DQp9DQoNCnRoaXMgd2ls
bCBiZSBjYWxsZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgRC1CVVMgUHJvcGVydHlDaGFuZ2Vk
IGV2ZW50IGZvciBlYWNoIGNoYW5nZWQgcHJvcGVydHksIGZvciBhbGwgcmVnaXN0ZXJlZCBwcm9w
ZXJ0eV9jaGFuZ2VkIGNhbGxiYWNrcyByZWdpc3RlcmVkLiANCg0KV2hhdCBkbyB5b3UgdGhpbmsg
Pw0KDQo+IA0KPiBPcGluaW9ucz8NCj4gDQoNCj4gQlIsDQo+IENsYXVkaW8NCg0KDQoNClRoYW5r
cywNCkNoZW4gR2FuaXINCg0K

2012-03-27 06:36:21

by Ganir, Chen

[permalink] [raw]
Subject: RE: [PATCH v2 5/5] DeviceInfo: Read PNP ID

Lizardo,

> -----Original Message-----
> From: Anderson Lizardo [mailto:[email protected]]
> Sent: Monday, March 26, 2012 5:55 PM
> To: Ganir, Chen
> Cc: [email protected]
> Subject: Re: [PATCH v2 5/5] DeviceInfo: Read PNP ID
>
> Hi Chen,
>
> On Mon, Mar 26, 2012 at 11:25 AM, <[email protected]> wrote:
> > diff --git a/src/device.c b/src/device.c
> > index 3b772ee..dad8c26 100644
> > --- a/src/device.c
> > +++ b/src/device.c
> > @@ -131,6 +131,7 @@ struct btd_device {
> > ? ? ? ?gchar ? ? ? ? ? *path;
> > ? ? ? ?char ? ? ? ? ? ?name[MAX_NAME_LENGTH + 1];
> > ? ? ? ?char ? ? ? ? ? ?*alias;
> > + ? ? ? uint16_t ? ? ? ?vendor_src;
> > ? ? ? ?uint16_t ? ? ? ?vendor;
> > ? ? ? ?uint16_t ? ? ? ?product;
> > ? ? ? ?uint16_t ? ? ? ?version;
> > @@ -377,6 +378,11 @@ static DBusMessage
> *get_properties(DBusConnection *conn,
> > ? ? ? ? ? ? ? ?dict_append_entry(&dict, "Vendor", DBUS_TYPE_UINT16,
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&device-
> >vendor);
> >
> > + ? ? ? /* Vendor Source*/
> > + ? ? ? if (device->vendor_src)
> > + ? ? ? ? ? ? ? dict_append_entry(&dict, "VendorSource",
> DBUS_TYPE_UINT16,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &device-
> >vendor_src);
> > +
>
> * How does this work for BR/EDR devices (without GATT)? Is zero a
> valid value for these devices?

For BR/EDR, you may have either DID or DIS. None of the specs define what is the relationship between those on BR/EDR (since in theory you may have both at the same time), so no special code was added to handle such a situation. As far as I can see, in a GATT capable device, the DIS should replace the DID since it extends its capabilities, but this is totally vendor dependant.

Regarding default values, the spec does not specify valid range for product id and product version. Both for DID in BR/EDR and DIS in LE, those values are totally dependent on vendor implementation and have no limits.

For the Vendor ID Source, 0x0000 is a reserved for future use, and currently should not be used.
A default value for nonexistent VID according to the DID spec is 0xFFF (the DIS spec does not define such a value).

The current device.c implementation was not changed, meaning that for the D-BUS interface, having a 0 value will remove the property from the dbus dictionary.

Do we want to change this behavior ? Maybe add a short bitmask field for existing fields ? What do you think ?
>
> * You need to update doc/device-api.txt
>
The only addition to the doc/device-api.txt is the addition of Vendroid ID Source. I'll add that and send a revised patch set.

> * Vendor Source looks like uint8, but you save it as uint16. Yes, I
> know there is no "uint8" for d-bus, but just wondering why "byte"
> cannot be used here.
>
This is a difference between DID and DIS. DID defines the VID Source as 2 bytes, and DIS defines it as 1 byte. Anyway, I'll need to change the propery VendorID Source from byte to uint16 to allow both to be sent to the user. The btd_device_get_vendor_src already returns a uint16_t.

> Regards,
> --
> Anderson Lizardo
> Instituto Nokia de Tecnologia - INdT
> Manaus - Brazil

2012-03-26 20:31:02

by Claudio Takahasi

[permalink] [raw]
Subject: Re: [PATCH v2 0/5] Add DeviceInformationService plugin

Hi Chen Ganir:

On Mon, Mar 26, 2012 at 12:25 PM, <[email protected]> wrote:
> From: Chen Ganir <[email protected]>
>
> Add Device Information Service GATT Client for reading peer
> device PNP_ID and store it.
>
> This is v2 of the patch set, removing some unused code to
> eliminate compilation warnings.

I am afraid of race conditions between HoG and DIS services.

ATT is a "serial" protocol, however there is no guarantee that PNP ID
characteristic value will be available before creating uhid device. It
depends on the probing order AND when the commands are added in the
GAttrib queue.

IMO, the alternatives are:
1. move the DIS/PnP discovery to the create device "procedure"
2. create plugin states and dependency before probing
3. uuid "notification" mechanism": callback gets called when a new
value is available for a given characteristic

Opinions?

BR,
Claudio

2012-03-26 15:54:49

by Anderson Lizardo

[permalink] [raw]
Subject: Re: [PATCH v2 5/5] DeviceInfo: Read PNP ID

Hi Chen,

On Mon, Mar 26, 2012 at 11:25 AM, <[email protected]> wrote:
> diff --git a/src/device.c b/src/device.c
> index 3b772ee..dad8c26 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -131,6 +131,7 @@ struct btd_device {
> ? ? ? ?gchar ? ? ? ? ? *path;
> ? ? ? ?char ? ? ? ? ? ?name[MAX_NAME_LENGTH + 1];
> ? ? ? ?char ? ? ? ? ? ?*alias;
> + ? ? ? uint16_t ? ? ? ?vendor_src;
> ? ? ? ?uint16_t ? ? ? ?vendor;
> ? ? ? ?uint16_t ? ? ? ?product;
> ? ? ? ?uint16_t ? ? ? ?version;
> @@ -377,6 +378,11 @@ static DBusMessage *get_properties(DBusConnection *conn,
> ? ? ? ? ? ? ? ?dict_append_entry(&dict, "Vendor", DBUS_TYPE_UINT16,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&device->vendor);
>
> + ? ? ? /* Vendor Source*/
> + ? ? ? if (device->vendor_src)
> + ? ? ? ? ? ? ? dict_append_entry(&dict, "VendorSource", DBUS_TYPE_UINT16,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &device->vendor_src);
> +

* How does this work for BR/EDR devices (without GATT)? Is zero a
valid value for these devices?

* You need to update doc/device-api.txt

* Vendor Source looks like uint8, but you save it as uint16. Yes, I
know there is no "uint8" for d-bus, but just wondering why "byte"
cannot be used here.

Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

2012-03-26 15:25:08

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v2 5/5] DeviceInfo: Read PNP ID

From: Chen Ganir <[email protected]>

Read the PNP ID characteristic of the DeviceInfo Service, and
store it inside the btd_device, for use by other profiles.
---
deviceinfo/deviceinfo.c | 38 ++++++++++++++++++++++++++++++++++++++
src/device.c | 33 +++++++++++++++++++++++++++++++++
src/device.h | 3 +++
3 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
index cc2b061..dffff60 100644
--- a/deviceinfo/deviceinfo.c
+++ b/deviceinfo/deviceinfo.c
@@ -90,6 +90,42 @@ static gint cmp_device(gconstpointer a, gconstpointer b)
return -1;
}

+static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
+ gpointer user_data)
+{
+ struct characteristic *ch = user_data;
+ uint8_t value[ATT_MAX_MTU];
+ int vlen;
+
+ if (status != 0) {
+ DBG("value read failed: %s",
+ att_ecode2str(status));
+ return;
+ }
+
+ if (!dec_read_resp(pdu, len, value, &vlen)) {
+ DBG("Protocol error\n");
+ return;
+ }
+
+ if (vlen < 7) {
+ DBG("Invalid deviceinfo received");
+ return;
+ }
+
+ device_set_pnpid(ch->d->dev,value[0],att_get_u16(&value[1]), att_get_u16(&value[3]),
+ att_get_u16(&value[5]));
+}
+
+static void process_deviceinfo_char(struct characteristic *ch)
+{
+ if (g_strcmp0(ch->attr.uuid, PNPID_UUID) == 0) {
+ gatt_read_char(ch->d->attrib, ch->attr.value_handle, 0,
+ read_pnpid_cb, ch);
+ return;
+ }
+}
+
static void configure_deviceinfo_cb(GSList *characteristics, guint8 status,
gpointer user_data)
{
@@ -114,6 +150,8 @@ static void configure_deviceinfo_cb(GSList *characteristics, guint8 status,
ch->d = d;

d->chars = g_slist_append(d->chars, ch);
+
+ process_deviceinfo_char(ch);
}
}
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
diff --git a/src/device.c b/src/device.c
index 3b772ee..dad8c26 100644
--- a/src/device.c
+++ b/src/device.c
@@ -131,6 +131,7 @@ struct btd_device {
gchar *path;
char name[MAX_NAME_LENGTH + 1];
char *alias;
+ uint16_t vendor_src;
uint16_t vendor;
uint16_t product;
uint16_t version;
@@ -377,6 +378,11 @@ static DBusMessage *get_properties(DBusConnection *conn,
dict_append_entry(&dict, "Vendor", DBUS_TYPE_UINT16,
&device->vendor);

+ /* Vendor Source*/
+ if (device->vendor_src)
+ dict_append_entry(&dict, "VendorSource", DBUS_TYPE_UINT16,
+ &device->vendor_src);
+
/* Product */
if (device->product)
dict_append_entry(&dict, "Product", DBUS_TYPE_UINT16,
@@ -983,6 +989,19 @@ static void device_set_vendor(struct btd_device *device, uint16_t value)
DBUS_TYPE_UINT16, &value);
}

+static void device_set_vendor_src(struct btd_device *device, uint16_t value)
+{
+ DBusConnection *conn = get_dbus_connection();
+
+ if (device->vendor_src == value)
+ return;
+
+ device->vendor_src = value;
+
+ emit_property_changed(conn, device->path, DEVICE_INTERFACE, "VendorSource",
+ DBUS_TYPE_UINT16, &value);
+}
+
static void device_set_product(struct btd_device *device, uint16_t value)
{
DBusConnection *conn = get_dbus_connection();
@@ -1102,6 +1121,11 @@ uint16_t btd_device_get_vendor(struct btd_device *device)
return device->vendor;
}

+uint16_t btd_device_get_vendor_src(struct btd_device *device)
+{
+ return device->vendor_src;
+}
+
uint16_t btd_device_get_product(struct btd_device *device)
{
return device->product;
@@ -2992,3 +3016,12 @@ gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)

return TRUE;
}
+
+void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
+ uint16_t vendor_id, uint16_t product_id, uint16_t product_ver)
+{
+ device_set_vendor(device, vendor_id);
+ device_set_vendor_src(device, vendor_id_src);
+ device_set_product(device, product_id);
+ device_set_version(device, product_ver);
+}
diff --git a/src/device.h b/src/device.h
index 7cb9bb2..c7973c5 100644
--- a/src/device.h
+++ b/src/device.h
@@ -39,6 +39,7 @@ struct btd_device *device_create(DBusConnection *conn,
void device_set_name(struct btd_device *device, const char *name);
void device_get_name(struct btd_device *device, char *name, size_t len);
uint16_t btd_device_get_vendor(struct btd_device *device);
+uint16_t btd_device_get_vendor_src(struct btd_device *device);
uint16_t btd_device_get_product(struct btd_device *device);
uint16_t btd_device_get_version(struct btd_device *device);
void device_remove(struct btd_device *device, gboolean remove_stored);
@@ -120,3 +121,5 @@ int device_block(DBusConnection *conn, struct btd_device *device,
gboolean update_only);
int device_unblock(DBusConnection *conn, struct btd_device *device,
gboolean silent, gboolean update_only);
+void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
+ uint16_t vendor_id, uint16_t product_id, uint16_t product_ver);
--
1.7.4.1


2012-03-26 15:25:07

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v2 4/5] Fix device version in GetProperties

From: Chen Ganir <[email protected]>

Fix how device version is added to the property dictionay.
---
src/device.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/device.c b/src/device.c
index eab7e4c..3b772ee 100644
--- a/src/device.c
+++ b/src/device.c
@@ -383,7 +383,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
&device->product);

/* Version */
- if (device->product)
+ if (device->version)
dict_append_entry(&dict, "Version", DBUS_TYPE_UINT16,
&device->version);

--
1.7.4.1


2012-03-26 15:25:06

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v2 3/5] DeviceInfo: Discover Characteristics

From: Chen Ganir <[email protected]>

Add logic to discover all characteristics and build a
characteristic list.
---
deviceinfo/deviceinfo.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-
deviceinfo/deviceinfo.h | 2 +-
deviceinfo/manager.c | 5 +++-
3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
index 8624a31..cc2b061 100644
--- a/deviceinfo/deviceinfo.c
+++ b/deviceinfo/deviceinfo.c
@@ -34,17 +34,33 @@
#include "att.h"
#include "gattrib.h"
#include "gatt.h"
+#include "log.h"
#include "deviceinfo.h"

+#define PNPID_UUID "00002a50-0000-1000-8000-00805f9b34fb"

struct deviceinfo {
struct btd_device *dev; /* Device reference */
GAttrib *attrib; /* GATT connection */
+ struct att_range *svc_range; /* DeviceInfo range */
guint attioid; /* Att watcher id */
+ GSList *chars; /* Characteristics */
};

static GSList *deviceinfoservers = NULL;

+struct characteristic {
+ struct gatt_char attr; /* Characteristic */
+ struct deviceinfo *d; /* deviceinfo where the char belongs */
+};
+
+static void char_free(gpointer user_data)
+{
+ struct characteristic *c = user_data;
+
+ g_free(c);
+}
+
static void deviceinfo_free(gpointer user_data)
{
struct deviceinfo *d = user_data;
@@ -55,7 +71,11 @@ static void deviceinfo_free(gpointer user_data)
if (d->attrib != NULL)
g_attrib_unref(d->attrib);

+ if (d->chars != NULL)
+ g_slist_free_full(d->chars, char_free);
+
btd_device_unref(d->dev);
+ g_free(d->svc_range);
g_free(d);
}

@@ -70,11 +90,40 @@ static gint cmp_device(gconstpointer a, gconstpointer b)
return -1;
}

+static void configure_deviceinfo_cb(GSList *characteristics, guint8 status,
+ gpointer user_data)
+{
+ struct deviceinfo *d = user_data;
+ GSList *l;
+
+ if (status != 0) {
+ error("Discover deviceinfo characteristics: %s",
+ att_ecode2str(status));
+ return;
+ }
+
+ for (l = characteristics; l; l = l->next) {
+ struct gatt_char *c = l->data;
+ struct characteristic *ch;
+
+ ch = g_new0(struct characteristic, 1);
+ ch->attr.handle = c->handle;
+ ch->attr.properties = c->properties;
+ ch->attr.value_handle = c->value_handle;
+ memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
+ ch->d = d;
+
+ d->chars = g_slist_append(d->chars, ch);
+ }
+}
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
struct deviceinfo *d = user_data;

d->attrib = g_attrib_ref(attrib);
+
+ gatt_discover_char(d->attrib, d->svc_range->start, d->svc_range->end,
+ NULL, configure_deviceinfo_cb, d);
}

static void attio_disconnected_cb(gpointer user_data)
@@ -85,12 +134,15 @@ static void attio_disconnected_cb(gpointer user_data)
d->attrib = NULL;
}

-int deviceinfo_register(struct btd_device *device)
+int deviceinfo_register(struct btd_device *device, struct gatt_primary *prim)
{
struct deviceinfo *d;

d = g_new0(struct deviceinfo, 1);
d->dev = btd_device_ref(device);
+ d->svc_range = g_new0(struct att_range, 1);
+ d->svc_range->start = prim->range.start;
+ d->svc_range->end = prim->range.end;

deviceinfoservers = g_slist_prepend(deviceinfoservers, d);

diff --git a/deviceinfo/deviceinfo.h b/deviceinfo/deviceinfo.h
index 0ea6ff5..7a804a5 100644
--- a/deviceinfo/deviceinfo.h
+++ b/deviceinfo/deviceinfo.h
@@ -20,5 +20,5 @@
*
*/

-int deviceinfo_register(struct btd_device *device);
+int deviceinfo_register(struct btd_device *device, struct gatt_primary *prim);
void deviceinfo_unregister(struct btd_device *device);
diff --git a/deviceinfo/manager.c b/deviceinfo/manager.c
index 025a076..c2378c2 100644
--- a/deviceinfo/manager.c
+++ b/deviceinfo/manager.c
@@ -44,6 +44,7 @@ static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)

static int deviceinfo_driver_probe(struct btd_device *device, GSList *uuids)
{
+ struct gatt_primary *prim;
GSList *primaries, *l;

primaries = btd_device_get_primaries(device);
@@ -53,7 +54,9 @@ static int deviceinfo_driver_probe(struct btd_device *device, GSList *uuids)
if (l == NULL)
return -EINVAL;

- return deviceinfo_register(device);
+ prim = l->data;
+
+ return deviceinfo_register(device, prim);
}

static void deviceinfo_driver_remove(struct btd_device *device)
--
1.7.4.1


2012-03-26 15:25:05

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v2 2/5] DeviceInfo: Add connection logic

From: Chen Ganir <[email protected]>

Add connection logic to the Device Information Plugin. When the
driver is loaded, it will request a connection to the remote device
and release the connection request when destroyed.
---
deviceinfo/deviceinfo.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
index 95e7f1d..8624a31 100644
--- a/deviceinfo/deviceinfo.c
+++ b/deviceinfo/deviceinfo.c
@@ -29,13 +29,18 @@
#include <bluetooth/uuid.h>
#include "adapter.h"
#include "device.h"
+#include "gattrib.h"
+#include "attio.h"
#include "att.h"
#include "gattrib.h"
#include "gatt.h"
#include "deviceinfo.h"

+
struct deviceinfo {
struct btd_device *dev; /* Device reference */
+ GAttrib *attrib; /* GATT connection */
+ guint attioid; /* Att watcher id */
};

static GSList *deviceinfoservers = NULL;
@@ -44,6 +49,12 @@ static void deviceinfo_free(gpointer user_data)
{
struct deviceinfo *d = user_data;

+ if (d->attioid > 0)
+ btd_device_remove_attio_callback(d->dev, d->attioid);
+
+ if (d->attrib != NULL)
+ g_attrib_unref(d->attrib);
+
btd_device_unref(d->dev);
g_free(d);
}
@@ -59,6 +70,21 @@ static gint cmp_device(gconstpointer a, gconstpointer b)
return -1;
}

+static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
+{
+ struct deviceinfo *d = user_data;
+
+ d->attrib = g_attrib_ref(attrib);
+}
+
+static void attio_disconnected_cb(gpointer user_data)
+{
+ struct deviceinfo *d = user_data;
+
+ g_attrib_unref(d->attrib);
+ d->attrib = NULL;
+}
+
int deviceinfo_register(struct btd_device *device)
{
struct deviceinfo *d;
@@ -68,6 +94,8 @@ int deviceinfo_register(struct btd_device *device)

deviceinfoservers = g_slist_prepend(deviceinfoservers, d);

+ d->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
+ attio_disconnected_cb, d);
return 0;
}

--
1.7.4.1


2012-03-26 15:25:04

by Ganir, Chen

[permalink] [raw]
Subject: [PATCH v2 1/5] Add DeviceInformation GATT Client

From: Chen Ganir <[email protected]>

Add the DeviceInformation GATT Client plugin skeleton.
---
Makefile.am | 9 +++--
deviceinfo/deviceinfo.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++
deviceinfo/deviceinfo.h | 24 +++++++++++++
deviceinfo/main.c | 55 +++++++++++++++++++++++++++++
deviceinfo/manager.c | 79 ++++++++++++++++++++++++++++++++++++++++++
deviceinfo/manager.h | 24 +++++++++++++
6 files changed, 275 insertions(+), 3 deletions(-)
create mode 100644 deviceinfo/deviceinfo.c
create mode 100644 deviceinfo/deviceinfo.h
create mode 100644 deviceinfo/main.c
create mode 100644 deviceinfo/manager.c
create mode 100644 deviceinfo/manager.h

diff --git a/Makefile.am b/Makefile.am
index ddc28d2..0a2a38d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -213,7 +213,8 @@ builtin_sources += health/hdp_main.c health/hdp_types.h \
endif

if GATTMODULES
-builtin_modules += thermometer alert time gatt_example proximity
+builtin_modules += thermometer alert time gatt_example proximity \
+ deviceinfo
builtin_sources += thermometer/main.c \
thermometer/manager.h thermometer/manager.c \
thermometer/thermometer.h thermometer/thermometer.c \
@@ -222,10 +223,12 @@ builtin_sources += thermometer/main.c \
plugins/gatt-example.c \
proximity/main.c proximity/manager.h proximity/manager.c \
proximity/monitor.h proximity/monitor.c \
- proximity/reporter.h proximity/reporter.c
+ proximity/reporter.h proximity/reporter.c \
+ deviceinfo/main.c \
+ deviceinfo/manager.h deviceinfo/manager.c \
+ deviceinfo/deviceinfo.h deviceinfo/deviceinfo.c
endif

-
builtin_modules += hciops mgmtops
builtin_sources += plugins/hciops.c plugins/mgmtops.c

diff --git a/deviceinfo/deviceinfo.c b/deviceinfo/deviceinfo.c
new file mode 100644
index 0000000..95e7f1d
--- /dev/null
+++ b/deviceinfo/deviceinfo.c
@@ -0,0 +1,87 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <glib.h>
+#include <bluetooth/uuid.h>
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "deviceinfo.h"
+
+struct deviceinfo {
+ struct btd_device *dev; /* Device reference */
+};
+
+static GSList *deviceinfoservers = NULL;
+
+static void deviceinfo_free(gpointer user_data)
+{
+ struct deviceinfo *d = user_data;
+
+ btd_device_unref(d->dev);
+ g_free(d);
+}
+
+static gint cmp_device(gconstpointer a, gconstpointer b)
+{
+ const struct deviceinfo *d = a;
+ const struct btd_device *dev = b;
+
+ if (dev == d->dev)
+ return 0;
+
+ return -1;
+}
+
+int deviceinfo_register(struct btd_device *device)
+{
+ struct deviceinfo *d;
+
+ d = g_new0(struct deviceinfo, 1);
+ d->dev = btd_device_ref(device);
+
+ deviceinfoservers = g_slist_prepend(deviceinfoservers, d);
+
+ return 0;
+}
+
+void deviceinfo_unregister(struct btd_device *device)
+{
+ struct deviceinfo *d;
+ GSList *l;
+
+ l = g_slist_find_custom(deviceinfoservers, device, cmp_device);
+ if (l == NULL)
+ return;
+
+ d = l->data;
+ deviceinfoservers = g_slist_remove(deviceinfoservers, d);
+
+ deviceinfo_free(d);
+}
diff --git a/deviceinfo/deviceinfo.h b/deviceinfo/deviceinfo.h
new file mode 100644
index 0000000..0ea6ff5
--- /dev/null
+++ b/deviceinfo/deviceinfo.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+int deviceinfo_register(struct btd_device *device);
+void deviceinfo_unregister(struct btd_device *device);
diff --git a/deviceinfo/main.c b/deviceinfo/main.c
new file mode 100644
index 0000000..3acf04b
--- /dev/null
+++ b/deviceinfo/main.c
@@ -0,0 +1,55 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include "plugin.h"
+#include "manager.h"
+#include "hcid.h"
+#include "log.h"
+
+static int deviceinfo_init(void)
+{
+ if (!main_opts.gatt_enabled) {
+ DBG("GATT is disabled");
+ return -ENOTSUP;
+ }
+
+ return deviceinfo_manager_init();
+}
+
+static void deviceinfo_exit(void)
+{
+ if (!main_opts.gatt_enabled)
+ return;
+
+ deviceinfo_manager_exit();
+}
+
+BLUETOOTH_PLUGIN_DEFINE(deviceinfo, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+ deviceinfo_init, deviceinfo_exit)
diff --git a/deviceinfo/manager.c b/deviceinfo/manager.c
new file mode 100644
index 0000000..025a076
--- /dev/null
+++ b/deviceinfo/manager.c
@@ -0,0 +1,79 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <glib.h>
+#include <errno.h>
+#include <bluetooth/uuid.h>
+
+#include "adapter.h"
+#include "device.h"
+#include "att.h"
+#include "gattrib.h"
+#include "gatt.h"
+#include "deviceinfo.h"
+#include "manager.h"
+
+#define DEVICE_INFORMATION_UUID "0000180a-0000-1000-8000-00805f9b34fb"
+
+static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct gatt_primary *prim = a;
+ const char *uuid = b;
+
+ return g_strcmp0(prim->uuid, uuid);
+}
+
+static int deviceinfo_driver_probe(struct btd_device *device, GSList *uuids)
+{
+ GSList *primaries, *l;
+
+ primaries = btd_device_get_primaries(device);
+
+ l = g_slist_find_custom(primaries, DEVICE_INFORMATION_UUID,
+ primary_uuid_cmp);
+ if (l == NULL)
+ return -EINVAL;
+
+ return deviceinfo_register(device);
+}
+
+static void deviceinfo_driver_remove(struct btd_device *device)
+{
+ deviceinfo_unregister(device);
+}
+
+static struct btd_device_driver deviceinfo_device_driver = {
+ .name = "deviceinfo-driver",
+ .uuids = BTD_UUIDS(DEVICE_INFORMATION_UUID),
+ .probe = deviceinfo_driver_probe,
+ .remove = deviceinfo_driver_remove
+};
+
+int deviceinfo_manager_init(void)
+{
+ return btd_register_device_driver(&deviceinfo_device_driver);
+}
+
+void deviceinfo_manager_exit(void)
+{
+ btd_unregister_device_driver(&deviceinfo_device_driver);
+}
diff --git a/deviceinfo/manager.h b/deviceinfo/manager.h
new file mode 100644
index 0000000..0f742ca
--- /dev/null
+++ b/deviceinfo/manager.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+int deviceinfo_manager_init(void);
+void deviceinfo_manager_exit(void);
--
1.7.4.1