@@ -21,6 +21,7 @@ import 'package:flutter/foundation.dart' hide internal;
2121import 'package:collection/collection.dart' ;
2222import 'package:connectivity_plus/connectivity_plus.dart' ;
2323import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
24+ import 'package:livekit_client/livekit_client.dart' ;
2425import 'package:meta/meta.dart' ;
2526
2627import '../events.dart' ;
@@ -149,6 +150,8 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
149150
150151 List <lk_models.Codec >? get enabledPublishCodecs => _enabledPublishCodecs;
151152
153+ E2EEManager ? _e2eeManager;
154+
152155 void clearReconnectTimeout () {
153156 if (reconnectTimeout != null ) {
154157 reconnectTimeout? .cancel ();
@@ -313,6 +316,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
313316 completer.completeError ('Engine disconnected' );
314317 }
315318 }
319+
316320 events.once <EngineClosingEvent >((e) => onClosing ());
317321
318322 while (! _dcBufferStatus[kind]! ) {
@@ -333,8 +337,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
333337 bool ? reliability = true ,
334338 }) async {
335339 // construct the data channel message
336- final message =
337- rtc.RTCDataChannelMessage .fromBinary (packet.writeToBuffer ());
340+ var message = rtc.RTCDataChannelMessage .fromBinary (packet.writeToBuffer ());
338341
339342 final reliabilityType =
340343 reliability == true ? Reliability .reliable : Reliability .lossy;
@@ -364,6 +367,28 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
364367 'Data channel for ${packet .kind .toSDKType ()} is null' );
365368 }
366369
370+ if (_e2eeManager != null && _e2eeManager! .isDataChannelEncryptionEnabled) {
371+ final encryptablePacket = asEncryptablePacket (packet);
372+ if (encryptablePacket != null ) {
373+ final encryptedData = await _e2eeManager? .encryptData (
374+ data: encryptablePacket.writeToBuffer ());
375+
376+ if (encryptedData == null ) {
377+ logger.warning ('Failed to encrypt data packet' );
378+ return ;
379+ }
380+
381+ final packet = lk_models.EncryptedPacket (
382+ encryptionType: lk_models.Encryption_Type .GCM ,
383+ encryptedValue: encryptedData.data,
384+ iv: encryptedData.iv,
385+ keyIndex: encryptedData.keyIndex,
386+ );
387+
388+ message = rtc.RTCDataChannelMessage .fromBinary (packet.writeToBuffer ());
389+ }
390+ }
391+
367392 logger.fine ('sendDataPacket(label:${channel .label })' );
368393 await channel.send (message);
369394
@@ -390,6 +415,22 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
390415 }
391416 }
392417
418+ lk_models.EncryptedPacketPayload ? asEncryptablePacket (
419+ lk_models.DataPacket packet) {
420+ if ([
421+ lk_models.DataPacket_Value .sipDtmf,
422+ lk_models.DataPacket_Value .metrics,
423+ lk_models.DataPacket_Value .speaker,
424+ lk_models.DataPacket_Value .transcription,
425+ lk_models.DataPacket_Value .encryptedPacket
426+ ].contains (packet.whichValue ()) ==
427+ false ) {
428+ return lk_models.EncryptedPacketPayload .fromBuffer (
429+ packet.writeToBuffer ());
430+ }
431+ return null ;
432+ }
433+
393434 Future <RTCConfiguration > _buildRtcConfiguration (
394435 {required lk_models.ClientConfigSetting serverResponseForceRelay,
395436 required List <RTCIceServer > serverProvidedIceServers}) async {
@@ -636,7 +677,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
636677 }
637678 }
638679
639- void _onDCMessage (rtc.RTCDataChannelMessage message) {
680+ void _onDCMessage (rtc.RTCDataChannelMessage message) async {
640681 // always expect binary
641682 if (! message.isBinary) {
642683 logger.warning ('Data message is not binary' );
@@ -711,6 +752,28 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
711752 identity: dp.participantIdentity,
712753 ),
713754 );
755+ } else if (dp.whichValue () == lk_models.DataPacket_Value .encryptedPacket) {
756+ if (_e2eeManager != null ) {
757+ logger.warning ('Received encrypted packet but E2EE not set up' );
758+ return ;
759+ }
760+ final decryptedData = await _e2eeManager? .handleEncryptedData (
761+ data: Uint8List .fromList (dp.encryptedPacket.encryptedValue),
762+ iv: Uint8List .fromList (dp.encryptedPacket.iv),
763+ participantIdentity: dp.participantIdentity,
764+ keyIndex: dp.encryptedPacket.keyIndex,
765+ );
766+ if (decryptedData == null ) {
767+ logger.warning ('Failed to decrypt data packet' );
768+ return ;
769+ }
770+ final newDp = lk_models.DataPacket .fromBuffer (decryptedData);
771+ // User packet
772+ events.emit (EngineDataPacketReceivedEvent (
773+ packet: newDp.user,
774+ kind: newDp.kind,
775+ identity: newDp.participantIdentity,
776+ ));
714777 } else {
715778 logger.warning ('Unknown data packet type: ${dp .whichValue ()}' );
716779 }
0 commit comments