# Open-Source MQTT-Based End-to-End IoT System for Smart City Scenarios
## 4 Proof-of-Concept
### Gateway Interface to the Broker: The Android Platform
#### 4.2.1 BLE Management
In case the connection occurs, the method discoverServices() is invoked in order to acquire and sync with the list of remote services, characteristics and descriptors. This is an asynchronous operation that triggers the callback method **public void** onServicesDiscovered (Bluetooth gatt, **int** status) and, if the discovery was successful, the services can be retrieved by calling the function getServices(). As pointed out in Section 4.1.1, each BLE characteristic of the ESP32 implements the Notify property, allowing the client to be notified whenever a change in one of the BLE characteristics occurs. However, the client must explicitly express its desire to use such system by writing the CCCD of the characteristic it wishes to receive notifications from. In order to enable the property, we have to check, first, if the characteristic is present; in this case, the descriptor is retrieved, with the function getDescriptor(UUID uuid) and its GATT-defined 32-bit UUID equal to h'0x2902, which is the standard for characteristic configuration descriptors. Once the sync is completed, the method setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE) must be called in order to modify the locally stored cached value of this descriptor. The new value assigned to the descriptor is BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE, corresponding to a two-bit field equal to b'0x01, while, if we enable the indication property, the bit-field would have been equal to b'0x10. The server should be aware of our intention to use that property; hence, the function writeDescriptor(BluetoothGattDescriptor descriptor) is called, and it writes the value of the locally stored cache onto the descriptor associated with the remote device. This function triggers the callback method **public void** onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, **int** status), which is part of the callback functions defined in Listing 1. Its role is to collect the result of a write operation concerning GATT descriptors; in our case, if the write request is successful, then, inside this callback function, the method setCharacteristicNotification(Descriptor descriptor, **boolean** enable) is updated, allowing the Android GATT client to asynchronously listen to GATT automatic server. In case one of the characteristics, whose descriptor has been written in order to allow the notify property, changes, the server sends a notification that triggers the callback function onCharacteristicChanged(BluetoothGatt gatt, BluetoothGatCharacteristic characteristic), which contains the characteristic that has been updated and its new value. In the app, the UI should be updated with the new sensor values whenever they are notified; this is accomplished by using a broadcast-receiver. Android apps can send or receive broadcast messages from the Android system similarly to the publish/subscribe design pattern we find in network protocols, such as MQTT. All the broadcasts sent will be routed to the activity that has been expressively declared through the use of specific intent filters. They can be used as a messaging system across apps and outside the normal user flow. In our case, the Bluetooth service we have implemented in the background allows sending custom broadcasts to the main Activity with the aim of updating the UI with the new sensor values.