From 3dfcd9e20420481997a2bac8b07fdd4b4b83986b Mon Sep 17 00:00:00 2001
From: Michal Pawluk
+Once the Bluetooth adapter state is changed to BT_ADAPTER_ENABLED and the +__bt_device_state_changed_cb() callback function is invoked, the advertiser is created and the service starts its normal operation. +
+ ++static void __bt_device_state_changed_cb(int result, bt_adapter_state_e adapter_state, void *user_data) +{ + if (adapter_state == BT_ADAPTER_ENABLED) { + if (bt_advertiser_create(&__ctrldata.adv_hrm_h, APPEARANCE_GENERIC_HEART_RATE_SENSOR)) { + dlog_print(DLOG_INFO, LOG_TAG, "Heart Rate Measurement advertiser started."); + } else { + dlog_print(DLOG_WARN, LOG_TAG, "Failed to start Heart Rate Measurement advertiser."); + } + } else { + bt_advertiser_delete(&__ctrldata.adv_hrm_h); + dlog_print(DLOG_WARN, LOG_TAG, "Heart Rate Measurement advertiser stopped."); + } +} ++ +
+In the advertiser creation procedure (bt_advertiser_create()) its initial configuration takes place and the advertising is started +(see the Advertiser creation section). +
+ +
+Each time data is received from the Heart Rate sensor, the __sensor_data_read_cb() callback function is invoked.
+Within this function, the Heart Rate measurement value is packed into the advertiser buffer and broadcasted over the Bluetooth network with the relevant UUID value. Together with the obtained measurement,
+the body sensor location data package is created and handled similarly.
+
+The structure of both types of data is implemented according to HDP (Health Device Profile) Bluetooth standard. For details, see the official characteristics defined by the
+Bluetooth SIG, Inc.:
+
+static void __sensor_data_read_cb(float *data, int data_count) +{ + int buffer_size = 0; + char *buffer = NULL; + const char *uuid = NULL; + + if (!__ctrldata.adv_hrm_h) + return; + + if (__pack_heart_rate_measurement_data(data[HEART_RATE_SENSOR_DATA_INDEX], &buffer, &buffer_size)) { + uuid = heart_rate_measurement_model_get_uuid(); + bt_advertizer_set_data(&__ctrldata.adv_hrm_h, uuid, (const char *)buffer, buffer_size); + free(buffer); + } + + if (__pack_body_sensor_location_data(&buffer, &buffer_size)) { + uuid = body_sensor_location_model_get_uuid(); + bt_advertizer_set_data(&__ctrldata.adv_hrm_h, uuid, (const char *)buffer, buffer_size); + free(buffer); + } +} ++ +
+The data is packed into the buffers using the following functions: +
+bool bt_advertizer_set_data(bt_advertiser_h *adv_h, const char *uuid, const char *data, int data_size) +{ + bt_common_stop_advertising(*adv_h); + + if (bt_common_clear_advertizer(*adv_h, BT_ADAPTER_LE_PACKET_SCAN_RESPONSE)) { + __set_scan_response_properties(*adv_h, __advertizer_appearance); + + if (bt_common_add_service_solicitation_uuid(*adv_h, BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, uuid)) + if (data_size > 0) + bt_common_set_service_data(*adv_h, BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, uuid, data, data_size); + } + + bt_common_start_advertising(*adv_h, NULL); + + return true; +} ++ +
+In order to add new data to the advertiser, it must first be stopped (bt_common_stop_advertising()) and internal data buffers responsible for +responding to scan request have to be cleared (bt_common_clear_advertizer()). The initial configuration of the advertiser's scan response buffer +must be configured again (__set_scan_response_properties()). Now it is ready to accept new data which will be provided to the requester +in a scan response message. The bt_common_add_service_solicitation_uuid() function creates a new service buffer for the relevant data +(identified by the provided UUID) added with the bt_common_set_service_data() function. At the end, the advertiser is started +(bt_common_start_advertising()). +
+