Understanding the GATT protocol in BLE

user2045557 picture user2045557 · May 19, 2014 · Viewed 7k times · Source

I have recently started to learn developing a mircocontroller-based device which will have BLE module. The device is supposed to send analog reading fetched from sensor to an android application that I am going to develop.
For what i have studied about the way GATT works is:

  1. The microntroller-based device will be GATT server.
  2. The android application will be GATT client.
  3. As seen from communication point of view, the microntroller-based device is Slave and the android application is Master.

Questions:

  1. How do I decide the number of attributes that I need to define in order to receive command from GATT Client and send the response (which is going to be a float value)? Do I need to have two distinct attributes: One for Android to send commands and one for the microncontroller-based device to send data to android? Or I can use a single attribute?
  2. GATT appears to be an event-driven system.
    2.1: What events will be generated when android sends a command to microcontroller-based device: (Client to Server) ?
    2.2: Will an event be generated when the data is written on the attribute which is going to be read by Android application: (Server to Client) ?
  3. The android application (GATT Client) should use read/write commands to communicate with the microncontroller-based device (GATT Server). And, the GATT Server should use Notify/Indicate to pass the data to the GATT Client. Is my understanding correct?

I am using this BlueGiga BLE112 Module for development.

The gatt.xml file that I so far have written is:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 1800: org.bluetooth.service.generic_access -->
<service uuid="1800" id="generic_access">
  <description>Generic Access</description>
  <!-- 2A00: org.bluetooth.characteristic.gap.device_name -->
    <characteristic uuid="2A00" id="c_device_name">
      <description>Device Name</description>
      <properties read="true" const="true" />
      <value>MyBLEDev</value>
    </characteristic>
  <!-- 2A01: org.bluetooth.characteristic.gap.appearance -->
    <characteristic uuid="2A01" id="c_appearance">
      <description>Appearance</description>
      <properties read="true" const="true" />
      <value type="hex">0300</value>
    </characteristic>
  </service>

  <!-- custom service -->
  <service uuid="624e957f-cb42-4cd6-bacc-84aeb898f69b" advertise="true">
    <description>Custom Device Service</description>

    <!-- custom write-only characteristic for Client to send commands to fetch reading -->
    <characteristic uuid="a57892fe-4f58-97d4-a5245-78a4125d3e6" id="c_cmd_TxReading">
      <description>Request for Reading</description>
      <properties write="true" />
      <value length="4" />
    </characteristic>

    <characteristic uuid="8fde302a-56ac-b289-65ed-a577ed66b89c" id="c_reading">
      <description>Measurement</description>
      <properties read="true" write="true" />
      <value length="4" type="float32" />
    </characteristic>
</service>

Answer

Tim Tisdall picture Tim Tisdall · May 20, 2014

I see a GATT server like a chunk of memory on another machine. You can request particular chunks by handles and get different information. You can make the other machine do different things or respond in different ways by writing values to those handles. The difference from memory space is that each handle can contain different sizes of information as well as each having a UUID that identifies how to interpret the data you find in there. In a regular memory space each "handle" would be an address, each chunk would be a single byte, and there's no way to figure out how to interpret that data without some other information.

So... questions:

  1. Like most questions on here, the answer is "it depends". If you just want to fetch the value, you just have a single attribute with the data in there that the client can fetch from. If you'd also like to set it up so the GATT server sends notifications whenever that value changes then you'd also have to add a Client Characteristic Configuration handle to that attribute. (Ex. I have one accelerometer that has 3 attributes for the X, Y, and Z values and another device that reports all 3 values as a single attribute. Because this is a type of value that hasn't been standardize they can do this by defining their own custom UUID. If you're measuring something that already has a standard layout then you should probably use that instead)

  2. GATT has some event driven aspects and other aspects that are done serially. For instance, you can only be negotiating one connection request at a time. However, you can be getting notifications in any order from any number of attributes at any time.

    1. You can't really define your own commands with GATT. You're restricted to things like "read from handle" or "write to handle" similar to manipulating a chunk of memory. The underlying implementation can be dependent on the hardware, but usually you can trigger some sort of event when a handle is manipulated.

    2. You can requests events by subscribing to notifications or indications on a particular attribute.

  3. Yes, that's correct.