Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tcp socket implementation #416

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 55 additions & 11 deletions example/lib/src/register.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sip_ua/sip_ua.dart';
import 'package:flutter/foundation.dart' show kIsWeb;

class RegisterWidget extends StatefulWidget {
final SIPUAHelper? _helper;
Expand All @@ -14,6 +15,7 @@ class RegisterWidget extends StatefulWidget {
class _MyRegisterWidget extends State<RegisterWidget>
implements SipUaHelperListener {
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _portController = TextEditingController();
final TextEditingController _wsUriController = TextEditingController();
final TextEditingController _sipUriController = TextEditingController();
final TextEditingController _displayNameController = TextEditingController();
Expand All @@ -26,6 +28,8 @@ class _MyRegisterWidget extends State<RegisterWidget>
late SharedPreferences _preferences;
late RegistrationState _registerState;

TransportType _selectedTransport = TransportType.TCP;

SIPUAHelper? get helper => widget._helper;

@override
Expand All @@ -34,6 +38,9 @@ class _MyRegisterWidget extends State<RegisterWidget>
_registerState = helper!.registerState;
helper!.addSipUaHelperListener(this);
_loadSettings();
if (kIsWeb) {
_selectedTransport = TransportType.WS;
}
}

@override
Expand All @@ -56,6 +63,7 @@ class _MyRegisterWidget extends State<RegisterWidget>
void _loadSettings() async {
_preferences = await SharedPreferences.getInstance();
setState(() {
_portController.text = '5060';
_wsUriController.text =
_preferences.getString('ws_uri') ?? 'wss://tryit.jssip.net:10443';
_sipUriController.text =
Expand All @@ -69,6 +77,7 @@ class _MyRegisterWidget extends State<RegisterWidget>
}

void _saveSettings() {
_preferences.setString('port', _portController.text);
_preferences.setString('ws_uri', _wsUriController.text);
_preferences.setString('sip_uri', _sipUriController.text);
_preferences.setString('display_name', _displayNameController.text);
Expand Down Expand Up @@ -113,12 +122,15 @@ class _MyRegisterWidget extends State<RegisterWidget>

UaSettings settings = UaSettings();

settings.webSocketUrl = _wsUriController.text;
settings.port = _portController.text;
settings.webSocketSettings.extraHeaders = _wsExtraHeaders;
settings.webSocketSettings.allowBadCertificate = true;
//settings.webSocketSettings.userAgent = 'Dart/2.8 (dart:io) for OpenSIPS.';

settings.tcpSocketSettings.allowBadCertificate = true;
settings.transportType = _selectedTransport;
settings.uri = _sipUriController.text;
settings.webSocketUrl = _wsUriController.text;
settings.host = _sipUriController.text.split('@')[1];
settings.authorizationUser = _authorizationUserController.text;
settings.password = _passwordController.text;
settings.displayName = _displayNameController.text;
Expand All @@ -143,14 +155,24 @@ class _MyRegisterWidget extends State<RegisterWidget>
style: TextStyle(fontSize: 18, color: Colors.black54),
),
),
SizedBox(height: 40),
Text('WebSocket:'),
TextFormField(
controller: _wsUriController,
keyboardType: TextInputType.text,
autocorrect: false,
textAlign: TextAlign.center,
),
SizedBox(height: 20),
if (_selectedTransport == TransportType.WS) ...[
Text('WebSocket:'),
TextFormField(
controller: _wsUriController,
keyboardType: TextInputType.text,
autocorrect: false,
textAlign: TextAlign.center,
),
],
if (_selectedTransport == TransportType.TCP) ...[
Text('Port:'),
TextFormField(
controller: _portController,
keyboardType: TextInputType.text,
textAlign: TextAlign.center,
),
],
SizedBox(height: 20),
Text('SIP URI:'),
TextFormField(
Expand Down Expand Up @@ -192,7 +214,29 @@ class _MyRegisterWidget extends State<RegisterWidget>
hintText: _displayNameController.text.isEmpty ? '[Empty]' : null,
),
),
const SizedBox(height: 40),
const SizedBox(height: 20),
if (!kIsWeb) ...[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RadioMenuButton<TransportType>(
value: TransportType.TCP,
groupValue: _selectedTransport,
onChanged: ((value) => setState(() {
_selectedTransport = value!;
})),
child: Text("TCP")),
RadioMenuButton<TransportType>(
value: TransportType.WS,
groupValue: _selectedTransport,
onChanged: ((value) => setState(() {
_selectedTransport = value!;
})),
child: Text("WS")),
],
),
],
const SizedBox(height: 20),
ElevatedButton(
child: Text('Register'),
onPressed: () => _handleSave(context),
Expand Down
1 change: 1 addition & 0 deletions lib/sip_ua.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// only expose the bare minimum of internals required
export 'src/enum_helper.dart';
export 'src/sip_ua_helper.dart';
export 'src/transport_type.dart';
23 changes: 17 additions & 6 deletions lib/src/config.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'package:sip_ua/sip_ua.dart';
import 'package:sip_ua/src/transports/socket_interface.dart';
import 'package:sip_ua/src/transports/tcp_socket.dart';
import 'constants.dart' as DartSIP_C;
import 'constants.dart';
import 'exceptions.dart' as Exceptions;
import 'grammar.dart';
import 'logger.dart';
import 'socket.dart' as Socket;
import 'transports/websocket_interface.dart';
import 'transports/web_socket.dart';
import 'uri.dart';
import 'utils.dart' as Utils;

Expand Down Expand Up @@ -43,8 +44,10 @@ class Settings {
// Dtmf mode
DtmfMode dtmf_mode = DtmfMode.INFO;

TransportType? transportType;

// Connection options.
List<WebSocketInterface>? sockets = <WebSocketInterface>[];
List<SIPUASocketInterface>? sockets = <SIPUASocketInterface>[];
int connection_recovery_max_interval = 30;
int connection_recovery_min_interval = 2;

Expand All @@ -71,16 +74,17 @@ class Checks {
Map<String, Null Function(Settings src, Settings? dst)> mandatory =
<String, Null Function(Settings src, Settings? dst)>{
'sockets': (Settings src, Settings? dst) {
List<WebSocketInterface>? sockets = src.sockets;
List<SIPUASocketInterface>? sockets = src.sockets;

/* Allow defining sockets parameter as:
* Socket: socket
* List of Socket: [socket1, socket2]
* List of Objects: [{socket: socket1, weight:1}, {socket: Socket2, weight:0}]
* List of Objects and Socket: [{socket: socket1}, socket2]
*/
List<WebSocketInterface> copy = <WebSocketInterface>[];
List<SIPUASocketInterface> copy = <SIPUASocketInterface>[];
if (sockets is List && sockets!.length > 0) {
for (WebSocketInterface socket in sockets) {
for (SIPUASocketInterface socket in sockets) {
copy.add(socket);
}
} else {
Expand All @@ -105,6 +109,13 @@ class Checks {
} else {
dst!.uri = parsed;
}
},
'transport_type': (Settings src, Settings? dst) {
dynamic transportType = src.transportType;
if (src.transportType == null && dst!.transportType == null) {
throw Exceptions.ConfigurationError('transport type', null);
}
dst!.transportType = transportType;
}
};
Map<String, Null Function(Settings src, Settings? dst)> optional =
Expand Down
4 changes: 2 additions & 2 deletions lib/src/event_manager/event_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class EventManager {
targets.remove(listener);
targets.add(listener);
} catch (e, s) {
logger.e(e.toString(), error: e, stackTrace: s);
logger.e(e.toString(), e, s);
}
}

Expand Down Expand Up @@ -108,7 +108,7 @@ class EventManager {
// logger.w("invoking $event on $target");
target(event);
} catch (e, s) {
logger.e(e.toString(), error: e, stackTrace: s);
logger.e(e.toString(), e, s);
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions lib/src/event_manager/transport_events.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import '../transports/websocket_interface.dart';
import 'package:sip_ua/src/transports/socket_interface.dart';
import '../transports/web_socket.dart';
import 'events.dart';

class EventSocketConnected extends EventType {
EventSocketConnected({this.socket});
WebSocketInterface? socket;
SIPUASocketInterface? socket;
}

class EventSocketConnecting extends EventType {
EventSocketConnecting({this.socket});
WebSocketInterface? socket;
SIPUASocketInterface? socket;
}

class EventSocketDisconnected extends EventType {
EventSocketDisconnected({WebSocketInterface? socket, this.cause});
WebSocketInterface? socket;
EventSocketDisconnected({SIPUASocketInterface? socket, this.cause});
SIPUASocketInterface? socket;
ErrorCause? cause;
}
2 changes: 1 addition & 1 deletion lib/src/logger.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class AnsiColor {

String call(String msg) {
if (color) {
return '$this$msg$ansiDefault';
return '$msg$ansiDefault';
} else {
return msg;
}
Expand Down
8 changes: 4 additions & 4 deletions lib/src/registrator.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:sip_ua/src/socket_transport.dart';
import 'constants.dart' as DartSIP_C;
import 'constants.dart';
import 'event_manager/event_manager.dart';
Expand All @@ -10,7 +11,6 @@ import 'name_addr_header.dart';
import 'request_sender.dart';
import 'sip_message.dart';
import 'timers.dart';
import 'transport.dart';
import 'ua.dart';
import 'uri.dart';
import 'utils.dart' as utils;
Expand All @@ -24,7 +24,7 @@ class UnHandledResponse {
}

class Registrator {
Registrator(UA ua, [Transport? transport]) {
Registrator(UA ua, [SocketTransport? transport]) {
int reg_id = 1; // Force reg_id to 1.

_ua = ua;
Expand Down Expand Up @@ -71,7 +71,7 @@ class Registrator {
}

late UA _ua;
Transport? _transport;
SocketTransport? _transport;
late URI _registrar;
int? _expires;
String? _call_id;
Expand All @@ -86,7 +86,7 @@ class Registrator {

bool get registered => _registered;

Transport? get transport => _transport;
SocketTransport? get transport => _transport;

void setExtraHeaders(List<String>? extraHeaders) {
_extraHeaders = extraHeaders ?? <String>[];
Expand Down
10 changes: 5 additions & 5 deletions lib/src/request_sender.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ class RequestSender {

switch (_method) {
case SipMethod.INVITE:
clientTransaction =
InviteClientTransaction(_ua, _ua.transport!, _request!, handlers);
clientTransaction = InviteClientTransaction(
_ua, _ua.socketTransport!, _request!, handlers);
break;
case SipMethod.ACK:
clientTransaction =
AckClientTransaction(_ua, _ua.transport!, _request!, handlers);
clientTransaction = AckClientTransaction(
_ua, _ua.socketTransport!, _request!, handlers);
break;
default:
clientTransaction = NonInviteClientTransaction(
_ua, _ua.transport!, _request!, handlers);
_ua, _ua.socketTransport!, _request!, handlers);
}

clientTransaction?.send();
Expand Down
43 changes: 22 additions & 21 deletions lib/src/rtc_session.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'dart:async';

import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:sdp_transform/sdp_transform.dart' as sdp_transform;

import 'package:sdp_transform/sdp_transform.dart';
import 'package:sip_ua/sip_ua.dart';
import 'constants.dart' as DartSIP_C;
import 'constants.dart';
Expand Down Expand Up @@ -692,8 +693,7 @@ class RTCSession extends EventManager implements Owner {
if (_status == C.STATUS_TERMINATED) {
return;
}
logger.e('Failed to answer(): ${error.toString()}',
error: error, stackTrace: s);
logger.e('Failed to answer(): ${error.toString()}', error, s);
}
}

Expand Down Expand Up @@ -1951,27 +1951,28 @@ class RTCSession extends EventManager implements Owner {
}

Future<RTCSessionDescription> _processInDialogSdpOffer(
dynamic request) async {
IncomingRequest request) async {
logger.d('_processInDialogSdpOffer()');

Map<String, dynamic> sdp = request.parseSDP();
Map<String, dynamic>? sdp = request.parseSDP();

bool hold = false;
if (sdp != null) {
for (Map<String, dynamic> m in sdp['media']) {
if (holdMediaTypes.indexOf(m['type']) == -1) {
continue;
}

for (Map<String, dynamic> m in sdp['media']) {
if (holdMediaTypes.indexOf(m['type']) == -1) {
continue;
}

String direction = m['direction'] ?? sdp['direction'] ?? 'sendrecv';
String direction = m['direction'] ?? sdp['direction'] ?? 'sendrecv';

if (direction == 'sendonly' || direction == 'inactive') {
hold = true;
}
// If at least one of the streams is active don't emit 'hold'.
else {
hold = false;
break;
if (direction == 'sendonly' || direction == 'inactive') {
hold = true;
}
// If at least one of the streams is active don't emit 'hold'.
else {
hold = false;
break;
}
}
}

Expand Down Expand Up @@ -2294,7 +2295,7 @@ class RTCSession extends EventManager implements Owner {

request_sender.send();
} catch (error, s) {
logger.e(error.toString(), error: error, stackTrace: s);
logger.e(error.toString(), error, s);
_failed('local', null, null, null, 500, DartSIP_C.CausesType.WEBRTC_ERROR,
'Can\'t create local SDP');
if (_status == C.STATUS_TERMINATED) {
Expand Down Expand Up @@ -2560,7 +2561,7 @@ class RTCSession extends EventManager implements Owner {
'eventHandlers': handlers
});
} catch (e, s) {
logger.e(e.toString(), error: e, stackTrace: s);
logger.e(e.toString(), e, s);
onFailed();
}
}
Expand Down
Loading
Loading