예제 #1
0
 def _NH_SIPSessionDidFail(self, notification):
     log.msg('Room %s - failed to add %s: %s' % (self.room_uri_str, self.refer_to_uri, notification.data.reason))
     notification.center.remove_observer(self, sender=notification.sender)
     if self._refer_request is not None:
         self._refer_request.end(notification.data.code or 500, notification.data.reason or  notification.data.code)
     self.session = None
     self.streams = []
예제 #2
0
 def _NH_SIPSessionDidFail(self, notification):
     log.msg("Room %s - failed to add %s: %s" % (self.room_uri_str, self.refer_to_uri, notification.data.reason))
     notification.center.remove_observer(self, sender=notification.sender)
     if self._refer_request is not None:
         self._refer_request.end(notification.data.code or 500, notification.data.reason or notification.data.code)
     self.session = None
     self.streams = []
예제 #3
0
 def start(self):
     if not self.refer_to_uri.startswith(('sip:', 'sips:')):
         self.refer_to_uri = 'sip:%s' % self.refer_to_uri
     try:
         self.refer_to_uri = SIPURI.parse(self.refer_to_uri)
     except SIPCoreError:
         log.msg('Room %s - failed to add %s' % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.reject(488)
         return
     notification_center = NotificationCenter()
     notification_center.add_observer(self, sender=self._refer_request)
     if self.method == 'INVITE':
         self._refer_request.accept()
         settings = SIPSimpleSettings()
         account = DefaultAccount()
         if account.sip.outbound_proxy is not None:
             uri = SIPURI(host=account.sip.outbound_proxy.host,
                          port=account.sip.outbound_proxy.port,
                          parameters={'transport': account.sip.outbound_proxy.transport})
         else:
             uri = self.refer_to_uri
         lookup = DNSLookup()
         notification_center.add_observer(self, sender=lookup)
         lookup.lookup_sip_proxy(uri, settings.sip.transport_list)
     elif self.method == 'BYE':
         log.msg('Room %s - %s removed %s from the room' % (self.room_uri_str, self._refer_headers.get('From').uri, self.refer_to_uri))
         self._refer_request.accept()
         conference_application = ConferenceApplication()
         conference_application.remove_participant(self.refer_to_uri, self.room_uri)
         self._refer_request.end(200)
     else:
         self._refer_request.reject(488)
예제 #4
0
 def remove_participant(self, participant_uri, room_uri):
     try:
         room = self.get_room(room_uri)
     except RoomNotFoundError:
         pass
     else:
         log.msg("Room %s - %s removed from conference" % (room_uri, participant_uri))
         room.terminate_sessions(participant_uri)
예제 #5
0
 def remove_participant(self, participant_uri, room_uri):
     try:
         room = self.get_room(room_uri)
     except RoomNotFoundError:
         pass
     else:
         log.msg('Room %s - %s removed from conference' % (room_uri, participant_uri))
         room.terminate_sessions(participant_uri)
예제 #6
0
 def _NH_SIPSessionDidEnd(self, notification):
     # If any stream fails to start we won't get SIPSessionDidFail, we'll get here instead
     log.msg("Room %s - failed to add %s" % (self.room_uri_str, self.refer_to_uri))
     notification.center.remove_observer(self, sender=notification.sender)
     if self._refer_request is not None:
         self._refer_request.end(200)
     self.session = None
     self.streams = []
예제 #7
0
 def _NH_SIPSessionDidEnd(self, notification):
     # If any stream fails to start we won't get SIPSessionDidFail, we'll get here instead
     log.msg('Room %s - failed to add %s' % (self.room_uri_str, self.refer_to_uri))
     notification.center.remove_observer(self, sender=notification.sender)
     if self._refer_request is not None:
         self._refer_request.end(200)
     self.session = None
     self.streams = []
예제 #8
0
 def _NH_SIPSessionDidStart(self, notification):
     notification.center.remove_observer(self, sender=notification.sender)
     if self._refer_request is not None:
         self._refer_request.end(200)
     conference_application = ConferenceApplication()
     conference_application.add_participant(self.session, self.room_uri)
     log.msg("Room %s - %s added %s" % (self.room_uri_str, self._refer_headers.get("From").uri, self.refer_to_uri))
     self.session = None
     self.streams = []
예제 #9
0
 def _NH_SIPSessionDidStart(self, notification):
     notification.center.remove_observer(self, sender=notification.sender)
     if self._refer_request is not None:
         self._refer_request.end(200)
     conference_application = ConferenceApplication()
     conference_application.add_participant(self.session, self.room_uri)
     log.msg('Room %s - %s added %s' % (self.room_uri_str, self._refer_headers.get('From').uri, self.refer_to_uri))
     self.session = None
     self.streams = []
예제 #10
0
 def add_participant(self, session, room_uri):
     # Keep track of the invited participants, we must skip ACL policy
     # for SUBSCRIBE requests
     room_uri_str = '%s@%s' % (room_uri.user, room_uri.host)
     log.msg(u'Room %s - outgoing session to %s started' % (room_uri_str, session.remote_identity.uri))
     d = self.invited_participants_map.setdefault(room_uri_str, {})
     d.setdefault(str(session.remote_identity.uri), 0)
     d[str(session.remote_identity.uri)] += 1
     NotificationCenter().add_observer(self, sender=session)
     room = self.get_room(room_uri, True)
     room.start()
     room.add_session(session)
예제 #11
0
 def add_participant(self, session, room_uri):
     # Keep track of the invited participants, we must skip ACL policy
     # for SUBSCRIBE requests
     room_uri_str = "%s@%s" % (room_uri.user, room_uri.host)
     log.msg(u"Room %s - outgoing session to %s started" % (room_uri_str, session.remote_identity.uri))
     d = self.invited_participants_map.setdefault(room_uri_str, {})
     d.setdefault(str(session.remote_identity.uri), 0)
     d[str(session.remote_identity.uri)] += 1
     NotificationCenter().add_observer(self, sender=session)
     room = self.get_room(room_uri, True)
     room.start()
     room.add_session(session)
예제 #12
0
 def _NH_DNSLookupDidSucceed(self, notification):
     notification_center = NotificationCenter()
     notification_center.remove_observer(self, sender=notification.sender)
     account = DefaultAccount()
     conference_application = ConferenceApplication()
     try:
         room = conference_application.get_room(self.room_uri)
     except RoomNotFoundError:
         log.msg("Room %s - failed to add %s" % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     active_media = set(room.active_media).intersection(("audio", "chat"))
     if not active_media:
         log.msg("Room %s - failed to add %s" % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     registry = MediaStreamRegistry()
     for stream_type in active_media:
         self.streams.append(registry.get(stream_type)())
     self.session = Session(account)
     notification_center.add_observer(self, sender=self.session)
     original_from_header = self._refer_headers.get("From")
     if original_from_header.display_name:
         original_identity = "%s <%s@%s>" % (
             original_from_header.display_name,
             original_from_header.uri.user,
             original_from_header.uri.host,
         )
     else:
         original_identity = "%s@%s" % (original_from_header.uri.user, original_from_header.uri.host)
     from_header = FromHeader(SIPURI.new(self.room_uri), u"Conference Call")
     to_header = ToHeader(self.refer_to_uri)
     extra_headers = []
     if self._refer_headers.get("Referred-By", None) is not None:
         extra_headers.append(Header.new(self._refer_headers.get("Referred-By")))
     else:
         extra_headers.append(Header("Referred-By", str(original_from_header.uri)))
     if ThorNodeConfig.enabled:
         extra_headers.append(Header("Thor-Scope", "conference-invitation"))
     extra_headers.append(Header("X-Originator-From", str(original_from_header.uri)))
     extra_headers.append(SubjectHeader(u"Join conference request from %s" % original_identity))
     route = notification.data.result[0]
     self.session.connect(
         from_header, to_header, route=route, streams=self.streams, is_focus=True, extra_headers=extra_headers
     )
예제 #13
0
    def incoming_referral(self, refer_request, data):
        from_header = data.headers.get('From', Null)
        to_header = data.headers.get('To', Null)
        refer_to_header = data.headers.get('Refer-To', Null)
        if Null in (from_header, to_header, refer_to_header):
            refer_request.reject(400)
            return

        log.msg(u'Room %s - join request from %s to %s' % ('%s@%s' % (to_header.uri.user, to_header.uri.host), from_header.uri, refer_to_header.uri))

        try:
            self.validate_acl(data.request_uri, from_header.uri)
        except ACLValidationError:
            log.msg(u'Room %s - invite participant request rejected: unauthorized by access list' % data.request_uri)
            refer_request.reject(403)
            return
        referral_handler = IncomingReferralHandler(refer_request, data)
        referral_handler.start()
예제 #14
0
    def start(self):
        self.web = ConferenceWeb(self)
        web_server.register_resource("conference", self.web.resource())

        # cleanup old files
        for path in (ConferenceConfig.file_transfer_dir, ConferenceConfig.screensharing_images_dir):
            try:
                shutil.rmtree(path)
            except EnvironmentError:
                pass

        if ServerConfig.enable_bonjour and ServerConfig.default_application == "conference":
            self.bonjour_focus_service = BonjourService(service="sipfocus")
            self.bonjour_focus_service.start()
            log.msg("Bonjour publication started for service 'sipfocus'")
            self.bonjour_room_service = BonjourService(service="sipuri", name="Conference Room", uri_user="******")
            self.bonjour_room_service.start()
            self.bonjour_room_service.presence_state = BonjourPresenceState("available", u"No participants")
            log.msg("Bonjour publication started for service 'sipuri'")
예제 #15
0
    def start(self):
        self.web = ConferenceWeb(self)
        web_server.register_resource('conference', self.web.resource())

        # cleanup old files
        for path in (ConferenceConfig.file_transfer_dir, ConferenceConfig.screensharing_images_dir):
            try:
                shutil.rmtree(path)
            except EnvironmentError:
                pass

        if ServerConfig.enable_bonjour and ServerConfig.default_application == 'conference':
            self.bonjour_focus_service = BonjourService(service='sipfocus')
            self.bonjour_focus_service.start()
            log.msg("Bonjour publication started for service 'sipfocus'")
            self.bonjour_room_service = BonjourService(service='sipuri', name='Conference Room', uri_user='******')
            self.bonjour_room_service.start()
            self.bonjour_room_service.presence_state = BonjourPresenceState('available', u'No participants')
            log.msg("Bonjour publication started for service 'sipuri'")
예제 #16
0
 def _NH_DNSLookupDidSucceed(self, notification):
     notification_center = NotificationCenter()
     notification_center.remove_observer(self, sender=notification.sender)
     account = DefaultAccount()
     conference_application = ConferenceApplication()
     try:
         room = conference_application.get_room(self.room_uri)
     except RoomNotFoundError:
         log.msg('Room %s - failed to add %s' % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     active_media = set(room.active_media).intersection(('audio', 'chat'))
     if not active_media:
         log.msg('Room %s - failed to add %s' % (self.room_uri_str, self.refer_to_uri))
         self._refer_request.end(500)
         return
     for stream_type in active_media:
         self.streams.append(MediaStreamRegistry.get(stream_type)())
     self.session = Session(account)
     notification_center.add_observer(self, sender=self.session)
     original_from_header = self._refer_headers.get('From')
     if original_from_header.display_name:
         original_identity = "%s <%s@%s>" % (original_from_header.display_name, original_from_header.uri.user, original_from_header.uri.host)
     else:
         original_identity = "%s@%s" % (original_from_header.uri.user, original_from_header.uri.host)
     from_header = FromHeader(SIPURI.new(self.room_uri), u'Conference Call')
     to_header = ToHeader(self.refer_to_uri)
     extra_headers = []
     if self._refer_headers.get('Referred-By', None) is not None:
         extra_headers.append(Header.new(self._refer_headers.get('Referred-By')))
     else:
         extra_headers.append(Header('Referred-By', str(original_from_header.uri)))
     if ThorNodeConfig.enabled:
         extra_headers.append(Header('Thor-Scope', 'conference-invitation'))
     extra_headers.append(Header('X-Originator-From', str(original_from_header.uri)))
     extra_headers.append(SubjectHeader(u'Join conference request from %s' % original_identity))
     route = notification.data.result[0]
     self.session.connect(from_header, to_header, route=route, streams=self.streams, is_focus=True, extra_headers=extra_headers)
예제 #17
0
    def incoming_subscription(self, subscribe_request, data):
        from_header = data.headers.get("From", Null)
        to_header = data.headers.get("To", Null)
        if Null in (from_header, to_header):
            subscribe_request.reject(400)
            return

        if subscribe_request.event != "conference":
            log.msg(u"Subscription for event %s rejected: only conference event is supported" % subscribe_request.event)
            subscribe_request.reject(489)
            return

        try:
            self.validate_acl(data.request_uri, from_header.uri)
        except ACLValidationError:
            try:
                self.validate_acl(to_header.uri, from_header.uri)
            except ACLValidationError:
                # Check if we need to skip the ACL because this was an invited participant
                if not (
                    str(from_header.uri)
                    in self.invited_participants_map.get("%s@%s" % (data.request_uri.user, data.request_uri.host), {})
                    or str(from_header.uri)
                    in self.invited_participants_map.get("%s@%s" % (to_header.uri.user, to_header.uri.host), {})
                ):
                    log.msg(u"Subscription rejected: unauthorized by access list")
                    subscribe_request.reject(403)
                    return
        try:
            room = self.get_room(data.request_uri)
        except RoomNotFoundError:
            try:
                room = self.get_room(to_header.uri)
            except RoomNotFoundError:
                log.msg(u"Subscription rejected: room not yet created")
                subscribe_request.reject(480)
                return
        if not room.started:
            log.msg(u"Subscription rejected: room not started yet")
            subscribe_request.reject(480)
        else:
            room.handle_incoming_subscription(subscribe_request, data)
예제 #18
0
    def incoming_subscription(self, subscribe_request, data):
        from_header = data.headers.get('From', Null)
        to_header = data.headers.get('To', Null)
        if Null in (from_header, to_header):
            subscribe_request.reject(400)
            return

        if subscribe_request.event != 'conference':
            log.msg(u'Subscription for event %s rejected: only conference event is supported' % subscribe_request.event)
            subscribe_request.reject(489)
            return

        try:
            self.validate_acl(data.request_uri, from_header.uri)
        except ACLValidationError:
            try:
                self.validate_acl(to_header.uri, from_header.uri)
            except ACLValidationError:
                # Check if we need to skip the ACL because this was an invited participant
                if not (str(from_header.uri) in self.invited_participants_map.get('%s@%s' % (data.request_uri.user, data.request_uri.host), {}) or
                        str(from_header.uri) in self.invited_participants_map.get('%s@%s' % (to_header.uri.user, to_header.uri.host), {})):
                    log.msg(u'Subscription rejected: unauthorized by access list')
                    subscribe_request.reject(403)
                    return
        try:
            room = self.get_room(data.request_uri)
        except RoomNotFoundError:
            try:
                room = self.get_room(to_header.uri)
            except RoomNotFoundError:
                log.msg(u'Subscription rejected: room not yet created')
                subscribe_request.reject(480)
                return
        if not room.started:
            log.msg(u'Subscription rejected: room not started yet')
            subscribe_request.reject(480)
        else:
            room.handle_incoming_subscription(subscribe_request, data)
예제 #19
0
    def incoming_session(self, session):
        log.msg('New session from %s to %s' % (session.remote_identity.uri, session.local_identity.uri))
        audio_streams = [stream for stream in session.proposed_streams if stream.type=='audio']
        chat_streams = [stream for stream in session.proposed_streams if stream.type=='chat']
        transfer_streams = [stream for stream in session.proposed_streams if stream.type=='file-transfer']
        if not audio_streams and not chat_streams and not transfer_streams:
            log.msg(u'Session rejected: invalid media, only RTP audio and MSRP chat are supported')
            session.reject(488)
            return
        audio_stream = audio_streams[0] if audio_streams else None
        chat_stream = chat_streams[0] if chat_streams else None
        transfer_stream = transfer_streams[0] if transfer_streams else None

        try:
            self.validate_acl(session.request_uri, session.remote_identity.uri)
        except ACLValidationError:
            log.msg(u'Session rejected: unauthorized by access list')
            session.reject(403)
            return

        if transfer_stream is not None:
            try:
                room = self.get_room(session.request_uri)
            except RoomNotFoundError:
                log.msg(u'Session rejected: room not found')
                session.reject(404)
                return
            if transfer_stream.direction == 'sendonly':
                # file transfer 'pull'
                try:
                    file = next(file for file in room.files if file.hash == transfer_stream.file_selector.hash)
                except StopIteration:
                    log.msg(u'Session rejected: requested file not found')
                    session.reject(404)
                    return
                try:
                    transfer_stream.file_selector = file.file_selector
                except EnvironmentError, e:
                    log.msg(u'Session rejected: error opening requested file: %s' % e)
                    session.reject(404)
                    return
            else:
                transfer_stream.handler.save_directory = os.path.join(ConferenceConfig.file_transfer_dir.normalized, room.uri)
예제 #20
0
 def incoming_message(self, message_request, data):
     log.msg(u'SIP MESSAGE is not supported, use MSRP media instead')
     message_request.answer(405)
예제 #21
0
 def _NH_SIPSessionDidFail(self, notification):
     session = notification.sender
     notification.center.remove_observer(self, sender=session)
     log.msg(u'Session from %s failed: %s' % (session.remote_identity.uri, notification.data.reason))
예제 #22
0
    def incoming_session(self, session):
        log.msg("New session from %s to %s" % (session.remote_identity.uri, session.local_identity.uri))
        audio_streams = [stream for stream in session.proposed_streams if stream.type == "audio"]
        chat_streams = [stream for stream in session.proposed_streams if stream.type == "chat"]
        transfer_streams = [stream for stream in session.proposed_streams if stream.type == "file-transfer"]
        if not audio_streams and not chat_streams and not transfer_streams:
            log.msg(u"Session rejected: invalid media, only RTP audio and MSRP chat are supported")
            session.reject(488)
            return
        audio_stream = audio_streams[0] if audio_streams else None
        chat_stream = chat_streams[0] if chat_streams else None
        transfer_stream = transfer_streams[0] if transfer_streams else None

        try:
            self.validate_acl(session.request_uri, session.remote_identity.uri)
        except ACLValidationError:
            log.msg(u"Session rejected: unauthorized by access list")
            session.reject(403)
            return

        if transfer_stream is not None:
            try:
                room = self.get_room(session.request_uri)
            except RoomNotFoundError:
                log.msg(u"Session rejected: room not found")
                session.reject(404)
                return
            if transfer_stream.direction == "sendonly":
                # file transfer 'pull'
                try:
                    file = next(file for file in room.files if file.hash == transfer_stream.file_selector.hash)
                except StopIteration:
                    log.msg(u"Session rejected: requested file not found")
                    session.reject(404)
                    return
                try:
                    transfer_stream.file_selector = file.file_selector
                except EnvironmentError, e:
                    log.msg(u"Session rejected: error opening requested file: %s" % e)
                    session.reject(404)
                    return
            else:
                transfer_stream.handler.save_directory = os.path.join(
                    ConferenceConfig.file_transfer_dir.normalized, room.uri
                )
예제 #23
0
 def incoming_message(self, message_request, data):
     log.msg(u"SIP MESSAGE is not supported, use MSRP media instead")
     message_request.answer(405)
예제 #24
0
 def _NH_SIPSessionDidFail(self, notification):
     session = notification.sender
     notification.center.remove_observer(self, sender=session)
     log.msg(u"Session from %s failed: %s" % (session.remote_identity.uri, notification.data.reason))