@annadata/capacitor-mqtt-quic 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/install/wolfssl-android/arm64-v8a/lib/libwolfssl.a +0 -0
- package/android/install/wolfssl-android/armeabi-v7a/lib/libwolfssl.a +0 -0
- package/android/install/wolfssl-android/x86_64/lib/libwolfssl.a +0 -0
- package/android/src/main/cpp/ngtcp2_jni.cpp +14 -0
- package/android/src/main/kotlin/ai/annadata/mqttquic/MqttQuicPlugin.kt +4 -1
- package/android/src/main/kotlin/ai/annadata/mqttquic/client/MQTTClient.kt +26 -21
- package/ios/Sources/MqttQuicPlugin/Client/MQTTClient.swift +37 -31
- package/ios/Sources/MqttQuicPlugin/MqttQuicPlugin.swift +1 -1
- package/ios/libs/libnghttp3.a +0 -0
- package/ios/libs/libngtcp2.a +0 -0
- package/ios/libs/libngtcp2_crypto_wolfssl.a +0 -0
- package/ios/libs/libwolfssl.a +0 -0
- package/ios/libs-simulator/libnghttp3.a +0 -0
- package/ios/libs-simulator/libngtcp2.a +0 -0
- package/ios/libs-simulator/libngtcp2_crypto_wolfssl.a +0 -0
- package/ios/libs-simulator/libwolfssl.a +0 -0
- package/ios/libs-simulator-x86_64/libnghttp3.a +0 -0
- package/ios/libs-simulator-x86_64/libngtcp2.a +0 -0
- package/ios/libs-simulator-x86_64/libngtcp2_crypto_wolfssl.a +0 -0
- package/ios/libs-simulator-x86_64/libwolfssl.a +0 -0
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -233,6 +233,20 @@ class QuicClient {
|
|
|
233
233
|
state.recv_buf.insert(state.recv_buf.end(), data, data + datalen);
|
|
234
234
|
LOGI("recv stream data stream_id=%" PRId64 " len=%zu recv_buf_total=%zu",
|
|
235
235
|
(int64_t)stream_id, datalen, state.recv_buf.size());
|
|
236
|
+
if (datalen > 2 && datalen <= 32) {
|
|
237
|
+
char hex[128];
|
|
238
|
+
size_t n = datalen < 16 ? datalen : 16u;
|
|
239
|
+
char *p = hex;
|
|
240
|
+
for (size_t i = 0; i < n && p < hex + sizeof(hex) - 4; i++)
|
|
241
|
+
p += snprintf(p, (size_t)(hex + sizeof(hex) - p), "%02x", data[i]);
|
|
242
|
+
LOGI("recv first bytes (type 0x%02x = %s) hex=%s",
|
|
243
|
+
(unsigned)data[0],
|
|
244
|
+
(data[0] & 0xF0) == 0x30 ? "PUBLISH" : (data[0] == (uint8_t)0xd0 ? "PINGRESP" : "other"),
|
|
245
|
+
hex);
|
|
246
|
+
} else if (datalen > 32) {
|
|
247
|
+
LOGI("recv large chunk len=%zu first_byte=0x%02x (PUBLISH=0x30)",
|
|
248
|
+
datalen, (unsigned)data[0]);
|
|
249
|
+
}
|
|
236
250
|
if (flags & NGTCP2_STREAM_DATA_FLAG_FIN) {
|
|
237
251
|
state.fin_received = true;
|
|
238
252
|
}
|
|
@@ -121,7 +121,10 @@ class MqttQuicPlugin : Plugin() {
|
|
|
121
121
|
} catch (_: Exception) {
|
|
122
122
|
Base64.encodeToString(payload, Base64.NO_WRAP)
|
|
123
123
|
}
|
|
124
|
-
|
|
124
|
+
// Ensure non-null strings so Capacitor bridge never receives undefined
|
|
125
|
+
val safeTopic = topic ?: ""
|
|
126
|
+
val safePayload = payloadStr ?: ""
|
|
127
|
+
val data = JSObject().put("topic", safeTopic).put("payload", safePayload)
|
|
125
128
|
Handler(Looper.getMainLooper()).post {
|
|
126
129
|
notifyListeners("message", data)
|
|
127
130
|
}
|
|
@@ -613,30 +613,35 @@ class MQTTClient {
|
|
|
613
613
|
}
|
|
614
614
|
MQTTMessageType.PUBLISH -> {
|
|
615
615
|
val qos = (msgType.toInt() shr 1) and 0x03
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
MQTTProtocol.parsePublish(rest, 0, qos)
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
val (cb, globalCb) = lock.withLock {
|
|
625
|
-
subscribedTopics[topic] to onPublish
|
|
626
|
-
}
|
|
627
|
-
globalCb?.invoke(topic, payload)
|
|
628
|
-
cb?.invoke(payload)
|
|
629
|
-
|
|
630
|
-
if (qos >= 1 && packetId != null) {
|
|
631
|
-
val w = lock.withLock { writer }
|
|
632
|
-
w?.let {
|
|
633
|
-
if (qos == 1) {
|
|
634
|
-
it.write(MQTTProtocol.buildPuback(packetId))
|
|
616
|
+
try {
|
|
617
|
+
val (topic, packetId, payload) = lock.withLock {
|
|
618
|
+
if (activeProtocolVersion == MQTTProtocolLevel.V5) {
|
|
619
|
+
MQTT5Protocol.parsePublishV5(rest, 0, qos, topicAliasMap)
|
|
635
620
|
} else {
|
|
636
|
-
|
|
621
|
+
MQTTProtocol.parsePublish(rest, 0, qos)
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
val (cb, globalCb) = lock.withLock {
|
|
625
|
+
subscribedTopics[topic] to onPublish
|
|
626
|
+
}
|
|
627
|
+
globalCb?.invoke(topic, payload)
|
|
628
|
+
cb?.invoke(payload)
|
|
629
|
+
|
|
630
|
+
if (qos >= 1 && packetId != null) {
|
|
631
|
+
val w = lock.withLock { writer }
|
|
632
|
+
w?.let {
|
|
633
|
+
if (qos == 1) {
|
|
634
|
+
it.write(MQTTProtocol.buildPuback(packetId))
|
|
635
|
+
} else {
|
|
636
|
+
it.write(MQTTProtocol.buildPubrec(packetId))
|
|
637
|
+
}
|
|
638
|
+
it.drain()
|
|
637
639
|
}
|
|
638
|
-
it.drain()
|
|
639
640
|
}
|
|
641
|
+
} catch (e: Exception) {
|
|
642
|
+
// PUBLISH parse failed: log and skip this message (don't disconnect)
|
|
643
|
+
val hex = rest.take(64).joinToString("") { "%02x".format(it) }
|
|
644
|
+
Log.w("MQTTClient", "PUBLISH parse failed: ${e.message} restLen=${rest.size} hex=$hex", e)
|
|
640
645
|
}
|
|
641
646
|
}
|
|
642
647
|
MQTTMessageType.PUBREL -> {
|
|
@@ -555,42 +555,48 @@ public final class MQTTClient {
|
|
|
555
555
|
pingCont?.resume()
|
|
556
556
|
case MQTTMessageType.PUBLISH.rawValue:
|
|
557
557
|
let qos = (msgType >> 1) & 0x03
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
let version = self.activeProtocolVersion
|
|
563
|
-
if version == MQTTProtocolLevel.v5 {
|
|
564
|
-
var map = self.topicAliasMap
|
|
565
|
-
self.lock.unlock()
|
|
566
|
-
(topic, packetId, payload) = try MQTT5Protocol.parsePublishV5(Data(rest), offset: 0, qos: UInt8(qos), topicAliasMap: &map)
|
|
558
|
+
do {
|
|
559
|
+
let topic: String
|
|
560
|
+
let packetId: UInt16?
|
|
561
|
+
let payload: Data
|
|
567
562
|
self.lock.lock()
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
cb?(payload)
|
|
563
|
+
let version = self.activeProtocolVersion
|
|
564
|
+
if version == MQTTProtocolLevel.v5 {
|
|
565
|
+
var map = self.topicAliasMap
|
|
566
|
+
self.lock.unlock()
|
|
567
|
+
(topic, packetId, payload) = try MQTT5Protocol.parsePublishV5(Data(rest), offset: 0, qos: UInt8(qos), topicAliasMap: &map)
|
|
568
|
+
self.lock.lock()
|
|
569
|
+
self.topicAliasMap = map
|
|
570
|
+
self.lock.unlock()
|
|
571
|
+
} else {
|
|
572
|
+
self.lock.unlock()
|
|
573
|
+
let (t, pid, pl, _) = try MQTTProtocol.parsePublish(Data(rest), offset: 0, qos: UInt8(qos))
|
|
574
|
+
topic = t
|
|
575
|
+
packetId = pid
|
|
576
|
+
payload = pl
|
|
577
|
+
}
|
|
584
578
|
|
|
585
|
-
if qos >= 1, let pid = packetId {
|
|
586
579
|
self.lock.lock()
|
|
587
|
-
let
|
|
580
|
+
let cb = self.subscribedTopics[topic]
|
|
581
|
+
let globalCb = self.onPublish
|
|
588
582
|
self.lock.unlock()
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
583
|
+
globalCb?(topic, payload)
|
|
584
|
+
cb?(payload)
|
|
585
|
+
|
|
586
|
+
if qos >= 1, let pid = packetId {
|
|
587
|
+
self.lock.lock()
|
|
588
|
+
let wPuback = self.writer
|
|
589
|
+
self.lock.unlock()
|
|
590
|
+
if let wPuback = wPuback {
|
|
591
|
+
let puback = MQTTProtocol.buildPuback(packetId: pid)
|
|
592
|
+
try await wPuback.write(Data(puback))
|
|
593
|
+
try await wPuback.drain()
|
|
594
|
+
}
|
|
593
595
|
}
|
|
596
|
+
} catch {
|
|
597
|
+
// PUBLISH parse failed: log and skip this message (don't disconnect)
|
|
598
|
+
let hex = rest.prefix(64).map { String(format: "%02x", $0) }.joined()
|
|
599
|
+
print("[MqttQuic] PUBLISH parse failed: \(error) restLen=\(rest.count) hex=\(hex)")
|
|
594
600
|
}
|
|
595
601
|
default:
|
|
596
602
|
break
|
|
@@ -139,7 +139,7 @@ public class MqttQuicPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
139
139
|
return payload.base64EncodedString()
|
|
140
140
|
}()
|
|
141
141
|
DispatchQueue.main.async {
|
|
142
|
-
self.notifyListeners("message", data: ["topic": topic
|
|
142
|
+
self.notifyListeners("message", data: ["topic": topic, "payload": payloadStr])
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
try await client.connect(
|
package/ios/libs/libnghttp3.a
CHANGED
|
Binary file
|
package/ios/libs/libngtcp2.a
CHANGED
|
Binary file
|
|
Binary file
|
package/ios/libs/libwolfssl.a
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@annadata/capacitor-mqtt-quic",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MQTT-over-QUIC client for Capacitor (iOS, Android, Web). Native: ngtcp2+WolfSSL; Web: MQTT over WebSocket (WSS), same API.",
|
|
6
6
|
"main": "dist/plugin.cjs.js",
|