This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Do characteristics have a fixed format?

Hello, it is to my understanding that profile & service do not have fixed forms. Services make up profiles and you can choose how many and what services make up a profile, like wise, since characteristics make up services, you can do the same (please correct me if I'm wrong). But what about characteristics? It has a fixed format, handle, UUID, value, etc, right?

  • The Bluetooth SIG has defined several "standard" services (www.bluetooth.com/.../services) that have well defined requirements and formats. Any device that uses some of the standard services should conform to the requirements. (Some of them contain some optional characteristics)

    When designing your own "custom profile" you can mix in whatever services you want. When designing your own services you are free to include your own mix characteristics.

    Characteristics can be variable length or fixed length (up to ~512 bytes). There are some limitations if characteristics exceed 20 bytes (Ex: writes to Nordic devices require additional code and you can't notify/indicate more than 20 bytes). When designing your own services you can use individual characteristics however you want. Many custom services use things like variant records and will use a single characteristic for several different types of message exchange. (That is, the message will begin with a tag value that dictates how the remainder of the bytes will be used)

    A characteristic's UUID should be fixed. The UUID is used by the client to determine what the characteristic can be used for, so it doesn't make any sense for it to change (it would be like changing the name of a Method in an Object). You could use an additional characteristic if you want a different type of interaction. The handle's actual value is dealt with at a lower level and usually isn't a concern for the application programmer.

    Since your other post mentioned OOP concepts, this may help: Think of UUIDs for Services as being like a class name --- they distinguish the kind of thing being interacted with. Think of UUIDs for Characteristics as being like method names --- they are a specific "channel" of interaction. (Characteristics can do Notifications/Indications and there isn't a good, general OOP analogy here)

    Most client applications will:

    1. Connect to a device
    2. List all services (or if looking for a specific function, just the ones of interest by using a UUID. If your custom service uses a UUID of X, a mobile app may just query for services of type X)
    3. Get a list of all the characteristics in each of the services of interest (this includes the handles, but at the application level you often don't know or care about the handles....unless you're packet sniffing to help with debugging)
    4. Interact with the Characteristic within the service that corresponds to the desired interaction. So, if UUID Y represents the data it wants to read from a service, it will read data from the characteristic with that UUID.
  • I can't thank you enough. I'm still digesting all of this and it's going to take time. Thank you.

  • No problem. Individual aspects of BLE are conceptually simple, but an actual system is quite complex (ex: mobile apps with high level object-oriented design, embedded apps with a low level API, protocols at the GATT layer and lower layers, etc.). It takes a while to understand how all different parts fit together. Here are some resources that you may find helpful: The AdaFruit Intro and/or Getting Started with Bluetooth Low Energy and/or Make: Bluetooth Projects. Each is reasonably readable. By the way, if you consider this question "answered" you might want to "Accept the Answer" (checkmark button) to close it, but if you need more detail add another comment.

Related