docs: async def _send(self, stream_id, pp_id, user_data,
                      expiry=None, max_retransmits=None, ordered=True):
          """
          Send data ULP -> stream.
          """
          if ordered:
              stream_seq = self._outbound_stream_seq.get(stream_id, 0)
          else:
              stream_seq = 0
  
          fragments = math.ceil(len(user_data) / USERDATA_MAX_LENGTH)
          pos = 0
          for fragment in range(0, fragments):
              chunk = DataChunk()
              chunk.flags = 0
              if not ordered:
                  chunk.flags = SCTP_DATA_UNORDERED
              if fragment == 0:
                  chunk.flags |= SCTP_DATA_FIRST_FRAG
              if fragment == fragments - 1:
                  chunk.flags |= SCTP_DATA_LAST_FRAG
              chunk.tsn = self._local_tsn
              chunk.stream_id = stream_id
              chunk.stream_seq = stream_seq
              chunk.protocol = pp_id
              chunk.user_data = user_data[pos:pos + USERDATA_MAX_LENGTH]
  
              # initialize counters
              chunk._abandoned = False
              chunk._acked = False
              chunk._book_size = len(chunk.user_data)
              chunk._expiry = expiry
              chunk._max_retransmits = max_retransmits
              chunk._misses = 0
              chunk._retransmit = False
              chunk._sent_count = 0
              chunk._sent_time = None
  
              pos += USERDATA_MAX_LENGTH
              self._local_tsn = tsn_plus_one(self._local_tsn)
              self._outbound_queue.append(chunk)
  
          if ordered:
              self._outbound_stream_seq[stream_id] = uint16_add(stream_seq, 1)
  
          # transmit outbound data
          if not self._t3_handle:
              await self._transmit()