@magicred-1/react-native-lxmf 0.2.3 → 0.2.5

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.
@@ -433,26 +433,18 @@ extension BLEManager: CBPeripheralDelegate {
433
433
  return
434
434
  }
435
435
 
436
- // Phone-to-phone mesh characteristics mark as bonded and register with Rust
436
+ // Phone-to-phone mesh: store RX char and subscribe to TX notifications.
437
+ // lxmf_ble_connected is deferred until didUpdateNotificationStateFor confirms
438
+ // the CCCD write — otherwise Rust tries to TX before the pipe is open.
437
439
  bondedPeripherals.insert(peripheral.identifier)
438
440
  saveBondedPeripherals()
439
441
  let addr = BLEManager.uuidToAddr(peripheral.identifier)
440
442
  addrToPeripheralUUID[addr] = peripheral.identifier
441
- addr.withUnsafeBytes { ptr in
442
- _ = lxmf_ble_connected(ptr.baseAddress?.assumingMemoryBound(to: UInt8.self))
443
- }
444
- // Report negotiated write limit so Rust segments correctly for this peer.
445
- let writeLimit = peripheral.maximumWriteValueLength(for: .withoutResponse)
446
- addr.withUnsafeBytes { ptr in
447
- _ = lxmf_ble_mtu_negotiated(ptr.baseAddress?.assumingMemoryBound(to: UInt8.self), UInt32(writeLimit))
448
- }
449
443
 
450
444
  for char in chars {
451
445
  if char.uuid == BLEManager.rxCharUUID {
452
- // This is the peer's RX — we write to it
453
446
  txCharacteristics[peripheral.identifier] = char
454
447
  } else if char.uuid == BLEManager.txCharUUID {
455
- // This is the peer's TX — subscribe for notifications
456
448
  peripheral.setNotifyValue(true, for: char)
457
449
  }
458
450
  }
@@ -486,6 +478,28 @@ extension BLEManager: CBPeripheralDelegate {
486
478
  }
487
479
  }
488
480
 
481
+ // CCCD subscription confirmed (or failed) — now safe to register peer with Rust.
482
+ func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
483
+ guard characteristic.uuid == BLEManager.txCharUUID else { return }
484
+
485
+ if let error = error {
486
+ NSLog("[BLE] CCCD subscribe failed for %@: %@", peripheral.identifier.uuidString, error.localizedDescription)
487
+ centralManager?.cancelPeripheralConnection(peripheral)
488
+ return
489
+ }
490
+ guard characteristic.isNotifying else { return }
491
+
492
+ let addr = BLEManager.uuidToAddr(peripheral.identifier)
493
+ addr.withUnsafeBytes { ptr in
494
+ _ = lxmf_ble_connected(ptr.baseAddress?.assumingMemoryBound(to: UInt8.self))
495
+ }
496
+ let writeLimit = peripheral.maximumWriteValueLength(for: .withoutResponse)
497
+ addr.withUnsafeBytes { ptr in
498
+ _ = lxmf_ble_mtu_negotiated(ptr.baseAddress?.assumingMemoryBound(to: UInt8.self), UInt32(writeLimit))
499
+ }
500
+ NSLog("[BLE] peer ready (client): %@, writeLimit=%d", peripheral.identifier.uuidString, writeLimit)
501
+ }
502
+
489
503
  // Called when writeValue(.withoutResponse) exhausted the internal queue.
490
504
  // Re-trigger TX drain so buffered frames get sent now that there's room.
491
505
  func peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral) {
@@ -524,6 +538,7 @@ extension BLEManager: CBPeripheralManagerDelegate {
524
538
  }
525
539
  }
526
540
  }
541
+ // CoreBluetooth no-ops this for writeWithoutResponse — safe to call unconditionally.
527
542
  peripheral.respond(to: request, withResult: .success)
528
543
  }
529
544
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magicred-1/react-native-lxmf",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "LXMF Reticulum mesh networking for React Native + Expo",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",