Writing the CCCD is the one GATT operation a peer can repeat freely on an
open connection: no authentication, no Noise session, no announcement, and
the Bluetooth spec puts no limit on how often a client may rewrite the
descriptor. onDescriptorWriteRequest attached two non-idempotent effects
to it.
Each ENABLE_NOTIFICATION write appended to subscribedDevices with no
contains() check, so N writes put N entries in the list one address owns.
broadcastSinglePacketInternal iterates that list and notifies per entry,
so every broadcast the mesh produces is then transmitted to that address N
times.
Each write also scheduled onDeviceConnected, which calls
sendBroadcastAnnounce(). That is unthrottled and floods at maxTtl, so a
peer could drive a mesh-wide ANNOUNCE at whatever rate it wrote the
descriptor.
Subscribe by address and return whether the device was newly subscribed,
run the peer-connect side effects only on that transition, and honour
DISABLE_NOTIFICATION_VALUE instead of keeping a peer on the broadcast feed
until it disconnects. Removal now matches on address like the connection
cleanup paths, so an unsubscribe cannot miss because the framework handed
us a different BluetoothDevice instance for the same address.
Refs #901
* tor voice wip
* worky BLE a bit
* can send sound
* remove tor
* ui cleanup
* recording time
* progress bar color
* nicknames for audio
* onboarding permissions no microphone
* may work
* fix destionation
* extend
* refactor voice input component
* fix keyboard collapse issue
* send images
* wip image open
* image sending works
* wip waveforms
* better
* better animation
* fix cursor for sending audio
* image sending animation
* image sending animation
* full screen image viewer
* gossip sync for fragments too
* reduce delays
* fix keyboard focus
* use v2 for file transfers
* do not sync fragments
* scrollable image viewer
* ui
* ui adjustments
* nicer animation
* seek through audio
* add spec
* add more details to documentation
* File sharing E2E:
- Add TLV BitchatFilePacket, FileSharingManager
- Implement sendFileNote in ChatViewModel
- File receive path: save to files/incoming and render [file] messages with FileMessageItem or FileSendingAnimation during transfer
- SAF FilePickerButton and dispatcher wiring; image/file choice to follow in MediaPickerOptions
- Add FileViewerDialog with system open/save, FileProvider and file_paths
- Hook transfer progress to file sending UI
- Manifest: READ_MEDIA_* and FileProvider
- Fix MessageHandler saving and prefix for non-image payloads
- Add helper utils (FileUtils)
* kinda wip
* fix buttons
* files half working
* wip file transfer
* file packet has 2-byte TLV and chunks. it wokrs but it sucks
* clean
* remove gossip sync for fragments
* fix audio and image rendering
* adjust FILE_SIZE TLV size too
* cleanup
* haptic
* private messages media
* read receipts for media
* use enum for message type not string
* delivery ack checks dont push content
* check
* animation fix
* refactor
* ui adjustments
* comments
* refactor
* fix crash on send and receive of the same file
* refactor notifications
* tests