[BL_T0003] BLE112-Protostick – Connecting, Characteristics, Handles, Services and Notifications under Windows

Introduction

This tutorial continues the tutorial BL_T0001. You will learn how to use Bluegiga’s BGLib to connect the BLE112-Protostick with other Bluetooth Low Energy devices and exchange informations with them. You will use UUIDs and handles to get specific informations or even change them if you want and you will activate a notification service which provides you with up to date data. The source code from the previous tutorial BL_T0001 was modified accordingly to make it as easy as possible for you to enter the world of services and characteristics of Bluetooth Low Energy.

BL_T0003 - Assembly

BL_T0003 – Assembly

BLEGUI Service Discovery

BLEGUI Service Discovery

Eclipse Debug Output

Eclipse Debug Output


Content

  1. Bill of material
  2. The Plan
    1. Insides of firmware bgdemo
    2. Insides of firmware uartdemo
    3. Procedure
    4. Preparations
  3. Application details
    1. Connecting
    2. Request informations
    3. Read by UUID
    4. Read by Handle
    5. Activate Notification and handling of a notification
  4. Conclusion

Bill of material

There’s a BLE112-Protostick development kit bundle (BLE112-Protostick Dev Kit #1) in our shop that includes all needed components [Shop-Link]

BLE112-Protostick Dev Kit #1 - Win, Linux, Mac

BLE112-Protostick Dev Kit #1 – Win, Linux, Mac

  • PC with minimum Windows XP required
  • 2 x BLE112-Protostick [Shop-Link]
    • #1 with Bluegiga API – Firmware
    • #2 with Advertiser/Peripherie/Broadcaster Firmware
  • USB to USART converter, LVTTL 3.3V, with RTS/CTS [Shop-Link]
  • Power supply 3.3V
  • 2 x Breadboards [Shop-Link]
  • Jumper Wires [Shop-Link]
  • TI’s CC-Debugger [Shop-Link] in case you need to flash the required firmware to the BLE112-Protosticks. Then you need also:
  • MinGW Toolchain
  • Eclipse C/C++ as an IDE, i.e. Eclipse Juno with CDT-Plugin
  • Example source code
  • Bluegiga’s BLEGUI Visual-Tool – bin/blegui2.exe (aus ble-1.1.1-71.zip vom Bluegiga – Tech Forum)
  • Documents (all available from Bluegiga – Tech Forum):
    • BLE112_Datasheet.pdf
      BLE112 modul datasheet, pin configuration on page 8.
    • Profile_development_kit_developer_guide_v29.pdf
      Explains how to create, compile and flash custom firmware for the BLE112 modul.
    • Bluetooth_Smart_API_11_11032013.pdf
      Complete description of the Bluegiga-API (BGAPI), here you can get details about message flow and the structure of messages.
    • BLEGUI_User_Guide_v1.7.pdf
      Complete description how to use this tool.

The Plan

Our start point is the previous tutorial BL_T0001, so make sure you already have all needed components installed and properly configured before you continue with this tutorial. If not do so now.

We have two BLE112-Protosticks BLE112-Protostick #1 and BLE112-Protostick #2. BLE112-Protostick #1 is equipped with the uartdemo firmware and BLE112-Protostick #2 is equipped with the bgdemo firmware.

Insides of firmware bgdemo

Let’s first take a look under the hood of the bgdemo firmware used by BLE112-Protostick #2 especially the GATT configuration in which those services and characteristics are defined we want to work with. The interesting code lines are highlighted.

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <service uuid="1800">
      <description>Generic Access Profile</description>

      <characteristic uuid="2a00">
        <properties read="true" const="true" />
        <value>BG Demo</value>
      </characteristic>

      <characteristic uuid="2a01">
        <properties read="true" const="true" />
        <value type="hex">4142</value>
      </characteristic>
    </service>

    <service type="primary" uuid="9000" id="manufacturer">
        <characteristic uuid="9100">
            <properties read="true" const="true" />
            <value type="hex">000780c0ffeef00d</value>
        </characteristic>
        <characteristic uuid="9101">
            <properties read="true" const="true" />
            <value>modelnumber</value>
        </characteristic>
        <characteristic uuid="9106">
            <properties read="true" const="true" />
            <value>Bluegiga</value>
        </characteristic>
    </service>

    <service uuid="e001">
       <description>Battery status</description>
       <include id="manufacturer" />
      <characteristic uuid="e101" id="xgatt_battery">
          <properties read="true" notify="true" />
          <value type="hex">ABCD</value>
      </characteristic>
    </service>
    
    <service uuid="00431c4a-a7a4-428b-a96d-d92d43c8c7cf">
        <description>Bluegiga demo service</description>
        <characteristic uuid="f1b41cde-dbf5-4acf-8679-ecb8b4dca6fe">
            <properties read="true" write="true"/>
            <value type="hex">coffee</value>
        </characteristic>
    </service>
</configuration>

The first line we want to take a closer look to is line 9. This line defines the value of the characteristic 0x2a00 which is attached to (a sibling of) the service 0×1800. The service characteristic 0×1800 is the very basic service characteristic every BLE device has to define, it is called Generic-Access-Profile. In the Generic-Access-Profile you’ll find informations about a device, i.e. the previously mentioned characteristic 0x2a00 defines the device name, it is an officially defined GATT characteristic. More of these GATT characteristics you’ll find at Bluetooth Developer Portal. In the portals page main menu click on “GATT specifications” there you’ll find every information you need to implement an BLE device (Services, Profiles, Declarations, Descriptors).

Line 37 defines the characteristic properties of the service “Battery Status”. This characteristic holds the voltage level value of the devices power supply. In this case the interesting part is the property “notify” which is set to true which means that the service “Battery Status” is able to notify us about a actualized characteristic value (Notifications) – we will later activate this function to get informed about the actual battery status.

In line 45 the property “write” of the characteristic is set to true which means we are able to overwrite the characteristics value. As you can see the characteristics UUID is 16 bytes long and not 2 bytes long like the others which means that this is not an official UUID but an unique UUID defined by Bluegiga. This unique UUID describes the value of the Service “Bluegiga Demo Service” – we will later overwrite this value and then read it out to be sure all works fine.

Insides of firmware uartdemo

Now let’s take a closer look to the BLE112-Protostick #1 firmware uartdemo. The firmware has an endpoint to the BGAPI via USART which means that data send to the USART will be interpreted and executed by the BGAPI. The endpoint to the BGAPI is set in the uartdemo project file hardware.xml:

<?xml version="1.0" encoding="UTF-8" ?>

<hardware>
    <sleeposc enable="true" ppm="30" />
    <usb enable="false" endpoint="none" />
    <txpower power="15" bias="5" />
    <usart channel="1" alternate="1" baud="57600"  endpoint="api" />
    <wakeup_pin enable="true" port="0" pin="0" />
    <port index="0" tristatemask="0" pull="down" />
    <pmux regulator_pin="7" />
</hardware>

This endpoint definition is what makes it possible for us to use the BGLib in our program to communicate with the BLE112 modul and let us control its behaviour.

But the BLE112-Protostick can not only be controlled by the BGLib, it is also possible to use the tool BLEGUI which comes with Bluegiga’s SDK. This visual tool gives you an easy way to control the BLE112 modul by using only buttons and dialogs. You can learn a lot about the BGAPI by watching the tools log functionality which shows the communication between the tool and the BLE112 modul in detail. We will use the BLEGUI to get some informations (handles, UUIDs) before we start, we’ll need this information later in the tutorial example this will avoid us some work.

Procedure

Start to wire BLE112-Protostick #1 and BLE112-Protostick #2 properly like described in BL_T0001 and connect the BLE112-Protostick #1 with the PC.

  1. Connect to the BLE112-Protostick #2 – You’ll need the targets MAC-address for that. You already know this address from the previous tutorial or you can use the BLEGUI tool to get it.
  2. Request information from BLE112-Protostick #2 with only one command
  3. Read a characteristics value by its UUID
  4. Overwrite a characteristics value by its handle and read it back by its long UUID
  5. Activate an notification service and listen to its notifications

Preparations

We are lazy programmers so lets get us some informations we need later.

  • Open the BLEGUI tool from the SDK location:
    BLEGUI Location

    BLEGUI Location

  • Choose the USB-USART converter connected to the BLE112-Protostick #1 and connect BLEGUI with the BLE112-Protostick #1 by clicking “Attach”. You should see a green highlighted field now.
    BLEGUI choose device & attach

    BLEGUI choose device & attach

  • Start to scan for other devices by clicking the according button on the left side. Make sure the BLE112-Protostick #2 is powered. Now you should get some device informations like the MAC-address and the RSSI valure. If not press the “Refresh” button in the lower right. Press “Connect” and then “GATT”. Don’t forget to write down the MAC-address.
    BLEGUI discovery

    BLEGUI discovery

  • Now you should see a white area with buttons named i.e. “Read” and “Write”. There you press “Service Discovery” to get all primary services of the BLE112-Protostick #2.
    BLEGUI connect

    BLEGUI connect

  • After the Service Discovery process is done the white area should show you all primary services. There should be exactly four services which are defined by the bgdemo project file gatt.xml. Now click on the service 0xe001 to select it and then press “Descriptors Discover”.
    BLEGUI select service

    BLEGUI select service

  • We now got all the details of the selected characteristic we need to activate the notification service. We need specifically the characteristic 0×2902 (for details see Bluetooth Developer Portal). We write down the handle of characteristic 0×2902 (17) and the handle of characteristic 0xe101 (16).
    BLEGUI discover descriptors

    BLEGUI discover descriptors

  • At least we need the handle and the UUID of the Bluegiga-Demo-Service characteristic. In the white area click “Clear”. Then click “Service Discover” again, select the list entry with handle 18 and click “Descriptors Discover”. Now write down the characteristics handle (20) and its long UUID (f1b41cde-dbf5-4acf-8679-ecb8b4dca6fe).
    BLEGUI - BGDemo Service - Characteristic

    BLEGUI – BGDemo Service – Characteristic

Eclipse-Project with Tutorial Source Code

Eclipse-Project with Tutorial Source Code

Now you only have to repeat the steps described in BL_T0001 in chapter 4 with the source code for this tutorial to install our example in Eclipse. You can get the source code from GitHub ZIP URL. The Eclipse project should then look like shown on the right.

Application details

There are some new variables. We need to store connection settings, a possibility to exchange data with the application layer and some sort of program state control.

/* BLE connection settings */
typedef struct hci_connection {
	bd_addr target;
	uint8 addr_type;
	uint16 conn_interval_min;
	uint16 conn_interval_max;
	uint16 timeout;
	uint16 latency;
	uint16 state;
	uint8 handle;
} hci_connection_t;
extern hci_connection_t app_connection;

/* BLE attclient data */
typedef struct hci_attclient {
	uint16 state;
	uint16 handle;
	struct {
		uint8 len;
		uint8 *data;
	} value;
} hci_attclient_t;
extern hci_attclient_t app_attclient;

/* State flag */
extern uint16 app_state;

Connecting

We already know the MAC address of our target device BLE112-Protostick #2 so we don’t have to start a discovering process, instead we can directly connect it. Assign your devices MAC address to the variable target (see next listing). We are also defining there some connection settings. Details about the settings you can find in the BGAPI documentation on page 92 (Bluetooth_Smart_API_11_11032013.pdf).

	/* Target MAC address */
	bd_addr target = { { 0x00, 0x07, 0x80, 0x6a, 0xf2, 0x8b } };
	/* API needs address reversed */
	reverseArray(target.addr, sizeof(target.addr));

	/* BLE settings */
	app_connection.addr_type = 0;
	app_connection.target = target;
	app_connection.conn_interval_min = 80; /*100ms*/
	app_connection.conn_interval_max = 3200; /*1s*/
	app_connection.timeout = 1000;/*10s*/
	app_connection.latency = 0;/*0ms*/

The previously defined connection settings are now used with the command “Connect Direct”.

	/* Connect to target with specific settings */
	printf("[###]Connect to target[###]\n");
	printf("[>] ble_cmd_gap_connect_direct\n");
	ble_cmd_gap_connect_direct(app_connection.target.addr, app_connection.addr_type, app_connection.conn_interval_min,
			app_connection.conn_interval_max, app_connection.timeout, app_connection.latency);
	if (wait_for_rsp() != APP_OK) {
		die();
	}
	wait_for_evt();

	/* Are we connected? */
	if (app_connection.state != APP_DEVICE_CONNECTED) {
		printf("[#] Connecting failed.\n");
		die();
	}

If the command was executed successfully we receive the event “Connection Status” where we check if we are connected and if so we set a flag to be able notify the application layer (main) about the status change.

void ble_evt_connection_status(const struct ble_msg_connection_status_evt_t *msg) {
	printf("[<] ble_evt_connection_status\n");
	clearFlag(app_state, APP_ATTCLIENT_PENDING);

	if (msg->flags == (connection_connected | connection_completed)) {
		printf("\tConnected\n");
		app_connection.state = APP_DEVICE_CONNECTED;
	} else {
		printf("\tNot Connected\n");
		app_connection.state = APP_DEVICE_DICONNECTED;
	}
}

Request informations

The BGAPI gives us some possibilities to request data from the target device. Following commands are used in this tutorial.

Attribut protocol commands
Command Description
Find Information Finds all characteristics within a handle range, returns handle and UUID.
Find By Type Value Finds all characteristics with a specific value within a handle range, returns handle.
Read By Group Type Reads value of all characteristics with the same UUID within a handle range, returns characteristics group handle range besides the value.
Read By Type Reads value of all characteristics with the same UUID within a handle range
Read Reads characteristics value by its handle
Write Write a characteristics value by its handle

If you us the complete possible handle range (0×0001 – 0xFFFF) with the command “Find Information” you get all characteristics the bgdemo firmware provides, that should be 20 in count, we’ll see that later.

	/* Handle range helpers */
	uint16 handle_start = 0x0001;
	uint16 handle_end = 0xFFFF;

	/* Give me all informations you can get */
	printf("[###]Find Informations[###]\n");
	printf("[>] ble_cmd_attclient_find_information\n");
	ble_cmd_attclient_find_information(app_connection.handle, handle_start, handle_end);
	if (wait_for_rsp() != APP_OK) {
		die();
	}
	wait_for_evt();

With the commands according Event-Callback we can print out the requested information.

void ble_evt_attclient_find_information_found(const struct ble_msg_attclient_find_information_found_evt_t *msg) {
	printf("[<] ble_evt_attclient_find_information_found\n");
	printf("\tConn: 0x%02x\n", msg->connection);
	printf("\tCharacteristic Handle: 0x%04x\n", msg->chrhandle);
	printf("\tUUID (Hex): ");
	printUUID((uint8 *)msg->uuid.data, msg->uuid.len);
	printf("\n");
}

We also want to do the same Service-Discover process like we did earlier with the BLEGUI tool. For that we request all primary GATT services which are defined by GATT_PRIMARY_SERVICES_UUID (0×2800), see next listing.

	/* Give me all primary services within the whole handle range */
	/* Hint: With handle start and handle end groups can be separated */
	uint8 uuid[] = GATT_PRIMARY_SERVICE_UUID;
	uint8 uuid_len = sizeof(uuid);
	printf("[>] ble_cmd_attclient_read_by_group_type\n");
	ble_cmd_attclient_read_by_group_type(app_connection.handle, handle_start, handle_end, uuid_len, uuid);
	if (wait_for_rsp() != APP_OK) {
		die();
	}
	wait_for_evt();

Now we get the following Event-Callback for the group request.

void ble_evt_attclient_group_found(const struct ble_msg_attclient_group_found_evt_t *msg) {
	printf("[<] ble_evt_attclient_group_found\n");
	printf("\tStart handle: 0x%04x\n", msg->start);
	printf("\tEnd handle: 0x%04x\n", msg->end);
	printf("\tUUID (Hex): ");
	printUUID((uint8 *)msg->uuid.data, msg->uuid.len);
	printf("\n");
}

Read by UUID

Now lets use a characteristics UUID to request a value, i.e. let’s find out the device name. The data we will get from the response is printed out to the console.

	/* Now lets get us some values with an UUID i.e. the device name */
	uint8 devicename_uuid[] = GATT_DEVICENAME_UUID;
	uint8 devicename_uuid_len = sizeof(devicename_uuid);

	/* Read device name by its UUID */
	printf("[###]Read target device name by 16bit UUID[###]\n");
	printf("[>] ble_cmd_attclient_read_by_type\n");
	ble_cmd_attclient_read_by_type(app_connection.handle, handle_start, handle_end, devicename_uuid_len,
			devicename_uuid);
	if (wait_for_rsp() != APP_OK) {
		die();
	}
	wait_for_evt();

	/* If we got a value back print it, it must be our targets device name */
	int i = 0;
	if (!issetFlag(app_state, APP_ATTCLIENT_ERROR)) {
		if (issetFlag(app_state, APP_ATTCLIENT_VALUE_PENDING)) {
			clearFlag(app_state, APP_ATTCLIENT_VALUE_PENDING);
			printf("[#] Device name: ");
			for (i = 0; i < app_attclient.value.len; i++) {
				printf("%c", app_attclient.value.data[i]);
			}
			printf("\n");
		}
	} else {
		die();
	}

In the according Event-Callback we use one of the new variables so the application layer (main, line 214 previous listing) has access to the received data, see next listing.

void ble_evt_attclient_attribute_value(const struct ble_msg_attclient_attribute_value_evt_t *msg) {
	printf("[<] ble_evt_attclient_attribute_value\n");
	printf("\tConn: 0x%02x\n", msg->connection);
	printf("\tHandle: 0x%04x\n", msg->atthandle);
	printf("\tType: 0x%02x\n", msg->type);
	printf("\tValue (Hex):\n");
	printHexdump((uint8 *)msg->value.data, msg->value.len, 10);
	printf("\n");
	memcpy(app_attclient.value.data, msg->value.data, msg->value.len * sizeof(uint8));
	app_attclient.value.len = msg->value.len;
	app_attclient.handle = msg->atthandle;

	switch (msg->type) {
	case ATTCLIENT_ATTRIBUTE_VALUE_TYPE_NOTIFY:
		setFlag(app_state, APP_ATTCLIENT_NOTIFICATION_PENDING);
		break;
	default:
		setFlag(app_state, APP_ATTCLIENT_VALUE_PENDING);
		break;
	}
}

Write by handle

Before you overwrite a value you have to take care not to exceed the capacity of the values target. Next we want to overwrite an characteristic which holds 3 bytes (Bluegiga Demo Service – Characteristic).

	/* Write a value with a handle */
	uint8 bgdemo_handle = 20;
	uint8 bgdemo_value[] = {0x12,0x34,0x56};
	uint8 bgdemo_value_len = sizeof(bgdemo_value);

	printf("[###]Write a value by handle[###]\n");
	printf("[>] ble_cmd_attclient_attribute_write\n");
	ble_cmd_attclient_attribute_write(app_connection.handle, bgdemo_handle, bgdemo_value_len, bgdemo_value);
	if (wait_for_rsp() != APP_OK) {
		die();
	}
	wait_for_evt();

After we have written a value we want to make sure we really nailed our goal. This time we use the 128-bit or 16-byte long UUID to read the characteristic value. The requested value is then printed out to the console.

	/* Read value with 128-bit UUID */
	uint8 bgdemo_char_uuid[16] = {0};
	uint8 bgdemo_char_uuid_len = sizeof(bgdemo_char_uuid);
	/* String representation of uuid */
	char str_uuid[] = "f1b41cde-dbf5-4acf-8679-ecb8b4dca6fe";
	/* Convert string uuid to uint8 array */
	uuid128StrToArray(str_uuid, bgdemo_char_uuid);
	/* Reverse address to network format */
	reverseArray(bgdemo_char_uuid, bgdemo_char_uuid_len);

	printf("[###]Read a value by 128bit UUID[###]\n");
	printf("[>] ble_cmd_attclient_read_by_type\n");
	ble_cmd_attclient_read_by_type(app_connection.handle, handle_start, handle_end, bgdemo_char_uuid_len,
			bgdemo_char_uuid);
	if (wait_for_rsp() != APP_OK) {
		die();
	}
	wait_for_evt();

	/* If we got a value back print it, it must be our 0xDEADBEEF */
	if (!issetFlag(app_state, APP_ATTCLIENT_ERROR)) {
		if (issetFlag(app_state, APP_ATTCLIENT_VALUE_PENDING)) {
			clearFlag(app_state, APP_ATTCLIENT_VALUE_PENDING);
			printf("[#] Is it 0x123456?: ");
			for (i = 0; i < app_attclient.value.len; i++) {
				printf("%02x", app_attclient.value.data[i]);
			}
			printf("\n");
		}
	} else {
		die();
	}

Activate Notification and handling of a notification

Now it gets interesting. We can use services which are able to notify us about a change of their value without having to poll the value of interest every time we want it. To do that we have to adjust the characteristics configuration. The characteristics configuration itself is also a characteristic which is called “Client Characteristic Configuration” it has the UUID 0×2902. If you want to know the details how to adjust the configuration you can read it in the official specification (Bluetooth Developer Portal).

Do you remember we wrote down a handle of a characteristic with the UUID 0×2902 earlier with the BLEGUI? This was the handle of the configuration characteristic which controls the service “Battery Status”. We will now use that handle to activate the notification by overwriting the configuration characteristics value with 1.

	/* The data is simply an unsigned 16-bit one in network format, this value will enable the notification */
	uint8 serv_conf_enable[2] = { 0x01, 0x00 };
	uint8 serv_conf_len = sizeof(serv_conf_enable);
	uint8 serv_conf_handle = 17;
	uint8 serv_notification_handle = 16;

	/* Write the data to a handle we already looked up with BLEGUI. It is the handle of the
	 * GATT_CLIENT_CHARACTERISTIC_CONFIGURATION_UUID related to the custom battery service.
	 * This handle is valid for the BGDemo example.
	 */
	printf("[###]Activate Service Notification by handle[###]\n");
	printf("[>] ble_cmd_attclient_attribute_write\n");
	ble_cmd_attclient_attribute_write(app_connection.handle, serv_conf_handle, serv_conf_len, serv_conf_enable);
	if (wait_for_rsp() != APP_OK) {
		die();
	}
	wait_for_evt();

We now receive periodically new values every time the “Battery Status” characteristics value is updated. So every time we get a notification we raise a flag to notify our application layer that a new value is available.

void ble_evt_attclient_attribute_value(const struct ble_msg_attclient_attribute_value_evt_t *msg) {
	printf("[<] ble_evt_attclient_attribute_value\n");
	printf("\tConn: 0x%02x\n", msg->connection);
	printf("\tHandle: 0x%04x\n", msg->atthandle);
	printf("\tType: 0x%02x\n", msg->type);
	printf("\tValue (Hex):\n");
	printHexdump((uint8 *)msg->value.data, msg->value.len, 10);
	printf("\n");
	memcpy(app_attclient.value.data, msg->value.data, msg->value.len * sizeof(uint8));
	app_attclient.value.len = msg->value.len;
	app_attclient.handle = msg->atthandle;

	switch (msg->type) {
	case ATTCLIENT_ATTRIBUTE_VALUE_TYPE_NOTIFY:
		setFlag(app_state, APP_ATTCLIENT_NOTIFICATION_PENDING);
		break;
	default:
		setFlag(app_state, APP_ATTCLIENT_VALUE_PENDING);
		break;
	}
}

In the application layer (main) we wait for the flag raise which signals us a new available value we can print out to the console. We are doing this 10 times and then we disconnect from the BLE112-Protostick #2 which automatically ends the notifications.

	/* Get notified 10 times ... */
	printf("[###]Watch for notifications and print them if arriving[###]\n");
	int notifications = 0;
	while (notifications < 10) {
		/* We have to check for BGLib messages, this was previously hidden within the wait_for_... functions. */
		if (read_message()) {
			printf("Error reading message\n");
			exit(-1);
		}

		/* Check if everything is fine */
		if (issetFlag(app_state, APP_ATTCLIENT_ERROR)) {
			die();
		};

		/* Check if a notification is pending and if yes check for the handle of the battery service we are looking for */
		if (issetFlag(app_state, APP_ATTCLIENT_NOTIFICATION_PENDING)) {
			clearFlag(app_state, APP_ATTCLIENT_NOTIFICATION_PENDING);

			/* We already know the handle of the custom battery service by looking it up with BLEGUI earlier */
			/* Now lets see if it is the handle we've waited for. */
			if (app_attclient.handle == serv_notification_handle) {
				/* The service characteristics value is simply the battery voltage in 10th of a millivolt.
				 * First put the 16-bit value together and then convert the value to volts. */
				uint16 voltage = (app_attclient.value.data[1] << 8) | app_attclient.value.data[0];
				printf("[#] Notification %d - Battery Voltage: %1.3f Volt\n", notifications, voltage * 0.0001);
				notifications++;
			}
		}
	}

Complete Debug Output

If everything was configured and adjusted properly the debug console output should look like in the following listing (each step we’ve done previously is highlighted).

>> BLELabs BLE112-Protostick Demo Application for Tutorial #3 (www.BLELabs.com) <<
---> Connect with another device
---> Read and write characteristics and handles
---> Activation of a notification service
---> Catch notifications

	Serial settings:
	----------------
	BaudRate:57600
	ByteSize:8
	Parity:0
	StopBits:0
	fOutxCtsFlow:1
	fRtsControl:1

[>] ble_cmd_gap_end_procedure
[<] ble_rsp_gap_end_procedure, result: 0x0181
[>] ble_cmd_connection_get_status
[<] ble_rsp_connection_get_status, connection: 0
[###]Connect to target[###]
[>] ble_cmd_gap_connect_direct
[<] ble_evt_connection_status
	Not Connected
[<] ble_rsp_gap_connect_direct, result: 0
[<] ble_evt_connection_status
        Connected
[###]Find Informations[###]
[>] ble_cmd_attclient_find_information
[<] ble_rsp_attclient_find_information, result: 0x0000
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0001
	UUID (Hex): 2800
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0002
	UUID (Hex): 2803
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0003
	UUID (Hex): 2a00
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0004
	UUID (Hex): 2803
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0005
	UUID (Hex): 2a01
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0006
	UUID (Hex): 2800
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0007
	UUID (Hex): 2803
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0008
	UUID (Hex): 9100
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0009
	UUID (Hex): 2803
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x000a
	UUID (Hex): 9101
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x000b
	UUID (Hex): 2803
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x000c
	UUID (Hex): 9106
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x000d
	UUID (Hex): 2800
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x000e
	UUID (Hex): 2802
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x000f
	UUID (Hex): 2803
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0010
	UUID (Hex): e101
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0011
	UUID (Hex): 2902
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0012
	UUID (Hex): 2800
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0013
	UUID (Hex): 2803
[<] ble_evt_attclient_find_information_found
	Conn: 0x00
	Characteristic Handle: 0x0014
	UUID (Hex): f1b41cde-dbf5-4acf-8679-ecb8b4dca6fe
[<] ble_evt_attclient_procedure_completed, handle: 0x0015, result: 0x0000
[>] ble_cmd_attclient_read_by_group_type
[<] ble_rsp_attclient_read_by_group_type, connection: 0
[<] ble_evt_attclient_group_found
	Start handle: 0x0001
	End handle: 0x0005
	UUID (Hex): 1800
[<] ble_evt_attclient_group_found
	Start handle: 0x0006
	End handle: 0x000c
	UUID (Hex): 9000
[<] ble_evt_attclient_group_found
	Start handle: 0x000d
	End handle: 0x0011
	UUID (Hex): e001
[<] ble_evt_attclient_group_found
	Start handle: 0x0012
	End handle: 0xffff
	UUID (Hex): 00431c4a-a7a4-428b-a96d-d92d43c8c7cf
[<] ble_evt_attclient_procedure_completed, handle: 0x0000, result: 0x0000
[###]Read target device name by 16bit UUID[###]
[>] ble_cmd_attclient_read_by_type
[<] ble_rsp_attclient_read_by_type, result: 0x0000
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0003
	Type: 0x03
	Value (Hex):
          42 47 20 44 65 6d 6f
[<] ble_evt_attclient_procedure_completed, handle: 0x0004, result: 0x0000
[#] Device name: BG Demo
[###]Write a value by handle[###]
[>] ble_cmd_attclient_attribute_write
[<] ble_rsp_attclient_attribute_write, result: 0
[<] ble_evt_attclient_procedure_completed, handle: 0x0014, result: 0x0000
[###]Read a value by 128bit UUID[###]
[>] ble_cmd_attclient_read_by_type
[<] ble_rsp_attclient_read_by_type, result: 0x0000
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0014
	Type: 0x03
	Value (Hex):
          12 34 56
[<] ble_evt_attclient_procedure_completed, handle: 0x0015, result: 0x0000
[#] Is it 0x123456?: 123456
[###]Activate Service Notification by handle[###]
[>] ble_cmd_attclient_attribute_write
[<] ble_rsp_attclient_attribute_write, result: 0
[<] ble_evt_attclient_procedure_completed, handle: 0x0011, result: 0x0000
[###]Watch for notifications and print them if arriving[###]
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          a4 68
[#] Notification 0 - Battery Voltage: 2.679 Volt
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          a4 68
[#] Notification 1 - Battery Voltage: 2.679 Volt
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          a8 68
[#] Notification 2 - Battery Voltage: 2.679 Volt
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          a4 68
[#] Notification 3 - Battery Voltage: 2.679 Volt
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          b4 68
[#] Notification 4 - Battery Voltage: 2.680 Volt
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          a4 68
[#] Notification 5 - Battery Voltage: 2.679 Volt
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          b0 68
[#] Notification 6 - Battery Voltage: 2.680 Volt
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          bc 68
[#] Notification 7 - Battery Voltage: 2.681 Volt
[<] ble_evt_attclient_attribute_value
	Conn: 0x00
	Handle: 0x0010
	Type: 0x01
	Value (Hex):
          ac 68
[#] Notification 8 - Battery Voltage: 2.680 Volt
[<] ble_evt_attclient_attribute_value
         Conn: 0x00
         Handle: 0x0010
         Type: 0x01
         Value (Hex):
          b8 68
[#] Notification 9 - Battery Voltage: 2.681 Volt
[###]Disconnect from target[###]
[>] ble_cmd_connection_disconnect
[<] ble_rsp_connection_disconnect
[<] ble_evt_connection_disconnected
[>] ble_cmd_connection_get_status
[<] ble_rsp_connection_get_status, connection: 0
[<] ble_evt_connection_status
	Not Connected

Conclusion

You are now able to build your own interesting application on top of the tutorials example by only changing small peaces of code. If you got stuck adjusting the BLE parts of the program to your needs you can always take a look into the BLEGUI tools logging console how the tool does something and then simply repeat it.

Now we know how the master/central side of a Bluetooth Low Energy communication works. We can use this knowledge to adapt BLE to other platforms i.e. the very popular Raspberry Pi and Arduino platforms. Soon there will be new tutorials covering these two platforms.

Afterwards we will take a closer look to the slave/peripheral side of the communication and how we can build our own sensor peripherals. Of course there will be new tutorials for this too.

This post is also available in: German

2 thoughts on “[BL_T0003] BLE112-Protostick – Connecting, Characteristics, Handles, Services and Notifications under Windows

  1. Pingback: Bluetooth Low Energy dongles with Linux compatibility | Simon Wiesmann

  2. Pingback: [BL_T0001] BLE112-Protostick – First steps under Windows | BLELabs Blog - News and Tutorials

Leave a Reply