Dateien nach „slixmpp/plugins/xep_0166“ hochladen

This commit is contained in:
apprenticius 2024-12-27 12:02:06 +00:00
parent 0338a40b56
commit 8abc9e4ab2
3 changed files with 346 additions and 0 deletions

View File

@ -0,0 +1,11 @@
# slixmpp: The Slick XMPP Library
# Copyright (C) 2020 Emmanuel Gil Peyrot
# This file is part of slixmpp.
# See the file LICENSE for copying permission.
from slixmpp.plugins.base import register_plugin
from slixmpp.plugins.xep_0166.stanza import Jingle, Content, Reason, Success, Cancel, Thread, Text
from slixmpp.plugins.xep_0166.jingle import XEP_0166
register_plugin(XEP_0166)

View File

@ -0,0 +1,228 @@
# slixmpp: The Slick XMPP Library
# Copyright (C) 2020 Emmanuel Gil Peyrot
# This file is part of slixmpp.
# See the file LICENSE for copying permission.
import logging
from slixmpp import Iq
from slixmpp.plugins import BasePlugin
from slixmpp.xmlstream import register_stanza_plugin
from slixmpp.xmlstream.handler import Callback
from slixmpp.xmlstream.matcher import StanzaPath
from slixmpp.plugins.xep_0166 import stanza, Jingle, Content, Reason, Cancel, Thread, Text
import re
log = logging.getLogger(__name__)
class XEP_0166(BasePlugin):
name = 'xep_0166'
description = 'XEP-0166: Jingle'
stanza = stanza
def plugin_init(self):
register_stanza_plugin(Iq,Jingle)
register_stanza_plugin(Jingle,Content, True)
register_stanza_plugin(Jingle,Reason)
register_stanza_plugin(Reason,Text)
register_stanza_plugin(Jingle,Thread)
self.xmpp.register_handler(
Callback('Accept Content',
StanzaPath('iq/jingle@action=content-accept'),
self._handle_content_accept))
self.xmpp.register_handler(
Callback('Add Content',
StanzaPath('iq/jingle@action=content-add'),
self._handle_content_add))
self.xmpp.register_handler(
Callback('Modify Content',
StanzaPath('iq/jingle@action=content-modify'),
self._handle_content_modify))
self.xmpp.register_handler(
Callback('Reject Content',
StanzaPath('iq/jingle@action=content-reject'),
self._handle_content_reject))
self.xmpp.register_handler(
Callback('Remove Content',
StanzaPath('iq/jingle@action=content-remove'),
self._handle_content_remove))
self.xmpp.register_handler(
Callback('Description Info',
StanzaPath('iq/jingle@action=description-info'),
self._handle_description_info))
self.xmpp.register_handler(
Callback('Security Info',
StanzaPath('iq/jingle@action=security-info'),
self._handle_security_info))
self.xmpp.register_handler(
Callback('Accept Session',
StanzaPath('iq/jingle@action=session-accept'),
self._handle_session_accept))
self.xmpp.register_handler(
Callback('Info Session',
StanzaPath('iq/jingle@action=session-info'),
self._handle_session_info))
self.xmpp.register_handler(
Callback('Initiate Session',
StanzaPath('iq/jingle@action=session-initiate'),
self._handle_session_initiate))
self.xmpp.register_handler(
Callback('Terminate Session',
StanzaPath('iq/jingle@action=session-terminate'),
self._handle_session_terminate))
self.xmpp.register_handler(
Callback('Accept Transport',
StanzaPath('iq/jingle@action=transport-accept'),
self._handle_transport_accept))
self.xmpp.register_handler(
Callback('Info Transport',
StanzaPath('iq/jingle@action=transport-info'),
self._handle_transport_info))
self.xmpp.register_handler(
Callback('Reject Transport',
StanzaPath('iq/jingle@action=transport-reject'),
self._handle_transport_reject))
self.xmpp.register_handler(
Callback('Replace Transport',
StanzaPath('iq/jingle@action=transport-replace'),
self._handle_transport_replace))
# def session_bind(self, jid):
# pass
# def plugin_end(self):
# pass
# def getSDP(self, jingle, username, userid, version):
# ip = jingle['content']['description']['transport'].getRtpIP()
# ret = "\r\no=%s %s %s IN IP4 %s" % (username, userid, version, ip or '127.0.0.1')
# ret += "\r\ns="+jingle['name']
# ret += "\r\nt=0 0"
# ret += jingle['content']['description']['transport'].getSDP(self['transport']) or ''
# return ret
#######################################################################
def _handle_jingle(self, message):
self.xmpp.event('jingle', message)
def _handle_content_accept(self, message):
self.xmpp.event('jingle_content_accept', message)
def _handle_content_add(self, message):
self.xmpp.event('jingle_content_add', message)
def _handle_content_modify(self, message):
self.xmpp.event('jingle_content_modify', message)
def _handle_content_reject(self, message):
self.xmpp.event('jingle_content_reject', message)
def _handle_content_remove(self, message):
self.xmpp.event('jingle_content_remove', message)
def _handle_description_info(self, message):
self.xmpp.event('jingle_description_info', message)
def _handle_security_info(self, message):
self.xmpp.event('jingle_security_info', message)
def _handle_session_accept(self, message):
self.xmpp.event('jingle_session_accept', message)
def _handle_session_info(self, message):
self.xmpp.event('jingle_session_info', message)
def _handle_session_initiate(self, message):
self.xmpp.event('jingle_session_initiate', message)
def _handle_session_terminate(self, message):
self.xmpp.event('jingle_session_terminate', message)
def _handle_transport_accept(self, message):
self.xmpp.event('jingle_transport_accept', message)
def _handle_transport_info(self, message):
self.xmpp.event('jingle_transport_info', message)
def _handle_transport_reject(self, message):
self.xmpp.event('jingle_transport_reject', message)
def _handle_transport_replace(self, message):
self.xmpp.event('jingle_transport_replace', message)
#######################################################################
# def accept(self, mto: JID, sid: str, descriptions: Iterable[Tuple[str, str]], *, mfrom: Optional[JID] = None):
# msg = self.xmpp.make_jingle(mto, mfrom=mfrom)
# msg['jingle_propose']['id'] = sid
# msg['jingle_propose']['descriptions'] = descriptions
# msg.send()
def make_jingle(self,sdp, initiator):
jingle = Jingle()
m = re.search(r'^o=(\S+) +(\S+)',sdp,re.M)
if m:
jingle['initiator'] = initiator
# jingle['initiator'] = m.group(1)
jingle['sid'] = m.group(1)
if self.xmpp['xep_0338']:
group = self.xmpp['xep_0338'].make_group(sdp)
if group:
jingle.append(group)
iter= re.finditer(r'^m=(\S+)',sdp,re.M)
counter = -1
for m in iter:
counter += 1
content = Content()
content['creator'] = 'initiator'
content['name'] = str(counter) #m.group(1)
# the mapext are only valid for the upper last media specified
msubsdp = re.search(r'^(m='+m.group(1)+'(?:.|\r|\n)+?)(?=m=)',sdp+'m=end-of-file',re.M)
if self.xmpp['xep_0167']:
description = self.xmpp['xep_0167'].make_description(msubsdp.group(1),m.group(1))
if description:
content.append(description)
if self.xmpp['xep_0176']:
transport = self.xmpp['xep_0176'].make_transport(sdp)
if transport:
content.append(transport)
if self.xmpp['xep_0177']:
transport = self.xmpp['xep_0177'].make_transport(sdp)
if transport:
content.append(transport)
m = re.search(r'^a=(sendrecv|recvonly|sendonly)\r$',msubsdp.group(1),re.M)
if m:
switcher = {'recvonly':'initiator', 'sendonly':'responder', 'sendrecv':'both'}
content['senders'] = switcher[m.group(1)]
jingle.append(content)
return jingle
def make_terminate(self, reason):
reason = Reason()
reason.append(Cancel())
return reason

View File

@ -0,0 +1,107 @@
# slixmpp: The Slick XMPP Library
# Copyright (C) 2020 Emmanuel Gil Peyrot
# This file is part of slixmpp.
# See the file LICENSE for copying permission.
from slixmpp.xmlstream import ElementBase
class Jingle(ElementBase):
name = 'jingle'
namespace = 'urn:xmpp:jingle:1'
plugin_attrib = 'jingle'
interfaces = {'action','initiator','sid'}
def getReason(self):
return self['reason'].getMessage()
def getAction(self):
return self['action']
def getSid(self):
return self['sid']
def getSDP(self):
ret = ''
if self['action']=='transport-info':
for content in self['contents']:
ret += content['ice-transport'].getSDP() or ''
return ret
else:
version = '0' # wird bei jeden neuen Version hochgezaehlt
ret = "v=%s" % (version) # Version des SDP-Protokoll.
ret += "\r\no=%s %s %s IN IP4 127.0.0.1" % (self['initiator'] or '-', self['sid'], version)
ret += "\r\ns=-" # +self['name']
ret += "\r\nt=0 0"
# Group muss den rtcp-mux entsprechen!
# if self.get_plugin(name='group',check=True):
# ret += self['group'].getSDP()
tmp = ''
bundle = ''
for content in self['contents']:
tmp += content.getSDP()
if content['description'].get_plugin(name='rtcp-mux',check=True):
bundle += ' ' + content['name']
tmp += "\r\na=mid:" + content['name']
if bundle!='':
ret += '\r\na=group:BUNDLE'+ bundle
ret += tmp
return ret+"\r\n"
class Content(ElementBase):
name = 'content'
namespace = 'urn:xmpp:jingle:1'
plugin_attrib = 'content'
interfaces = {'creator','name','senders'}
plugin_multi_attrib = 'contents'
def getSourceSSRC(self):
ssrc = []
for source in self['description']['sources']:
ssrc.append(int(source['ssrc']))
return ssrc
def getSDP(self):
if self.get_plugin(name='raw-transport',check=True):
ret = self['description'].getSDP(self['raw-transport']['candidate']['port'],self['raw-transport'].getSDP()) or ''
else:
ret = self['description'].getSDP() or ''
ret += self['ice-transport'].getSDP() or ''
if self.get_plugin(name='senders',check=True):
switcher = {'initiator':'recvonly', 'responder':'sendonly', 'both':'sendrecv'}
ret += "\r\na=%s" % switcher[self['senders']]
else:
ret += "\r\na=sendrecv"
return ret
class Reason(ElementBase):
name = 'reason'
namespace = 'urn:xmpp:jingle:1'
plugin_attrib = 'reason'
interfaces = {}
def getMessage(self):
return self['text'].xml.text
class Success(ElementBase):
name = 'success'
namespace = 'urn:xmpp:jingle:1'
plugin_attrib = 'success'
interfaces = {}
class Cancel(ElementBase):
name = 'cancel'
namespace = 'urn:xmpp:jingle:1'
plugin_attrib = 'cancel'
interfaces = {}
class Thread(ElementBase):
name = 'thread'
namespace = 'urn:xmpp:jingle:1'
plugin_attrib = 'thread'
interfaces = {}
class Text(ElementBase):
name = 'text'
namespace = 'urn:xmpp:jingle:1'
plugin_attrib = 'text'
interfaces = {}