Configure device

“NF Interface” uses GATT profile from Bluetooth Low Energy (BLE) for communication with the device and to construct an interface. It’s designed to read GATT services along with their characteristics, types, and corresponding values.

Standard characteristics

BLE specification defines set of standard characteristics. If a device already exposes them, then no further configuration is necessary.

Service
Name Device information
UUID 0x180A
Charasteristic
Name Model Number String
UUID 0x2A24
Charasteristic
Name Manufacturer Name String
UUID 0x2A29

In the example above, the device exposes Device information service using the standard UUID 0x180A. This service includes two standard characteristics: Model Number String and Manufacturer Name String. These characteristics are documented in the official Bluetooth specifications and can be interpreted by the “NF Interface.”

Custom characteristics

It is also possible to expose custom services and characteristics, both of which can be supported by the “NF Interface”. However, additional configuration is required. Please consider the following example:

Service
UUID 43033f70-aab1-4159-bad0-07dff2602374
Charasteristic
UUID a6172cec-dce5-4d51-8e3e-fbd61fd25ddc
Descriptor
Name Characteristic User Description
UUID 0x2901
Value Custom parameter
Descriptor
Name Characteristic Presentation Format
UUID 0x2904
Value 0x19002700000000

Any custom characteristic must have 2 standard descriptors:

  • Characteristic User Description with UUID 0x2901. In the example above it provides the name which is “Custom parameter”.
  • Characteristic Presentation Format with UUID 0x2904.

The value of Characteristic Presentation Format descriptor should follow Bluetooth Specification 4.0 (Vol. 3), Part G, Section 3.3.3.5.

typedef struct {
  uint8_t gatt_format;
  int8_t exponent;
  uint16_t gatt_unit;
  uint8_t gatt_namespace;
  uint16_t gatt_nsdesc;
} presentation_format_t;

In the example above format defined as unitless (0x2700) UTF-8 string (0x19).

Multiple devices

Sometimes device doesn’t have bluetooth, but have something to expose. Or several devices connected together and only one has bluetooth chip. In that case QR codes can be generated for individual service. Where every device should provide all characteristics under its own service UUID.

Service
UUID 810915bd-7a4a-467e-ae9b-fbad996604da
Charasteristic
Name Model Number String
UUID 0x2A24
Charasteristic
Name Manufacturer Name String
UUID 0x2A29
Service
UUID fa7ed53b-3f3f-46a1-aaa3-9ee64af081a0
Charasteristic
Name Model Number String
UUID 0x2A24
Charasteristic
Name Manufacturer Name String
UUID 0x2A29

Receive notifications

According to BLE specification, a device has the capability to “push” updates to a characteristic. “NF Interface” checks if characteristic has Client Characteristic Configuration descriptor (UUID 0x2902) and if it exists, then it will set the first bit to enable the reception of notifications.

Service
Name Device information
UUID 0x180A
Charasteristic
UUID ef150ac3-8944-46c8-b26f-90d28a66e653
Descriptor
Name Characteristic User Description
UUID 0x2901
Value Load average
Descriptor
Name Characteristic Presentation Format
UUID 0x2904
Value 0x14002700000000
Descriptor
Name Client Characteristic Configuration
UUID 0x2902
Value 0x1
Charasteristic
Name Model Number String
UUID 0x2A24

In the example above, device has two characteristics: a standard one, Model Number String, and a custom one named Load Average. Since the custom characteristic includes a Client Characteristic Configuration descriptor “NF Interface” will write value 0x1 to it and wait for any updates.

Receive historical data

BLE specification allows showing only a single last value for characteristic. However in some certain cases it is useful to show historical data. For example, device can share current temperature and update it every minute. “NF Interface” can read temperature readings for the last day and show them as a graph. This protocol is custom and must be supported by device.

BLE server which is implemented on the device should add the following custom descriptor to the characteristic to indicate historical support:

Descriptor
Name Historical support
UUID 65407396-50e4-7fee-6540-739650e47fee
Value 0x0000

If characteristic has the descriptor above, then “NF Interface” will show it’s current value, but also mark it as “historical”. If user tap on it, then “NF Interface” will attempt to write a value for this descriptor and expect to receive several notifications with historical data.

“NF Interface” will write request in the following format:

typedef struct {
   uint8_t format;
} message_t;

Where format can be one of:

  • 0x00 - Last day
  • 0x01 - Last month
  • 0x02 - Last year

Notification from the device must be in the following format:

typedef struct {
  uint64_t timestamp;
  float value;
} data_point_t;

typedef struct {
  uint8_t protocol_version;
  uint8_t type;
  uint8_t points_length;
  data_point_t *points;
} historical_message_t;

Where type can be one of:

typedef enum {
  NOTIFICATION_REALTIME = 0x00,
  NOTIFICATION_GRAPH = 0x01,
  NOTIFICATION_END_OF_GRAPH = 0x02
} message_type_t;

Once all messages sent, device must send the final message with NOTIFICATION_END_OF_GRAPH type.

If characteristic supports historical data AND normal notifications, then notifications will be in the following format:

typedef struct {
  uint8_t protocol_version;
  uint8_t type;
  void *value;
} notification_message_t;

Where type=NOTIFICATION_REALTIME and value determined by Characteristic Presentation Format.