예제 #1
0
    def incoming_message(self, message_request, data):
        content_type = data.headers.get("Content-Type", Null).content_type
        from_header = data.headers.get("From", Null)
        to_header = data.headers.get("To", Null)
        if Null in (content_type, from_header, to_header):
            message_request.answer(400)
            return
        log.msg("New SIP Message from %s to %s" % (from_header.uri, to_header.uri))

        # Check domain
        if from_header.uri.host not in XMPPGatewayConfig.domains:
            log.msg("Message rejected: From domain is not a local XMPP domain")
            message_request.answer(606)
            return

        if content_type == "message/cpim":
            try:
                cpim_message = CPIMPayload.decode(data.body)
            except CPIMParserError:
                log.msg("Message rejected: CPIM parse error")
                message_request.answer(400)
                return
            else:
                body = cpim_message.content
                content_type = cpim_message.content_type
                sender = cpim_message.sender or from_header
                from_uri = sender.uri
        else:
            body = data.body
            from_uri = from_header.uri
        to_uri = str(to_header.uri)
        message_request.answer(200)
        if from_uri.parameters.get("gr", None) is None:
            from_uri = SIPURI.new(from_uri)
            from_uri.parameters["gr"] = generate_sylk_resource()
        sender = Identity(FrozenURI.parse(from_uri))
        recipient = Identity(FrozenURI.parse(to_uri))
        if content_type in ("text/plain", "text/html"):
            if content_type == "text/plain":
                html_body = None
            else:
                html_body = body
                body = None
            if XMPPGatewayConfig.use_msrp_for_chat:
                message = NormalMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
            else:
                message = ChatMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
        elif content_type == IsComposingDocument.content_type:
            if not XMPPGatewayConfig.use_msrp_for_chat:
                try:
                    msg = IsComposingMessage.parse(body)
                except ParserError:
                    pass
                else:
                    state = "composing" if msg.state == "active" else "paused"
                    message = ChatComposingIndication(sender, recipient, state, use_receipt=False)
                    self.xmpp_manager.send_stanza(message)
예제 #2
0
    def incoming_message(self, message_request, data):
        content_type = data.headers.get('Content-Type', Null).content_type
        from_header = data.headers.get('From', Null)
        to_header = data.headers.get('To', Null)
        if Null in (content_type, from_header, to_header):
            message_request.answer(400)
            return
        log.msg('New SIP Message from %s to %s' % (from_header.uri, to_header.uri))

        # Check domain
        if from_header.uri.host not in XMPPGatewayConfig.domains:
            log.msg('Message rejected: From domain is not a local XMPP domain')
            message_request.answer(606)
            return

        if content_type == 'message/cpim':
            try:
                cpim_message = CPIMMessage.parse(data.body)
            except CPIMParserError:
                log.msg('Message rejected: CPIM parse error')
                message_request.answer(400)
                return
            else:
                body = cpim_message.body
                content_type = cpim_message.content_type
                sender = cpim_message.sender or from_header
                from_uri = sender.uri
        else:
            body = data.body
            from_uri = from_header.uri
        to_uri = str(to_header.uri)
        message_request.answer(200)
        if from_uri.parameters.get('gr', None) is None:
            from_uri = SIPURI.new(from_uri)
            from_uri.parameters['gr'] = generate_sylk_resource()
        sender = Identity(FrozenURI.parse(from_uri))
        recipient = Identity(FrozenURI.parse(to_uri))
        if content_type in ('text/plain', 'text/html'):
            if content_type == 'text/plain':
                html_body = None
            else:
                html_body = body
                body = None
            if XMPPGatewayConfig.use_msrp_for_chat:
                message = NormalMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
            else:
                message = ChatMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
        elif content_type == IsComposingDocument.content_type:
            if not XMPPGatewayConfig.use_msrp_for_chat:
                try:
                    msg = IsComposingMessage.parse(body)
                except ParserError:
                    pass
                else:
                    state = 'composing' if msg.state == 'active' else 'paused'
                    message = ChatComposingIndication(sender, recipient, state, use_receipt=False)
                    self.xmpp_manager.send_stanza(message)
예제 #3
0
    def incoming_message(self, message_request, data):
        content_type = data.headers.get('Content-Type', Null).content_type
        from_header = data.headers.get('From', Null)
        to_header = data.headers.get('To', Null)
        if Null in (content_type, from_header, to_header):
            message_request.answer(400)
            return
        log.info('New SIP Message from %s to %s' % (from_header.uri, to_header.uri))

        # Check domain
        if from_header.uri.host not in XMPPGatewayConfig.domains:
            log.info('Message rejected: From domain is not a local XMPP domain')
            message_request.answer(606)
            return

        if content_type == 'message/cpim':
            try:
                cpim_message = CPIMPayload.decode(data.body)
            except CPIMParserError:
                log.info('Message rejected: CPIM parse error')
                message_request.answer(400)
                return
            else:
                body = cpim_message.content
                content_type = cpim_message.content_type
                sender = cpim_message.sender or from_header
                from_uri = sender.uri
        else:
            body = data.body
            from_uri = from_header.uri
        to_uri = str(to_header.uri)
        message_request.answer(200)
        if from_uri.parameters.get('gr', None) is None:
            from_uri = SIPURI.new(from_uri)
            from_uri.parameters['gr'] = generate_sylk_resource()
        sender = Identity(FrozenURI.parse(from_uri))
        recipient = Identity(FrozenURI.parse(to_uri))
        if content_type in ('text/plain', 'text/html'):
            if content_type == 'text/plain':
                html_body = None
            else:
                html_body = body
                body = None
            if XMPPGatewayConfig.use_msrp_for_chat:
                message = NormalMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
            else:
                message = ChatMessage(sender, recipient, body, html_body, use_receipt=False)
                self.xmpp_manager.send_stanza(message)
        elif content_type == IsComposingDocument.content_type:
            if not XMPPGatewayConfig.use_msrp_for_chat:
                try:
                    msg = IsComposingMessage.parse(body)
                except ParserError:
                    pass
                else:
                    state = 'composing' if msg.state == 'active' else 'paused'
                    message = ChatComposingIndication(sender, recipient, state, use_receipt=False)
                    self.xmpp_manager.send_stanza(message)
예제 #4
0
 def unavailableReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     presence_stanza = MUCAvailabilityPresence(sender, recipient, available=False, id=id)
     NotificationCenter().post_notification('XMPPMucGotPresenceAvailability', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
예제 #5
0
    def send_available(self, stanza):
        sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
        sender = Identity(sender_uri)
        recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
        recipient = Identity(recipient_uri)

        available = AvailabilityPresence(sender=recipient, recipient=sender)
        self.send(available.to_xml_element())
예제 #6
0
 def unavailableReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     presence_stanza = MUCAvailabilityPresence(sender, recipient, available=False, id=id)
     NotificationCenter().post_notification('XMPPMucGotPresenceAvailability', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
예제 #7
0
 def probeReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     presence_stanza = ProbePresence(sender, recipient, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceProbe', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
예제 #8
0
 def probeReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     presence_stanza = ProbePresence(sender, recipient, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceProbe', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
예제 #9
0
    def send_available(self, stanza):
        sender_uri = FrozenURI.parse('xmpp:' + stanza.element['from'])
        sender = Identity(sender_uri)
        recipient_uri = FrozenURI.parse('xmpp:' + stanza.element['to'])
        recipient = Identity(recipient_uri)

        available = AvailabilityPresence(sender=recipient, recipient=sender)
        self.send(available.to_xml_element())
예제 #10
0
 def _process_subscription_stanza(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     type = stanza.element.getAttribute('type')
     presence_stanza = SubscriptionPresence(sender, recipient, type, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceSubscriptionStatus', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
예제 #11
0
 def _process_subscription_stanza(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     type = stanza.element.getAttribute('type')
     presence_stanza = SubscriptionPresence(sender, recipient, type, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceSubscriptionStatus', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
예제 #12
0
 def availableReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     show = stanza.show
     statuses = stanza.statuses
     presence_stanza = AvailabilityPresence(sender, recipient, available=True, show=show, statuses=statuses, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceAvailability', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
예제 #13
0
 def availableReceived(self, stanza):
     sender_uri = FrozenURI.parse('xmpp:'+stanza.element['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+stanza.element['to'])
     recipient = Identity(recipient_uri)
     id = stanza.element.getAttribute('id')
     show = stanza.show
     statuses = stanza.statuses
     presence_stanza = AvailabilityPresence(sender, recipient, available=True, show=show, statuses=statuses, id=id)
     NotificationCenter().post_notification('XMPPGotPresenceAvailability', sender=self.parent, data=NotificationData(presence_stanza=presence_stanza))
예제 #14
0
    def init_incoming(self, stanza):
        self._id = stanza.jingle.sid
        self._local_identity = Identity(FrozenURI.parse(stanza.recipient))
        self._remote_identity = Identity(FrozenURI.parse(stanza.sender))
        self._local_jid = self._local_identity.uri.as_xmpp_jid()
        self._remote_jid = self._remote_identity.uri.as_xmpp_jid()

        remote_sdp = jingle_to_sdp(stanza.jingle)
        try:
            self._sdp_negotiator = SDPNegotiator.create_with_remote_offer(remote_sdp)
        except SIPCoreError, e:
            self._fail(originator='local', reason='general-error', description=str(e))
            return
예제 #15
0
    def init_incoming(self, stanza):
        self._id = stanza.jingle.sid
        self._local_identity = Identity(FrozenURI.parse(stanza.recipient))
        self._remote_identity = Identity(FrozenURI.parse(stanza.sender))
        self._local_jid = self._local_identity.uri.as_xmpp_jid()
        self._remote_jid = self._remote_identity.uri.as_xmpp_jid()

        remote_sdp = jingle_to_sdp(stanza.jingle)
        try:
            self._sdp_negotiator = SDPNegotiator.create_with_remote_offer(remote_sdp)
        except SIPCoreError, e:
            self._fail(originator='local', reason='general-error', description=str(e))
            return
예제 #16
0
 def onInvitation(self, msg):
     sender_uri = FrozenURI.parse('xmpp:'+msg['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+msg['to'])
     recipient = Identity(recipient_uri)
     invited_user_uri = FrozenURI.parse('xmpp:'+msg.x.invite['to'])
     invited_user = Identity(invited_user_uri)
     if msg.x.invite.reason is not None and msg.x.invite.reason.uri == MUC_USER_NS:
         reason = unicode(msg.x.invite.reason)
     else:
         reason = None
     invitation = IncomingInvitationMessage(sender, recipient, invited_user=invited_user, reason=reason, id=msg.getAttribute('id', None))
     NotificationCenter().post_notification('XMPPMucGotInvitation', sender=self.parent, data=NotificationData(invitation=invitation))
예제 #17
0
 def onInvitation(self, msg):
     sender_uri = FrozenURI.parse('xmpp:'+msg['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+msg['to'])
     recipient = Identity(recipient_uri)
     invited_user_uri = FrozenURI.parse('xmpp:'+msg.x.invite['to'])
     invited_user = Identity(invited_user_uri)
     if msg.x.invite.reason is not None and msg.x.invite.reason.uri == MUC_USER_NS:
         reason = unicode(msg.x.invite.reason)
     else:
         reason = None
     invitation = IncomingInvitationMessage(sender, recipient, invited_user=invited_user, reason=reason, id=msg.getAttribute('id', None))
     NotificationCenter().post_notification('XMPPMucGotInvitation', sender=self.parent, data=NotificationData(invitation=invitation))
예제 #18
0
 def onGroupChat(self, msg):
     sender_uri = FrozenURI.parse('xmpp:'+msg['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:'+msg['to'])
     recipient = Identity(recipient_uri)
     body = None
     html_body = None
     if msg.html is not None:
         html_body = msg.html.toXml()
     if msg.body is not None:
         body = unicode(msg.body)
     message = GroupChatMessage(sender, recipient, body, html_body, id=msg.getAttribute('id', None))
     NotificationCenter().post_notification('XMPPMucGotGroupChat', sender=self.parent, data=NotificationData(message=message))
예제 #19
0
파일: im.py 프로젝트: turbojavaC/sylkserver
 def _NH_ChatStreamGotMessage(self, notification):
     # Notification is sent by the MSRP stream
     message = notification.data.message
     content_type = message.content_type.lower()
     if content_type not in ('text/plain', 'text/html'):
         return
     if content_type == 'text/plain':
         html_body = None
         body = message.content
     else:
         html_body = message.content
         body = None
     if self._sip_session_timer is not None and self._sip_session_timer.active(
     ):
         self._sip_session_timer.reset(SESSION_TIMEOUT)
     chunk = notification.data.chunk
     if self.started:
         self.xmpp_session.send_message(body,
                                        html_body,
                                        message_id=chunk.message_id)
         if self.use_receipts:
             self._pending_msrp_chunks[chunk.message_id] = chunk
         else:
             self.msrp_stream.msrp_session.send_report(chunk, 200, 'OK')
     else:
         sender = self.sip_identity
         recipient_uri = FrozenURI.parse(message.recipients[0].uri)
         recipient = Identity(recipient_uri,
                              message.recipients[0].display_name)
         xmpp_manager = XMPPManager()
         xmpp_manager.send_stanza(
             ChatMessage(sender, recipient, body, html_body))
         self.msrp_stream.msrp_session.send_report(chunk, 200, 'OK')
예제 #20
0
파일: im.py 프로젝트: madhawa/sylkserver
 def _NH_ChatStreamGotMessage(self, notification):
     # Notification is sent by the MSRP stream
     message = notification.data.message
     content_type = message.content_type.lower()
     if content_type not in ('text/plain', 'text/html'):
         return
     if content_type == 'text/plain':
         html_body = None
         body = message.body
     else:
         html_body = message.body
         body = None
     if self._sip_session_timer is not None and self._sip_session_timer.active():
         self._sip_session_timer.reset(SESSION_TIMEOUT)
     chunk = notification.data.chunk
     if self.started:
         self.xmpp_session.send_message(body, html_body, message_id=chunk.message_id)
         if self.use_receipts:
             self._pending_msrp_chunks[chunk.message_id] = chunk
         else:
             self.msrp_stream.msrp_session.send_report(chunk, 200, 'OK')
     else:
         sender = self.sip_identity
         recipient_uri = FrozenURI.parse(message.recipients[0].uri)
         recipient = Identity(recipient_uri, message.recipients[0].display_name)
         xmpp_manager = XMPPManager()
         xmpp_manager.send_stanza(ChatMessage(sender, recipient, body, html_body))
         self.msrp_stream.msrp_session.send_report(chunk, 200, 'OK')
예제 #21
0
    def init_incoming(self, stanza):
        self._id = stanza.jingle.sid
        self._local_identity = Identity(FrozenURI.parse(stanza.recipient))
        self._remote_identity = Identity(FrozenURI.parse(stanza.sender))
        self._local_jid = self._local_identity.uri.as_xmpp_jid()
        self._remote_jid = self._remote_identity.uri.as_xmpp_jid()

        remote_sdp = jingle_to_sdp(stanza.jingle)
        try:
            self._sdp_negotiator = SDPNegotiator.create_with_remote_offer(
                remote_sdp)
        except SIPCoreError as e:
            self._fail(originator='local',
                       reason='general-error',
                       description=str(e))
            return

        self.proposed_streams = []
        for index, media_stream in enumerate(remote_sdp.media):
            if media_stream.port != 0:
                for stream_type in MediaStreamRegistry:
                    try:
                        stream = stream_type.new_from_sdp(
                            self, remote_sdp, index)
                    except InvalidStreamError:
                        break
                    except UnknownStreamError:
                        continue
                    else:
                        stream.index = index
                        self.proposed_streams.append(stream)
                        break

        if self.proposed_streams:
            self.direction = 'incoming'
            self.state = 'incoming'
            NotificationCenter().post_notification(
                'JingleSessionNewIncoming',
                sender=self,
                data=NotificationData(streams=self.proposed_streams))
        else:
            self._fail(originator='local', reason='unsupported-applications')
예제 #22
0
 def onGroupChat(self, msg):
     sender_uri = FrozenURI.parse('xmpp:' + msg['from'])
     sender = Identity(sender_uri)
     recipient_uri = FrozenURI.parse('xmpp:' + msg['to'])
     recipient = Identity(recipient_uri)
     body = None
     html_body = None
     if msg.html is not None:
         html_body = msg.html.toXml()
     if msg.body is not None:
         body = unicode(msg.body)
     message = GroupChatMessage(sender,
                                recipient,
                                body,
                                html_body,
                                id=msg.getAttribute('id', None))
     NotificationCenter().post_notification(
         'XMPPMucGotGroupChat',
         sender=self.parent,
         data=NotificationData(message=message))
예제 #23
0
    def _start_outgoing_jingle_session(self, streams):
        if self.xmpp_identity.uri.resource is not None:
            self.sip_session.reject()
            return
        xmpp_manager = XMPPManager()
        local_jid = self.sip_identity.uri.as_xmpp_jid()
        remote_jid = self.xmpp_identity.uri.as_xmpp_jid()

        # If this was an invitation to a conference, use the information in the Referred-By header
        if self.sip_identity.uri.host in xmpp_manager.muc_domains and self.sip_session.transfer_info and self.sip_session.transfer_info.referred_by:
            try:
                referred_by_uri = SIPURI.parse(self.sip_session.transfer_info.referred_by)
            except SIPCoreError:
                self.sip_session.reject(488)
                return
            else:
                inviter_uri = FrozenURI(referred_by_uri.user, referred_by_uri.host)
                local_jid = inviter_uri.as_xmpp_jid()

        # Use disco to gather potential JIDs to call
        d = xmpp_manager.disco_client_protocol.requestItems(remote_jid, sender=local_jid)
        try:
            items = block_on(d)
        except Exception:
            items = []
        if not items:
            self.sip_session.reject(480)
            return

        # Check which items support Jingle
        valid = []
        for item in items:
            d = xmpp_manager.disco_client_protocol.requestInfo(item.entity, nodeIdentifier=item.nodeIdentifier, sender=local_jid)
            try:
                info = block_on(d)
            except Exception:
                continue
            if jingle.NS_JINGLE in info.features and jingle.NS_JINGLE_APPS_RTP in info.features:
                valid.append(item.entity)
        if not valid:
            self.sip_session.reject(480)
            return

        # TODO: start multiple sessions?
        self._xmpp_identity = Identity(FrozenURI.parse(valid[0]))

        notification_center = NotificationCenter()
        if self.sip_identity.uri.host in xmpp_manager.muc_domains:
            self.jingle_session = JingleSession(xmpp_manager.jingle_coin_protocol)
        else:
            self.jingle_session = JingleSession(xmpp_manager.jingle_protocol)
        notification_center.add_observer(self, sender=self.jingle_session)
        self.jingle_session.connect(self.sip_identity, self.xmpp_identity, streams, is_focus=self.sip_session.remote_focus)
예제 #24
0
    def _start_outgoing_jingle_session(self, streams):
        if self.xmpp_identity.uri.resource is not None:
            self.sip_session.reject()
            return
        xmpp_manager = XMPPManager()
        local_jid = self.sip_identity.uri.as_xmpp_jid()
        remote_jid = self.xmpp_identity.uri.as_xmpp_jid()

        # If this was an invitation to a conference, use the information in the Referred-By header
        if self.sip_identity.uri.host in xmpp_manager.muc_domains and self.sip_session.transfer_info and self.sip_session.transfer_info.referred_by:
            try:
                referred_by_uri = SIPURI.parse(self.sip_session.transfer_info.referred_by)
            except SIPCoreError:
                self.sip_session.reject(488)
                return
            else:
                inviter_uri = FrozenURI(referred_by_uri.user, referred_by_uri.host)
                local_jid = inviter_uri.as_xmpp_jid()

        # Use disco to gather potential JIDs to call
        d = xmpp_manager.disco_client_protocol.requestItems(remote_jid, sender=local_jid)
        try:
            items = block_on(d)
        except Exception:
            items = []
        if not items:
            self.sip_session.reject(480)
            return

        # Check which items support Jingle
        valid = []
        for item in items:
            d = xmpp_manager.disco_client_protocol.requestInfo(item.entity, nodeIdentifier=item.nodeIdentifier, sender=local_jid)
            try:
                info = block_on(d)
            except Exception:
                continue
            if jingle.NS_JINGLE in info.features and jingle.NS_JINGLE_APPS_RTP in info.features:
                valid.append(item.entity)
        if not valid:
            self.sip_session.reject(480)
            return

        # TODO: start multiple sessions?
        self._xmpp_identity = Identity(FrozenURI.parse(valid[0]))

        notification_center = NotificationCenter()
        if self.sip_identity.uri.host in xmpp_manager.muc_domains:
            self.jingle_session = JingleSession(xmpp_manager.jingle_coin_protocol)
        else:
            self.jingle_session = JingleSession(xmpp_manager.jingle_protocol)
        notification_center.add_observer(self, sender=self.jingle_session)
        self.jingle_session.connect(self.sip_identity, self.xmpp_identity, streams, is_focus=self.sip_session.remote_focus)
예제 #25
0
파일: muc.py 프로젝트: samykabu/sylkserver
 def _NH_SIPSessionGotConferenceInfo(self, notification):
     # Translate to XMPP payload
     xmpp_manager = XMPPManager()
     own_uri = FrozenURI(self.xmpp_identity.uri.user,
                         self.xmpp_identity.uri.host)
     conference_info = notification.data.conference_info
     new_participants = set()
     for user in conference_info.users:
         user_uri = FrozenURI.parse(user.entity if user.entity.startswith((
             'sip:', 'sips:')) else 'sip:' + user.entity)
         nickname = user.display_text.value if user.display_text else user.entity
         new_participants.add((user_uri, nickname))
     # Remove participants that are no longer in the room
     for uri, nickname in self._participants - new_participants:
         sender = Identity(
             FrozenURI(self.sip_identity.uri.user,
                       self.sip_identity.uri.host, nickname))
         stanza = MUCAvailabilityPresence(sender,
                                          self.xmpp_identity,
                                          available=False)
         xmpp_manager.send_muc_stanza(stanza)
     # Send presence for current participants
     for uri, nickname in new_participants:
         if uri == own_uri:
             continue
         sender = Identity(
             FrozenURI(self.sip_identity.uri.user,
                       self.sip_identity.uri.host, nickname))
         stanza = MUCAvailabilityPresence(sender,
                                          self.xmpp_identity,
                                          available=True)
         stanza.jid = Identity(uri)
         xmpp_manager.send_muc_stanza(stanza)
     self._participants = new_participants
     # Send own status last
     sender = Identity(
         FrozenURI(self.sip_identity.uri.user, self.sip_identity.uri.host,
                   self.nickname))
     stanza = MUCAvailabilityPresence(sender,
                                      self.xmpp_identity,
                                      available=True)
     stanza.jid = self.xmpp_identity
     stanza.muc_statuses.append('110')
     xmpp_manager.send_muc_stanza(stanza)
예제 #26
0
 def _onMessage(self, message):
     if message.handled:
         return
     messageType = message.getAttribute("type")
     if messageType == 'error':
         return
     if messageType not in self.messageTypes:
         message['type'] = 'normal'
     if messageType == 'groupchat':
         self.onGroupChat(message)
     else:
         to_uri = FrozenURI.parse('xmpp:' + message['to'])
         if to_uri.host in self.parent.domains:
             # Check if it's an invitation
             if message.x is not None and message.x.invite is not None and message.x.invite.uri == MUC_USER_NS:
                 self.onInvitation(message)
         else:
             # TODO: give error, private messages not supported
             pass
예제 #27
0
 def _onMessage(self, message):
     if message.handled:
         return
     messageType = message.getAttribute("type")
     if messageType == 'error':
         return
     if messageType not in self.messageTypes:
         message['type'] = 'normal'
     if messageType == 'groupchat':
         self.onGroupChat(message)
     else:
         to_uri = FrozenURI.parse('xmpp:'+message['to'])
         if to_uri.host in self.parent.domains:
             # Check if it's an invitation
             if message.x is not None and message.x.invite is not None and message.x.invite.uri == MUC_USER_NS:
                 self.onInvitation(message)
         else:
             # TODO: give error, private messages not supported
             pass
예제 #28
0
 def _process_pidf(self, body):
     try:
         pidf_doc = pidf.PIDF.parse(body)
     except ParserError as e:
         log.warn('Error parsing PIDF document: %s' % e)
         return
     # Build XML stanzas out of PIDF documents
     try:
         person = next(p for p in pidf_doc.persons)
     except StopIteration:
         person = None
     for service in pidf_doc.services:
         sip_contact = self.sip_identity.uri.as_sip_uri()
         if service.device_info is not None:
             sip_contact.parameters[
                 'gr'] = 'urn:uuid:%s' % service.device_info.id
         else:
             sip_contact.parameters['gr'] = service.id
         sender = Identity(FrozenURI.parse(sip_contact))
         if service.status.extended is not None:
             available = service.status.extended != 'offline'
         else:
             available = service.status.basic == 'open'
         stanza = AvailabilityPresence(sender, self.xmpp_identity,
                                       available)
         for note in service.notes:
             stanza.statuses[note.lang] = note
         if service.status.extended is not None:
             if service.status.extended == 'away':
                 stanza.show = 'away'
             elif service.status.extended == 'busy':
                 stanza.show = 'dnd'
         elif person is not None and person.activities is not None:
             activities = set(list(person.activities))
             if 'away' in activities:
                 stanza.show = 'away'
             elif {'holiday', 'vacation'}.intersection(activities):
                 stanza.show = 'xa'
             elif 'busy' in activities:
                 stanza.show = 'dnd'
         self._xmpp_subscription.send_presence(stanza)
예제 #29
0
    def onMessage(self, msg):
        notification_center = NotificationCenter()

        sender_uri = FrozenURI.parse('xmpp:'+msg['from'])
        sender = Identity(sender_uri)
        recipient_uri = FrozenURI.parse('xmpp:'+msg['to'])
        recipient = Identity(recipient_uri)

        msg_type = msg.getAttribute('type')
        msg_id = msg.getAttribute('id', None)
        is_empty = msg.body is None and msg.html is None

        if msg_type == 'error':
            error_type = msg.error['type']
            conditions = [(child.name, child.defaultUri) for child in msg.error.elements()]
            error_message = ErrorStanza('message', sender, recipient, error_type, conditions, id=msg_id)
            notification_center.post_notification('XMPPGotErrorMessage', sender=self.parent, data=NotificationData(error_message=error_message))
            return

        if msg_type in (None, 'normal', 'chat') and not is_empty:
            body = None
            html_body = None
            if msg.html is not None:
                html_body = msg.html.toXml()
            if msg.body is not None:
                body = unicode(msg.body)
            try:
                elem = next(c for c in msg.elements() if c.uri == RECEIPTS_NS)
            except StopIteration:
                use_receipt = False
            else:
                use_receipt = elem.name == u'request'
            if msg_type == 'chat':
                message = ChatMessage(sender, recipient, body, html_body, id=msg_id, use_receipt=use_receipt)
                notification_center.post_notification('XMPPGotChatMessage', sender=self.parent, data=NotificationData(message=message))
            else:
                message = NormalMessage(sender, recipient, body, html_body, id=msg_id, use_receipt=use_receipt)
                notification_center.post_notification('XMPPGotNormalMessage', sender=self.parent, data=NotificationData(message=message))
            return

        # Check if it's a composing indication
        if msg_type == 'chat' and is_empty:
            for elem in msg.elements():
                try:
                    elem = next(c for c in msg.elements() if c.uri == CHATSTATES_NS)
                except StopIteration:
                    pass
                else:
                    composing_indication = ChatComposingIndication(sender, recipient, elem.name, id=msg_id)
                    notification_center.post_notification('XMPPGotComposingIndication', sender=self.parent, data=NotificationData(composing_indication=composing_indication))
                    return

        # Check if it's a receipt acknowledgement
        if is_empty:
            try:
                elem = next(c for c in msg.elements() if c.uri == RECEIPTS_NS)
            except StopIteration:
                pass
            else:
                if elem.name == u'received' and msg_id is not None:
                    receipt = MessageReceipt(sender, recipient, msg_id)
                    notification_center.post_notification('XMPPGotReceipt', sender=self.parent, data=NotificationData(receipt=receipt))
예제 #30
0
class X2SPresenceHandler(object):
    implements(IObserver)

    sip_identity = WriteOnceAttribute()
    xmpp_identity = WriteOnceAttribute()

    def __init__(self, sip_identity, xmpp_identity):
        self.ended = False
        self.sip_identity = sip_identity
        self.xmpp_identity = xmpp_identity
        self.subscribed = False
        self._command_proc = None
        self._command_channel = coros.queue()
        self._data_channel = coros.queue()
        self._sip_subscription = None
        self._sip_subscription_proc = None
        self._sip_subscription_timer = None
        self._xmpp_subscription = None

    def start(self):
        notification_center = NotificationCenter()
        self._xmpp_subscription = XMPPIncomingSubscription(local_identity=self.sip_identity, remote_identity=self.xmpp_identity)
        notification_center.add_observer(self, sender=self._xmpp_subscription)
        self._xmpp_subscription.start()
        self._command_proc = proc.spawn(self._run)
        self._subscribe_sip()
        notification_center.post_notification('X2SPresenceHandlerDidStart', sender=self)

    def end(self):
        if self.ended:
            return
        notification_center = NotificationCenter()
        if self._xmpp_subscription is not None:
            notification_center.remove_observer(self, sender=self._xmpp_subscription)
            self._xmpp_subscription.end()
            self._xmpp_subscription = None
        if self._sip_subscription:
            self._unsubscribe_sip()
        self.ended = True
        notification_center.post_notification('X2SPresenceHandlerDidEnd', sender=self)

    @run_in_green_thread
    def _subscribe_sip(self):
        command = Command('subscribe')
        self._command_channel.send(command)

    @run_in_green_thread
    def _unsubscribe_sip(self):
        command = Command('unsubscribe')
        self._command_channel.send(command)
        command.wait()
        self._command_proc.kill()
        self._command_proc = None

    def _run(self):
        while True:
            command = self._command_channel.wait()
            handler = getattr(self, '_CH_%s' % command.name)
            handler(command)

    def _CH_subscribe(self, command):
        if self._sip_subscription_timer is not None and self._sip_subscription_timer.active():
            self._sip_subscription_timer.cancel()
        self._sip_subscription_timer = None
        if self._sip_subscription_proc is not None:
            subscription_proc = self._sip_subscription_proc
            subscription_proc.kill(InterruptSubscription)
            subscription_proc.wait()
        self._sip_subscription_proc = proc.spawn(self._sip_subscription_handler, command)

    def _CH_unsubscribe(self, command):
        # Cancel any timer which would restart the subscription process
        if self._sip_subscription_timer is not None and self._sip_subscription_timer.active():
            self._sip_subscription_timer.cancel()
        self._sip_subscription_timer = None
        if self._sip_subscription_proc is not None:
            subscription_proc = self._sip_subscription_proc
            subscription_proc.kill(TerminateSubscription)
            subscription_proc.wait()
            self._sip_subscription_proc = None
        command.signal()

    def _process_pidf(self, body):
        try:
            pidf_doc = pidf.PIDF.parse(body)
        except ParserError, e:
            log.warn('Error parsing PIDF document: %s' % e)
            return
        # Build XML stanzas out of PIDF documents
        try:
            person = next(p for p in pidf_doc.persons)
        except StopIteration:
            person = None
        for service in pidf_doc.services:
            sip_contact = self.sip_identity.uri.as_sip_uri()
            if service.device_info is not None:
                sip_contact.parameters['gr'] = 'urn:uuid:%s' % service.device_info.id
            else:
                sip_contact.parameters['gr'] = service.id
            sender = Identity(FrozenURI.parse(sip_contact))
            if service.status.extended is not None:
                available = service.status.extended != 'offline'
            else:
                available = service.status.basic == 'open'
            stanza = AvailabilityPresence(sender, self.xmpp_identity, available)
            for note in service.notes:
                stanza.statuses[note.lang] = note
            if service.status.extended is not None:
                if service.status.extended == 'away':
                    stanza.show = 'away'
                elif service.status.extended == 'busy':
                    stanza.show = 'dnd'
            elif person is not None and person.activities is not None:
                activities = set(list(person.activities))
                if 'away' in activities:
                    stanza.show = 'away'
                elif {'holiday', 'vacation'}.intersection(activities):
                    stanza.show = 'xa'
                elif 'busy' in activities:
                    stanza.show = 'dnd'
            self._xmpp_subscription.send_presence(stanza)
예제 #31
0
    def onMessage(self, msg):
        notification_center = NotificationCenter()

        sender_uri = FrozenURI.parse('xmpp:' + msg['from'])
        sender = Identity(sender_uri)
        recipient_uri = FrozenURI.parse('xmpp:' + msg['to'])
        recipient = Identity(recipient_uri)

        msg_type = msg.getAttribute('type')
        msg_id = msg.getAttribute('id', None)
        is_empty = msg.body is None and msg.html is None

        if msg_type == 'error':
            error_type = msg.error['type']
            conditions = [(child.name, child.defaultUri)
                          for child in msg.error.elements()]
            error_message = ErrorStanza('message',
                                        sender,
                                        recipient,
                                        error_type,
                                        conditions,
                                        id=msg_id)
            notification_center.post_notification(
                'XMPPGotErrorMessage',
                sender=self.parent,
                data=NotificationData(error_message=error_message))
            return

        if msg_type in (None, 'normal', 'chat') and not is_empty:
            body = None
            html_body = None
            if msg.html is not None:
                html_body = msg.html.toXml()
            if msg.body is not None:
                body = unicode(msg.body)
            try:
                elem = next(c for c in msg.elements() if c.uri == RECEIPTS_NS)
            except StopIteration:
                use_receipt = False
            else:
                use_receipt = elem.name == u'request'
            if msg_type == 'chat':
                message = ChatMessage(sender,
                                      recipient,
                                      body,
                                      html_body,
                                      id=msg_id,
                                      use_receipt=use_receipt)
                notification_center.post_notification(
                    'XMPPGotChatMessage',
                    sender=self.parent,
                    data=NotificationData(message=message))
            else:
                message = NormalMessage(sender,
                                        recipient,
                                        body,
                                        html_body,
                                        id=msg_id,
                                        use_receipt=use_receipt)
                notification_center.post_notification(
                    'XMPPGotNormalMessage',
                    sender=self.parent,
                    data=NotificationData(message=message))
            return

        # Check if it's a composing indication
        if msg_type == 'chat' and is_empty:
            for elem in msg.elements():
                try:
                    elem = next(c for c in msg.elements()
                                if c.uri == CHATSTATES_NS)
                except StopIteration:
                    pass
                else:
                    composing_indication = ChatComposingIndication(sender,
                                                                   recipient,
                                                                   elem.name,
                                                                   id=msg_id)
                    notification_center.post_notification(
                        'XMPPGotComposingIndication',
                        sender=self.parent,
                        data=NotificationData(
                            composing_indication=composing_indication))
                    return

        # Check if it's a receipt acknowledgement
        if is_empty:
            try:
                elem = next(c for c in msg.elements() if c.uri == RECEIPTS_NS)
            except StopIteration:
                pass
            else:
                if elem.name == u'received' and msg_id is not None:
                    receipt = MessageReceipt(sender, recipient, msg_id)
                    notification_center.post_notification(
                        'XMPPGotReceipt',
                        sender=self.parent,
                        data=NotificationData(receipt=receipt))