diff --git a/app/build.gradle b/app/build.gradle
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -95,7 +95,7 @@
     implementation 'com.google.protobuf:protobuf-java:3.17.2'
     // mqtt library
     implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
-    implementation 'com.github.hannesa2:paho.mqtt.android:3.5.3'
+    implementation 'com.github.hannesa2:paho.mqtt.android:4.1'
 
 
     // ViewModel
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -9,6 +9,7 @@
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
 
     <queries>
         <intent>
diff --git a/app/src/main/java/it/reyboz/bustorino/backend/mato/MQTTMatoClient.kt b/app/src/main/java/it/reyboz/bustorino/backend/mato/MQTTMatoClient.kt
--- a/app/src/main/java/it/reyboz/bustorino/backend/mato/MQTTMatoClient.kt
+++ b/app/src/main/java/it/reyboz/bustorino/backend/mato/MQTTMatoClient.kt
@@ -5,13 +5,10 @@
 import androidx.lifecycle.LifecycleOwner
 import info.mqtt.android.service.Ack
 import it.reyboz.bustorino.backend.gtfs.LivePositionUpdate
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
 import org.eclipse.paho.client.mqttv3.*
 import info.mqtt.android.service.MqttAndroidClient
 import info.mqtt.android.service.QoS
 
-import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence
 import org.json.JSONArray
 import org.json.JSONException
 import java.lang.ref.WeakReference
@@ -34,10 +31,11 @@
 
     private lateinit var lifecycle: LifecycleOwner
     private var context: Context?= null
+    private var connectionTrials = 0
 
     private fun connect(context: Context, iMqttActionListener: IMqttActionListener?){
 
-        val clientID = "mqttjs_${getRandomString(8)}"
+        val clientID = "mqtt-explorer-${getRandomString(8)}"//"mqttjs_${getRandomString(8)}"
 
         client = MqttAndroidClient(context,SERVER_ADDR,clientID,Ack.AUTO_ACK)
 
@@ -49,6 +47,7 @@
         headersPars.setProperty("Host","mapi.5t.torino.it")
         options.customWebSocketHeaders = headersPars
 
+        Log.d(DEBUG_TAG,"client name: $clientID")
         //actually connect
         client.connect(options,null, iMqttActionListener)
         isStarted = true
@@ -63,28 +62,47 @@
         Log.d(DEBUG_TAG, "Connected to server, reconnect: $reconnect")
         Log.d(DEBUG_TAG, "Have listeners: $respondersMap")
     }
+    private fun connectTopic(topic: String){
+        if(context==null){
+            Log.e(DEBUG_TAG, "Trying to connect but context is null")
+            return
+        }
+        connectionTrials += 1
+        connect(context!!, object : IMqttActionListener{
+            override fun onSuccess(asyncActionToken: IMqttToken?) {
+                val disconnectedBufferOptions = DisconnectedBufferOptions()
+                disconnectedBufferOptions.isBufferEnabled = true
+                disconnectedBufferOptions.bufferSize = 100
+                disconnectedBufferOptions.isPersistBuffer = false
+                disconnectedBufferOptions.isDeleteOldestMessages = false
+                client.setBufferOpts(disconnectedBufferOptions)
+                client.subscribe(topic, QoS.AtMostOnce.value)
+                isStarted = true
+            }
+
+            override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
+                Log.e(DEBUG_TAG, "FAILED To connect to the server",exception)
+                if (connectionTrials < 10) {
+                    Log.d(DEBUG_TAG, "Reconnecting")
+                    connectTopic(topic)
+                }
+                else {
+                    //reset connection trials
+                    connectionTrials = 0
+                }
+            }
+
+        })
+    }
 
     fun startAndSubscribe(lineId: String, responder: MQTTMatoListener, context: Context): Boolean{
         //start the client, and then subscribe to the topic
         val topic = mapTopic(lineId)
+        this.context = context.applicationContext
         synchronized(this) {
             if(!isStarted){
-                connect(context, object : IMqttActionListener{
-                    override fun onSuccess(asyncActionToken: IMqttToken?) {
-                        val disconnectedBufferOptions = DisconnectedBufferOptions()
-                        disconnectedBufferOptions.isBufferEnabled = true
-                        disconnectedBufferOptions.bufferSize = 100
-                        disconnectedBufferOptions.isPersistBuffer = false
-                        disconnectedBufferOptions.isDeleteOldestMessages = false
-                        client.setBufferOpts(disconnectedBufferOptions)
-                        client.subscribe(topic, QoS.AtMostOnce.value)
-                    }
 
-                    override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
-                        Log.e(DEBUG_TAG, "FAILED To connect to the server")
-                    }
-
-                })
+                connectTopic(topic)
                 //wait for connection
             } else {
                 client.subscribe(topic, QoS.AtMostOnce.value)
@@ -137,16 +155,22 @@
         return currentPositions
     }
 
-    fun sendUpdateToResponders(responders: ArrayList<WeakReference<MQTTMatoListener>>): Boolean{
-        var sent = false
-        for (wrD in responders)
-            if (wrD.get() == null)
+    private fun sendUpdateToResponders(responders: ArrayList<WeakReference<MQTTMatoListener>>): Int{
+        //var sent = false
+        var count = 0
+        for (wrD in responders) {
+            if (wrD.get() == null) {
+                Log.d(DEBUG_TAG, "Removing weak reference")
                 responders.remove(wrD)
+            }
             else {
                 wrD.get()!!.onUpdateReceived(currentPositions)
-                sent = true
+                //sent = true
+                count++
             }
-        return sent
+        }
+
+        return count
     }
 
     override fun connectionLost(cause: Throwable?) {
@@ -185,7 +209,7 @@
 
     override fun messageArrived(topic: String?, message: MqttMessage?) {
         if (topic==null || message==null) return
-
+        //Log.d(DEBUG_TAG,"Arrived message on topic $topic, ${String(message.payload)}")
         parseMessageAndAddToList(topic, message)
         //GlobalScope.launch { }
 
@@ -243,17 +267,20 @@
                 it[vehicleId] = posUpdate
                 valid = true
             }
-            var sent = false
+            //sending
+            //Log.d(DEBUG_TAG, "Parsed update on topic $topic, line $lineId, responders $respondersMap")
+            var cc = 0
             if (LINES_ALL in respondersMap.keys) {
-                sent = sendUpdateToResponders(respondersMap[LINES_ALL]!!)
-
-
+                val count = sendUpdateToResponders(respondersMap[LINES_ALL]!!)
+                cc +=count
             }
+
             if(lineId in respondersMap.keys){
-                sent = sendUpdateToResponders(respondersMap[lineId]!!) or sent
+                cc += sendUpdateToResponders(respondersMap[lineId]!!)
 
             }
-            if(!sent){
+            //Log.d(DEBUG_TAG, "Sent to $cc responders, have $respondersMap")
+            if(cc==0){
                 Log.w(DEBUG_TAG, "We have received an update but apparently there is no one to send it")
                 var emptyResp = true
                 for(en in respondersMap.values){
@@ -270,8 +297,10 @@
             }
             //Log.d(DEBUG_TAG, "We have update on line $lineId, vehicle $vehicleId")
         } catch (e: JSONException){
-            Log.e(DEBUG_TAG,"Cannot decipher message on topic $topic, line $lineId, veh $vehicleId")
-            e.printStackTrace()
+            Log.w(DEBUG_TAG,"Cannot decipher message on topic $topic, line $lineId, veh $vehicleId (bad JSON)")
+
+        } catch (e: Exception){
+            Log.e(DEBUG_TAG, "Exception occurred", e)
         }
     }
 
diff --git a/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt b/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
--- a/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
+++ b/app/src/main/java/it/reyboz/bustorino/data/MatoTripsDownloadWorker.kt
@@ -57,9 +57,9 @@
         for(trip in tripsList){
             queriedMatoTrips.add(trip)
             matoRepository.requestTripUpdate(trip,{error->
-                Log.e(DEBUG_TAG, "Cannot download Gtfs Trip $trip")
-                val stacktrace  = error.stackTrace.take(5)
-                Log.w(DEBUG_TAG, "Stacktrace:\n$stacktrace")
+                Log.e(DEBUG_TAG, "Cannot download Gtfs Trip $trip", error)
+                //val stacktrace  = error.stackTrace.take(5)
+                //Log.w(DEBUG_TAG, "Stacktrace:\n$stacktrace")
                 failedMatoTripsDownload.add(trip)
                 requestCountDown.countDown()
             }){
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
@@ -540,7 +540,8 @@
         val paint = Paint()
         paint.color = ContextCompat.getColor(requireContext(),R.color.line_drawn_poly)
         paint.isAntiAlias = true
-        paint.strokeWidth = 16f
+        paint.strokeWidth = 13f
+
         paint.style = Paint.Style.FILL_AND_STROKE
         paint.strokeJoin = Paint.Join.ROUND
         paint.strokeCap = Paint.Cap.ROUND
diff --git a/app/src/main/java/it/reyboz/bustorino/viewmodels/LivePositionsViewModel.kt b/app/src/main/java/it/reyboz/bustorino/viewmodels/LivePositionsViewModel.kt
--- a/app/src/main/java/it/reyboz/bustorino/viewmodels/LivePositionsViewModel.kt
+++ b/app/src/main/java/it/reyboz/bustorino/viewmodels/LivePositionsViewModel.kt
@@ -70,7 +70,7 @@
         }
         val time = System.currentTimeMillis()
         if(lastTimeReceived == (0.toLong()) || (time-lastTimeReceived)>500){
-            updatesLiveData.value = (mupds)
+            updatesLiveData.postValue(mupds)
             lastTimeReceived = time
         }
 
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -168,9 +168,10 @@
 
 
 
-    <string name="default_notification_channel_description">Canale unico delle notifiche</string>
-    <string name="database_notification_channel">Database</string>
+    <string name="default_notification_channel_description">Canale default delle notifiche</string>
+    <string name="database_notification_channel">Operazioni sul database</string>
     <string name="database_notification_channel_desc">Informazioni sul database (aggiornamento)</string>
+
     <string name="db_trips_download_message">Downloading trips from MaTO server</string>
 
 
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -196,8 +196,9 @@
     -->
     <string name="default_notification_channel" translatable="false">Default</string>
     <string name="default_notification_channel_description">Default channel for notifications</string>
-    <string name="database_notification_channel">Database</string>
-    <string name="database_notification_channel_desc">Notifications on the update of the database</string>
+    <string name="database_notification_channel">Database operations</string>
+    <string name="database_notification_channel_desc">Updates of the app database</string>
+
     <string name="db_trips_download_message">Downloading trips from MaTO server</string>
 
     <string name="too_many_permission_asks">Asked for %1$s permission too many times</string>