I'm working on android app where I need to communicate over MQTT, so for this one I've chose HiveMQ. The thing is that sometimes it will connect straight away, but there are cases when I'll receive a lot of errors saying NOT_AUTHORIZED or it won't connect at all.
Do you have any suggestions or see something wrong?
This is my code for the builder:
Mqtt5Client.builder()
.identifier(deviceSerialNo)
.serverHost(SERVER_HOST)
.serverPort(SERVER_PORT)
.automaticReconnect(
MqttClientAutoReconnect.builder()
.initialDelay(2L, TimeUnit.SECONDS)
.maxDelay(10L, TimeUnit.SECONDS)
.build()
)
.sslWithDefaultConfig()
.addConnectedListener {
Log.d(TAG, "Client: ${client.state}")
}
.addDisconnectedListener {
Log.d(TAG, "Client: DISCONNECTED => Reason: ${it.cause.message}")
}
.build()
Connect method:
client.toBlocking().connectWith()
.simpleAuth()
.username("")
.password(
generateAuthPassword(deviceSerialNo, credentials).toByteArray()
)
.applySimpleAuth()
.send()
private fun generateAuthPassword(
serial: String,
credentials: String
): String {
val expiryDate = DocSigningHelper.generateExpiryDate()
val uriDoc = "URI_DOC?sx=$expiryDate"
val signature = DocSigningHelper.generateSignature(uriDoc, credentials)
return "$uriDoc&si=$signature"
}
object DocSigningHelper {
fun generateExpiryDate(): Long =
(System.currentTimeMillis() + 100_000L) / 1000L
@OptIn(ExperimentalEncodingApi::class)
fun generateSignature(doc: String, credentials: String): String {
val decodedUsername = Base64.decode(credentials)
val macAlgorithm = "HMACSHA256"
val hashMethod = Mac.getInstance(macAlgorithm)
val secretKey = SecretKeySpec(decodedUsername, macAlgorithm)
hashMethod.init(secretKey)
val signature = hashMethod.doFinal(doc.toByteArray(Charsets.UTF_8))
return Base64.encode(signature)
}
}