<commit_before>const SDPUtils = require('sdp');

import {
    convertIntermediateToTransportInfo,
    convertRequestToIntermediate,
    convertIntermediateToTransport
} from './lib/Protocol';
import { importFromSDP, exportToSDP } from './lib/Intermediate';
import BaseSession from './Session';

export default class ICESession extends BaseSession {
    constructor(opts) {
        super(opts);

        this.pc = new RTCPeerConnection(opts.config, opts.constraints);

        this.pc.addEventListener('iceconnectionstatechange', () => {
            this.onIceStateChange();
            this.restrictRelayBandwidth();
        });

        this.pc.addEventListener('icecandidate', e => {
            if (e.candidate) {
                this.onIceCandidate(e);
            } else {
                this.onIceEndOfCandidates();
            }
        });

        this.bitrateLimit = 0;
        this.maxRelayBandwidth = opts.maxRelayBandwidth;
    }

    end(reason, silent) {
        this.pc.close();
        super.end(reason, silent);
    }

    // ----------------------------------------------------------------
    // Jingle action handers
    // ----------------------------------------------------------------

    onTransportInfo(changes, cb) {
        if (changes.contents[0].transport.gatheringComplete) {
            this.pc
                .addIceCandidate(null)
                .then(cb)
                .catch(e => this._log('error', 'Could not add null ICE candidate', e.name));
            return Promise.resolve();
        }
        // detect an ice restart.
        if (this.pc.remoteDescription) {
            const remoteDescription = this.pc.remoteDescription;
            const remoteJSON = importFromSDP(remoteDescription.sdp);
            const remoteMedia = remoteJSON.media.find(m => m.mid === changes.contents[0].name);
            const currentUsernameFragment = remoteMedia.iceParameters.usernameFragment;
            const remoteUsernameFragment = changes.contents[0].transport.ufrag;
            if (remoteUsernameFragment && currentUsernameFragment !== remoteUsernameFragment) {
                changes.contents.forEach((content, idx) => {
                    remoteJSON.media[idx].iceParameters = {
                        password: content.transport.pwd,
                        usernameFragment: content.transport.ufrag
                    };
                    remoteJSON.media[idx].candidates = [];
                });
                if (remoteDescription.type === 'offer') {
                    return this.pc
                        .setRemoteDescription(remoteDescription)
                        .then(() => this.pc.createAnswer())
                        .then(answer => {
                            const json = importFromSDP(answer.sdp);
                            const jingle = {
                                action: 'transport-info',
                                contents: json.media.map(media => {
                                    return {
                                        creator: 'initiator',
                                        name: media.mid,
                                        transport: convertIntermediateToTransport(media)
                                    };
                                }),
                                sessionId: this.sid
                            };
                            this.send('transport-info', jingle);
                            return this.pc.setLocalDescription(answer);
                        })
                        .then(() => cb())
                        .catch(err => {
                            this._log('error', 'Could not do remote ICE restart', err);
                            this.end('failed-application', true);
                            cb(err);
                        });
                }
                return this.pc
                    .setRemoteDescription(remoteDescription)
                    .then(() => cb())
                    .catch(err => {
                        this._log('error', 'Could not do local ICE restart', err);
                        this.end('failed-application', true);
                        cb(err);
                    });
            }
        }

        const all = changes.contents.map(content => {
            const sdpMid = content.name;
            const results = content.transport.candidates.map(json => {
                json.relatedAddress = json.relAddr;
                json.relatedPort = json.relPort;
                const candidate = SDPUtils.writeCandidate(json);

                let sdpMLineIndex;
                // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1456417
                const remoteSDP = this.pc.remoteDescription.sdp;
                const mediaSections = SDPUtils.getMediaSections(remoteSDP);
                for (let i = 0; i < mediaSections.length; i++) {
                    if (SDPUtils.getMid(mediaSections[i]) === candidate.sdpMid) {
                        sdpMLineIndex = i;
                        break;
                    }
                }
                return this.pc
                    .addIceCandidate({ sdpMid, sdpMLineIndex, candidate })
                    .catch(e => this._log('error', 'Could not add ICE candidate', e.name));
            });
            return Promise.all(results);
        });
        return Promise.all(all).then(() => cb());
    }

    onSessionAccept(changes, cb) {
        this.state = 'active';

        const json = convertRequestToIntermediate(changes, this.peerRole);
        const sdp = exportToSDP(json);
        this.pc.setRemoteDescription({ type: 'answer', sdp }).then(
            () => {
                this.emit('accepted', undefined);
                cb();<commit_msg>Fix jingle:accepted event<commit_after>const SDPUtils = require('sdp');

import {
    convertIntermediateToTransportInfo,
    convertRequestToIntermediate,
    convertIntermediateToTransport
} from './lib/Protocol';
import { importFromSDP, exportToSDP } from './lib/Intermediate';
import BaseSession from './Session';

export default class ICESession extends BaseSession {
    constructor(opts) {
        super(opts);

        this.pc = new RTCPeerConnection(opts.config, opts.constraints);

        this.pc.addEventListener('iceconnectionstatechange', () => {
            this.onIceStateChange();
            this.restrictRelayBandwidth();
        });

        this.pc.addEventListener('icecandidate', e => {
            if (e.candidate) {
                this.onIceCandidate(e);
            } else {
                this.onIceEndOfCandidates();
            }
        });

        this.bitrateLimit = 0;
        this.maxRelayBandwidth = opts.maxRelayBandwidth;
    }

    end(reason, silent) {
        this.pc.close();
        super.end(reason, silent);
    }

    // ----------------------------------------------------------------
    // Jingle action handers
    // ----------------------------------------------------------------

    onTransportInfo(changes, cb) {
        if (changes.contents[0].transport.gatheringComplete) {
            this.pc
                .addIceCandidate(null)
                .then(cb)
                .catch(e => this._log('error', 'Could not add null ICE candidate', e.name));
            return Promise.resolve();
        }
        // detect an ice restart.
        if (this.pc.remoteDescription) {
            const remoteDescription = this.pc.remoteDescription;
            const remoteJSON = importFromSDP(remoteDescription.sdp);
            const remoteMedia = remoteJSON.media.find(m => m.mid === changes.contents[0].name);
            const currentUsernameFragment = remoteMedia.iceParameters.usernameFragment;
            const remoteUsernameFragment = changes.contents[0].transport.ufrag;
            if (remoteUsernameFragment && currentUsernameFragment !== remoteUsernameFragment) {
                changes.contents.forEach((content, idx) => {
                    remoteJSON.media[idx].iceParameters = {
                        password: <PASSWORD>,
                        usernameFragment: content.transport.ufrag
                    };
                    remoteJSON.media[idx].candidates = [];
                });
                if (remoteDescription.type === 'offer') {
                    return this.pc
                        .setRemoteDescription(remoteDescription)
                        .then(() => this.pc.createAnswer())
                        .then(answer => {
                            const json = importFromSDP(answer.sdp);
                            const jingle = {
                                action: 'transport-info',
                                contents: json.media.map(media => {
                                    return {
                                        creator: 'initiator',
                                        name: media.mid,
                                        transport: convertIntermediateToTransport(media)
                                    };
                                }),
                                sessionId: this.sid
                            };
                            this.send('transport-info', jingle);
                            return this.pc.setLocalDescription(answer);
                        })
                        .then(() => cb())
                        .catch(err => {
                            this._log('error', 'Could not do remote ICE restart', err);
                            this.end('failed-application', true);
                            cb(err);
                        });
                }
                return this.pc
                    .setRemoteDescription(remoteDescription)
                    .then(() => cb())
                    .catch(err => {
                        this._log('error', 'Could not do local ICE restart', err);
                        this.end('failed-application', true);
                        cb(err);
                    });
            }
        }

        const all = changes.contents.map(content => {
            const sdpMid = content.name;
            const results = content.transport.candidates.map(json => {
                json.relatedAddress = json.relAddr;
                json.relatedPort = json.relPort;
                const candidate = SDPUtils.writeCandidate(json);

                let sdpMLineIndex;
                // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1456417
                const remoteSDP = this.pc.remoteDescription.sdp;
                const mediaSections = SDPUtils.getMediaSections(remoteSDP);
                for (let i = 0; i < mediaSections.length; i++) {
                    if (SDPUtils.getMid(mediaSections[i]) === candidate.sdpMid) {
                        sdpMLineIndex = i;
                        break;
                    }
                }
                return this.pc
                    .addIceCandidate({ sdpMid, sdpMLineIndex, candidate })
                    .catch(e => this._log('error', 'Could not add ICE candidate', e.name));
            });
            return Promise.all(results);
        });
        return Promise.all(all).then(() => cb());
    }

    onSessionAccept(changes, cb) {
        this.state = 'active';

        const json = convertRequestToIntermediate(changes, this.peerRole);
        const sdp = exportToSDP(json);
        this.pc.setRemoteDescription({ type: 'answer', sdp }).then(
            () => {
                this.emit('accepted', this, undefined);
                cb();
{'fraction_non_alphanumeric': 0.12505412661297308, 'fraction_numerical': 0.0020784619381657575, 'mean_word_length': 1.250194855806703, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 38, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5415653', 'n_tokens_mistral': 2778, 'n_tokens_neox': 2595, 'n_words': 492}