@magicred-1/react-native-lxmf 0.2.15 → 0.2.17
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/src/main/jniLibs/arm64-v8a/liblxmf_rn.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/liblxmf_rn.so +0 -0
- package/android/src/main/jniLibs/x86_64/liblxmf_rn.so +0 -0
- package/android/src/main/kotlin/expo/modules/lxmf/LxmfModule.kt +12 -10
- package/build/LxmfModule.d.ts +3 -3
- package/build/index.d.ts +1 -1
- package/build/useLxmf.d.ts +21 -2
- package/build/useLxmf.js +9 -5
- package/ios/LxmfModule.swift +40 -13
- package/ios/RustCore/liblxmf_rn.xcframework/ios-arm64/liblxmf_rn.a +0 -0
- package/ios/RustCore/liblxmf_rn.xcframework/ios-arm64_x86_64-simulator/liblxmf_rn.a +0 -0
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -66,8 +66,9 @@ class LxmfModule : Module() {
|
|
|
66
66
|
|
|
67
67
|
AsyncFunction("start") { identityHex: String, lxmfAddressHex: String, mode: Int,
|
|
68
68
|
announceIntervalMs: Double, bleMtuHint: Int,
|
|
69
|
-
tcpInterfaces: List<Map<String, Any>>, displayName: String
|
|
70
|
-
|
|
69
|
+
tcpInterfaces: List<Map<String, Any>>, displayName: String,
|
|
70
|
+
isBeacon: Boolean ->
|
|
71
|
+
Log.d(TAG, "start() mode=$mode interfaces=$tcpInterfaces name=$displayName beacon=$isBeacon")
|
|
71
72
|
val interfacesJson = org.json.JSONArray(tcpInterfaces.map { iface ->
|
|
72
73
|
org.json.JSONObject().apply {
|
|
73
74
|
put("host", iface["host"] ?: "")
|
|
@@ -75,7 +76,7 @@ class LxmfModule : Module() {
|
|
|
75
76
|
}
|
|
76
77
|
}).toString()
|
|
77
78
|
val rc = nativeStart(identityHex, lxmfAddressHex, mode, announceIntervalMs.toLong(),
|
|
78
|
-
bleMtuHint.toShort(), interfacesJson, displayName)
|
|
79
|
+
bleMtuHint.toShort(), interfacesJson, displayName, isBeacon)
|
|
79
80
|
if (rc != 0) throw RuntimeException("nativeStart returned $rc")
|
|
80
81
|
true
|
|
81
82
|
}
|
|
@@ -91,13 +92,13 @@ class LxmfModule : Module() {
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
// Messaging
|
|
94
|
-
AsyncFunction("send") { destHex: String, bodyBase64: String ->
|
|
95
|
-
nativeSend(destHex, bodyBase64).toDouble()
|
|
95
|
+
AsyncFunction("send") { destHex: String, bodyBase64: String, fieldsJson: String? ->
|
|
96
|
+
nativeSend(destHex, bodyBase64, fieldsJson).toDouble()
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
AsyncFunction("broadcast") { destsHex: List<String>, bodyBase64: String ->
|
|
99
|
+
AsyncFunction("broadcast") { destsHex: List<String>, bodyBase64: String, fieldsJson: String? ->
|
|
99
100
|
val destsJson = org.json.JSONArray(destsHex).toString()
|
|
100
|
-
nativeBroadcast(destsJson, bodyBase64).toDouble()
|
|
101
|
+
nativeBroadcast(destsJson, bodyBase64, fieldsJson).toDouble()
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
// Identity
|
|
@@ -195,13 +196,14 @@ class LxmfModule : Module() {
|
|
|
195
196
|
announceIntervalMs: Long,
|
|
196
197
|
bleMtuHint: Short,
|
|
197
198
|
tcpInterfacesJson: String,
|
|
198
|
-
displayName: String
|
|
199
|
+
displayName: String,
|
|
200
|
+
isBeacon: Boolean
|
|
199
201
|
): Int
|
|
200
202
|
private external fun nativeStop(): Int
|
|
201
203
|
private external fun nativeIsRunning(): Boolean
|
|
202
204
|
private external fun nativePollEvents(): String?
|
|
203
|
-
private external fun nativeSend(destHex: String, bodyBase64: String): Long
|
|
204
|
-
private external fun nativeBroadcast(destsJson: String, bodyBase64: String): Long
|
|
205
|
+
private external fun nativeSend(destHex: String, bodyBase64: String, fieldsJson: String?): Long
|
|
206
|
+
private external fun nativeBroadcast(destsJson: String, bodyBase64: String, fieldsJson: String?): Long
|
|
205
207
|
private external fun nativeGetIdentityHex(): String?
|
|
206
208
|
private external fun nativeGetStatus(): String?
|
|
207
209
|
private external fun nativeGetBeacons(): String?
|
package/build/LxmfModule.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ export type NativeModuleType = {
|
|
|
3
3
|
start(identityHex: string, lxmfAddressHex: string, mode: number, announceIntervalMs: number, bleMtuHint: number, tcpInterfaces: {
|
|
4
4
|
host: string;
|
|
5
5
|
port: number;
|
|
6
|
-
}[], displayName: string): Promise<boolean>;
|
|
6
|
+
}[], displayName: string, isBeacon: boolean): Promise<boolean>;
|
|
7
7
|
stop(): Promise<boolean>;
|
|
8
8
|
isRunning(): boolean;
|
|
9
|
-
send(destHex: string, bodyBase64: string): Promise<number>;
|
|
10
|
-
broadcast(destsHex: string[], bodyBase64: string): Promise<number>;
|
|
9
|
+
send(destHex: string, bodyBase64: string, fieldsJson?: string | null): Promise<number>;
|
|
10
|
+
broadcast(destsHex: string[], bodyBase64: string, fieldsJson?: string | null): Promise<number>;
|
|
11
11
|
getIdentityHex(): string | null;
|
|
12
12
|
getStatus(): string | null;
|
|
13
13
|
getBeacons(): string | null;
|
package/build/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { LxmfModule, LxmfModuleNative, isLxmfNativeAvailable, NativeModuleType } from './LxmfModule';
|
|
2
|
-
export { useLxmf, LxmfNodeMode, type UseLxmfOptions, type TcpInterface, type LxmfNodeStatus, type Beacon, type LxmfEvent } from './useLxmf';
|
|
2
|
+
export { useLxmf, LxmfNodeMode, type UseLxmfOptions, type TcpInterface, type LxmfNodeStatus, type Beacon, type LxmfEvent, type LxmfMedia } from './useLxmf';
|
package/build/useLxmf.d.ts
CHANGED
|
@@ -39,6 +39,22 @@ export interface TcpInterface {
|
|
|
39
39
|
host: string;
|
|
40
40
|
port: number;
|
|
41
41
|
}
|
|
42
|
+
/** Media attachments to include in an LXMF message.
|
|
43
|
+
* Encoded as LXMF standard fields: FIELD_IMAGE (0x06) and FIELD_FILE_ATTACHMENTS (0x05).
|
|
44
|
+
* Compatible with Sideband and other LXMF clients.
|
|
45
|
+
*/
|
|
46
|
+
export interface LxmfMedia {
|
|
47
|
+
/** Inline image: LXMF FIELD_IMAGE — rendered by receiving clients. */
|
|
48
|
+
image?: {
|
|
49
|
+
mimeType: string;
|
|
50
|
+
dataBase64: string;
|
|
51
|
+
};
|
|
52
|
+
/** File attachments: LXMF FIELD_FILE_ATTACHMENTS — list of named blobs. */
|
|
53
|
+
files?: {
|
|
54
|
+
name: string;
|
|
55
|
+
dataBase64: string;
|
|
56
|
+
}[];
|
|
57
|
+
}
|
|
42
58
|
export interface UseLxmfOptions {
|
|
43
59
|
autoStart?: boolean;
|
|
44
60
|
identityHex?: string;
|
|
@@ -55,6 +71,8 @@ export interface UseLxmfOptions {
|
|
|
55
71
|
bleMtuHint?: number;
|
|
56
72
|
/** Display name broadcast in LXMF announces. Default: "lxmf-mobile" */
|
|
57
73
|
displayName?: string;
|
|
74
|
+
/** Advertise this node as an anonmesh beacon (app_data = "anonmesh::beacon::v1\0<name>"). Default: false */
|
|
75
|
+
isBeacon?: boolean;
|
|
58
76
|
}
|
|
59
77
|
export declare function useLxmf(options?: UseLxmfOptions): {
|
|
60
78
|
status: LxmfNodeStatus | null;
|
|
@@ -69,10 +87,11 @@ export declare function useLxmf(options?: UseLxmfOptions): {
|
|
|
69
87
|
mode?: LxmfNodeMode;
|
|
70
88
|
tcpInterfaces?: TcpInterface[];
|
|
71
89
|
displayName?: string;
|
|
90
|
+
isBeacon?: boolean;
|
|
72
91
|
}) => Promise<boolean>;
|
|
73
92
|
stop: () => Promise<void>;
|
|
74
|
-
send: (destHex: string, bodyBase64: string) => Promise<number>;
|
|
75
|
-
broadcast: (destsHex: string[], bodyBase64: string) => Promise<number>;
|
|
93
|
+
send: (destHex: string, bodyBase64: string, media?: LxmfMedia) => Promise<number>;
|
|
94
|
+
broadcast: (destsHex: string[], bodyBase64: string, media?: LxmfMedia) => Promise<number>;
|
|
76
95
|
getStatus: () => LxmfNodeStatus | null;
|
|
77
96
|
getBeacons: () => Beacon[];
|
|
78
97
|
fetchMessages: (limit?: number) => any[];
|
package/build/useLxmf.js
CHANGED
|
@@ -131,11 +131,12 @@ function useLxmf(options = {}) {
|
|
|
131
131
|
const announceMs = options.announceIntervalMs ?? 5000;
|
|
132
132
|
const bleMtu = options.bleMtuHint ?? 255;
|
|
133
133
|
const displayName = overrides?.displayName ?? options.displayName ?? '';
|
|
134
|
+
const isBeacon = overrides?.isBeacon ?? options.isBeacon ?? false;
|
|
134
135
|
if (mode !== LxmfNodeMode.BleOnly && tcpInterfaces.length === 0) {
|
|
135
136
|
setError(`Mode ${mode} requires at least one TCP interface.`);
|
|
136
137
|
return false;
|
|
137
138
|
}
|
|
138
|
-
await LxmfModule_1.LxmfModule.start(resolvedIdentityHex, resolvedLxmfAddressHex, mode, announceMs, bleMtu, tcpInterfaces, displayName);
|
|
139
|
+
await LxmfModule_1.LxmfModule.start(resolvedIdentityHex, resolvedLxmfAddressHex, mode, announceMs, bleMtu, tcpInterfaces, displayName, isBeacon);
|
|
139
140
|
setRunning(true);
|
|
140
141
|
syncStatus();
|
|
141
142
|
setError(null);
|
|
@@ -153,6 +154,7 @@ function useLxmf(options = {}) {
|
|
|
153
154
|
options.announceIntervalMs,
|
|
154
155
|
options.bleMtuHint,
|
|
155
156
|
options.displayName,
|
|
157
|
+
options.isBeacon,
|
|
156
158
|
syncStatus,
|
|
157
159
|
]);
|
|
158
160
|
(0, react_1.useEffect)(() => {
|
|
@@ -175,18 +177,20 @@ function useLxmf(options = {}) {
|
|
|
175
177
|
setError(e?.message ?? 'Failed to stop');
|
|
176
178
|
}
|
|
177
179
|
}, []);
|
|
178
|
-
const send = (0, react_1.useCallback)(async (destHex, bodyBase64) => {
|
|
180
|
+
const send = (0, react_1.useCallback)(async (destHex, bodyBase64, media) => {
|
|
179
181
|
try {
|
|
180
|
-
|
|
182
|
+
const fieldsJson = media ? JSON.stringify(media) : null;
|
|
183
|
+
return await LxmfModule_1.LxmfModule.send(destHex, bodyBase64, fieldsJson);
|
|
181
184
|
}
|
|
182
185
|
catch (e) {
|
|
183
186
|
setError(e.message);
|
|
184
187
|
return -1;
|
|
185
188
|
}
|
|
186
189
|
}, []);
|
|
187
|
-
const broadcast = (0, react_1.useCallback)(async (destsHex, bodyBase64) => {
|
|
190
|
+
const broadcast = (0, react_1.useCallback)(async (destsHex, bodyBase64, media) => {
|
|
188
191
|
try {
|
|
189
|
-
|
|
192
|
+
const fieldsJson = media ? JSON.stringify(media) : null;
|
|
193
|
+
return await LxmfModule_1.LxmfModule.broadcast(destsHex, bodyBase64, fieldsJson);
|
|
190
194
|
}
|
|
191
195
|
catch (e) {
|
|
192
196
|
setError(e.message);
|
package/ios/LxmfModule.swift
CHANGED
|
@@ -13,7 +13,8 @@ func lxmf_start(
|
|
|
13
13
|
_ announceIntervalMs: UInt64,
|
|
14
14
|
_ bleMtuHint: UInt16,
|
|
15
15
|
_ tcpInterfacesJson: UnsafePointer<CChar>?,
|
|
16
|
-
_ displayName: UnsafePointer<CChar
|
|
16
|
+
_ displayName: UnsafePointer<CChar>?,
|
|
17
|
+
_ isBeacon: UInt8
|
|
17
18
|
) -> Int32
|
|
18
19
|
|
|
19
20
|
@_silgen_name("lxmf_stop")
|
|
@@ -26,7 +27,8 @@ func lxmf_is_running() -> Int32
|
|
|
26
27
|
func lxmf_send(
|
|
27
28
|
_ destPtr: UnsafePointer<UInt8>?,
|
|
28
29
|
_ bodyPtr: UnsafePointer<UInt8>?,
|
|
29
|
-
_ bodyLen: Int
|
|
30
|
+
_ bodyLen: Int,
|
|
31
|
+
_ fieldsJson: UnsafePointer<CChar>?
|
|
30
32
|
) -> Int64
|
|
31
33
|
|
|
32
34
|
@_silgen_name("lxmf_broadcast")
|
|
@@ -34,7 +36,8 @@ func lxmf_broadcast(
|
|
|
34
36
|
_ destsPtr: UnsafePointer<UInt8>?,
|
|
35
37
|
_ destCount: Int,
|
|
36
38
|
_ bodyPtr: UnsafePointer<UInt8>?,
|
|
37
|
-
_ bodyLen: Int
|
|
39
|
+
_ bodyLen: Int,
|
|
40
|
+
_ fieldsJson: UnsafePointer<CChar>?
|
|
38
41
|
) -> Int64
|
|
39
42
|
|
|
40
43
|
@_silgen_name("lxmf_poll_events")
|
|
@@ -182,7 +185,8 @@ public class LxmfModule: Module {
|
|
|
182
185
|
announceIntervalMs: Double,
|
|
183
186
|
bleMtuHint: Int,
|
|
184
187
|
tcpInterfaces: [[String: Any]],
|
|
185
|
-
displayName: String
|
|
188
|
+
displayName: String,
|
|
189
|
+
isBeacon: Bool
|
|
186
190
|
) -> Bool in
|
|
187
191
|
// Serialize TCP interfaces to JSON (matches Android pattern)
|
|
188
192
|
let interfacesJson: String
|
|
@@ -200,7 +204,8 @@ public class LxmfModule: Module {
|
|
|
200
204
|
lxmf_start(
|
|
201
205
|
idPtr, addrPtr,
|
|
202
206
|
UInt32(mode), UInt64(announceIntervalMs),
|
|
203
|
-
UInt16(bleMtuHint), ifacesPtr, namePtr
|
|
207
|
+
UInt16(bleMtuHint), ifacesPtr, namePtr,
|
|
208
|
+
isBeacon ? 1 : 0
|
|
204
209
|
)
|
|
205
210
|
}
|
|
206
211
|
}
|
|
@@ -227,22 +232,33 @@ public class LxmfModule: Module {
|
|
|
227
232
|
|
|
228
233
|
// --- Messaging ---
|
|
229
234
|
|
|
230
|
-
AsyncFunction("send") { (destHex: String, bodyBase64: String) -> Double in
|
|
235
|
+
AsyncFunction("send") { (destHex: String, bodyBase64: String, fieldsJson: String?) -> Double in
|
|
231
236
|
guard let destBytes = Self.hexToBytes(destHex),
|
|
232
237
|
destBytes.count == 16,
|
|
233
238
|
let bodyData = Data(base64Encoded: bodyBase64) else {
|
|
234
239
|
return -1
|
|
235
240
|
}
|
|
236
241
|
|
|
237
|
-
let opId
|
|
238
|
-
|
|
239
|
-
|
|
242
|
+
let opId: Int64
|
|
243
|
+
if let json = fieldsJson {
|
|
244
|
+
opId = destBytes.withUnsafeBufferPointer { destBuf in
|
|
245
|
+
[UInt8](bodyData).withUnsafeBufferPointer { bodyBuf in
|
|
246
|
+
json.withCString { jsonPtr in
|
|
247
|
+
lxmf_send(destBuf.baseAddress, bodyBuf.baseAddress, bodyData.count, jsonPtr)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
opId = destBytes.withUnsafeBufferPointer { destBuf in
|
|
253
|
+
[UInt8](bodyData).withUnsafeBufferPointer { bodyBuf in
|
|
254
|
+
lxmf_send(destBuf.baseAddress, bodyBuf.baseAddress, bodyData.count, nil)
|
|
255
|
+
}
|
|
240
256
|
}
|
|
241
257
|
}
|
|
242
258
|
return Double(opId)
|
|
243
259
|
}
|
|
244
260
|
|
|
245
|
-
AsyncFunction("broadcast") { (destsHex: [String], bodyBase64: String) -> Double in
|
|
261
|
+
AsyncFunction("broadcast") { (destsHex: [String], bodyBase64: String, fieldsJson: String?) -> Double in
|
|
246
262
|
guard let bodyData = Data(base64Encoded: bodyBase64) else { return -1 }
|
|
247
263
|
|
|
248
264
|
var flatDests = [UInt8]()
|
|
@@ -251,9 +267,20 @@ public class LxmfModule: Module {
|
|
|
251
267
|
flatDests.append(contentsOf: bytes)
|
|
252
268
|
}
|
|
253
269
|
|
|
254
|
-
let opId
|
|
255
|
-
|
|
256
|
-
|
|
270
|
+
let opId: Int64
|
|
271
|
+
if let json = fieldsJson {
|
|
272
|
+
opId = flatDests.withUnsafeBufferPointer { destBuf in
|
|
273
|
+
[UInt8](bodyData).withUnsafeBufferPointer { bodyBuf in
|
|
274
|
+
json.withCString { jsonPtr in
|
|
275
|
+
lxmf_broadcast(destBuf.baseAddress, destsHex.count, bodyBuf.baseAddress, bodyData.count, jsonPtr)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
opId = flatDests.withUnsafeBufferPointer { destBuf in
|
|
281
|
+
[UInt8](bodyData).withUnsafeBufferPointer { bodyBuf in
|
|
282
|
+
lxmf_broadcast(destBuf.baseAddress, destsHex.count, bodyBuf.baseAddress, bodyData.count, nil)
|
|
283
|
+
}
|
|
257
284
|
}
|
|
258
285
|
}
|
|
259
286
|
return Double(opId)
|
|
Binary file
|
|
Binary file
|