Beispiel #1
0
    def _OH_ConnectOperation(self, operation):
        if self.state is not None:
            return

        settings = SIPSimpleSettings()
        notification_center = NotificationCenter()

        self.direction = 'outgoing'
        self.state = 'connecting'
        self.proposed_streams = operation.streams
        self.local_focus = operation.is_focus
        self._id = random_id()
        self._local_identity = operation.sender
        self._remote_identity = operation.recipient
        self._local_jid = self._local_identity.uri.as_xmpp_jid()
        self._remote_jid = self._remote_identity.uri.as_xmpp_jid()

        notification_center.post_notification('JingleSessionNewOutgoing', self, NotificationData(streams=operation.streams))

        for stream in self.proposed_streams:
            notification_center.add_observer(self, sender=stream)
            stream.initialize(self, direction='outgoing')

        try:
            wait_count = len(self.proposed_streams)
            while wait_count > 0:
                notification = operation.channel.wait()
                if notification.name == 'MediaStreamDidInitialize':
                    wait_count -= 1
            # Build local SDP and negotiator
            local_ip = SIPConfig.local_ip.normalized
            local_sdp = SDPSession(local_ip, connection=SDPConnection(local_ip), name=settings.user_agent)
            for index, stream in enumerate(self.proposed_streams):
                stream.index = index
                media = stream.get_local_media(remote_sdp=None, index=index)
                local_sdp.media.append(media)
            self._sdp_negotiator = SDPNegotiator.create_with_local_offer(local_sdp)
            # Build the payload and send it over
            payload = sdp_to_jingle(local_sdp)
            payload.sid = self._id
            if self.local_focus:
                payload.conference_info = jingle.ConferenceInfo(True)
            stanza = self._protocol.sessionInitiate(self._local_jid, self._remote_jid, payload)
            d = self._send_stanza(stanza)
            block_on(d)
        except (MediaStreamDidNotInitializeError, MediaStreamDidFailError, IqTimeoutError, StanzaError, SIPCoreError), e:
            for stream in self.proposed_streams:
                notification_center.remove_observer(self, sender=stream)
                stream.deactivate()
                stream.end()
            if isinstance(e, IqTimeoutError):
                error = 'timeout sending IQ stanza'
            elif isinstance(e, StanzaError):
                error = str(e.condition)
            elif isinstance(e, SIPCoreError):
                error = str(e)
            else:
                error = 'media stream failed: %s' % e.data.reason
            self.state = 'terminated'
            NotificationCenter().post_notification('JingleSessionDidFail', sender=self, data=NotificationData(originator='local', reason=error))
            self._channel.send_exception(proc.ProcExit)
Beispiel #2
0
    def _OH_AcceptOperation(self, operation):
        if self.state != 'incoming':
            return

        notification_center = NotificationCenter()
        settings = SIPSimpleSettings()
        streams = operation.streams

        for stream in self.proposed_streams:
            if stream in streams:
                notification_center.add_observer(self, sender=stream)
                stream.initialize(self, direction='incoming')

        try:
            wait_count = len(self.proposed_streams)
            while wait_count > 0:
                notification = operation.channel.wait()
                if notification.name == 'MediaStreamDidInitialize':
                    wait_count -= 1

            remote_sdp = self._sdp_negotiator.current_remote
            local_ip = SIPConfig.local_ip.normalized
            local_sdp = SDPSession(local_ip, connection=SDPConnection(local_ip), name=settings.user_agent)
            stream_map = dict((stream.index, stream) for stream in self.proposed_streams)
            for index, media in enumerate(remote_sdp.media):
                stream = stream_map.get(index, None)
                if stream is not None:
                    media = stream.get_local_media(remote_sdp=remote_sdp, index=index)
                else:
                    media = SDPMediaStream.new(media)
                    media.port = 0
                    media.attributes = []
                local_sdp.media.append(media)
            try:
                self._sdp_negotiator.set_local_answer(local_sdp)
                self._sdp_negotiator.negotiate()
            except SIPCoreError, e:
                self._fail(originator='local', reason='incompatible-parameters', description=str(e))
                return

            self.local_focus = operation.is_focus

            notification_center.post_notification('JingleSessionWillStart', sender=self)

            # Get active SDPs (negotiator may make changes)
            local_sdp = self._sdp_negotiator.active_local
            remote_sdp = self._sdp_negotiator.active_remote

            # Build the payload and send it over
            payload = sdp_to_jingle(local_sdp)
            payload.sid = self._id
            if self.local_focus:
                payload.conference_info = jingle.ConferenceInfo(True)
            stanza = self._protocol.sessionAccept(self._local_jid, self._remote_jid, payload)
            d = self._send_stanza(stanza)
            block_on(d)

            wait_count = 0
            stream_map = dict((stream.index, stream) for stream in self.proposed_streams)
            for index, local_media in enumerate(local_sdp.media):
                remote_media = remote_sdp.media[index]
                stream = stream_map.get(index, None)
                if stream is not None:
                    if remote_media.port:
                        wait_count += 1
                        stream.start(local_sdp, remote_sdp, index)
                    else:
                        notification_center.remove_observer(self, sender=stream)
                        self.proposed_streams.remove(stream)
                        del stream_map[stream.index]
                        stream.deactivate()
                        stream.end()
            removed_streams = [stream for stream in self.proposed_streams if stream.index >= len(local_sdp.media)]
            for stream in removed_streams:
                notification_center.remove_observer(self, sender=stream)
                self.proposed_streams.remove(stream)
                del stream_map[stream.index]
                stream.deactivate()
                stream.end()
            with api.timeout(self.media_stream_timeout):
                while wait_count > 0:
                    notification = operation.channel.wait()
                    if notification.name == 'MediaStreamDidStart':
                        wait_count -= 1