Skip to content

Commit 024d0e8

Browse files
mikaelwillsMikael Wills
and
Mikael Wills
authored
Tcp socket implementation (#416)
Co-authored-by: Mikael Wills <mikael.wills@ideaworks.co.uk>
1 parent ec66172 commit 024d0e8

32 files changed

+574
-218
lines changed

example/lib/src/register.dart

+55-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:shared_preferences/shared_preferences.dart';
33
import 'package:sip_ua/sip_ua.dart';
4+
import 'package:flutter/foundation.dart' show kIsWeb;
45

56
class RegisterWidget extends StatefulWidget {
67
final SIPUAHelper? _helper;
@@ -14,6 +15,7 @@ class RegisterWidget extends StatefulWidget {
1415
class _MyRegisterWidget extends State<RegisterWidget>
1516
implements SipUaHelperListener {
1617
final TextEditingController _passwordController = TextEditingController();
18+
final TextEditingController _portController = TextEditingController();
1719
final TextEditingController _wsUriController = TextEditingController();
1820
final TextEditingController _sipUriController = TextEditingController();
1921
final TextEditingController _displayNameController = TextEditingController();
@@ -26,6 +28,8 @@ class _MyRegisterWidget extends State<RegisterWidget>
2628
late SharedPreferences _preferences;
2729
late RegistrationState _registerState;
2830

31+
TransportType _selectedTransport = TransportType.TCP;
32+
2933
SIPUAHelper? get helper => widget._helper;
3034

3135
@override
@@ -34,6 +38,9 @@ class _MyRegisterWidget extends State<RegisterWidget>
3438
_registerState = helper!.registerState;
3539
helper!.addSipUaHelperListener(this);
3640
_loadSettings();
41+
if (kIsWeb) {
42+
_selectedTransport = TransportType.WS;
43+
}
3744
}
3845

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

7179
void _saveSettings() {
80+
_preferences.setString('port', _portController.text);
7281
_preferences.setString('ws_uri', _wsUriController.text);
7382
_preferences.setString('sip_uri', _sipUriController.text);
7483
_preferences.setString('display_name', _displayNameController.text);
@@ -113,12 +122,15 @@ class _MyRegisterWidget extends State<RegisterWidget>
113122

114123
UaSettings settings = UaSettings();
115124

116-
settings.webSocketUrl = _wsUriController.text;
125+
settings.port = _portController.text;
117126
settings.webSocketSettings.extraHeaders = _wsExtraHeaders;
118127
settings.webSocketSettings.allowBadCertificate = true;
119128
//settings.webSocketSettings.userAgent = 'Dart/2.8 (dart:io) for OpenSIPS.';
120-
129+
settings.tcpSocketSettings.allowBadCertificate = true;
130+
settings.transportType = _selectedTransport;
121131
settings.uri = _sipUriController.text;
132+
settings.webSocketUrl = _wsUriController.text;
133+
settings.host = _sipUriController.text.split('@')[1];
122134
settings.authorizationUser = _authorizationUserController.text;
123135
settings.password = _passwordController.text;
124136
settings.displayName = _displayNameController.text;
@@ -143,14 +155,24 @@ class _MyRegisterWidget extends State<RegisterWidget>
143155
style: TextStyle(fontSize: 18, color: Colors.black54),
144156
),
145157
),
146-
SizedBox(height: 40),
147-
Text('WebSocket:'),
148-
TextFormField(
149-
controller: _wsUriController,
150-
keyboardType: TextInputType.text,
151-
autocorrect: false,
152-
textAlign: TextAlign.center,
153-
),
158+
SizedBox(height: 20),
159+
if (_selectedTransport == TransportType.WS) ...[
160+
Text('WebSocket:'),
161+
TextFormField(
162+
controller: _wsUriController,
163+
keyboardType: TextInputType.text,
164+
autocorrect: false,
165+
textAlign: TextAlign.center,
166+
),
167+
],
168+
if (_selectedTransport == TransportType.TCP) ...[
169+
Text('Port:'),
170+
TextFormField(
171+
controller: _portController,
172+
keyboardType: TextInputType.text,
173+
textAlign: TextAlign.center,
174+
),
175+
],
154176
SizedBox(height: 20),
155177
Text('SIP URI:'),
156178
TextFormField(
@@ -192,7 +214,29 @@ class _MyRegisterWidget extends State<RegisterWidget>
192214
hintText: _displayNameController.text.isEmpty ? '[Empty]' : null,
193215
),
194216
),
195-
const SizedBox(height: 40),
217+
const SizedBox(height: 20),
218+
if (!kIsWeb) ...[
219+
Row(
220+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
221+
children: [
222+
RadioMenuButton<TransportType>(
223+
value: TransportType.TCP,
224+
groupValue: _selectedTransport,
225+
onChanged: ((value) => setState(() {
226+
_selectedTransport = value!;
227+
})),
228+
child: Text("TCP")),
229+
RadioMenuButton<TransportType>(
230+
value: TransportType.WS,
231+
groupValue: _selectedTransport,
232+
onChanged: ((value) => setState(() {
233+
_selectedTransport = value!;
234+
})),
235+
child: Text("WS")),
236+
],
237+
),
238+
],
239+
const SizedBox(height: 20),
196240
ElevatedButton(
197241
child: Text('Register'),
198242
onPressed: () => _handleSave(context),

lib/sip_ua.dart

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/// only expose the bare minimum of internals required
22
export 'src/enum_helper.dart';
33
export 'src/sip_ua_helper.dart';
4+
export 'src/transport_type.dart';

lib/src/config.dart

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import 'package:sip_ua/sip_ua.dart';
2+
import 'package:sip_ua/src/transports/socket_interface.dart';
3+
import 'package:sip_ua/src/transports/tcp_socket.dart';
24
import 'constants.dart' as DartSIP_C;
35
import 'constants.dart';
46
import 'exceptions.dart' as Exceptions;
57
import 'grammar.dart';
68
import 'logger.dart';
7-
import 'socket.dart' as Socket;
8-
import 'transports/websocket_interface.dart';
9+
import 'transports/web_socket.dart';
910
import 'uri.dart';
1011
import 'utils.dart' as Utils;
1112

@@ -43,8 +44,10 @@ class Settings {
4344
// Dtmf mode
4445
DtmfMode dtmf_mode = DtmfMode.INFO;
4546

47+
TransportType? transportType;
48+
4649
// Connection options.
47-
List<WebSocketInterface>? sockets = <WebSocketInterface>[];
50+
List<SIPUASocketInterface>? sockets = <SIPUASocketInterface>[];
4851
int connection_recovery_max_interval = 30;
4952
int connection_recovery_min_interval = 2;
5053

@@ -71,16 +74,17 @@ class Checks {
7174
Map<String, Null Function(Settings src, Settings? dst)> mandatory =
7275
<String, Null Function(Settings src, Settings? dst)>{
7376
'sockets': (Settings src, Settings? dst) {
74-
List<WebSocketInterface>? sockets = src.sockets;
77+
List<SIPUASocketInterface>? sockets = src.sockets;
78+
7579
/* Allow defining sockets parameter as:
7680
* Socket: socket
7781
* List of Socket: [socket1, socket2]
7882
* List of Objects: [{socket: socket1, weight:1}, {socket: Socket2, weight:0}]
7983
* List of Objects and Socket: [{socket: socket1}, socket2]
8084
*/
81-
List<WebSocketInterface> copy = <WebSocketInterface>[];
85+
List<SIPUASocketInterface> copy = <SIPUASocketInterface>[];
8286
if (sockets is List && sockets!.length > 0) {
83-
for (WebSocketInterface socket in sockets) {
87+
for (SIPUASocketInterface socket in sockets) {
8488
copy.add(socket);
8589
}
8690
} else {
@@ -105,6 +109,13 @@ class Checks {
105109
} else {
106110
dst!.uri = parsed;
107111
}
112+
},
113+
'transport_type': (Settings src, Settings? dst) {
114+
dynamic transportType = src.transportType;
115+
if (src.transportType == null && dst!.transportType == null) {
116+
throw Exceptions.ConfigurationError('transport type', null);
117+
}
118+
dst!.transportType = transportType;
108119
}
109120
};
110121
Map<String, Null Function(Settings src, Settings? dst)> optional =

lib/src/event_manager/event_manager.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class EventManager {
6969
targets.remove(listener);
7070
targets.add(listener);
7171
} catch (e, s) {
72-
logger.e(e.toString(), error: e, stackTrace: s);
72+
logger.e(e.toString(), e, s);
7373
}
7474
}
7575

@@ -108,7 +108,7 @@ class EventManager {
108108
// logger.w("invoking $event on $target");
109109
target(event);
110110
} catch (e, s) {
111-
logger.e(e.toString(), error: e, stackTrace: s);
111+
logger.e(e.toString(), e, s);
112112
}
113113
}
114114
}
+6-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
import '../transports/websocket_interface.dart';
1+
import 'package:sip_ua/src/transports/socket_interface.dart';
2+
import '../transports/web_socket.dart';
23
import 'events.dart';
34

45
class EventSocketConnected extends EventType {
56
EventSocketConnected({this.socket});
6-
WebSocketInterface? socket;
7+
SIPUASocketInterface? socket;
78
}
89

910
class EventSocketConnecting extends EventType {
1011
EventSocketConnecting({this.socket});
11-
WebSocketInterface? socket;
12+
SIPUASocketInterface? socket;
1213
}
1314

1415
class EventSocketDisconnected extends EventType {
15-
EventSocketDisconnected({WebSocketInterface? socket, this.cause});
16-
WebSocketInterface? socket;
16+
EventSocketDisconnected({SIPUASocketInterface? socket, this.cause});
17+
SIPUASocketInterface? socket;
1718
ErrorCause? cause;
1819
}

lib/src/logger.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class AnsiColor {
130130

131131
String call(String msg) {
132132
if (color) {
133-
return '$this$msg$ansiDefault';
133+
return '$msg$ansiDefault';
134134
} else {
135135
return msg;
136136
}

lib/src/registrator.dart

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:async';
22

3+
import 'package:sip_ua/src/socket_transport.dart';
34
import 'constants.dart' as DartSIP_C;
45
import 'constants.dart';
56
import 'event_manager/event_manager.dart';
@@ -10,7 +11,6 @@ import 'name_addr_header.dart';
1011
import 'request_sender.dart';
1112
import 'sip_message.dart';
1213
import 'timers.dart';
13-
import 'transport.dart';
1414
import 'ua.dart';
1515
import 'uri.dart';
1616
import 'utils.dart' as utils;
@@ -24,7 +24,7 @@ class UnHandledResponse {
2424
}
2525

2626
class Registrator {
27-
Registrator(UA ua, [Transport? transport]) {
27+
Registrator(UA ua, [SocketTransport? transport]) {
2828
int reg_id = 1; // Force reg_id to 1.
2929

3030
_ua = ua;
@@ -71,7 +71,7 @@ class Registrator {
7171
}
7272

7373
late UA _ua;
74-
Transport? _transport;
74+
SocketTransport? _transport;
7575
late URI _registrar;
7676
int? _expires;
7777
String? _call_id;
@@ -86,7 +86,7 @@ class Registrator {
8686

8787
bool get registered => _registered;
8888

89-
Transport? get transport => _transport;
89+
SocketTransport? get transport => _transport;
9090

9191
void setExtraHeaders(List<String>? extraHeaders) {
9292
_extraHeaders = extraHeaders ?? <String>[];

lib/src/request_sender.dart

+5-5
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,16 @@ class RequestSender {
5959

6060
switch (_method) {
6161
case SipMethod.INVITE:
62-
clientTransaction =
63-
InviteClientTransaction(_ua, _ua.transport!, _request!, handlers);
62+
clientTransaction = InviteClientTransaction(
63+
_ua, _ua.socketTransport!, _request!, handlers);
6464
break;
6565
case SipMethod.ACK:
66-
clientTransaction =
67-
AckClientTransaction(_ua, _ua.transport!, _request!, handlers);
66+
clientTransaction = AckClientTransaction(
67+
_ua, _ua.socketTransport!, _request!, handlers);
6868
break;
6969
default:
7070
clientTransaction = NonInviteClientTransaction(
71-
_ua, _ua.transport!, _request!, handlers);
71+
_ua, _ua.socketTransport!, _request!, handlers);
7272
}
7373

7474
clientTransaction?.send();

lib/src/rtc_session.dart

+22-21
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import 'dart:async';
2-
2+
import 'dart:convert';
3+
import 'package:crypto/crypto.dart';
34
import 'package:flutter_webrtc/flutter_webrtc.dart';
45
import 'package:sdp_transform/sdp_transform.dart' as sdp_transform;
5-
6+
import 'package:sdp_transform/sdp_transform.dart';
67
import 'package:sip_ua/sip_ua.dart';
78
import 'constants.dart' as DartSIP_C;
89
import 'constants.dart';
@@ -692,8 +693,7 @@ class RTCSession extends EventManager implements Owner {
692693
if (_status == C.STATUS_TERMINATED) {
693694
return;
694695
}
695-
logger.e('Failed to answer(): ${error.toString()}',
696-
error: error, stackTrace: s);
696+
logger.e('Failed to answer(): ${error.toString()}', error, s);
697697
}
698698
}
699699

@@ -1951,27 +1951,28 @@ class RTCSession extends EventManager implements Owner {
19511951
}
19521952

19531953
Future<RTCSessionDescription> _processInDialogSdpOffer(
1954-
dynamic request) async {
1954+
IncomingRequest request) async {
19551955
logger.d('_processInDialogSdpOffer()');
19561956

1957-
Map<String, dynamic> sdp = request.parseSDP();
1957+
Map<String, dynamic>? sdp = request.parseSDP();
19581958

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

1961-
for (Map<String, dynamic> m in sdp['media']) {
1962-
if (holdMediaTypes.indexOf(m['type']) == -1) {
1963-
continue;
1964-
}
1965-
1966-
String direction = m['direction'] ?? sdp['direction'] ?? 'sendrecv';
1966+
String direction = m['direction'] ?? sdp['direction'] ?? 'sendrecv';
19671967

1968-
if (direction == 'sendonly' || direction == 'inactive') {
1969-
hold = true;
1970-
}
1971-
// If at least one of the streams is active don't emit 'hold'.
1972-
else {
1973-
hold = false;
1974-
break;
1968+
if (direction == 'sendonly' || direction == 'inactive') {
1969+
hold = true;
1970+
}
1971+
// If at least one of the streams is active don't emit 'hold'.
1972+
else {
1973+
hold = false;
1974+
break;
1975+
}
19751976
}
19761977
}
19771978

@@ -2294,7 +2295,7 @@ class RTCSession extends EventManager implements Owner {
22942295

22952296
request_sender.send();
22962297
} catch (error, s) {
2297-
logger.e(error.toString(), error: error, stackTrace: s);
2298+
logger.e(error.toString(), error, s);
22982299
_failed('local', null, null, null, 500, DartSIP_C.CausesType.WEBRTC_ERROR,
22992300
'Can\'t create local SDP');
23002301
if (_status == C.STATUS_TERMINATED) {
@@ -2560,7 +2561,7 @@ class RTCSession extends EventManager implements Owner {
25602561
'eventHandlers': handlers
25612562
});
25622563
} catch (e, s) {
2563-
logger.e(e.toString(), error: e, stackTrace: s);
2564+
logger.e(e.toString(), e, s);
25642565
onFailed();
25652566
}
25662567
}

0 commit comments

Comments
 (0)