diff --git a/src/Transport.ts b/src/Transport.ts index d41f79d4..02dba8b4 100644 --- a/src/Transport.ts +++ b/src/Transport.ts @@ -765,11 +765,13 @@ export class Transport< return this._awaitQueue.push(async () => { const { dataChannel, sctpStreamParameters } = await this._handler.sendDataChannel({ - ordered, - maxPacketLifeTime, - maxRetransmits, - label, - protocol, + sctpStreamParameters: { + ordered, + maxPacketLifeTime, + maxRetransmits, + label, + protocol, + }, }); // This will fill sctpStreamParameters's missing fields with default values. @@ -849,6 +851,7 @@ export class Transport< // Enqueue command. return this._awaitQueue.push(async () => { const { dataChannel } = await this._handler.receiveDataChannel({ + maxMessageSize: this._maxSctpMessageSize!, sctpStreamParameters: clonedSctpStreamParameters, label, protocol, diff --git a/src/handlers/Chrome111.ts b/src/handlers/Chrome111.ts index 18f173ca..5a3e7fa7 100644 --- a/src/handlers/Chrome111.ts +++ b/src/handlers/Chrome111.ts @@ -827,11 +827,7 @@ export class Chrome111 } async sendDataChannel({ - ordered, - maxPacketLifeTime, - maxRetransmits, - label, - protocol, + sctpStreamParameters, }: HandlerSendDataChannelOptions): Promise { this.assertNotClosed(); this.assertSendDirection(); @@ -839,15 +835,18 @@ export class Chrome111 const options = { negotiated: true, id: this._nextSendSctpStreamId, - ordered, - maxPacketLifeTime, - maxRetransmits, - protocol, + ordered: sctpStreamParameters.ordered, + maxPacketLifeTime: sctpStreamParameters.maxPacketLifeTime, + maxRetransmits: sctpStreamParameters.maxRetransmits, + protocol: sctpStreamParameters.protocol, }; logger.debug('sendDataChannel() [options:%o]', options); - const dataChannel = this._pc.createDataChannel(label!, options); + const dataChannel = this._pc.createDataChannel( + sctpStreamParameters.label!, + options + ); // Increase next id. this._nextSendSctpStreamId = @@ -893,14 +892,14 @@ export class Chrome111 this._hasDataChannelMediaSection = true; } - const sctpStreamParameters: SctpStreamParameters = { + const newSctpStreamParameters: SctpStreamParameters = { streamId: options.id, ordered: options.ordered, maxPacketLifeTime: options.maxPacketLifeTime, maxRetransmits: options.maxRetransmits, }; - return { dataChannel, sctpStreamParameters }; + return { dataChannel, sctpStreamParameters: newSctpStreamParameters }; } async receive( @@ -1163,6 +1162,7 @@ export class Chrome111 } async receiveDataChannel({ + maxMessageSize, sctpStreamParameters, label, protocol, @@ -1207,19 +1207,28 @@ export class Chrome111 await this._pc.setRemoteDescription(offer); - const answer = await this._pc.createAnswer(); + let answer = await this._pc.createAnswer(); + const localSdpObject = sdpTransform.parse(answer.sdp!); + const answerMediaObject = localSdpObject.media.find( + m => m.type === 'application' + )!; - if (!this._transportReady) { - const localSdpObject = sdpTransform.parse(answer.sdp!); + answerMediaObject.maxMessageSize = maxMessageSize; + if (!this._transportReady) { await this.setupTransport({ localDtlsRole: this._forcedLocalDtlsRole ?? 'client', localSdpObject, }); } + answer = { + type: 'answer', + sdp: sdpTransform.write(localSdpObject), + }; + logger.debug( - 'receiveDataChannel() | calling pc.setRemoteDescription() [answer:%o]', + 'receiveDataChannel() | calling pc.setLocalDescription() [answer:%o]', answer ); diff --git a/src/handlers/Chrome74.ts b/src/handlers/Chrome74.ts index 6e3aec51..f2c7dcec 100644 --- a/src/handlers/Chrome74.ts +++ b/src/handlers/Chrome74.ts @@ -850,11 +850,7 @@ export class Chrome74 } async sendDataChannel({ - ordered, - maxPacketLifeTime, - maxRetransmits, - label, - protocol, + sctpStreamParameters, }: HandlerSendDataChannelOptions): Promise { this.assertNotClosed(); this.assertSendDirection(); @@ -862,15 +858,18 @@ export class Chrome74 const options = { negotiated: true, id: this._nextSendSctpStreamId, - ordered, - maxPacketLifeTime, - maxRetransmits, - protocol, + ordered: sctpStreamParameters.ordered, + maxPacketLifeTime: sctpStreamParameters.maxPacketLifeTime, + maxRetransmits: sctpStreamParameters.maxRetransmits, + protocol: sctpStreamParameters.protocol, }; logger.debug('sendDataChannel() [options:%o]', options); - const dataChannel = this._pc.createDataChannel(label!, options); + const dataChannel = this._pc.createDataChannel( + sctpStreamParameters.label!, + options + ); // Increase next id. this._nextSendSctpStreamId = @@ -916,14 +915,14 @@ export class Chrome74 this._hasDataChannelMediaSection = true; } - const sctpStreamParameters: SctpStreamParameters = { + const newSctpStreamParameters: SctpStreamParameters = { streamId: options.id, ordered: options.ordered, maxPacketLifeTime: options.maxPacketLifeTime, maxRetransmits: options.maxRetransmits, }; - return { dataChannel, sctpStreamParameters }; + return { dataChannel, sctpStreamParameters: newSctpStreamParameters }; } async receive( @@ -1169,6 +1168,7 @@ export class Chrome74 } async receiveDataChannel({ + maxMessageSize, sctpStreamParameters, label, protocol, @@ -1213,19 +1213,28 @@ export class Chrome74 await this._pc.setRemoteDescription(offer); - const answer = await this._pc.createAnswer(); + let answer = await this._pc.createAnswer(); + const localSdpObject = sdpTransform.parse(answer.sdp!); + const answerMediaObject = localSdpObject.media.find( + m => m.type === 'application' + )!; - if (!this._transportReady) { - const localSdpObject = sdpTransform.parse(answer.sdp!); + answerMediaObject.maxMessageSize = maxMessageSize; + if (!this._transportReady) { await this.setupTransport({ localDtlsRole: this._forcedLocalDtlsRole ?? 'client', localSdpObject, }); } + answer = { + type: 'answer', + sdp: sdpTransform.write(localSdpObject), + }; + logger.debug( - 'receiveDataChannel() | calling pc.setRemoteDescription() [answer:%o]', + 'receiveDataChannel() | calling pc.setLocalDescription() [answer:%o]', answer ); diff --git a/src/handlers/FakeHandler.ts b/src/handlers/FakeHandler.ts index 8f18ab32..72a2cc84 100644 --- a/src/handlers/FakeHandler.ts +++ b/src/handlers/FakeHandler.ts @@ -334,11 +334,7 @@ export class FakeHandler } async sendDataChannel({ - ordered, - maxPacketLifeTime, - maxRetransmits, - label, - protocol, + sctpStreamParameters, }: HandlerSendDataChannelOptions): Promise { this.assertNotClosed(); @@ -350,21 +346,21 @@ export class FakeHandler const dataChannel = new FakeRTCDataChannel({ id: this._nextSctpStreamId++, - ordered, - maxPacketLifeTime, - maxRetransmits, - label, - protocol, + ordered: sctpStreamParameters.ordered, + maxPacketLifeTime: sctpStreamParameters.maxPacketLifeTime, + maxRetransmits: sctpStreamParameters.maxRetransmits, + label: sctpStreamParameters.label, + protocol: sctpStreamParameters.protocol, }); - const sctpStreamParameters = { + const newSctpStreamParameters = { streamId: this._nextSctpStreamId, - ordered: ordered, - maxPacketLifeTime: maxPacketLifeTime, - maxRetransmits: maxRetransmits, + ordered: sctpStreamParameters.ordered, + maxPacketLifeTime: sctpStreamParameters.maxPacketLifeTime, + maxRetransmits: sctpStreamParameters.maxRetransmits, }; - return { dataChannel, sctpStreamParameters }; + return { dataChannel, sctpStreamParameters: newSctpStreamParameters }; } async receive( @@ -432,6 +428,7 @@ export class FakeHandler } async receiveDataChannel({ + // maxMessageSize, sctpStreamParameters, label, protocol, diff --git a/src/handlers/Firefox120.ts b/src/handlers/Firefox120.ts index 4867dd53..deda2728 100644 --- a/src/handlers/Firefox120.ts +++ b/src/handlers/Firefox120.ts @@ -798,11 +798,7 @@ export class Firefox120 } async sendDataChannel({ - ordered, - maxPacketLifeTime, - maxRetransmits, - label, - protocol, + sctpStreamParameters, }: HandlerSendDataChannelOptions): Promise { this.assertNotClosed(); this.assertSendDirection(); @@ -810,15 +806,18 @@ export class Firefox120 const options = { negotiated: true, id: this._nextSendSctpStreamId, - ordered, - maxPacketLifeTime, - maxRetransmits, - protocol, + ordered: sctpStreamParameters.ordered, + maxPacketLifeTime: sctpStreamParameters.maxPacketLifeTime, + maxRetransmits: sctpStreamParameters.maxRetransmits, + protocol: sctpStreamParameters.protocol, }; logger.debug('sendDataChannel() [options:%o]', options); - const dataChannel = this._pc.createDataChannel(label!, options); + const dataChannel = this._pc.createDataChannel( + sctpStreamParameters.label!, + options + ); // Increase next id. this._nextSendSctpStreamId = @@ -861,14 +860,14 @@ export class Firefox120 this._hasDataChannelMediaSection = true; } - const sctpStreamParameters: SctpStreamParameters = { + const newSctpStreamParameters: SctpStreamParameters = { streamId: options.id, ordered: options.ordered, maxPacketLifeTime: options.maxPacketLifeTime, maxRetransmits: options.maxRetransmits, }; - return { dataChannel, sctpStreamParameters }; + return { dataChannel, sctpStreamParameters: newSctpStreamParameters }; } async receive( @@ -1127,6 +1126,7 @@ export class Firefox120 } async receiveDataChannel({ + maxMessageSize, sctpStreamParameters, label, protocol, @@ -1171,16 +1171,25 @@ export class Firefox120 await this._pc.setRemoteDescription(offer); - const answer = await this._pc.createAnswer(); + let answer = await this._pc.createAnswer(); + const localSdpObject = sdpTransform.parse(answer.sdp!); + const answerMediaObject = localSdpObject.media.find( + m => m.type === 'application' + )!; - if (!this._transportReady) { - const localSdpObject = sdpTransform.parse(answer.sdp!); + answerMediaObject.maxMessageSize = maxMessageSize; + if (!this._transportReady) { await this.setupTransport({ localDtlsRole: 'client', localSdpObject }); } + answer = { + type: 'answer', + sdp: sdpTransform.write(localSdpObject), + }; + logger.debug( - 'receiveDataChannel() | calling pc.setRemoteDescription() [answer:%o]', + 'receiveDataChannel() | calling pc.setLocalDescription() [answer:%o]', answer ); diff --git a/src/handlers/HandlerInterface.ts b/src/handlers/HandlerInterface.ts index df2eaf2c..e0e9db2d 100644 --- a/src/handlers/HandlerInterface.ts +++ b/src/handlers/HandlerInterface.ts @@ -95,7 +95,9 @@ export type HandlerReceiveResult = { rtpReceiver?: RTCRtpReceiver; }; -export type HandlerSendDataChannelOptions = SctpStreamParameters; +export type HandlerSendDataChannelOptions = { + sctpStreamParameters: SctpStreamParameters; +}; export type HandlerSendDataChannelResult = { dataChannel: RTCDataChannel; @@ -103,6 +105,7 @@ export type HandlerSendDataChannelResult = { }; export type HandlerReceiveDataChannelOptions = { + maxMessageSize: number; sctpStreamParameters: SctpStreamParameters; label?: string; protocol?: string; diff --git a/src/handlers/ReactNative106.ts b/src/handlers/ReactNative106.ts index 205d7bdc..a45b77b3 100644 --- a/src/handlers/ReactNative106.ts +++ b/src/handlers/ReactNative106.ts @@ -884,11 +884,7 @@ export class ReactNative106 } async sendDataChannel({ - ordered, - maxPacketLifeTime, - maxRetransmits, - label, - protocol, + sctpStreamParameters, }: HandlerSendDataChannelOptions): Promise { this.assertNotClosed(); this.assertSendDirection(); @@ -896,15 +892,18 @@ export class ReactNative106 const options = { negotiated: true, id: this._nextSendSctpStreamId, - ordered, - maxPacketLifeTime, - maxRetransmits, - protocol, + ordered: sctpStreamParameters.ordered, + maxPacketLifeTime: sctpStreamParameters.maxPacketLifeTime, + maxRetransmits: sctpStreamParameters.maxRetransmits, + protocol: sctpStreamParameters.protocol, }; logger.debug('sendDataChannel() [options:%o]', options); - const dataChannel = this._pc.createDataChannel(label!, options); + const dataChannel = this._pc.createDataChannel( + sctpStreamParameters.label!, + options + ); // Increase next id. this._nextSendSctpStreamId = @@ -950,14 +949,14 @@ export class ReactNative106 this._hasDataChannelMediaSection = true; } - const sctpStreamParameters: SctpStreamParameters = { + const newSctpStreamParameters: SctpStreamParameters = { streamId: options.id, ordered: options.ordered, maxPacketLifeTime: options.maxPacketLifeTime, maxRetransmits: options.maxRetransmits, }; - return { dataChannel, sctpStreamParameters }; + return { dataChannel, sctpStreamParameters: newSctpStreamParameters }; } async receive( @@ -1220,6 +1219,7 @@ export class ReactNative106 } async receiveDataChannel({ + maxMessageSize, sctpStreamParameters, label, protocol, @@ -1264,19 +1264,28 @@ export class ReactNative106 await this._pc.setRemoteDescription(offer); - const answer = await this._pc.createAnswer(); + let answer = await this._pc.createAnswer(); + const localSdpObject = sdpTransform.parse(answer.sdp!); + const answerMediaObject = localSdpObject.media.find( + m => m.type === 'application' + )!; - if (!this._transportReady) { - const localSdpObject = sdpTransform.parse(answer.sdp!); + answerMediaObject.maxMessageSize = maxMessageSize; + if (!this._transportReady) { await this.setupTransport({ localDtlsRole: this._forcedLocalDtlsRole ?? 'client', localSdpObject, }); } + answer = { + type: 'answer', + sdp: sdpTransform.write(localSdpObject), + }; + logger.debug( - 'receiveDataChannel() | calling pc.setRemoteDescription() [answer:%o]', + 'receiveDataChannel() | calling pc.setLocalDescription() [answer:%o]', answer ); diff --git a/src/handlers/Safari12.ts b/src/handlers/Safari12.ts index de96f265..85140ba3 100644 --- a/src/handlers/Safari12.ts +++ b/src/handlers/Safari12.ts @@ -836,11 +836,7 @@ export class Safari12 } async sendDataChannel({ - ordered, - maxPacketLifeTime, - maxRetransmits, - label, - protocol, + sctpStreamParameters, }: HandlerSendDataChannelOptions): Promise { this.assertNotClosed(); this.assertSendDirection(); @@ -848,15 +844,18 @@ export class Safari12 const options = { negotiated: true, id: this._nextSendSctpStreamId, - ordered, - maxPacketLifeTime, - maxRetransmits, - protocol, + ordered: sctpStreamParameters.ordered, + maxPacketLifeTime: sctpStreamParameters.maxPacketLifeTime, + maxRetransmits: sctpStreamParameters.maxRetransmits, + protocol: sctpStreamParameters.protocol, }; logger.debug('sendDataChannel() [options:%o]', options); - const dataChannel = this._pc.createDataChannel(label!, options); + const dataChannel = this._pc.createDataChannel( + sctpStreamParameters.label!, + options + ); // Increase next id. this._nextSendSctpStreamId = @@ -902,14 +901,14 @@ export class Safari12 this._hasDataChannelMediaSection = true; } - const sctpStreamParameters: SctpStreamParameters = { + const newSctpStreamParameters: SctpStreamParameters = { streamId: options.id, ordered: options.ordered, maxPacketLifeTime: options.maxPacketLifeTime, maxRetransmits: options.maxRetransmits, }; - return { dataChannel, sctpStreamParameters }; + return { dataChannel, sctpStreamParameters: newSctpStreamParameters }; } async receive( @@ -1172,6 +1171,7 @@ export class Safari12 } async receiveDataChannel({ + maxMessageSize, sctpStreamParameters, label, protocol, @@ -1216,19 +1216,28 @@ export class Safari12 await this._pc.setRemoteDescription(offer); - const answer = await this._pc.createAnswer(); + let answer = await this._pc.createAnswer(); + const localSdpObject = sdpTransform.parse(answer.sdp!); + const answerMediaObject = localSdpObject.media.find( + m => m.type === 'application' + )!; - if (!this._transportReady) { - const localSdpObject = sdpTransform.parse(answer.sdp!); + answerMediaObject.maxMessageSize = maxMessageSize; + if (!this._transportReady) { await this.setupTransport({ localDtlsRole: this._forcedLocalDtlsRole ?? 'client', localSdpObject, }); } + answer = { + type: 'answer', + sdp: sdpTransform.write(localSdpObject), + }; + logger.debug( - 'receiveDataChannel() | calling pc.setRemoteDescription() [answer:%o]', + 'receiveDataChannel() | calling pc.setLocalDescription() [answer:%o]', answer );