Why aren't sctp Paramaters passed into Transport ConsumeData?

Hi,

Been having an issue with DataConsumers with libmediasoup. My issue is that if dataconsumers are created with the wrong streamId by libmediasoup then everything goes bananas.

Here is the constructor for the dataconsumers [libmediasoupclient/Transport.cpp at v3 · versatica/libmediasoupclient · GitHub]

Is there a reason why sctpParamaters aren’t passed in?

Garrett

1 Like

I don’t follow. Obviously this works according to the documented API. I don’t know how to answer to “Is there a reason why sctpParamaters aren’t passed in?”, that’s not the point.

  1. A DataConsumer/DataChannel requires sctp Parameters when its constructed: libmediasoupclient/DataConsumer.cpp at v3 · versatica/libmediasoupclient · GitHub

  2. In Transport.cpp no sctp Parameters are provided from the application. Instead ReceiveDataChannel constructs sctp parameters using an internal counter for the streamId.

  3. In the application if each data consumer provides sctp parameters. If you do not process those messages in order of when they’re received (i.e. 1,2,3,4,5,6) and instead they get processed (1,2,4,3,5,6). Then when the datachannel in Transport.cpp it will have the wrong streamId because the internal streamId counter will map users incorrectly resulting in messages sent by user 3 showing up as user 4.

Is there a reason why sctp parameters are not passed into Transport.cpp and are instead created by the library?

@ibc I mocked up the changes I’m talking about in this commit GitHub - GEverding/libmediasoupclient at feat-consumeData-with-sctpStreamParameters

It is not complete and only to be a proof of concept. I’m happy to finish it I just would need to know how you want to handle API changes.

@GEverding, you are not provided nor you provide a streamId. You provide the transport with a Consumer ID given by the server.

Neither do I understand the problem.

@jmillan actually there is a big difference in how we receive a DataChannel in mediasoup-client and in libmediasoupclient. The latter seems indeed wrong. Look:

  • In mediasoup-client Chrome74.ts handler:
  async receiveDataChannel(
    { sctpStreamParameters, label, protocol }: HandlerReceiveDataChannelOptions
  ): Promise<HandlerReceiveDataChannelResult>
  {
    this._assertRecvDirection();

    const {
      streamId,
      ordered,
      maxPacketLifeTime,
      maxRetransmits
    }: SctpStreamParameters = sctpStreamParameters;

    const options =
    {
      negotiated : true,
      id         : streamId,
      ordered,
      maxPacketLifeTime,
      maxRetransmits,
      protocol
    };

    logger.debug('receiveDataChannel() [options:%o]', options);

    const dataChannel = this._pc.createDataChannel(label, options);
  • In libmediasoupclient Handler.cpp:
  Handler::DataChannel RecvHandler::ReceiveDataChannel(
    const std::string& label, webrtc::DataChannelInit dataChannelInit)
  {
    MSC_TRACE();

    uint16_t streamId = this->nextSendSctpStreamId;

    dataChannelInit.negotiated = true;
    dataChannelInit.id         = streamId;

    /* clang-format off */
    nlohmann::json sctpStreamParameters =
    {
      { "streamId", streamId                },
      { "ordered",  dataChannelInit.ordered }
    };
    /* clang-format on */

    // This will fill sctpStreamParameters's missing fields with default values.
    ortc::validateSctpStreamParameters(sctpStreamParameters);

    rtc::scoped_refptr<webrtc::DataChannelInterface> webrtcDataChannel =
      this->pc->CreateDataChannel(label, &dataChannelInit);

    // Increase next id.
    this->nextSendSctpStreamId = (this->nextSendSctpStreamId + 1) % SctpNumStreamsMis;

In mediasoup-client we read streamId from the given sctpStreamParameters (as it should be). However, in libmediasoupclient we assume streamId is incremental based on a local count. It doesn’t make any sense.

I’ve created an issue in GitHub: