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
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Safe timeout management with automatic cleanup
|
|
5
|
+
* @module utils/TimeoutManager
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Manages timeouts with automatic cleanup to prevent memory leaks.
|
|
10
|
+
* Essential for React Native where component unmounts don't clear timers.
|
|
11
|
+
*
|
|
12
|
+
* @class TimeoutManager
|
|
13
|
+
* @example
|
|
14
|
+
* const timeouts = new TimeoutManager();
|
|
15
|
+
* timeouts.set('retry', () => retryOperation(), 5000);
|
|
16
|
+
* // Later, or on cleanup:
|
|
17
|
+
* timeouts.clear('retry');
|
|
18
|
+
* // Or clear all:
|
|
19
|
+
* timeouts.clearAll();
|
|
20
|
+
*/
|
|
21
|
+
class TimeoutManager {
|
|
22
|
+
constructor() {
|
|
23
|
+
/** @private */
|
|
24
|
+
this._timeouts = new Map();
|
|
25
|
+
/** @private */
|
|
26
|
+
this._intervals = new Map();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Set a timeout (clears existing timeout with same key)
|
|
31
|
+
* @param {string} key - Unique identifier for this timeout
|
|
32
|
+
* @param {Function} callback - Function to call when timeout fires
|
|
33
|
+
* @param {number} delay - Delay in milliseconds
|
|
34
|
+
* @returns {TimeoutManager} This instance for chaining
|
|
35
|
+
*/
|
|
36
|
+
set(key, callback, delay) {
|
|
37
|
+
this.clear(key);
|
|
38
|
+
const id = setTimeout(() => {
|
|
39
|
+
this._timeouts.delete(key);
|
|
40
|
+
callback();
|
|
41
|
+
}, delay);
|
|
42
|
+
this._timeouts.set(key, id);
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Set an interval (clears existing interval with same key)
|
|
48
|
+
* @param {string} key - Unique identifier for this interval
|
|
49
|
+
* @param {Function} callback - Function to call on each interval
|
|
50
|
+
* @param {number} interval - Interval in milliseconds
|
|
51
|
+
* @returns {TimeoutManager} This instance for chaining
|
|
52
|
+
*/
|
|
53
|
+
setInterval(key, callback, interval) {
|
|
54
|
+
this.clearInterval(key);
|
|
55
|
+
const id = setInterval(callback, interval);
|
|
56
|
+
this._intervals.set(key, id);
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Clear a timeout by key
|
|
62
|
+
* @param {string} key - The timeout key to clear
|
|
63
|
+
* @returns {boolean} True if timeout was cleared
|
|
64
|
+
*/
|
|
65
|
+
clear(key) {
|
|
66
|
+
if (this._timeouts.has(key)) {
|
|
67
|
+
clearTimeout(this._timeouts.get(key));
|
|
68
|
+
this._timeouts.delete(key);
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Clear an interval by key
|
|
76
|
+
* @param {string} key - The interval key to clear
|
|
77
|
+
* @returns {boolean} True if interval was cleared
|
|
78
|
+
*/
|
|
79
|
+
clearInterval(key) {
|
|
80
|
+
if (this._intervals.has(key)) {
|
|
81
|
+
clearInterval(this._intervals.get(key));
|
|
82
|
+
this._intervals.delete(key);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if a timeout exists
|
|
90
|
+
* @param {string} key - The timeout key
|
|
91
|
+
* @returns {boolean} True if timeout exists
|
|
92
|
+
*/
|
|
93
|
+
has(key) {
|
|
94
|
+
return this._timeouts.has(key);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Check if an interval exists
|
|
99
|
+
* @param {string} key - The interval key
|
|
100
|
+
* @returns {boolean} True if interval exists
|
|
101
|
+
*/
|
|
102
|
+
hasInterval(key) {
|
|
103
|
+
return this._intervals.has(key);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Clear all timeouts
|
|
108
|
+
* @returns {number} Number of timeouts cleared
|
|
109
|
+
*/
|
|
110
|
+
clearAllTimeouts() {
|
|
111
|
+
const count = this._timeouts.size;
|
|
112
|
+
for (const id of this._timeouts.values()) {
|
|
113
|
+
clearTimeout(id);
|
|
114
|
+
}
|
|
115
|
+
this._timeouts.clear();
|
|
116
|
+
return count;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Clear all intervals
|
|
121
|
+
* @returns {number} Number of intervals cleared
|
|
122
|
+
*/
|
|
123
|
+
clearAllIntervals() {
|
|
124
|
+
const count = this._intervals.size;
|
|
125
|
+
for (const id of this._intervals.values()) {
|
|
126
|
+
clearInterval(id);
|
|
127
|
+
}
|
|
128
|
+
this._intervals.clear();
|
|
129
|
+
return count;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Clear all timeouts and intervals
|
|
134
|
+
* @returns {number} Total number cleared
|
|
135
|
+
*/
|
|
136
|
+
clearAll() {
|
|
137
|
+
return this.clearAllTimeouts() + this.clearAllIntervals();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get count of active timeouts
|
|
142
|
+
* @returns {number} Number of active timeouts
|
|
143
|
+
*/
|
|
144
|
+
get timeoutCount() {
|
|
145
|
+
return this._timeouts.size;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get count of active intervals
|
|
150
|
+
* @returns {number} Number of active intervals
|
|
151
|
+
*/
|
|
152
|
+
get intervalCount() {
|
|
153
|
+
return this._intervals.size;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Destroy the manager (clears all timers)
|
|
158
|
+
*/
|
|
159
|
+
destroy() {
|
|
160
|
+
this.clearAll();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = TimeoutManager;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Optimized Base64 encoding/decoding for React Native
|
|
5
|
+
* @module utils/base64
|
|
6
|
+
*
|
|
7
|
+
* This implementation avoids string concatenation in loops which is O(n²).
|
|
8
|
+
* Uses array building which is O(n) - critical for React Native performance.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Base64 character lookup table
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Reverse lookup table for decoding
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
const BASE64_LOOKUP = new Uint8Array(256);
|
|
22
|
+
for (let i = 0; i < BASE64_CHARS.length; i++) {
|
|
23
|
+
BASE64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Encode Uint8Array to Base64 string (optimized for React Native)
|
|
28
|
+
*
|
|
29
|
+
* Uses array building instead of string concatenation to avoid O(n²) performance.
|
|
30
|
+
*
|
|
31
|
+
* @param {Uint8Array} bytes - The bytes to encode
|
|
32
|
+
* @returns {string} Base64 encoded string
|
|
33
|
+
* @throws {TypeError} If input is not a Uint8Array
|
|
34
|
+
* @example
|
|
35
|
+
* const encoded = encode(new Uint8Array([72, 101, 108, 108, 111]));
|
|
36
|
+
* console.log(encoded); // "SGVsbG8="
|
|
37
|
+
*/
|
|
38
|
+
function encode(bytes) {
|
|
39
|
+
if (!(bytes instanceof Uint8Array)) {
|
|
40
|
+
throw new TypeError('Input must be a Uint8Array');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const len = bytes.length;
|
|
44
|
+
const resultLen = Math.ceil(len / 3) * 4;
|
|
45
|
+
const result = new Array(resultLen);
|
|
46
|
+
|
|
47
|
+
let i = 0;
|
|
48
|
+
let j = 0;
|
|
49
|
+
|
|
50
|
+
// Process 3 bytes at a time
|
|
51
|
+
while (i < len - 2) {
|
|
52
|
+
const b1 = bytes[i++];
|
|
53
|
+
const b2 = bytes[i++];
|
|
54
|
+
const b3 = bytes[i++];
|
|
55
|
+
|
|
56
|
+
result[j++] = BASE64_CHARS[b1 >> 2];
|
|
57
|
+
result[j++] = BASE64_CHARS[((b1 & 0x03) << 4) | (b2 >> 4)];
|
|
58
|
+
result[j++] = BASE64_CHARS[((b2 & 0x0f) << 2) | (b3 >> 6)];
|
|
59
|
+
result[j++] = BASE64_CHARS[b3 & 0x3f];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Handle remaining bytes
|
|
63
|
+
const remaining = len - i;
|
|
64
|
+
if (remaining === 1) {
|
|
65
|
+
const b1 = bytes[i];
|
|
66
|
+
result[j++] = BASE64_CHARS[b1 >> 2];
|
|
67
|
+
result[j++] = BASE64_CHARS[(b1 & 0x03) << 4];
|
|
68
|
+
result[j++] = '=';
|
|
69
|
+
result[j++] = '=';
|
|
70
|
+
} else if (remaining === 2) {
|
|
71
|
+
const b1 = bytes[i];
|
|
72
|
+
const b2 = bytes[i + 1];
|
|
73
|
+
result[j++] = BASE64_CHARS[b1 >> 2];
|
|
74
|
+
result[j++] = BASE64_CHARS[((b1 & 0x03) << 4) | (b2 >> 4)];
|
|
75
|
+
result[j++] = BASE64_CHARS[(b2 & 0x0f) << 2];
|
|
76
|
+
result[j++] = '=';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return result.join('');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Decode Base64 string to Uint8Array (optimized for React Native)
|
|
84
|
+
*
|
|
85
|
+
* @param {string} base64 - The Base64 string to decode
|
|
86
|
+
* @returns {Uint8Array} Decoded bytes
|
|
87
|
+
* @throws {TypeError} If input is not a string
|
|
88
|
+
* @throws {Error} If input contains invalid Base64 characters
|
|
89
|
+
* @example
|
|
90
|
+
* const decoded = decode("SGVsbG8=");
|
|
91
|
+
* console.log(decoded); // Uint8Array([72, 101, 108, 108, 111])
|
|
92
|
+
*/
|
|
93
|
+
function decode(base64) {
|
|
94
|
+
if (typeof base64 !== 'string') {
|
|
95
|
+
throw new TypeError('Input must be a string');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Remove padding and calculate output length
|
|
99
|
+
const len = base64.length;
|
|
100
|
+
let padding = 0;
|
|
101
|
+
|
|
102
|
+
if (len > 0 && base64[len - 1] === '=') {
|
|
103
|
+
padding++;
|
|
104
|
+
if (len > 1 && base64[len - 2] === '=') {
|
|
105
|
+
padding++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const outputLen = (len * 3 / 4) - padding;
|
|
110
|
+
const result = new Uint8Array(outputLen);
|
|
111
|
+
|
|
112
|
+
let i = 0;
|
|
113
|
+
let j = 0;
|
|
114
|
+
|
|
115
|
+
// Process 4 characters at a time
|
|
116
|
+
while (i < len) {
|
|
117
|
+
const c1 = BASE64_LOOKUP[base64.charCodeAt(i++)];
|
|
118
|
+
const c2 = BASE64_LOOKUP[base64.charCodeAt(i++)];
|
|
119
|
+
const c3 = BASE64_LOOKUP[base64.charCodeAt(i++)];
|
|
120
|
+
const c4 = BASE64_LOOKUP[base64.charCodeAt(i++)];
|
|
121
|
+
|
|
122
|
+
result[j++] = (c1 << 2) | (c2 >> 4);
|
|
123
|
+
if (j < outputLen) {
|
|
124
|
+
result[j++] = ((c2 & 0x0f) << 4) | (c3 >> 2);
|
|
125
|
+
}
|
|
126
|
+
if (j < outputLen) {
|
|
127
|
+
result[j++] = ((c3 & 0x03) << 6) | c4;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Check if a string is valid Base64
|
|
136
|
+
* @param {string} str - String to check
|
|
137
|
+
* @returns {boolean} True if valid Base64
|
|
138
|
+
*/
|
|
139
|
+
function isValid(str) {
|
|
140
|
+
if (typeof str !== 'string') {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
// Base64 regex: only valid chars, proper length, proper padding
|
|
144
|
+
return /^[A-Za-z0-9+/]*={0,2}$/.test(str) && str.length % 4 === 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module.exports = {
|
|
148
|
+
encode,
|
|
149
|
+
decode,
|
|
150
|
+
isValid
|
|
151
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Byte manipulation utilities
|
|
5
|
+
* @module utils/bytes
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Concatenates multiple Uint8Arrays into a single array
|
|
10
|
+
* @param {...Uint8Array} arrays - Arrays to concatenate
|
|
11
|
+
* @returns {Uint8Array} Concatenated array
|
|
12
|
+
*/
|
|
13
|
+
function concat(...arrays) {
|
|
14
|
+
// Filter out undefined/null and calculate total length
|
|
15
|
+
const validArrays = arrays.filter(arr => arr !== null && arr !== undefined);
|
|
16
|
+
const totalLength = validArrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
17
|
+
|
|
18
|
+
const result = new Uint8Array(totalLength);
|
|
19
|
+
let offset = 0;
|
|
20
|
+
|
|
21
|
+
for (const arr of validArrays) {
|
|
22
|
+
result.set(arr, offset);
|
|
23
|
+
offset += arr.length;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Compares two byte arrays in constant time to prevent timing attacks
|
|
31
|
+
* @param {Uint8Array} a - First array
|
|
32
|
+
* @param {Uint8Array} b - Second array
|
|
33
|
+
* @returns {boolean} True if arrays are equal
|
|
34
|
+
*/
|
|
35
|
+
function constantTimeEqual(a, b) {
|
|
36
|
+
if (!(a instanceof Uint8Array) || !(b instanceof Uint8Array)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (a.length !== b.length) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let result = 0;
|
|
45
|
+
for (let i = 0; i < a.length; i++) {
|
|
46
|
+
result |= a[i] ^ b[i];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return result === 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Generates cryptographically secure random bytes
|
|
54
|
+
* @param {number} length - Number of bytes to generate
|
|
55
|
+
* @returns {Uint8Array} Random bytes
|
|
56
|
+
* @throws {Error} If crypto is not available
|
|
57
|
+
*/
|
|
58
|
+
function randomBytes(length) {
|
|
59
|
+
if (length < 0 || !Number.isInteger(length)) {
|
|
60
|
+
throw new Error('Length must be a non-negative integer');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (length === 0) {
|
|
64
|
+
return new Uint8Array(0);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const bytes = new Uint8Array(length);
|
|
68
|
+
|
|
69
|
+
// Try Web Crypto API (browser and modern Node.js)
|
|
70
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
71
|
+
crypto.getRandomValues(bytes);
|
|
72
|
+
return bytes;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Try globalThis.crypto (Node.js 19+, browsers)
|
|
76
|
+
if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues) {
|
|
77
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
78
|
+
return bytes;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Try Node.js crypto module
|
|
82
|
+
try {
|
|
83
|
+
const nodeCrypto = require('crypto');
|
|
84
|
+
const nodeBytes = nodeCrypto.randomBytes(length);
|
|
85
|
+
bytes.set(nodeBytes);
|
|
86
|
+
return bytes;
|
|
87
|
+
} catch (e) {
|
|
88
|
+
// Ignore and throw error below
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
throw new Error('No secure random number generator available');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* XORs two byte arrays together
|
|
96
|
+
* @param {Uint8Array} a - First array
|
|
97
|
+
* @param {Uint8Array} b - Second array
|
|
98
|
+
* @returns {Uint8Array} XOR result (length matches shorter array)
|
|
99
|
+
*/
|
|
100
|
+
function xor(a, b) {
|
|
101
|
+
const length = Math.min(a.length, b.length);
|
|
102
|
+
const result = new Uint8Array(length);
|
|
103
|
+
|
|
104
|
+
for (let i = 0; i < length; i++) {
|
|
105
|
+
result[i] = a[i] ^ b[i];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Fills a byte array with a specific value
|
|
113
|
+
* @param {Uint8Array} array - Array to fill
|
|
114
|
+
* @param {number} value - Value to fill with (0-255)
|
|
115
|
+
* @returns {Uint8Array} The filled array (same reference)
|
|
116
|
+
*/
|
|
117
|
+
function fill(array, value) {
|
|
118
|
+
const byte = value & 0xff;
|
|
119
|
+
for (let i = 0; i < array.length; i++) {
|
|
120
|
+
array[i] = byte;
|
|
121
|
+
}
|
|
122
|
+
return array;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Creates a copy of a byte array
|
|
127
|
+
* @param {Uint8Array} array - Array to copy
|
|
128
|
+
* @returns {Uint8Array} Copy of the array
|
|
129
|
+
*/
|
|
130
|
+
function copy(array) {
|
|
131
|
+
const result = new Uint8Array(array.length);
|
|
132
|
+
result.set(array);
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Securely wipes a byte array by overwriting with zeros
|
|
138
|
+
* @param {Uint8Array} array - Array to wipe
|
|
139
|
+
*/
|
|
140
|
+
function secureWipe(array) {
|
|
141
|
+
fill(array, 0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Checks if two byte arrays are equal (non-constant-time)
|
|
146
|
+
* Use constantTimeEqual for security-sensitive comparisons
|
|
147
|
+
* @param {Uint8Array} a - First array
|
|
148
|
+
* @param {Uint8Array} b - Second array
|
|
149
|
+
* @returns {boolean} True if arrays are equal
|
|
150
|
+
*/
|
|
151
|
+
function equals(a, b) {
|
|
152
|
+
if (a.length !== b.length) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < a.length; i++) {
|
|
157
|
+
if (a[i] !== b[i]) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Creates a view into a byte array without copying
|
|
167
|
+
* @param {Uint8Array} array - Source array
|
|
168
|
+
* @param {number} start - Start offset
|
|
169
|
+
* @param {number} [length] - Length of view (defaults to rest of array)
|
|
170
|
+
* @returns {Uint8Array} View into the array
|
|
171
|
+
*/
|
|
172
|
+
function slice(array, start, length) {
|
|
173
|
+
const end = length !== undefined ? start + length : array.length;
|
|
174
|
+
return array.subarray(start, end);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
module.exports = {
|
|
178
|
+
concat,
|
|
179
|
+
constantTimeEqual,
|
|
180
|
+
randomBytes,
|
|
181
|
+
xor,
|
|
182
|
+
fill,
|
|
183
|
+
copy,
|
|
184
|
+
secureWipe,
|
|
185
|
+
equals,
|
|
186
|
+
slice
|
|
187
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Debug and logging utilities for BLE Mesh
|
|
5
|
+
*
|
|
6
|
+
* Enable debug output by setting:
|
|
7
|
+
* - Environment variable: DEBUG=ble-mesh:*
|
|
8
|
+
* - Or programmatically: debug.enable('ble-mesh:*')
|
|
9
|
+
*
|
|
10
|
+
* Namespaces:
|
|
11
|
+
* - ble-mesh:service - MeshService events
|
|
12
|
+
* - ble-mesh:transport - Transport layer
|
|
13
|
+
* - ble-mesh:crypto - Cryptographic operations
|
|
14
|
+
* - ble-mesh:handshake - Noise handshake
|
|
15
|
+
* - ble-mesh:mesh - Mesh routing
|
|
16
|
+
* - ble-mesh:* - All namespaces
|
|
17
|
+
*
|
|
18
|
+
* @module utils/debug
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// Check for debug environment variable
|
|
22
|
+
const DEBUG_ENV = typeof process !== 'undefined' && process.env && process.env.DEBUG;
|
|
23
|
+
|
|
24
|
+
// Active debug namespaces
|
|
25
|
+
const activeNamespaces = new Set();
|
|
26
|
+
|
|
27
|
+
// Parse debug patterns
|
|
28
|
+
function parseDebugPatterns(patterns) {
|
|
29
|
+
if (!patterns) { return; }
|
|
30
|
+
const parts = patterns.split(',').map(p => p.trim());
|
|
31
|
+
for (const part of parts) {
|
|
32
|
+
if (part.startsWith('-')) {
|
|
33
|
+
activeNamespaces.delete(part.slice(1));
|
|
34
|
+
} else {
|
|
35
|
+
activeNamespaces.add(part);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Initialize from environment
|
|
41
|
+
if (DEBUG_ENV) {
|
|
42
|
+
parseDebugPatterns(DEBUG_ENV);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Check if a namespace is enabled
|
|
47
|
+
* @param {string} namespace - Namespace to check
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
function isEnabled(namespace) {
|
|
51
|
+
if (activeNamespaces.has('*') || activeNamespaces.has('ble-mesh:*')) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
if (activeNamespaces.has(namespace)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
// Check wildcard patterns
|
|
58
|
+
for (const pattern of activeNamespaces) {
|
|
59
|
+
if (pattern.endsWith(':*')) {
|
|
60
|
+
const prefix = pattern.slice(0, -1);
|
|
61
|
+
if (namespace.startsWith(prefix)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Create a debug logger for a namespace
|
|
71
|
+
* @param {string} namespace - Debug namespace (e.g., 'ble-mesh:service')
|
|
72
|
+
* @returns {Function} Debug logger function
|
|
73
|
+
*/
|
|
74
|
+
function createDebugger(namespace) {
|
|
75
|
+
const logger = (...args) => {
|
|
76
|
+
if (!isEnabled(namespace)) { return; }
|
|
77
|
+
|
|
78
|
+
const timestamp = new Date().toISOString();
|
|
79
|
+
const prefix = `[${timestamp}] ${namespace}`;
|
|
80
|
+
|
|
81
|
+
// Format message
|
|
82
|
+
const message = args
|
|
83
|
+
.map(arg => {
|
|
84
|
+
if (arg instanceof Error) {
|
|
85
|
+
return `${arg.name}: ${arg.message}`;
|
|
86
|
+
}
|
|
87
|
+
if (typeof arg === 'object') {
|
|
88
|
+
try {
|
|
89
|
+
return JSON.stringify(arg, null, 2);
|
|
90
|
+
} catch {
|
|
91
|
+
return String(arg);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return String(arg);
|
|
95
|
+
})
|
|
96
|
+
.join(' ');
|
|
97
|
+
|
|
98
|
+
console.log(`${prefix} ${message}`);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
logger.namespace = namespace;
|
|
102
|
+
logger.enabled = () => isEnabled(namespace);
|
|
103
|
+
|
|
104
|
+
return logger;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Enable debug namespaces
|
|
109
|
+
* @param {string} patterns - Comma-separated namespace patterns
|
|
110
|
+
* @example
|
|
111
|
+
* debug.enable('ble-mesh:*')
|
|
112
|
+
* debug.enable('ble-mesh:service,ble-mesh:crypto')
|
|
113
|
+
*/
|
|
114
|
+
function enable(patterns) {
|
|
115
|
+
parseDebugPatterns(patterns);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Disable debug output
|
|
120
|
+
*/
|
|
121
|
+
function disable() {
|
|
122
|
+
activeNamespaces.clear();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Get list of enabled namespaces
|
|
127
|
+
* @returns {string[]}
|
|
128
|
+
*/
|
|
129
|
+
function getEnabled() {
|
|
130
|
+
return Array.from(activeNamespaces);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Pre-defined debuggers for common namespaces
|
|
134
|
+
const debuggers = {
|
|
135
|
+
service: createDebugger('ble-mesh:service'),
|
|
136
|
+
transport: createDebugger('ble-mesh:transport'),
|
|
137
|
+
crypto: createDebugger('ble-mesh:crypto'),
|
|
138
|
+
handshake: createDebugger('ble-mesh:handshake'),
|
|
139
|
+
mesh: createDebugger('ble-mesh:mesh'),
|
|
140
|
+
protocol: createDebugger('ble-mesh:protocol'),
|
|
141
|
+
storage: createDebugger('ble-mesh:storage')
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
module.exports = {
|
|
145
|
+
createDebugger,
|
|
146
|
+
enable,
|
|
147
|
+
disable,
|
|
148
|
+
isEnabled,
|
|
149
|
+
getEnabled,
|
|
150
|
+
...debuggers
|
|
151
|
+
};
|