Polymorphic GATT and Service Change Indications

Background

This code example has related User's Guides, here:

Description

In this example, a server that can dynamically change its GATT database structure (polymorphic GATT) and a client that can subscribe to service change indications are implemented.

The server uses the polymorphic GATT feature i.e., it can enable and disable some of its services / characteristics at runtime. In this example, two versions of the same service (My LED Switch Service) are defined in the database, from which only one at a time is enabled to imitate two different versions of the database. The database versions can be changed by push button presses.

The client discovers the Service Changed characteristic in the master's GATT database and subscribes for service change indications to be notified about GATT database changes. After the GATT database of the server changes, the client gets a service change indication.

To be notified about changes that happened while the client was not connected, the client has to create a bonding with the master. If the devices are bonded, the master will notify the client upon reconnection about the changes.

Setting up

To try this example, you need two radio boards, one for the server side and one for the client side.

Server

  1. Create a new SoC-Empty project for your device.

  2. Copy the attached app_server.c file into your project, and remove app.c from the project.

  3. Set DEBUG_LEVEL to 1 in app.h.

  4. Copy gpiointerrupt.c from C:\SiliconLabs\SimplicityStudio\v4\developer\sdks\gecko_sdk_suite\<version>\platform\emdrv\gpiointerrupt\src into your project, under /platform/emdrv/gpiointerrupt/src.

  5. Open GATT Configurator and import the attached gatt_server.xml with the import button found on the right side.

  6. Press Save and Generate in the GATT Configurator.

  7. Build and flash the project to your device.

Client

  1. Create a new SoC-Empty project for your device.

  2. Copy the attached app_client.c file into your project and remove app.c from the project.

  3. Set DEBUG_LEVEL to 1 in app.h.

  4. Build and flash your project to your device.

Usage

When running the two examples next to each other, the client will automatically find the server (based on the device name). Upon connection

The database version can be changed at any time on the server using the push buttons of the WSTK. PB0 sets the database to version 1, and PB1 sets the database to version 2. After the version is changed, the server will automatically send out a service change indication to the client. The client receives the indication, confirms it, and restarts database discovery to update characteristic handles. Updated handles are stored again in persistent storage.

To test the example

  1. Open two terminal programs (such as TeraTerm) on your PC and connect to the virtual COM ports (JLink CDC UART port).

  2. Reset both WSTKs. You should now see the client connecting to the server, creating bonding, and discovering or loading the database structure.

  3. On the server side, press PB1 to switch to database version 2. You can see the client receiving service change indication and rediscovering the database.

  4. Press PB0 on the server to switch back to database version 1 and observe the change on the client side again.

  5. Press and hold the reset button on the client while you press PB1 on the server. This will result in a database change while the client is not connected.

  6. Release the reset button of the client and observe that the server will send a service change indication right after the client has reconnected.

Log of the server and the client

Source