def start(self, local_sdp, remote_sdp, stream_index): self.greenlet = api.getcurrent() notification_center = NotificationCenter() context = 'sdp_negotiation' try: remote_media = remote_sdp.media[stream_index] self.remote_media = remote_media self.remote_accept_types = remote_media.attributes.getfirst( b'accept-types', b'').decode().split() self.remote_accept_wrapped_types = remote_media.attributes.getfirst( b'accept-wrapped-types', b'').decode().split() self.cpim_enabled = contains_mime_type( self.accept_types, 'message/cpim') and contains_mime_type( self.remote_accept_types, 'message/cpim') remote_uri_path = remote_media.attributes.getfirst(b'path') if remote_uri_path is None: raise AttributeError( "remote SDP media does not have 'path' attribute") full_remote_path = [ URI.parse(uri) for uri in remote_uri_path.decode().split() ] remote_transport = 'tls' if full_remote_path[0].use_tls else 'tcp' if self.transport != remote_transport: raise MSRPStreamError( "remote transport ('%s') different from local transport ('%s')" % (remote_transport, self.transport)) if isinstance(self.session.account, Account) and self.local_role == 'actpass': remote_setup = remote_media.attributes.getfirst( 'setup', 'passive') if remote_setup == 'passive': # If actpass is offered connectors are always started as passive # We need to switch to active if the remote answers with passive if self.session.account.msrp.connection_model == 'relay': self.msrp_connector.mode = 'active' else: local_uri = self.msrp_connector.local_uri logger = self.msrp_connector.logger self.msrp_connector = DirectConnector( logger=logger, use_sessmatch=True) self.msrp_connector.prepare(local_uri) context = 'start' self.msrp = self.msrp_connector.complete(full_remote_path) if self.msrp_session_class is not None: self.msrp_session = self.msrp_session_class( self.msrp, accept_types=self.accept_types, on_incoming_cb=self._handle_incoming, automatic_reports=False) self.msrp_connector = None except Exception as e: self._failure_reason = str(e) traceback.print_exc() notification_center.post_notification( 'MediaStreamDidFail', sender=self, data=NotificationData(context=context, reason=self._failure_reason)) else: notification_center.post_notification('MediaStreamDidStart', sender=self) finally: self.greenlet = None
def initialize(self, session, direction): self.greenlet = api.getcurrent() notification_center = NotificationCenter() notification_center.add_observer(self, sender=self) try: self.session = session self.transport = self.session.account.msrp.transport outgoing = direction == 'outgoing' logger = NotificationProxyLogger() if self.session.account is BonjourAccount(): if outgoing: self.msrp_connector = DirectConnector(logger=logger) self.local_role = 'active' else: if self.transport == 'tls' and None in ( self.session.account.tls_credentials.cert, self.session.account.tls_credentials.key): raise MSRPStreamError( "Cannot accept MSRP connection without a TLS certificate" ) self.msrp_connector = DirectAcceptor(logger=logger) self.local_role = 'passive' else: if self.session.account.msrp.connection_model == 'relay': if not outgoing and self.remote_role in ('actpass', 'passive'): # 'passive' not allowed by the RFC but play nice for interoperability. -Saul self.msrp_connector = DirectConnector( logger=logger, use_sessmatch=True) self.local_role = 'active' elif outgoing and not self.session.account.nat_traversal.use_msrp_relay_for_outbound: self.msrp_connector = DirectConnector( logger=logger, use_sessmatch=True) self.local_role = 'active' else: if self.session.account.nat_traversal.msrp_relay is None: relay_host = relay_port = None else: if self.transport != self.session.account.nat_traversal.msrp_relay.transport: raise MSRPStreamError( "MSRP relay transport conflicts with MSRP transport setting" ) relay_host = self.session.account.nat_traversal.msrp_relay.host relay_port = self.session.account.nat_traversal.msrp_relay.port relay = MSRPRelaySettings( domain=self.session.account.uri.host.decode(), username=self.session.account.uri.user.decode(), password=self.session.account.credentials.password. decode(), host=relay_host, port=relay_port, use_tls=self.transport == 'tls') self.msrp_connector = RelayConnection( relay, 'passive', logger=logger, use_sessmatch=True) self.local_role = 'actpass' if outgoing else 'passive' else: if not outgoing and self.remote_role in ('actpass', 'passive'): # 'passive' not allowed by the RFC but play nice for interoperability. -Saul self.msrp_connector = DirectConnector( logger=logger, use_sessmatch=True) self.local_role = 'active' else: if not outgoing and self.transport == 'tls' and None in ( self.session.account.tls_credentials.cert, self.session.account.tls_credentials.key): raise MSRPStreamError( "Cannot accept MSRP connection without a TLS certificate" ) self.msrp_connector = DirectAcceptor( logger=logger, use_sessmatch=True) self.local_role = 'actpass' if outgoing else 'passive' full_local_path = self.msrp_connector.prepare(local_uri=URI( host=host.default_ip, port=0, use_tls=self.transport == 'tls', credentials=self.session.account.tls_credentials)) self.local_media = self._create_local_media(full_local_path) except (CertificateError, CertificateAuthorityError, CertificateExpiredError, CertificateSecurityError, CertificateRevokedError) as e: reason = "%s for %s" % (e.error, e.certificate.subject.CN.lower()) notification_center.post_notification( 'MediaStreamDidNotInitialize', sender=self, data=NotificationData(reason=reason)) except Exception as e: notification_center.post_notification( 'MediaStreamDidNotInitialize', sender=self, data=NotificationData(reason=str(e))) else: notification_center.post_notification('MediaStreamDidInitialize', sender=self) finally: self._initialize_done = True self.greenlet = None
def get_client_uri(self): return URI(use_tls=self.use_tls)
def get_server_uri(self): return URI(port=0, use_tls=self.use_tls, credentials=self.server_credentials)
# Copyright (C) 2008-2009 AG Projects. See LICENSE for details. # import sys from eventlib import proc from msrplib.connect import AcceptorDirect from msrplib.protocol import URI from msrplib.trafficlog import Logger from msrplib.session import GreenMSRPSession from twisted.internet import reactor # let eventlib know we want twisted-based hub local_uri = URI(session_id='server', use_tls=False) remote_uri = URI(session_id='client', use_tls=False) connector = AcceptorDirect(logger=Logger()) connector.prepare(local_uri) transport = connector.complete([remote_uri]) session = GreenMSRPSession(transport) session.send_message('hello', 'text/plain') print 'received: %s' % session.receive_chunk().data session.shutdown()