react-native-ble-mesh 1.0.1
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/CHANGELOG.md +151 -0
- package/LICENSE +21 -0
- package/README.md +706 -0
- package/docs/API.md +462 -0
- package/docs/ARCHITECTURE.md +384 -0
- package/docs/CONTRIBUTING.md +244 -0
- package/docs/NODE_QUICKSTART.md +259 -0
- package/docs/PROTOCOL.md +195 -0
- package/docs/REACT_NATIVE.md +315 -0
- package/docs/SECURITY.md +152 -0
- package/docs/api/constants_audio.js.html +184 -0
- package/docs/api/constants_ble.js.html +165 -0
- package/docs/api/constants_crypto.js.html +107 -0
- package/docs/api/constants_errors.js.html +256 -0
- package/docs/api/constants_events.js.html +148 -0
- package/docs/api/constants_index.js.html +76 -0
- package/docs/api/constants_protocol.js.html +205 -0
- package/docs/api/crypto_aead.js.html +243 -0
- package/docs/api/crypto_chacha20.js.html +235 -0
- package/docs/api/crypto_hkdf.js.html +241 -0
- package/docs/api/crypto_hmac.js.html +197 -0
- package/docs/api/crypto_index.js.html +126 -0
- package/docs/api/crypto_keys_KeyManager.js.html +325 -0
- package/docs/api/crypto_keys_KeyPair.js.html +270 -0
- package/docs/api/crypto_keys_SecureStorage.js.html +273 -0
- package/docs/api/crypto_keys_index.js.html +86 -0
- package/docs/api/crypto_noise_handshake.js.html +464 -0
- package/docs/api/crypto_noise_index.js.html +81 -0
- package/docs/api/crypto_noise_session.js.html +307 -0
- package/docs/api/crypto_noise_state.js.html +322 -0
- package/docs/api/crypto_poly1305.js.html +167 -0
- package/docs/api/crypto_sha256.js.html +294 -0
- package/docs/api/crypto_x25519.js.html +208 -0
- package/docs/api/errors_AudioError.js.html +218 -0
- package/docs/api/errors_ConnectionError.js.html +163 -0
- package/docs/api/errors_CryptoError.js.html +157 -0
- package/docs/api/errors_HandshakeError.js.html +176 -0
- package/docs/api/errors_MeshError.js.html +154 -0
- package/docs/api/errors_MessageError.js.html +183 -0
- package/docs/api/errors_ValidationError.js.html +204 -0
- package/docs/api/errors_index.js.html +78 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/api/hooks_AppStateManager.js.html +233 -0
- package/docs/api/hooks_index.js.html +87 -0
- package/docs/api/hooks_useMesh.js.html +213 -0
- package/docs/api/hooks_useMessages.js.html +263 -0
- package/docs/api/hooks_usePeers.js.html +165 -0
- package/docs/api/index.html +868 -0
- package/docs/api/index.js.html +236 -0
- package/docs/api/mesh_dedup_BloomFilter.js.html +261 -0
- package/docs/api/mesh_dedup_DedupManager.js.html +266 -0
- package/docs/api/mesh_dedup_MessageCache.js.html +273 -0
- package/docs/api/mesh_dedup_index.js.html +70 -0
- package/docs/api/mesh_fragment_Assembler.js.html +335 -0
- package/docs/api/mesh_fragment_Fragmenter.js.html +230 -0
- package/docs/api/mesh_fragment_index.js.html +75 -0
- package/docs/api/mesh_index.js.html +72 -0
- package/docs/api/mesh_peer_Peer.js.html +296 -0
- package/docs/api/mesh_peer_PeerDiscovery.js.html +334 -0
- package/docs/api/mesh_peer_PeerManager.js.html +320 -0
- package/docs/api/mesh_peer_index.js.html +70 -0
- package/docs/api/mesh_router_MessageRouter.js.html +411 -0
- package/docs/api/mesh_router_PathFinder.js.html +386 -0
- package/docs/api/mesh_router_RouteTable.js.html +346 -0
- package/docs/api/mesh_router_index.js.html +70 -0
- package/docs/api/module-audio_buffer.html +168 -0
- package/docs/api/module-audio_buffer_FrameBuffer-FrameBuffer.html +2971 -0
- package/docs/api/module-audio_buffer_FrameBuffer.html +178 -0
- package/docs/api/module-audio_buffer_JitterBuffer-JitterBuffer.html +2761 -0
- package/docs/api/module-audio_buffer_JitterBuffer.html +178 -0
- package/docs/api/module-audio_codec.html +168 -0
- package/docs/api/module-audio_codec_LC3Codec-LC3Codec.html +2876 -0
- package/docs/api/module-audio_codec_LC3Codec.html +178 -0
- package/docs/api/module-audio_codec_LC3Decoder-LC3Decoder.html +1788 -0
- package/docs/api/module-audio_codec_LC3Decoder.html +178 -0
- package/docs/api/module-audio_codec_LC3Encoder-LC3Encoder.html +1512 -0
- package/docs/api/module-audio_codec_LC3Encoder.html +178 -0
- package/docs/api/module-audio_session.html +168 -0
- package/docs/api/module-audio_session_AudioSession-AudioSession.html +3922 -0
- package/docs/api/module-audio_session_AudioSession.html +178 -0
- package/docs/api/module-audio_session_VoiceMessage-VoiceMessage.html +3690 -0
- package/docs/api/module-audio_session_VoiceMessage-VoiceMessageRecorder.html +1780 -0
- package/docs/api/module-audio_session_VoiceMessage.html +332 -0
- package/docs/api/module-audio_transport.html +168 -0
- package/docs/api/module-audio_transport_AudioFragmenter-AudioAssembler.html +1545 -0
- package/docs/api/module-audio_transport_AudioFragmenter-AudioFragmenter.html +658 -0
- package/docs/api/module-audio_transport_AudioFragmenter.html +181 -0
- package/docs/api/module-audio_transport_AudioFramer.html +1414 -0
- package/docs/api/module-constants.html +168 -0
- package/docs/api/module-constants_audio.html +1782 -0
- package/docs/api/module-constants_ble.html +940 -0
- package/docs/api/module-constants_crypto.html +823 -0
- package/docs/api/module-constants_errors.html +316 -0
- package/docs/api/module-constants_events.html +244 -0
- package/docs/api/module-constants_protocol.html +1534 -0
- package/docs/api/module-crypto.html +169 -0
- package/docs/api/module-crypto_aead.html +1625 -0
- package/docs/api/module-crypto_chacha20.html +1440 -0
- package/docs/api/module-crypto_hkdf.html +1421 -0
- package/docs/api/module-crypto_hmac.html +828 -0
- package/docs/api/module-crypto_keys.html +169 -0
- package/docs/api/module-crypto_keys_KeyManager-KeyManager.html +2364 -0
- package/docs/api/module-crypto_keys_KeyManager.html +252 -0
- package/docs/api/module-crypto_keys_KeyPair.html +245 -0
- package/docs/api/module-crypto_keys_SecureStorage-MemorySecureStorage.html +923 -0
- package/docs/api/module-crypto_keys_SecureStorage-SecureStorage.html +942 -0
- package/docs/api/module-crypto_keys_SecureStorage.html +516 -0
- package/docs/api/module-crypto_noise.html +169 -0
- package/docs/api/module-crypto_noise_handshake-NoiseHandshake.html +2240 -0
- package/docs/api/module-crypto_noise_handshake.html +782 -0
- package/docs/api/module-crypto_noise_session-NoiseSession.html +1804 -0
- package/docs/api/module-crypto_noise_session.html +325 -0
- package/docs/api/module-crypto_noise_state-SymmetricState.html +1387 -0
- package/docs/api/module-crypto_noise_state.html +324 -0
- package/docs/api/module-crypto_poly1305.html +884 -0
- package/docs/api/module-crypto_sha256-HashContext.html +447 -0
- package/docs/api/module-crypto_sha256.html +942 -0
- package/docs/api/module-crypto_x25519.html +1503 -0
- package/docs/api/module-errors.html +168 -0
- package/docs/api/module-errors_AudioError-AudioError.html +4711 -0
- package/docs/api/module-errors_AudioError.html +178 -0
- package/docs/api/module-errors_ConnectionError-ConnectionError.html +3649 -0
- package/docs/api/module-errors_ConnectionError.html +178 -0
- package/docs/api/module-errors_CryptoError-CryptoError.html +3453 -0
- package/docs/api/module-errors_CryptoError.html +178 -0
- package/docs/api/module-errors_HandshakeError-HandshakeError.html +4261 -0
- package/docs/api/module-errors_HandshakeError.html +178 -0
- package/docs/api/module-errors_MeshError-MeshError.html +2155 -0
- package/docs/api/module-errors_MeshError.html +178 -0
- package/docs/api/module-errors_MessageError-MessageError.html +4545 -0
- package/docs/api/module-errors_MessageError.html +178 -0
- package/docs/api/module-errors_ValidationError-ValidationError.html +3432 -0
- package/docs/api/module-errors_ValidationError.html +178 -0
- package/docs/api/module-hooks.html +182 -0
- package/docs/api/module-hooks_AppStateManager-AppStateManager.html +1620 -0
- package/docs/api/module-hooks_AppStateManager.html +178 -0
- package/docs/api/module-hooks_useMesh.html +457 -0
- package/docs/api/module-hooks_useMessages.html +466 -0
- package/docs/api/module-hooks_usePeers.html +348 -0
- package/docs/api/module-mesh.html +168 -0
- package/docs/api/module-mesh_dedup.html +168 -0
- package/docs/api/module-mesh_dedup_BloomFilter-BloomFilter.html +2158 -0
- package/docs/api/module-mesh_dedup_BloomFilter.html +178 -0
- package/docs/api/module-mesh_dedup_DedupManager-DedupManager.html +2880 -0
- package/docs/api/module-mesh_dedup_DedupManager.html +178 -0
- package/docs/api/module-mesh_dedup_MessageCache-CacheNode.html +246 -0
- package/docs/api/module-mesh_dedup_MessageCache-MessageCache.html +2314 -0
- package/docs/api/module-mesh_dedup_MessageCache.html +181 -0
- package/docs/api/module-mesh_fragment.html +168 -0
- package/docs/api/module-mesh_fragment_Assembler-Assembler.html +2869 -0
- package/docs/api/module-mesh_fragment_Assembler-PendingFragmentSet.html +895 -0
- package/docs/api/module-mesh_fragment_Assembler.html +181 -0
- package/docs/api/module-mesh_fragment_Fragmenter.html +1084 -0
- package/docs/api/module-mesh_peer.html +168 -0
- package/docs/api/module-mesh_peer_Peer-Peer.html +4986 -0
- package/docs/api/module-mesh_peer_Peer.html +178 -0
- package/docs/api/module-mesh_peer_PeerDiscovery-PeerDiscovery.html +3423 -0
- package/docs/api/module-mesh_peer_PeerDiscovery.html +438 -0
- package/docs/api/module-mesh_peer_PeerManager-PeerManager.html +5258 -0
- package/docs/api/module-mesh_peer_PeerManager.html +178 -0
- package/docs/api/module-mesh_router.html +168 -0
- package/docs/api/module-mesh_router_MessageRouter-MessageRouter.html +3285 -0
- package/docs/api/module-mesh_router_MessageRouter.html +178 -0
- package/docs/api/module-mesh_router_PathFinder-PathFinder.html +3323 -0
- package/docs/api/module-mesh_router_PathFinder.html +421 -0
- package/docs/api/module-mesh_router_RouteTable-RouteTable.html +4115 -0
- package/docs/api/module-mesh_router_RouteTable.html +421 -0
- package/docs/api/module-protocol.html +169 -0
- package/docs/api/module-protocol_crc32.html +815 -0
- package/docs/api/module-protocol_deserializer.html +1393 -0
- package/docs/api/module-protocol_header-MessageHeader.html +2879 -0
- package/docs/api/module-protocol_header.html +892 -0
- package/docs/api/module-protocol_message-Message.html +4682 -0
- package/docs/api/module-protocol_message.html +178 -0
- package/docs/api/module-protocol_serializer.html +911 -0
- package/docs/api/module-protocol_validator.html +1396 -0
- package/docs/api/module-rn-ble-mesh.html +866 -0
- package/docs/api/module-service.html +168 -0
- package/docs/api/module-service_HandshakeManager-HandshakeManager.html +185 -0
- package/docs/api/module-service_HandshakeManager.html +175 -0
- package/docs/api/module-service_MeshService-MeshService.html +185 -0
- package/docs/api/module-service_MeshService.html +175 -0
- package/docs/api/module-service_SessionManager-SessionManager.html +174 -0
- package/docs/api/module-service_SessionManager.html +175 -0
- package/docs/api/module-service_audio.html +168 -0
- package/docs/api/module-service_audio_AudioManager-AudioManager.html +4653 -0
- package/docs/api/module-service_audio_AudioManager.html +254 -0
- package/docs/api/module-service_text.html +168 -0
- package/docs/api/module-service_text_TextManager-TextManager.html +6104 -0
- package/docs/api/module-service_text_TextManager.html +254 -0
- package/docs/api/module-service_text_broadcast.html +168 -0
- package/docs/api/module-service_text_broadcast_BroadcastManager-BroadcastManager.html +2434 -0
- package/docs/api/module-service_text_broadcast_BroadcastManager.html +254 -0
- package/docs/api/module-service_text_channel.html +168 -0
- package/docs/api/module-service_text_channel_Channel-Channel.html +4337 -0
- package/docs/api/module-service_text_channel_Channel.html +178 -0
- package/docs/api/module-service_text_channel_ChannelManager-ChannelManager.html +1927 -0
- package/docs/api/module-service_text_channel_ChannelManager.html +175 -0
- package/docs/api/module-service_text_message.html +168 -0
- package/docs/api/module-service_text_message_TextMessage-TextMessage.html +4162 -0
- package/docs/api/module-service_text_message_TextMessage.html +178 -0
- package/docs/api/module-service_text_message_TextSerializer.html +1725 -0
- package/docs/api/module-storage.html +168 -0
- package/docs/api/module-storage_AsyncStorageAdapter-AsyncStorageAdapter.html +4159 -0
- package/docs/api/module-storage_AsyncStorageAdapter.html +178 -0
- package/docs/api/module-storage_MemoryStorage-MemoryStorage.html +3154 -0
- package/docs/api/module-storage_MemoryStorage.html +178 -0
- package/docs/api/module-storage_MessageStore-MessageStore.html +5299 -0
- package/docs/api/module-storage_MessageStore.html +178 -0
- package/docs/api/module-storage_Storage-Storage.html +4169 -0
- package/docs/api/module-storage_Storage.html +178 -0
- package/docs/api/module-transport.html +168 -0
- package/docs/api/module-transport_BLEAdapter-BLEAdapter.html +4724 -0
- package/docs/api/module-transport_BLEAdapter.html +178 -0
- package/docs/api/module-transport_BLETransport-BLETransport.html +3263 -0
- package/docs/api/module-transport_BLETransport.html +178 -0
- package/docs/api/module-transport_MockTransport-MockTransport.html +3947 -0
- package/docs/api/module-transport_MockTransport.html +178 -0
- package/docs/api/module-transport_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
- package/docs/api/module-transport_NodeBLEAdapter.html +178 -0
- package/docs/api/module-transport_RNBLEAdapter-RNBLEAdapter.html +3216 -0
- package/docs/api/module-transport_RNBLEAdapter.html +178 -0
- package/docs/api/module-transport_Transport-Transport.html +4071 -0
- package/docs/api/module-transport_Transport.html +254 -0
- package/docs/api/module-transport_adapters.html +168 -0
- package/docs/api/module-transport_adapters_BLEAdapter-BLEAdapter.html +4724 -0
- package/docs/api/module-transport_adapters_BLEAdapter.html +178 -0
- package/docs/api/module-transport_adapters_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
- package/docs/api/module-transport_adapters_NodeBLEAdapter.html +178 -0
- package/docs/api/module-transport_adapters_RNBLEAdapter-RNBLEAdapter.html +3216 -0
- package/docs/api/module-transport_adapters_RNBLEAdapter.html +178 -0
- package/docs/api/module-utils.html +168 -0
- package/docs/api/module-utils_BoundedMap-BoundedMap.html +3301 -0
- package/docs/api/module-utils_BoundedMap.html +178 -0
- package/docs/api/module-utils_EventEmitter-EventEmitter.html +3358 -0
- package/docs/api/module-utils_EventEmitter.html +178 -0
- package/docs/api/module-utils_LRUCache-LRUCache.html +4134 -0
- package/docs/api/module-utils_LRUCache.html +178 -0
- package/docs/api/module-utils_RateLimiter-RateLimiter.html +2176 -0
- package/docs/api/module-utils_RateLimiter.html +500 -0
- package/docs/api/module-utils_TimeoutManager-TimeoutManager.html +1781 -0
- package/docs/api/module-utils_TimeoutManager.html +175 -0
- package/docs/api/module-utils_bytes.html +1789 -0
- package/docs/api/module-utils_debug.html +837 -0
- package/docs/api/module-utils_encoding.html +1184 -0
- package/docs/api/module-utils_retry.html +1457 -0
- package/docs/api/module-utils_time.html +1665 -0
- package/docs/api/module-utils_uuid.html +1269 -0
- package/docs/api/module-utils_validation.html +2176 -0
- package/docs/api/protocol_crc32.js.html +147 -0
- package/docs/api/protocol_deserializer.js.html +295 -0
- package/docs/api/protocol_header.js.html +276 -0
- package/docs/api/protocol_index.js.html +120 -0
- package/docs/api/protocol_message.js.html +287 -0
- package/docs/api/protocol_serializer.js.html +240 -0
- package/docs/api/protocol_validator.js.html +330 -0
- package/docs/api/scripts/linenumber.js +25 -0
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/api/scripts/prettify/lang-css.js +2 -0
- package/docs/api/scripts/prettify/prettify.js +28 -0
- package/docs/api/service_HandshakeManager.js.html +232 -0
- package/docs/api/service_MeshService.js.html +371 -0
- package/docs/api/service_SessionManager.js.html +153 -0
- package/docs/api/service_audio_AudioManager.js.html +541 -0
- package/docs/api/service_audio_buffer_FrameBuffer.js.html +223 -0
- package/docs/api/service_audio_buffer_JitterBuffer.js.html +244 -0
- package/docs/api/service_audio_buffer_index.js.html +68 -0
- package/docs/api/service_audio_codec_LC3Codec.js.html +345 -0
- package/docs/api/service_audio_codec_LC3Decoder.js.html +185 -0
- package/docs/api/service_audio_codec_LC3Encoder.js.html +194 -0
- package/docs/api/service_audio_codec_index.js.html +70 -0
- package/docs/api/service_audio_index.js.html +96 -0
- package/docs/api/service_audio_session_AudioSession.js.html +348 -0
- package/docs/api/service_audio_session_VoiceMessage.js.html +432 -0
- package/docs/api/service_audio_session_index.js.html +70 -0
- package/docs/api/service_audio_transport_AudioFragmenter.js.html +314 -0
- package/docs/api/service_audio_transport_AudioFramer.js.html +236 -0
- package/docs/api/service_audio_transport_index.js.html +69 -0
- package/docs/api/service_index.js.html +93 -0
- package/docs/api/service_text_TextManager.js.html +578 -0
- package/docs/api/service_text_broadcast_BroadcastManager.js.html +276 -0
- package/docs/api/service_text_broadcast_index.js.html +66 -0
- package/docs/api/service_text_channel_Channel.js.html +280 -0
- package/docs/api/service_text_channel_ChannelManager.js.html +225 -0
- package/docs/api/service_text_channel_index.js.html +68 -0
- package/docs/api/service_text_index.js.html +85 -0
- package/docs/api/service_text_message_TextMessage.js.html +350 -0
- package/docs/api/service_text_message_TextSerializer.js.html +218 -0
- package/docs/api/service_text_message_index.js.html +68 -0
- package/docs/api/storage_AsyncStorageAdapter.js.html +357 -0
- package/docs/api/storage_MemoryStorage.js.html +279 -0
- package/docs/api/storage_MessageStore.js.html +369 -0
- package/docs/api/storage_Storage.js.html +214 -0
- package/docs/api/storage_index.js.html +72 -0
- package/docs/api/styles/jsdoc-default.css +358 -0
- package/docs/api/styles/prettify-jsdoc.css +111 -0
- package/docs/api/styles/prettify-tomorrow.css +132 -0
- package/docs/api/transport_BLEAdapter.js.html +231 -0
- package/docs/api/transport_BLETransport.js.html +411 -0
- package/docs/api/transport_MockTransport.js.html +339 -0
- package/docs/api/transport_NodeBLEAdapter.js.html +479 -0
- package/docs/api/transport_RNBLEAdapter.js.html +382 -0
- package/docs/api/transport_Transport.js.html +242 -0
- package/docs/api/transport_adapters_BLEAdapter.js.html +231 -0
- package/docs/api/transport_adapters_NodeBLEAdapter.js.html +479 -0
- package/docs/api/transport_adapters_RNBLEAdapter.js.html +382 -0
- package/docs/api/transport_adapters_index.js.html +70 -0
- package/docs/api/transport_index.js.html +87 -0
- package/docs/api/utils_BoundedMap.js.html +205 -0
- package/docs/api/utils_EventEmitter.js.html +259 -0
- package/docs/api/utils_LRUCache.js.html +256 -0
- package/docs/api/utils_RateLimiter.js.html +256 -0
- package/docs/api/utils_TimeoutManager.js.html +218 -0
- package/docs/api/utils_base64%0A%0AThis%20implementation%20avoids%20string%20concatenation%20in%20loops%20which%20is%20O(n%C2%B2).%0AUses%20array%20building%20which%20is%20O(n)%20-%20critical%20for%20React%20Native%20performance.module_.html +717 -0
- package/docs/api/utils_base64.js.html +205 -0
- package/docs/api/utils_bytes.js.html +241 -0
- package/docs/api/utils_debug.js.html +205 -0
- package/docs/api/utils_encoding.js.html +302 -0
- package/docs/api/utils_index.js.html +160 -0
- package/docs/api/utils_retry.js.html +200 -0
- package/docs/api/utils_time.js.html +220 -0
- package/docs/api/utils_uuid.js.html +199 -0
- package/docs/api/utils_validation.js.html +259 -0
- package/examples/node-chat/chat.js +220 -0
- package/examples/node-quickstart/index.js +94 -0
- package/examples/testing/test-helper.js +182 -0
- package/package.json +111 -0
- package/src/constants/audio.js +130 -0
- package/src/constants/ble.js +111 -0
- package/src/constants/crypto.js +53 -0
- package/src/constants/errors.js +202 -0
- package/src/constants/events.js +94 -0
- package/src/constants/index.js +22 -0
- package/src/constants/protocol.js +151 -0
- package/src/crypto/aead.js +189 -0
- package/src/crypto/chacha20.js +181 -0
- package/src/crypto/hkdf.js +187 -0
- package/src/crypto/hmac.js +143 -0
- package/src/crypto/index.js +72 -0
- package/src/crypto/keys/KeyManager.js +271 -0
- package/src/crypto/keys/KeyPair.js +216 -0
- package/src/crypto/keys/SecureStorage.js +219 -0
- package/src/crypto/keys/index.js +32 -0
- package/src/crypto/noise/handshake.js +410 -0
- package/src/crypto/noise/index.js +27 -0
- package/src/crypto/noise/session.js +253 -0
- package/src/crypto/noise/state.js +268 -0
- package/src/crypto/poly1305.js +113 -0
- package/src/crypto/sha256.js +240 -0
- package/src/crypto/x25519.js +154 -0
- package/src/errors/AudioError.js +164 -0
- package/src/errors/ConnectionError.js +109 -0
- package/src/errors/CryptoError.js +103 -0
- package/src/errors/HandshakeError.js +122 -0
- package/src/errors/MeshError.js +100 -0
- package/src/errors/MessageError.js +129 -0
- package/src/errors/ValidationError.js +150 -0
- package/src/errors/index.js +24 -0
- package/src/hooks/AppStateManager.js +179 -0
- package/src/hooks/index.js +33 -0
- package/src/hooks/useMesh.js +159 -0
- package/src/hooks/useMessages.js +209 -0
- package/src/hooks/usePeers.js +111 -0
- package/src/index.d.ts +494 -0
- package/src/index.js +182 -0
- package/src/index.mjs +62 -0
- package/src/mesh/dedup/BloomFilter.js +207 -0
- package/src/mesh/dedup/DedupManager.js +212 -0
- package/src/mesh/dedup/MessageCache.js +219 -0
- package/src/mesh/dedup/index.js +16 -0
- package/src/mesh/fragment/Assembler.js +281 -0
- package/src/mesh/fragment/Fragmenter.js +176 -0
- package/src/mesh/fragment/index.js +21 -0
- package/src/mesh/index.js +18 -0
- package/src/mesh/peer/Peer.js +242 -0
- package/src/mesh/peer/PeerDiscovery.js +280 -0
- package/src/mesh/peer/PeerManager.js +266 -0
- package/src/mesh/peer/index.js +16 -0
- package/src/mesh/router/MessageRouter.js +357 -0
- package/src/mesh/router/PathFinder.js +332 -0
- package/src/mesh/router/RouteTable.js +292 -0
- package/src/mesh/router/index.js +16 -0
- package/src/protocol/crc32.js +93 -0
- package/src/protocol/deserializer.js +241 -0
- package/src/protocol/header.js +222 -0
- package/src/protocol/index.js +66 -0
- package/src/protocol/message.js +233 -0
- package/src/protocol/serializer.js +186 -0
- package/src/protocol/validator.js +276 -0
- package/src/service/HandshakeManager.js +178 -0
- package/src/service/MeshService.js +317 -0
- package/src/service/SessionManager.js +99 -0
- package/src/service/audio/AudioManager.js +487 -0
- package/src/service/audio/buffer/FrameBuffer.js +169 -0
- package/src/service/audio/buffer/JitterBuffer.js +190 -0
- package/src/service/audio/buffer/index.js +14 -0
- package/src/service/audio/codec/LC3Codec.js +291 -0
- package/src/service/audio/codec/LC3Decoder.js +131 -0
- package/src/service/audio/codec/LC3Encoder.js +140 -0
- package/src/service/audio/codec/index.js +16 -0
- package/src/service/audio/index.js +42 -0
- package/src/service/audio/session/AudioSession.js +294 -0
- package/src/service/audio/session/VoiceMessage.js +378 -0
- package/src/service/audio/session/index.js +16 -0
- package/src/service/audio/transport/AudioFragmenter.js +260 -0
- package/src/service/audio/transport/AudioFramer.js +182 -0
- package/src/service/audio/transport/index.js +15 -0
- package/src/service/index.js +39 -0
- package/src/service/text/TextManager.js +524 -0
- package/src/service/text/broadcast/BroadcastManager.js +222 -0
- package/src/service/text/broadcast/index.js +12 -0
- package/src/service/text/channel/Channel.js +226 -0
- package/src/service/text/channel/ChannelManager.js +171 -0
- package/src/service/text/channel/index.js +14 -0
- package/src/service/text/index.js +31 -0
- package/src/service/text/message/TextMessage.js +296 -0
- package/src/service/text/message/TextSerializer.js +164 -0
- package/src/service/text/message/index.js +14 -0
- package/src/storage/AsyncStorageAdapter.js +303 -0
- package/src/storage/MemoryStorage.js +225 -0
- package/src/storage/MessageStore.js +315 -0
- package/src/storage/Storage.js +160 -0
- package/src/storage/index.js +18 -0
- package/src/transport/BLEAdapter.js +177 -0
- package/src/transport/BLETransport.js +357 -0
- package/src/transport/MockTransport.js +285 -0
- package/src/transport/NodeBLEAdapter.js +425 -0
- package/src/transport/RNBLEAdapter.js +328 -0
- package/src/transport/Transport.js +188 -0
- package/src/transport/adapters/BLEAdapter.js +177 -0
- package/src/transport/adapters/NodeBLEAdapter.js +425 -0
- package/src/transport/adapters/RNBLEAdapter.js +328 -0
- package/src/transport/adapters/index.js +16 -0
- package/src/transport/index.js +33 -0
- package/src/utils/BoundedMap.js +151 -0
- package/src/utils/EventEmitter.js +205 -0
- package/src/utils/LRUCache.js +202 -0
- package/src/utils/RateLimiter.js +202 -0
- package/src/utils/TimeoutManager.js +164 -0
- package/src/utils/base64.js +151 -0
- package/src/utils/bytes.js +187 -0
- package/src/utils/debug.js +151 -0
- package/src/utils/encoding.js +248 -0
- package/src/utils/index.js +106 -0
- package/src/utils/retry.js +146 -0
- package/src/utils/time.js +166 -0
- package/src/utils/uuid.js +145 -0
- package/src/utils/validation.js +205 -0
package/README.md
ADDED
|
@@ -0,0 +1,706 @@
|
|
|
1
|
+
# react-native-ble-mesh
|
|
2
|
+
|
|
3
|
+
> Inspired by [Bitchat](https://github.com/permissionlesstech/bitchat) - this is the React Native version.
|
|
4
|
+
|
|
5
|
+
A **production-ready BLE Mesh Network library** for Node.js and React Native with Noise Protocol security. This library enables peer-to-peer communication over Bluetooth Low Energy with end-to-end encryption, multi-hop routing, and offline-first capabilities.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/react-native-ble-mesh)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **End-to-End Encryption** - Noise Protocol XX handshake with ChaCha20-Poly1305 AEAD
|
|
13
|
+
- **Digital Signatures** - Ed25519 signatures for message authentication and identity verification
|
|
14
|
+
- **Multi-Hop Routing** - Messages can traverse multiple peers to reach their destination
|
|
15
|
+
- **Offline-First** - Works without internet connectivity using BLE
|
|
16
|
+
- **Forward Secrecy** - Automatic session rekeying for enhanced security
|
|
17
|
+
- **Replay Protection** - Sliding window algorithm prevents replay attacks
|
|
18
|
+
- **Traffic Analysis Resistance** - PKCS#7 padding to fixed block sizes
|
|
19
|
+
- **LZ4 Compression** - Efficient bandwidth usage for larger messages
|
|
20
|
+
- **Power Management** - Multiple power modes for battery optimization
|
|
21
|
+
- **Trust Management** - Peer verification, favorites, and blocking
|
|
22
|
+
- **Message Reliability** - Automatic retry with exponential backoff
|
|
23
|
+
|
|
24
|
+
## Use Cases
|
|
25
|
+
|
|
26
|
+
- Offline messaging apps (like Bridgefy, Briar)
|
|
27
|
+
- Disaster communication networks
|
|
28
|
+
- Privacy-focused P2P chat
|
|
29
|
+
- IoT mesh networks
|
|
30
|
+
- Gaming multiplayer over BLE
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install react-native-ble-mesh
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### React Native
|
|
39
|
+
|
|
40
|
+
For React Native projects, you also need to install the BLE dependency:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install react-native-ble-plx
|
|
44
|
+
cd ios && pod install
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Node.js
|
|
48
|
+
|
|
49
|
+
For Node.js projects using Noble:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install @abandonware/noble
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
### Basic Setup
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
const { MeshService, BLETransport } = require('react-native-ble-mesh');
|
|
61
|
+
|
|
62
|
+
// Create and initialize the mesh service
|
|
63
|
+
const mesh = new MeshService();
|
|
64
|
+
|
|
65
|
+
async function start() {
|
|
66
|
+
// Initialize with optional configuration
|
|
67
|
+
await mesh.initialize({
|
|
68
|
+
displayName: 'Alice',
|
|
69
|
+
storage: null, // Use in-memory storage
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Create transport layer
|
|
73
|
+
const transport = new BLETransport();
|
|
74
|
+
|
|
75
|
+
// Start the mesh service
|
|
76
|
+
await mesh.start(transport);
|
|
77
|
+
|
|
78
|
+
console.log('Mesh network started!');
|
|
79
|
+
console.log('My fingerprint:', mesh.getFingerprint());
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
start();
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Discovering Peers
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
// Listen for peer discovery events
|
|
89
|
+
mesh.on('peer-discovered', (peer) => {
|
|
90
|
+
console.log('Discovered peer:', peer.id);
|
|
91
|
+
console.log('Display name:', peer.getDisplayName());
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
mesh.on('peer-connected', (peer) => {
|
|
95
|
+
console.log('Connected to peer:', peer.id);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
mesh.on('peer-secured', (peer) => {
|
|
99
|
+
console.log('Secure session established with:', peer.id);
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Sending Messages
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
// Send a broadcast message to all nearby peers
|
|
107
|
+
const broadcastId = mesh.sendBroadcast('Hello, mesh network!');
|
|
108
|
+
|
|
109
|
+
// Send a private encrypted message to a specific peer
|
|
110
|
+
const peerId = 'abc123...';
|
|
111
|
+
try {
|
|
112
|
+
const messageId = await mesh.sendPrivateMessage(peerId, 'Hello, this is private!');
|
|
113
|
+
console.log('Message sent:', messageId);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error('Failed to send:', error.message);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Send a message to a channel
|
|
119
|
+
const channelMessageId = mesh.sendChannelMessage('general', 'Hello channel!');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Receiving Messages
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
// Listen for incoming messages
|
|
126
|
+
mesh.on('message', (message) => {
|
|
127
|
+
console.log('Received message:', message.content);
|
|
128
|
+
console.log('From:', message.senderId);
|
|
129
|
+
console.log('Type:', message.type);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Listen for private messages specifically
|
|
133
|
+
mesh.on('private-message', (message) => {
|
|
134
|
+
console.log('Private message from', message.senderId);
|
|
135
|
+
console.log('Content:', message.content);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Listen for channel messages
|
|
139
|
+
mesh.on('channel-message', (message) => {
|
|
140
|
+
console.log('Channel:', message.channelId);
|
|
141
|
+
console.log('Content:', message.content);
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Handling Acknowledgments and Read Receipts
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
// Listen for message delivery confirmations
|
|
149
|
+
mesh.on('message-delivered', ({ messageId, peerId, timestamp }) => {
|
|
150
|
+
console.log(`Message ${messageId} delivered to ${peerId}`);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Listen for read receipts
|
|
154
|
+
mesh.on('read-receipt', ({ messageIds, fromPeerId, timestamp }) => {
|
|
155
|
+
console.log(`Peer ${fromPeerId} read messages:`, messageIds);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Send read receipts for messages you've read
|
|
159
|
+
mesh.sendReadReceipt(['msg-id-1', 'msg-id-2']);
|
|
160
|
+
|
|
161
|
+
// Mark a single message as read
|
|
162
|
+
mesh.markMessageRead('msg-id-1');
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## API Reference
|
|
166
|
+
|
|
167
|
+
### MeshService
|
|
168
|
+
|
|
169
|
+
The main orchestrator for the mesh network.
|
|
170
|
+
|
|
171
|
+
#### Lifecycle Methods
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
// Initialize the service
|
|
175
|
+
await mesh.initialize(options);
|
|
176
|
+
|
|
177
|
+
// Start with a transport
|
|
178
|
+
await mesh.start(transport);
|
|
179
|
+
|
|
180
|
+
// Stop the service
|
|
181
|
+
await mesh.stop();
|
|
182
|
+
|
|
183
|
+
// Clean up resources
|
|
184
|
+
await mesh.destroy();
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
#### Identity Management
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
// Get your identity information
|
|
191
|
+
const identity = mesh.getIdentity();
|
|
192
|
+
// Returns: { publicKey, signingPublicKey, displayName, fingerprint }
|
|
193
|
+
|
|
194
|
+
// Set your display name
|
|
195
|
+
mesh.setDisplayName('Alice');
|
|
196
|
+
|
|
197
|
+
// Get your fingerprint for out-of-band verification
|
|
198
|
+
const fingerprint = mesh.getFingerprint();
|
|
199
|
+
|
|
200
|
+
// Export identity for backup
|
|
201
|
+
const exported = mesh.exportIdentity();
|
|
202
|
+
|
|
203
|
+
// Import identity from backup
|
|
204
|
+
mesh.importIdentity(exported);
|
|
205
|
+
|
|
206
|
+
// Announce identity to network
|
|
207
|
+
mesh.announceIdentity();
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### Peer Management
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
// Get all known peers
|
|
214
|
+
const peers = mesh.getPeers();
|
|
215
|
+
|
|
216
|
+
// Get a specific peer
|
|
217
|
+
const peer = mesh.getPeer(peerId);
|
|
218
|
+
|
|
219
|
+
// Initiate secure handshake with a peer
|
|
220
|
+
await mesh.initiateHandshake(peerId);
|
|
221
|
+
|
|
222
|
+
// Block a peer
|
|
223
|
+
mesh.blockPeer(peerId);
|
|
224
|
+
|
|
225
|
+
// Unblock a peer
|
|
226
|
+
mesh.unblockPeer(peerId);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### Trust Management
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
// Verify a peer using their fingerprint
|
|
233
|
+
mesh.verifyPeer(peerId, fingerprint);
|
|
234
|
+
|
|
235
|
+
// Remove verification
|
|
236
|
+
mesh.unverifyPeer(peerId);
|
|
237
|
+
|
|
238
|
+
// Add to favorites
|
|
239
|
+
mesh.addFavorite(peerId);
|
|
240
|
+
|
|
241
|
+
// Remove from favorites
|
|
242
|
+
mesh.removeFavorite(peerId);
|
|
243
|
+
|
|
244
|
+
// Get verified peers
|
|
245
|
+
const verified = mesh.getVerifiedPeers();
|
|
246
|
+
|
|
247
|
+
// Get favorite peers
|
|
248
|
+
const favorites = mesh.getFavoritePeers();
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### Power Management
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
// Available power modes: PERFORMANCE, BALANCED, POWER_SAVER, ULTRA_POWER_SAVER
|
|
255
|
+
mesh.setPowerMode('BALANCED');
|
|
256
|
+
|
|
257
|
+
// Get current power mode
|
|
258
|
+
const mode = mesh.getPowerMode();
|
|
259
|
+
|
|
260
|
+
// Enable automatic power adjustment based on battery level
|
|
261
|
+
mesh.setAutoPowerAdjust(true);
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### Status and Statistics
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
// Get service status
|
|
268
|
+
const status = mesh.getStatus();
|
|
269
|
+
|
|
270
|
+
// Get current state
|
|
271
|
+
const state = mesh.getState();
|
|
272
|
+
|
|
273
|
+
// Get detailed statistics
|
|
274
|
+
const stats = mesh.getStats();
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Events
|
|
278
|
+
|
|
279
|
+
| Event | Description | Payload |
|
|
280
|
+
|-------|-------------|---------|
|
|
281
|
+
| `peer-discovered` | New peer found | `{ peer }` |
|
|
282
|
+
| `peer-connected` | Connected to peer | `{ peer }` |
|
|
283
|
+
| `peer-disconnected` | Disconnected from peer | `{ peer }` |
|
|
284
|
+
| `peer-secured` | Secure session established | `{ peer }` |
|
|
285
|
+
| `message` | Any message received | `{ message }` |
|
|
286
|
+
| `private-message` | Private message received | `{ message }` |
|
|
287
|
+
| `channel-message` | Channel message received | `{ message }` |
|
|
288
|
+
| `message-delivered` | Message delivery confirmed | `{ messageId, peerId, timestamp }` |
|
|
289
|
+
| `message-failed` | Message delivery failed | `{ messageId, peerId, error }` |
|
|
290
|
+
| `read-receipt` | Read receipt received | `{ messageIds, fromPeerId, timestamp }` |
|
|
291
|
+
| `identity-announced` | Peer announced identity | `{ peerId, fingerprint, nickname }` |
|
|
292
|
+
| `peer-verified` | Peer verification changed | `{ peerId, fingerprint }` |
|
|
293
|
+
| `peer-compromised` | Fingerprint mismatch detected | `{ peerId, expected, actual }` |
|
|
294
|
+
|
|
295
|
+
## Configuration
|
|
296
|
+
|
|
297
|
+
### Initialization Options
|
|
298
|
+
|
|
299
|
+
```javascript
|
|
300
|
+
await mesh.initialize({
|
|
301
|
+
// Display name for this node
|
|
302
|
+
displayName: 'My Device',
|
|
303
|
+
|
|
304
|
+
// Storage adapter (null for in-memory)
|
|
305
|
+
storage: null,
|
|
306
|
+
|
|
307
|
+
// Custom key manager (optional)
|
|
308
|
+
keyManager: null,
|
|
309
|
+
|
|
310
|
+
// Enable compression for messages > 64 bytes
|
|
311
|
+
compressionEnabled: true,
|
|
312
|
+
|
|
313
|
+
// Compression threshold in bytes
|
|
314
|
+
compressionThreshold: 64,
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Power Modes
|
|
319
|
+
|
|
320
|
+
| Mode | Scan Interval | Window | Use Case |
|
|
321
|
+
|------|---------------|--------|----------|
|
|
322
|
+
| `PERFORMANCE` | 1s | 800ms | Active foreground use |
|
|
323
|
+
| `BALANCED` | 5s | 2s | Default mode |
|
|
324
|
+
| `POWER_SAVER` | 30s | 5s | Background operation |
|
|
325
|
+
| `ULTRA_POWER_SAVER` | 60s | 5s | Minimal battery drain |
|
|
326
|
+
|
|
327
|
+
### Message Options
|
|
328
|
+
|
|
329
|
+
```javascript
|
|
330
|
+
// Send with options
|
|
331
|
+
await mesh.sendPrivateMessage(peerId, content, {
|
|
332
|
+
// Request delivery acknowledgment
|
|
333
|
+
requiresAck: true,
|
|
334
|
+
|
|
335
|
+
// Enable compression
|
|
336
|
+
compress: true,
|
|
337
|
+
|
|
338
|
+
// Maximum hop count (1-15)
|
|
339
|
+
maxHops: 7,
|
|
340
|
+
|
|
341
|
+
// Priority level
|
|
342
|
+
priority: 'high', // 'normal' | 'high'
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Security Features
|
|
347
|
+
|
|
348
|
+
### Cryptographic Primitives
|
|
349
|
+
|
|
350
|
+
- **Key Exchange**: X25519 (Curve25519 ECDH)
|
|
351
|
+
- **Signatures**: Ed25519
|
|
352
|
+
- **Encryption**: ChaCha20-Poly1305 AEAD
|
|
353
|
+
- **Hashing**: SHA-256, SHA-512
|
|
354
|
+
- **Key Derivation**: HKDF
|
|
355
|
+
|
|
356
|
+
### Noise Protocol XX Handshake
|
|
357
|
+
|
|
358
|
+
The library implements the Noise XX handshake pattern:
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
-> e
|
|
362
|
+
<- e, ee, s, es
|
|
363
|
+
-> s, se
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
This provides:
|
|
367
|
+
- Mutual authentication
|
|
368
|
+
- Forward secrecy
|
|
369
|
+
- Identity hiding
|
|
370
|
+
|
|
371
|
+
### Session Security
|
|
372
|
+
|
|
373
|
+
- **Automatic Rekeying**: Sessions rekey every hour or after 10,000 messages
|
|
374
|
+
- **Replay Protection**: Sliding window algorithm with configurable window size
|
|
375
|
+
- **Nonce Management**: Automatic nonce tracking prevents reuse
|
|
376
|
+
|
|
377
|
+
### Identity Verification
|
|
378
|
+
|
|
379
|
+
Verify peer identities out-of-band using fingerprints:
|
|
380
|
+
|
|
381
|
+
```javascript
|
|
382
|
+
// Get your fingerprint to share
|
|
383
|
+
const myFingerprint = mesh.getFingerprint();
|
|
384
|
+
// Format: "A1B2 C3D4 E5F6 G7H8 I9J0 K1L2 M3N4 O5P6"
|
|
385
|
+
|
|
386
|
+
// Verify a peer after out-of-band confirmation
|
|
387
|
+
mesh.verifyPeer(peerId, theirFingerprint);
|
|
388
|
+
|
|
389
|
+
// Check if a peer is verified
|
|
390
|
+
const peer = mesh.getPeer(peerId);
|
|
391
|
+
console.log('Verified:', peer.verificationStatus === 'verified');
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Protocol Details
|
|
395
|
+
|
|
396
|
+
### Message Header Format
|
|
397
|
+
|
|
398
|
+
The library uses an optimized 24-32 byte header:
|
|
399
|
+
|
|
400
|
+
| Field | Size | Description |
|
|
401
|
+
|-------|------|-------------|
|
|
402
|
+
| version | 1 | Protocol version |
|
|
403
|
+
| type | 1 | Message type |
|
|
404
|
+
| flags | 1 | Feature flags |
|
|
405
|
+
| ttl | 1 | Hop count + max hops |
|
|
406
|
+
| timestamp | 8 | Unix timestamp (ms) |
|
|
407
|
+
| payloadLength | 2 | Payload size |
|
|
408
|
+
| fragmentIndex | 1 | Fragment index |
|
|
409
|
+
| fragmentTotal | 1 | Total fragments |
|
|
410
|
+
| senderId | 8 | Truncated peer ID |
|
|
411
|
+
| recipientId | 8 | (Optional) Recipient ID |
|
|
412
|
+
|
|
413
|
+
### Message Types
|
|
414
|
+
|
|
415
|
+
| Category | Types |
|
|
416
|
+
|----------|-------|
|
|
417
|
+
| Data | TEXT, TEXT_ACK, BINARY, BINARY_ACK |
|
|
418
|
+
| Handshake | HANDSHAKE_INIT, HANDSHAKE_RESPONSE, HANDSHAKE_FINAL |
|
|
419
|
+
| Discovery | PEER_ANNOUNCE, PEER_REQUEST, PEER_RESPONSE, IDENTITY_ANNOUNCE |
|
|
420
|
+
| Channels | CHANNEL_JOIN, CHANNEL_LEAVE, CHANNEL_MESSAGE |
|
|
421
|
+
| Private | PRIVATE_MESSAGE, PRIVATE_ACK, READ_RECEIPT |
|
|
422
|
+
| Control | HEARTBEAT, PING, PONG |
|
|
423
|
+
| Fragments | FRAGMENT_START, FRAGMENT_CONTINUE, FRAGMENT_END |
|
|
424
|
+
|
|
425
|
+
## Error Handling
|
|
426
|
+
|
|
427
|
+
The library provides detailed error classes:
|
|
428
|
+
|
|
429
|
+
```javascript
|
|
430
|
+
const {
|
|
431
|
+
MeshError,
|
|
432
|
+
CryptoError,
|
|
433
|
+
ConnectionError,
|
|
434
|
+
HandshakeError,
|
|
435
|
+
MessageError,
|
|
436
|
+
FragmentError,
|
|
437
|
+
TrustError,
|
|
438
|
+
RetryError
|
|
439
|
+
} = require('react-native-ble-mesh/errors');
|
|
440
|
+
|
|
441
|
+
mesh.on('error', (error) => {
|
|
442
|
+
if (error instanceof CryptoError) {
|
|
443
|
+
console.error('Crypto error:', error.code, error.message);
|
|
444
|
+
} else if (error instanceof ConnectionError) {
|
|
445
|
+
console.error('Connection error:', error.code, error.message);
|
|
446
|
+
} else if (error instanceof TrustError) {
|
|
447
|
+
console.error('Trust error:', error.code, error.message);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// All errors have these properties
|
|
451
|
+
console.log('Error code:', error.code);
|
|
452
|
+
console.log('Category:', error.category);
|
|
453
|
+
console.log('Recoverable:', error.recoverable);
|
|
454
|
+
console.log('Details:', error.details);
|
|
455
|
+
});
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Error Codes
|
|
459
|
+
|
|
460
|
+
| Category | Codes |
|
|
461
|
+
|----------|-------|
|
|
462
|
+
| Crypto | E_CRYPTO_001 - E_CRYPTO_006 |
|
|
463
|
+
| Connection | E_CONN_001 - E_CONN_003 |
|
|
464
|
+
| Handshake | E_HAND_001 - E_HAND_003 |
|
|
465
|
+
| Message | E_MSG_001 - E_MSG_004 |
|
|
466
|
+
| Fragment | E_FRAG_001 - E_FRAG_004 |
|
|
467
|
+
| Trust | E_TRUST_001 - E_TRUST_004 |
|
|
468
|
+
| Retry | E_RETRY_001 - E_RETRY_003 |
|
|
469
|
+
|
|
470
|
+
## Platform Support
|
|
471
|
+
|
|
472
|
+
### React Native
|
|
473
|
+
|
|
474
|
+
```javascript
|
|
475
|
+
const { MeshService, BLETransport } = require('react-native-ble-mesh');
|
|
476
|
+
const { RNBLEAdapter } = require('react-native-ble-mesh/adapters');
|
|
477
|
+
|
|
478
|
+
const transport = new BLETransport({
|
|
479
|
+
adapter: new RNBLEAdapter(),
|
|
480
|
+
});
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
**Required permissions (iOS):**
|
|
484
|
+
- NSBluetoothAlwaysUsageDescription
|
|
485
|
+
- NSBluetoothPeripheralUsageDescription
|
|
486
|
+
|
|
487
|
+
**Required permissions (Android):**
|
|
488
|
+
- BLUETOOTH
|
|
489
|
+
- BLUETOOTH_ADMIN
|
|
490
|
+
- BLUETOOTH_SCAN
|
|
491
|
+
- BLUETOOTH_ADVERTISE
|
|
492
|
+
- BLUETOOTH_CONNECT
|
|
493
|
+
- ACCESS_FINE_LOCATION
|
|
494
|
+
|
|
495
|
+
### Node.js
|
|
496
|
+
|
|
497
|
+
```javascript
|
|
498
|
+
const { MeshService, BLETransport } = require('react-native-ble-mesh');
|
|
499
|
+
const { NodeBLEAdapter } = require('react-native-ble-mesh/adapters');
|
|
500
|
+
|
|
501
|
+
const transport = new BLETransport({
|
|
502
|
+
adapter: new NodeBLEAdapter(),
|
|
503
|
+
});
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
## Examples
|
|
507
|
+
|
|
508
|
+
### Basic Chat Application
|
|
509
|
+
|
|
510
|
+
```javascript
|
|
511
|
+
const { MeshService, BLETransport, MemoryStorage } = require('react-native-ble-mesh');
|
|
512
|
+
|
|
513
|
+
class ChatApp {
|
|
514
|
+
constructor() {
|
|
515
|
+
this.mesh = new MeshService();
|
|
516
|
+
this.messages = [];
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
async start(displayName) {
|
|
520
|
+
await this.mesh.initialize({
|
|
521
|
+
displayName,
|
|
522
|
+
storage: new MemoryStorage(),
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
const transport = new BLETransport();
|
|
526
|
+
await this.mesh.start(transport);
|
|
527
|
+
|
|
528
|
+
this.setupEventHandlers();
|
|
529
|
+
console.log('Chat started! Your fingerprint:', this.mesh.getFingerprint());
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
setupEventHandlers() {
|
|
533
|
+
this.mesh.on('peer-discovered', (peer) => {
|
|
534
|
+
console.log(`[+] Discovered: ${peer.getDisplayName()}`);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
this.mesh.on('private-message', (message) => {
|
|
538
|
+
this.messages.push(message);
|
|
539
|
+
console.log(`[${message.senderId.slice(0, 8)}]: ${message.content}`);
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
this.mesh.on('message-delivered', ({ messageId }) => {
|
|
543
|
+
console.log(`[OK] Delivered: ${messageId.slice(0, 8)}`);
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
async sendMessage(peerId, content) {
|
|
548
|
+
return await this.mesh.sendPrivateMessage(peerId, content, {
|
|
549
|
+
requiresAck: true,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
getPeers() {
|
|
554
|
+
return this.mesh.getPeers();
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
verifyPeer(peerId, fingerprint) {
|
|
558
|
+
this.mesh.verifyPeer(peerId, fingerprint);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
async stop() {
|
|
562
|
+
await this.mesh.stop();
|
|
563
|
+
await this.mesh.destroy();
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Usage
|
|
568
|
+
const chat = new ChatApp();
|
|
569
|
+
await chat.start('Alice');
|
|
570
|
+
|
|
571
|
+
// List discovered peers
|
|
572
|
+
const peers = chat.getPeers();
|
|
573
|
+
peers.forEach(p => console.log(p.id, p.getDisplayName()));
|
|
574
|
+
|
|
575
|
+
// Send a message
|
|
576
|
+
await chat.sendMessage(peers[0].id, 'Hello!');
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Multi-Hop Messaging
|
|
580
|
+
|
|
581
|
+
```javascript
|
|
582
|
+
// Messages automatically route through multiple hops
|
|
583
|
+
const messageId = await mesh.sendPrivateMessage(distantPeerId, 'Hello distant peer!', {
|
|
584
|
+
maxHops: 10, // Allow up to 10 hops
|
|
585
|
+
requiresAck: true,
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
// Track routing statistics
|
|
589
|
+
const stats = mesh.getStats();
|
|
590
|
+
console.log('Messages relayed:', stats.messagesRelayed);
|
|
591
|
+
console.log('Average hop count:', stats.averageHopCount);
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
### Secure File Transfer
|
|
595
|
+
|
|
596
|
+
```javascript
|
|
597
|
+
const fs = require('fs');
|
|
598
|
+
const path = require('path');
|
|
599
|
+
|
|
600
|
+
async function sendFile(mesh, peerId, filePath) {
|
|
601
|
+
const fileData = fs.readFileSync(filePath);
|
|
602
|
+
const fileName = path.basename(filePath);
|
|
603
|
+
|
|
604
|
+
// The library automatically handles:
|
|
605
|
+
// - Compression for large payloads
|
|
606
|
+
// - Fragmentation for BLE MTU limits
|
|
607
|
+
// - Encryption with peer's session key
|
|
608
|
+
// - Automatic retry on failure
|
|
609
|
+
|
|
610
|
+
const messageId = await mesh.sendPrivateMessage(peerId, {
|
|
611
|
+
type: 'file',
|
|
612
|
+
name: fileName,
|
|
613
|
+
data: fileData.toString('base64'),
|
|
614
|
+
size: fileData.length,
|
|
615
|
+
}, {
|
|
616
|
+
compress: true,
|
|
617
|
+
requiresAck: true,
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
console.log('File transfer initiated:', messageId);
|
|
621
|
+
}
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
## Testing
|
|
625
|
+
|
|
626
|
+
Run the test suite:
|
|
627
|
+
|
|
628
|
+
```bash
|
|
629
|
+
npm test
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
Run with coverage:
|
|
633
|
+
|
|
634
|
+
```bash
|
|
635
|
+
npm run test:coverage
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
Run specific test files:
|
|
639
|
+
|
|
640
|
+
```bash
|
|
641
|
+
npm test -- __tests__/crypto/sha256.test.js
|
|
642
|
+
npm test -- __tests__/integration/handshake.test.js
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
## Project Structure
|
|
646
|
+
|
|
647
|
+
```
|
|
648
|
+
react-native-ble-mesh/
|
|
649
|
+
├── src/
|
|
650
|
+
│ ├── index.js # Main exports
|
|
651
|
+
│ ├── constants/ # Protocol, BLE, crypto constants
|
|
652
|
+
│ ├── errors/ # Custom error classes
|
|
653
|
+
│ ├── crypto/ # Cryptographic implementations
|
|
654
|
+
│ │ ├── noise/ # Noise Protocol (handshake, session)
|
|
655
|
+
│ │ └── keys/ # Key management
|
|
656
|
+
│ ├── protocol/ # Message serialization/deserialization
|
|
657
|
+
│ ├── mesh/ # Mesh networking logic
|
|
658
|
+
│ │ ├── router/ # Message routing
|
|
659
|
+
│ │ ├── dedup/ # Duplicate detection
|
|
660
|
+
│ │ ├── fragment/ # Message fragmentation
|
|
661
|
+
│ │ └── peer/ # Peer management
|
|
662
|
+
│ ├── transport/ # BLE transport layer
|
|
663
|
+
│ ├── storage/ # Persistence adapters
|
|
664
|
+
│ ├── utils/ # Utility functions
|
|
665
|
+
│ └── service/ # High-level service orchestration
|
|
666
|
+
├── __tests__/ # Test files
|
|
667
|
+
├── docs/ # Documentation
|
|
668
|
+
├── examples/ # Example applications
|
|
669
|
+
└── package.json
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
## Contributing
|
|
673
|
+
|
|
674
|
+
1. Fork the repository
|
|
675
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
676
|
+
3. Run tests and linting (`npm run validate`)
|
|
677
|
+
4. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
678
|
+
5. Push to the branch (`git push origin feature/amazing-feature`)
|
|
679
|
+
6. Open a Pull Request
|
|
680
|
+
|
|
681
|
+
### Code Style
|
|
682
|
+
|
|
683
|
+
- Maximum 200 lines per file
|
|
684
|
+
- JSDoc comments on all public APIs
|
|
685
|
+
- ESLint with strict rules
|
|
686
|
+
- 100% test coverage on crypto modules
|
|
687
|
+
- >80% coverage on other modules
|
|
688
|
+
|
|
689
|
+
## Documentation
|
|
690
|
+
|
|
691
|
+
- [API Reference](docs/API.md) - Complete API documentation
|
|
692
|
+
- [Architecture](docs/ARCHITECTURE.md) - System design and module structure
|
|
693
|
+
- [Security](docs/SECURITY.md) - Threat model and security properties
|
|
694
|
+
- [Protocol](docs/PROTOCOL.md) - Wire format and message types
|
|
695
|
+
|
|
696
|
+
## License
|
|
697
|
+
|
|
698
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
699
|
+
|
|
700
|
+
## Acknowledgments
|
|
701
|
+
|
|
702
|
+
This project is inspired by [bitchat](https://github.com/permissionlesstech/bitchat).
|
|
703
|
+
|
|
704
|
+
- [Noise Protocol Framework](https://noiseprotocol.org/) - Cryptographic handshake pattern
|
|
705
|
+
- [react-native-ble-plx](https://github.com/Polidea/react-native-ble-plx) - React Native BLE library
|
|
706
|
+
- [Noble](https://github.com/abandonware/noble) - Node.js BLE library
|