Beispiel #1
0
    def _OH_session_terminate(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                session = data['session']
            except KeyError:
                raise APIError('Invalid parameters: "session" must be specified')

            try:
                session_info = self.sessions_map[session]
            except KeyError:
                raise APIError('Unknown session specified: %s' % session)
            if session_info.state not in ('connecting', 'progress', 'accepted', 'established'):
                raise APIError('Invalid state for session terminate: \"%s\"' % session_info.state)

            if session_info.direction == 'incoming' and session_info.state == 'connecting':
                data = {'request': 'decline', 'code': 486}
            else:
                data = {'request': 'hangup'}
            block_on(self.backend.janus_message(self.janus_session_id, session_info.janus_handle_id, data))
            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('%s terminated session %s' % (session_info.account_id, session))
        except APIError, e:
            log.error('session-terminate: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
Beispiel #2
0
    def _OH_session_answer(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                session = data['session']
                sdp = data['sdp']
            except KeyError:
                raise APIError('Invalid parameters: "session" and "sdp" must be specified')

            try:
                session_info = self.sessions_map[session]
            except KeyError:
                raise APIError('Unknown session specified: %s' % session)

            if session_info.direction != 'incoming':
                raise APIError('Cannot answer outgoing session')
            if session_info.state != 'connecting':
                raise APIError('Invalid state for session answer')

            data = {'request': 'accept'}
            jsep = {'type': 'answer', 'sdp': sdp}
            block_on(self.backend.janus_message(self.janus_session_id, session_info.janus_handle_id, data, jsep))
            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('%s answered session %s' % (session_info.account_id, session))
        except APIError, e:
            log.error('session-answer: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
Beispiel #3
0
    def _OH_session_trickle(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                session = data['session']
                candidates = data['candidates']
            except KeyError:
                raise APIError('Invalid parameters: "session" and "candidates" must be specified')

            try:
                session_info = self.sessions_map[session]
            except KeyError:
                raise APIError('Unknown session specified: %s' % session)
            if session_info.state == 'terminated':
                raise APIError('Session is terminated')

            block_on(self.backend.janus_trickle(self.janus_session_id, session_info.janus_handle_id, candidates))
            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('Trickled ICE candidate(s) for session %s' % session)
        except APIError, e:
            log.error('session-trickle: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
Beispiel #4
0
    def _OH_account_unregister(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                account = data['account']
            except KeyError:
                raise APIError('Invalid parameters: "account" must be specified')

            try:
                account_info = self.accounts_map[account]
            except KeyError:
                raise APIError('Unknown account specified: %s' % account)

            handle_id = account_info.janus_handle_id
            if handle_id is not None:
                block_on(self.backend.janus_detach(self.janus_session_id, handle_id))
                self.backend.janus_set_event_handler(handle_id, None)
                account_info.janus_handle_id = None
                self.account_handles_map.pop(handle_id)

            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('Account %s will unregister' % account)
        except APIError, e:
            log.error('account-unregister: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
Beispiel #5
0
    def _OH_session_create(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                account = data['account']
                session = data['session']
                uri = data['uri']
                sdp = data['sdp']
            except KeyError:
                raise APIError('Invalid parameters: "account", "session", "uri" and "sdp" must be specified')

            try:
                account_info = self.accounts_map[account]
            except KeyError:
                raise APIError('Unknown account specified: %s' % account)

            if session in self.sessions_map:
                raise APIError('Session ID (%s) already in use' % session)

            # Create a new plugin handle and 'register' it, without actually doing so
            handle_id = block_on(self.backend.janus_attach(self.janus_session_id, 'janus.plugin.sip'))
            self.backend.janus_set_event_handler(handle_id, self._handle_janus_event)
            try:
                proxy = self._lookup_sip_proxy(account_info.id)
            except DNSLookupError:
                block_on(self.backend.janus_detach(self.janus_session_id, handle_id))
                self.backend.janus_set_event_handler(handle_id, None)
                raise APIError('DNS lookup error')
            account_uri = 'sip:%s' % account_info.id
            data = {'request': 'register', 'username': account_uri, 'ha1_secret': account_info.password, 'proxy': proxy, 'send_register': False}
            block_on(self.backend.janus_message(self.janus_session_id, handle_id, data))

            session_info = JanusSessionInfo(session)
            session_info.janus_handle_id = handle_id
            session_info.init_outgoing(account, uri)
            self.sessions_map[session_info.id] = session_info
            self.session_handles_map[handle_id] = session_info

            data = {'request': 'call', 'uri': 'sip:%s' % SIP_PREFIX_RE.sub('', uri)}
            jsep = {'type': 'offer', 'sdp': sdp}
            block_on(self.backend.janus_message(self.janus_session_id, handle_id, data, jsep))
            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('Outgoing session %s from %s to %s created' % (session, account, uri))
        except APIError, e:
            log.error('session-create: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
Beispiel #6
0
    def _OH_account_register(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                account = data['account']
            except KeyError:
                raise APIError('Invalid parameters: "account" must be specified')

            try:
                account_info = self.accounts_map[account]
            except KeyError:
                raise APIError('Unknown account specified: %s' % account)

            proxy = self._lookup_sip_proxy(account)

            handle_id = account_info.janus_handle_id
            if handle_id is not None:
                # Destroy the existing plugin handle
                block_on(self.backend.janus_detach(self.janus_session_id, handle_id))
                self.backend.janus_set_event_handler(handle_id, None)
                self.account_handles_map.pop(handle_id)
                account_info.janus_handle_id = None

            # Create a plugin handle
            handle_id = block_on(self.backend.janus_attach(self.janus_session_id, 'janus.plugin.sip'))
            self.backend.janus_set_event_handler(handle_id, self._handle_janus_event)
            account_info.janus_handle_id = handle_id
            self.account_handles_map[handle_id] = account_info

            data = {'request': 'register',
                    'username': account_info.uri,
                    'ha1_secret': account_info.password,
                    'proxy': proxy}
            block_on(self.backend.janus_message(self.janus_session_id, handle_id, data))

            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('Account %s will register' % account)
        except APIError, e:
            log.error('account-register: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
Beispiel #7
0
    def _OH_account_add(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                account = data['account']
                password = data['password']
            except KeyError:
                raise APIError('Invalid parameters: "account" and "password" must be specified')

            if account in self.accounts_map:
                log.warn('Account %s already added' % account)
                data = dict(sylkrtc='error', transaction=transaction, error='Account already added')
                self._send_data(json.dumps(data))
                return

            # Validate URI
            uri = 'sip:%s' % account
            try:
                sip_uri = SIPURI.parse(uri)
            except SIPCoreError:
                raise APIError('Invalid account specified: %s' % account)
            if not {'*', sip_uri.host}.intersection(GeneralConfig.sip_domains):
                raise APIError('SIP domain not allowed: %s' % sip_uri.host)

            # Create and store our mapping
            account_info = AccountInfo(account, password)
            self.accounts_map[account_info.id] = account_info

            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('Account %s added' % account)
        except APIError, e:
            log.error('account_add: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
Beispiel #8
0
            if not {'*', sip_uri.host}.intersection(GeneralConfig.sip_domains):
                raise APIError('SIP domain not allowed: %s' % sip_uri.host)

            # Create and store our mapping
            account_info = AccountInfo(account, password)
            self.accounts_map[account_info.id] = account_info

            data = dict(sylkrtc='ack', transaction=transaction)
            self._send_data(json.dumps(data))
            log.msg('Account %s added' % account)
        except APIError, e:
            log.error('account_add: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))
        except Exception, e:
            log.error('Unexpected error in account_add: %s' % e)
            data = dict(sylkrtc='error', transaction=transaction, error=str(e))
            self._send_data(json.dumps(data))

    def _OH_account_remove(self, data):
        transaction = data.get('transaction', None)
        if transaction is None:
            log.warn('Transaction not specified!')
            return

        try:
            try:
                account = data['account']
            except KeyError:
                raise APIError('Invalid parameters: "account" must be specified')