diff --git a/lib/main.dart b/lib/main.dart index d34ffa3..386b70d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -61,7 +61,7 @@ Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { switch (message.socketMethod) { case SocketMethod.BYE: { - //make sure to disconnect the telnyxclient on Bye for Decline + // make sure to disconnect the telnyxclient on Bye for Decline // Only disconnect the socket when the call was ended from push notifications print("telnyxClient disconnected"); telnyxClient.disconnect(); diff --git a/packages/telnyx_webrtc/lib/model/push_notification.dart b/packages/telnyx_webrtc/lib/model/push_notification.dart index c7eaddc..bd1ad2f 100644 --- a/packages/telnyx_webrtc/lib/model/push_notification.dart +++ b/packages/telnyx_webrtc/lib/model/push_notification.dart @@ -9,7 +9,8 @@ class PushNotification { } class PushMetaData { - PushMetaData({this.caller_name, this.caller_number, this.call_id}); + PushMetaData( + {this.caller_name, this.caller_number, this.call_id, this.voice_sdk_id}); String? caller_name; String? caller_number; @@ -18,7 +19,6 @@ class PushMetaData { bool? isAnswer; bool? isDecline; - PushMetaData.fromJson(Map json) { caller_name = json['caller_name']; caller_number = json['caller_number']; diff --git a/packages/telnyx_webrtc/lib/model/verto/receive/received_message_body.dart b/packages/telnyx_webrtc/lib/model/verto/receive/received_message_body.dart index 71cec37..da89232 100644 --- a/packages/telnyx_webrtc/lib/model/verto/receive/received_message_body.dart +++ b/packages/telnyx_webrtc/lib/model/verto/receive/received_message_body.dart @@ -10,6 +10,7 @@ class ReceivedMessage { StateParams? stateParams; IncomingInviteParams? inviteParams; DialogParams? dialogParams; + String? voiceSdkId; ReceivedMessage( {this.jsonrpc, @@ -18,8 +19,8 @@ class ReceivedMessage { this.reattachedParams, this.stateParams, this.inviteParams, - this.dialogParams - }); + this.dialogParams, + this.voiceSdkId}); ReceivedMessage.fromJson(Map json) { jsonrpc = json['jsonrpc']; @@ -33,9 +34,14 @@ class ReceivedMessage { inviteParams = json['params'] != null ? IncomingInviteParams.fromJson(json['params']) : null; - if(json['params']['dialogParams'] != null){ + if (json['params']['dialogParams'] != null) { dialogParams = DialogParams.fromJson(json['params']['dialogParams']); } + + if (json['params']['voice_sdk_id'] != null) { + voiceSdkId = json['params']['voice_sdk_id']; + Logger().i('Voice SDK ID: $voiceSdkId'); + } } Map toJson() { @@ -71,16 +77,13 @@ class ReceivedResult { String? sessId; TelnyxSocketError? error; - ReceivedResult( - {this.jsonrpc, - this.id, - this.resultParams}); + ReceivedResult({this.jsonrpc, this.id, this.resultParams}); ReceivedResult.fromJson(Map json) { jsonrpc = json['jsonrpc']; id = json['id']; resultParams = - json['result'] != null ? ResultParams.fromJson(json['result']) : null; + json['result'] != null ? ResultParams.fromJson(json['result']) : null; sessId = json['sessid']; error = json['error'] != null ? TelnyxSocketError.fromJson(json['error']) @@ -104,7 +107,6 @@ class ReceivedResult { } } - class ReattachedParams { List? reattachedSessions; @@ -136,12 +138,11 @@ class ReattachedParams { class ResultParams { StateParams? stateParams; - ResultParams( - {this.stateParams}); + ResultParams({this.stateParams}); ResultParams.fromJson(Map json) { stateParams = - json['params'] != null ? StateParams.fromJson(json['params']) : null; + json['params'] != null ? StateParams.fromJson(json['params']) : null; } Map toJson() { @@ -152,6 +153,7 @@ class ResultParams { return data; } } + class StateParams { String? state; diff --git a/packages/telnyx_webrtc/lib/telnyx_client.dart b/packages/telnyx_webrtc/lib/telnyx_client.dart index f15b8eb..4e4f7e4 100644 --- a/packages/telnyx_webrtc/lib/telnyx_client.dart +++ b/packages/telnyx_webrtc/lib/telnyx_client.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:ffi'; import 'package:logger/logger.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:telnyx_webrtc/model/verto/send/attach_call_message.dart'; @@ -25,6 +24,7 @@ import 'model/call_state.dart'; import 'model/jsonrpc.dart'; import 'model/push_notification.dart'; import 'model/verto/send/pong_message_body.dart'; +import 'package:internet_connection_checker/internet_connection_checker.dart'; typedef OnSocketMessageReceived = void Function(TelnyxMessage message); typedef OnSocketErrorReceived = void Function(TelnyxSocketError message); @@ -87,6 +87,26 @@ class TelnyxClient { String ringtonePath = ""; String ringBackpath = ""; PushMetaData? _pushMetaData; + StreamSubscription? _connectionCheckerSubscription; + + final connectionChecker = InternetConnectionChecker(); + + void checkReconnection() { + final _connectionCheckerSubscription = + connectionChecker.onStatusChange.listen( + (InternetConnectionStatus status) { + if (status == InternetConnectionStatus.connected) { + if (activeCalls().isNotEmpty) { + _reconnectToSocket(); + } + } else { + // + } + }, + ); + + // Remember to cancel the subscription when it's no longer needed + } TelnyxClient() { // Default implementation of onSocketMessageReceived @@ -209,6 +229,7 @@ class TelnyxClient { void _connectWithCallBack( PushMetaData? pushMetaData, OnOpenCallback openCallback) { _logger.i('connect() ${pushMetaData?.toJson()}'); + _pushMetaData = pushMetaData; try { if (pushMetaData?.voice_sdk_id != null) { txSocket.hostAddress = @@ -220,6 +241,7 @@ class TelnyxClient { txSocket.hostAddress = _storedHostAddress; _logger.i('connecting to WebSocket $_storedHostAddress'); } + txSocket.connect(); txSocket.onOpen = () { @@ -228,6 +250,7 @@ class TelnyxClient { _logger.i('Web Socket is now connected'); _onOpen(); openCallback.call(); + _connectionCheckerSubscription?.cancel(); }; txSocket.onMessage = (dynamic data) { @@ -579,11 +602,7 @@ class TelnyxClient { } void updateCall(Call call) { - if (calls.containsKey(call.callId)) { - calls[call.callId!] = call; - } else { - calls[call.callId!] = call; - } + calls[call.callId!] = call; } /// Closes the socket connection, effectively logging the user out. @@ -611,6 +630,8 @@ class TelnyxClient { } /// Closes the socket connection, effectively logging the user out. + /// You must recconnect to the socket connection to continue using the SDK or may result in + /// Unhandled Exception: Bad state: StreamSink is closed void disconnect() { _invalidateGatewayResponseTimer(); _resetGatewayCounters(); @@ -831,6 +852,13 @@ class TelnyxClient { Call offerCall = _createCall(); offerCall.callId = invite.inviteParams?.callID; updateCall(offerCall); + + //set voice_sdk_id + _pushMetaData = PushMetaData( + caller_number: null, + caller_name: null, + voice_sdk_id: message.message.voiceSdkId); + onSocketMessageReceived.call(message); offerCall.callHandler diff --git a/packages/telnyx_webrtc/pubspec.yaml b/packages/telnyx_webrtc/pubspec.yaml index 8bde5b9..f2a1ffc 100644 --- a/packages/telnyx_webrtc/pubspec.yaml +++ b/packages/telnyx_webrtc/pubspec.yaml @@ -21,6 +21,7 @@ dependencies: audioplayers: ^5.2.1 assets_audio_player: ^3.1.1 shared_preferences: ^2.2.3 + internet_connection_checker: ^2.0.0 dev_dependencies: flutter_test: diff --git a/pubspec.yaml b/pubspec.yaml index 928b2b5..fc6d738 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: flutter_callkit_incoming: ^2.0.4+1 shared_preferences: ^2.2.3 permission_handler: ^11.3.1 + internet_connection_checker: ^2.0.0 dev_dependencies: