Creating a Gatt Server?

Alxjrvs picture Alxjrvs · Oct 23, 2013 · Viewed 26.7k times · Source

I have a wider range question here, so if someone could point me to a doc or article that could explain this, that would suffice. Needless to say, a days worth of googling has gotten me nowhere, and I could use a helping hand.

I am connecting to a BeagleBoard with BlueZ 5.9, and my intent is to:

  1. Create a Gatt server,
  2. Load it up with some writeable attributes, and
  3. Advertise that server to connect to an android device.

I've created the Android app that will connect and operate as the central, rendering 3 basically complete. I don't know how the commands - the literal things to type - to initiate a Gatt server / create attributes on the BeagleBoard. I am knew to hardware writ large, so it is possible I just have my terminology completely incorrect - that said, any help would be a appreciated in completing 1 and 2, even if it is just a shove in the right direction. Thanks!

Answer

Etan picture Etan · Oct 26, 2013

Your terminology is mainly correct.

Typically, a GATT database has the services 0x1800 (Generic Access) and 0x1801 (Generic Attribute) at least. The Generic Access service contains two mandatory characteristics: Device Name and Appearance. The Generic Attribute service should be empty.

Therefore, the minimal GATT database looks like this:

Handle  Description
 0000   Service: Generic Access (1800)
 0001   Characteristic: Device Name (2A00, readable)
 0002   Characteristic Value (string)
 0003   Characteristic: Appearance (2A01, readable)
 0004   Characteristic Value (16bit enum)
 0005   Service: Generic Attribute (1801) 

After these two services, you can add your own services. In your case, you don't seem to target a well-known service, so you'll create an own one.

First, create a 128-bit UUID, for example using the uuidgen tool on your Mac's command line

$ uuidgen
DCDF2725-56C8-4235-A4BC-F7951D5C3762

This will be your service UUID

 0006   Service: Custom defined Service (DCDF2725-56C8-4235-A4BC-F7951D5C3762)

Then, you mentioned that you want several writeable characteristics. So, let's create another UUID for that one.

$ uuidgen
4C06C6F4-C90D-4C58-8E31-20C8C74FF832

And add a characteristic to the service

 0007   Characteristic: Custom Characteristic (4C06C...FF832, writeable)
 0008   Characteristic Value (hex, 20 bytes)

Your characteristic value shouldn't exceed 20 bytes, and you should select "Write Request" to ensure that acknowledgments of writes are sent to the central. If you choose "Write Command", writes may be discarded by either your phone's stack or the peripheral.

After you have defined this characteristic, you are ready to start coding.

I don't know the BeagleBoard SDK, but typically, you start by initializing the GATT library and additional modules (for example, to support writes, you have to initialize a second part of the library).

After this initialization, you register your GATT database. If you don't have a nice tool for generating the binary data, you may have to write them yourselves. That's explained in the Bluetooth Core Spec V4.0. Let's hope you can find an API that does the transformation for you :-)

When the registration is successful, you'll have to set the advertising parameters and can start advertising (consult your SDK's documentation and samples for this, again).

What happens now, is that at some time, you will get a callback that a connection has been established, and later, you'll get an attribute request for a given handle. Then, you just have to process the request by looking at the handle, the supplied value and the type of the operation (read / write). Don't forget to always return a success value or an error code in response to the request, as otherwise, you'll lock up the Bluetooth communications.

Normally, those Bluetooth chips always work with asynchronous operations. You'll send a request, and then have to wait until the request is completed before sending the next one. Remember that when programming, it saves you time :-).

If you want to try on Android first because it's more familiar for you, you can try the Galaxy S 4 with Android 4.2. It also has an LE peripheral mode - I haven't tested its reliability, though. The most reliable smartphone stack at the moment to act as LE peripheral is currently in iOS 7 - so it may be worth picking up an iPod touch if it's affordable to play around with it.