| 1235 | } |
| 1236 | |
| 1237 | func (t *PCTransport) CreateDataChannel(label string, dci *webrtc.DataChannelInit) error { |
| 1238 | if label == DataTrackDataChannel && !t.params.EnableDataTracks { |
| 1239 | t.params.Logger.Debugw("data tracks not enabled") |
| 1240 | return nil |
| 1241 | } |
| 1242 | |
| 1243 | dc, err := t.pc.CreateDataChannel(label, dci) |
| 1244 | if err != nil { |
| 1245 | return err |
| 1246 | } |
| 1247 | var ( |
| 1248 | dcPtr **datachannel.DataChannelWriter[*webrtc.DataChannel] |
| 1249 | dcReady *bool |
| 1250 | isDataTrack bool |
| 1251 | isUnlabeled bool |
| 1252 | kind livekit.DataPacket_Kind |
| 1253 | ) |
| 1254 | switch dc.Label() { |
| 1255 | default: |
| 1256 | isUnlabeled = true |
| 1257 | t.params.Logger.Infow("unlabeled datachannel added", "label", dc.Label()) |
| 1258 | |
| 1259 | case ReliableDataChannel: |
| 1260 | dcPtr = &t.reliableDC |
| 1261 | dcReady = &t.reliableDCOpened |
| 1262 | kind = livekit.DataPacket_RELIABLE |
| 1263 | |
| 1264 | case LossyDataChannel: |
| 1265 | dcPtr = &t.lossyDC |
| 1266 | dcReady = &t.lossyDCOpened |
| 1267 | kind = livekit.DataPacket_LOSSY |
| 1268 | |
| 1269 | case DataTrackDataChannel: |
| 1270 | dcPtr = &t.dataTrackDC |
| 1271 | isDataTrack = true |
| 1272 | } |
| 1273 | |
| 1274 | dc.OnOpen(func() { |
| 1275 | rawDC, err := dc.DetachWithDeadline() |
| 1276 | if err != nil { |
| 1277 | t.params.Logger.Warnw("failed to detach data channel", err) |
| 1278 | return |
| 1279 | } |
| 1280 | |
| 1281 | var slowThreshold int |
| 1282 | if dc.Label() == ReliableDataChannel || isUnlabeled { |
| 1283 | slowThreshold = t.params.DatachannelSlowThreshold |
| 1284 | } |
| 1285 | |
| 1286 | t.lock.Lock() |
| 1287 | if isUnlabeled { |
| 1288 | t.unlabeledDataChannels = append( |
| 1289 | t.unlabeledDataChannels, |
| 1290 | datachannel.NewDataChannelWriterReliable(dc, rawDC, slowThreshold), |
| 1291 | ) |
| 1292 | } else { |
| 1293 | if *dcPtr != nil { |
| 1294 | (*dcPtr).Close() |