def on_presence(self, presence): print('received presence: %s' % presence.toXml().encode('utf-8')) user, host, res = parse(presence['from']) jid = '@'.join((user, host)) if presence.hasAttribute('type'): if presence['type'] == 'subscribe': if jid in self.users: print('received subscription') if self.users[jid] is False: iq = IQ(self.xmlstream, 'set') query = domish.Element(('jabber:iq:roster', 'query')) item = domish.Element((None, 'item')) item['jid'] = jid item['name'] = jid item.addElement('group', content='controllers') query.addChild(item) iq.addChild(query) iq.addCallback(self.subscribed, jid) self.xmlstream.send(iq) pres = domish.Element((None, 'presence')) pres['type'] = 'subscribed' pres['to'] = jid self.xmlstream.send(pres) else: presence = domish.Element((None, 'presence')) presence['type'] = 'unsubscribed' presence['to'] = presence['from'] self.xmlstream.send(presence)
def dump_description(self, dest): def sent(res): self.log.debug('description sent') pass self.log.debug('send description') # print(dest['id']) if self.description: self.log.debug('cached description') iq = IQ(self.xmlstream, 'result') iq.addRawXml(self.description) iq['id'] = dest['id'] else: self.log.debug('generate description') iq = IQ(self.xmlstream, 'result') query = domish.Element(('urn:schemas-upnp-org:cloud-1-0', 'query')) query['type'] = 'described' query['name'] = self.device.uuid d = tostring(self.device.dump(), encoding='unicode') query.addRawXml(d) # print(query.toXml()) for service in self.device.services: s = tostring(service.dump(), encoding='unicode') # print(s) query.addRawXml(s) # print(query.toXml()) self.description = query.toXml() iq.addChild(query) iq['id'] = dest['id'] # self.description = iq # print(iq.toXml()) iq.addCallback(sent) iq.send(to=dest['from'])
def on_description(self, iq): # print( # 'Received description from %s: %s' # % (iq['from'], iq.toXml().encode('utf-8'))) pause = IQ(self.xmlstream, 'set') pause['to'] = iq['from'] # enveloppe = domish.Element( # ('http://schemas.xmlsoap.org/soap/envelope/', 'Envelope')) enveloppe = domish.Element( ('http://schemas.xmlsoap.org/soap/envelope/', 'Envelope'), localPrefixes={'s': 'http://schemas.xmlsoap.org/soap/envelope/'}) enveloppe[ 's:encodingStyle'] = "http://schemas.xmlsoap.org/soap/encoding/" header = domish.Element((None, 's:Header')) # header = domish.Element(('http://schemas.xmlsoap.org/soap/envelope/', 'Header')) header['mustUnderstand'] = "1" uc = domish.Element(('urn:schemas-upnp-org:cloud-1-0', 'uc')) uc['serviceId'] = 'urn:av-openhome-org:serviceId:Playlist' header.addChild(uc) enveloppe.addChild(header) body = domish.Element((None, 's:Body')) # body = domish.Element(('http://schemas.xmlsoap.org/soap/envelope/', 'Body')) action = domish.Element( ('urn:av-openhome-org:service:Playlist:1', 'Read'), localPrefixes={'u': 'urn:av-openhome-org:service:Playlist:1'}) # action = domish.Element( # ('urn:av-openhome-org:service:Playlist:1', 'Pause')) body.addChild(action) enveloppe.addChild(body) pause.addChild(enveloppe) pause.addCallback(self.paused) print('send pause') print(pause.toXml()) pause.send()
def on_description(self, iq): # print( # 'Received description from %s: %s' # % (iq['from'], iq.toXml().encode('utf-8'))) pause = IQ(self.xmlstream, 'set') pause['to'] = iq['from'] # enveloppe = domish.Element( # ('http://schemas.xmlsoap.org/soap/envelope/', 'Envelope')) enveloppe = domish.Element( ('http://schemas.xmlsoap.org/soap/envelope/', 'Envelope'), localPrefixes={'s': 'http://schemas.xmlsoap.org/soap/envelope/'}) enveloppe['s:encodingStyle'] = "http://schemas.xmlsoap.org/soap/encoding/" header = domish.Element((None, 's:Header')) # header = domish.Element(('http://schemas.xmlsoap.org/soap/envelope/', 'Header')) header['mustUnderstand'] = "1" uc = domish.Element(('urn:schemas-upnp-org:cloud-1-0', 'uc')) uc['serviceId'] = 'urn:av-openhome-org:serviceId:Playlist' header.addChild(uc) enveloppe.addChild(header) body = domish.Element((None, 's:Body')) # body = domish.Element(('http://schemas.xmlsoap.org/soap/envelope/', 'Body')) action = domish.Element( ('urn:av-openhome-org:service:Playlist:1', 'Read'), localPrefixes={'u': 'urn:av-openhome-org:service:Playlist:1'}) # action = domish.Element( # ('urn:av-openhome-org:service:Playlist:1', 'Pause')) body.addChild(action) enveloppe.addChild(body) pause.addChild(enveloppe) pause.addCallback(self.paused) print('send pause') print(pause.toXml()) pause.send()
def delete_ps_node(self, node): def deleted(res): if res['type'] == 'error': self.log.error('node deletion failed: %s' % res.toXml()) iq = IQ(self.xmlstream, 'set') ps = domish.Element( ('http://jabber.org/protocol/pubsub#owner', 'pubsub')) delete = domish.Element((None, 'delete')) delete['node'] = node ps.addChild(delete) iq.addChild(ps) iq.send(to='pubsub.' + self.jid.host)
def check_users(self): for user, value in self.users.items(): if value['state'] is False: iq = IQ(self.xmlstream, 'set') query = domish.Element(('jabber:iq:roster', 'query')) item = domish.Element((None, 'item')) item['name'] = user item['jid'] = user item.addElement('group', content='hosts') query.addChild(item) iq.addChild(query) iq.addCallback(self.subscribe, user) print('send IQ: %s' % (iq.toXml().encode('utf-8'))) iq.send()
def _gtalk_stanza(self, action): iq = IQ(self.stream, 'set') iq['from'] = self.remote_jid iq['to'] = self.local_jid sess = domish.Element(("http://www.google.com/session", 'session')) if self.direction == 'incoming': sess['initiator'] = self.remote_jid elif self.direction == 'outgoing': sess['initiator'] = self.local_jid sess['type'] = action sess['id'] = self.session_id iq.addChild(sess) return (iq, sess)
def _jingle_stanza(self, action): iq = IQ(self.stream, 'set') iq['from'] = self.remote_jid iq['to'] = self.local_jid jingle = domish.Element(("http://jabber.org/protocol/jingle", 'jingle')) if self.direction == 'incoming': jingle['initiator'] = self.remote_jid elif self.direction == 'outgoing': jingle['initiator'] = self.local_jid jingle['action'] = action jingle['sid'] = self.session_id iq.addChild(jingle) return (iq, jingle)
def check_users(self): for user, value in self.users.items(): if value['state'] is False: iq = IQ(self.xmlstream, 'set') query = domish.Element(('jabber:iq:roster', 'query')) item = domish.Element((None, 'item')) item['name'] = user item['jid'] = user item.addElement('group', content='hosts') query.addChild(item) iq.addChild(query) iq.addCallback(self.cloud_subscribe, user) # print('send IQ: %s' % (iq.toXml().encode('utf-8'))) iq.send()
def send_error_reply(stream, iq, error_stanza=None): result = IQ(stream, "error") result["id"] = iq["id"] query = iq.firstChildElement() to = iq.getAttribute('to') if to is not None: result["from"] = to if query: result.addElement((query.uri, query.name)) if error_stanza: result.addChild(error_stanza) stream.send(result)
def create_ps_node(self, node): def registered(node, iq): if iq['type'] == 'result': node_name = '/'.join((self._jid, node[1])) if node_name in self.registrations: return event = XmppEvent(node_name, self, 'pubsub.' + self.jid.host) node[2].subscribe(event, 100) self.reactor.callLater(95, self.renew_subscription, *(node_name, node)) self.registrations.append(node_name) self.log.debug('node {node} registered', node=node_name) else: self.log.error('node creation {name} failed:{iq}', name=node, iq=iq.toXml()) iq = IQ(self.xmlstream, 'set') ps = domish.Element(('http://jabber.org/protocol/pubsub', 'pubsub')) create = domish.Element((None, 'create')) create['node'] = '/'.join((self._jid, node[1], node[0].name)) ps.addChild(create) configure = domish.Element((None, 'configure')) x = domish.Element(('jabber:x:data', 'x')) x['type'] = 'submit' field = domish.Element((None, 'field')) field['var'] = 'FORM_TYPE' field['type'] = 'hidden' field.addElement( 'value', content='http://jabber.org/protocol/pubsub#node_config') x.addChild(field) access = domish.Element((None, 'field')) access['var'] = 'pubsub#access_model' access.addElement('value', content='roster') x.addChild(access) # expire = domish.Element((None, 'field')) # expire['var'] = 'pubsub#item_expire' # expire.addElement('value', content='60') # x.addChild(expire) last = domish.Element((None, 'field')) last['var'] = 'pubsub#send_last_published_item' last.addElement('value', content='on_sub_and_presence') x.addChild(last) configure.addChild(x) ps.addChild(configure) iq.addChild(ps) iq.addCallback(registered, node) iq.send(to='pubsub.' + self.jid.host)
def on_presence(self, presence): self.log.debug('received presence: %s' % presence.toXml().encode('utf-8')) if presence.hasAttribute('from'): user, host, res = parse(presence['from']) if presence['from'] in self.active_controllers: if presence.hasAttribute('type'): if presence['type'] == 'unavailable': self.active_controllers.remove(presence['from']) self.log.info('User {_from} disconnected', _from=presence['from']) return elif 'ControlPoint' in res: if presence.hasAttribute('type'): if presence['type'] == 'unavailable': return self.log.info('control point %s added' % presence['from']) if len(self.active_controllers) == 0: self.check_ps_nodes() self.active_controllers.append(presence['from']) del (res) jid = '@'.join((user, host)) if presence.hasAttribute('type'): if presence['type'] == 'subscribe': if jid in self.users: self.log.info('received subscription from %s' % jid) if self.users[jid] is False: iq = IQ(self.xmlstream, 'set') query = domish.Element( ('jabber:iq:roster', 'query')) item = domish.Element((None, 'item')) item['jid'] = jid item['name'] = jid item.addElement('group', content='UPnPCloud') query.addChild(item) iq.addChild(query) iq.addCallback(self.subscribed, jid) iq.send() else: self.log.error('subscription for user %s failed: %s' % (jid, 'Not in user list')) pres = domish.Element((None, 'presence')) pres['type'] = 'unsubscribed' pres['to'] = presence['from'] self.xmlstream.send(pres)
def on_presence(self, resp): print('got presence: %s' % resp.toXml().encode('utf-8')) print('from :%s' % resp['from']) user, host, res = parse(resp['from']) jid = '@'.join((user, host)) if resp.hasAttribute('type'): if resp['type'] == 'subscribed': if jid in self.users: self.users[jid].update({'state': True}) if 'services' in self.users[jid]: self.users[jid]['services'].append(res) else: self.users[jid].update({'services': [res]}) presence = domish.Element((None, 'presence')) presence['type'] = 'subscribe' presence['to'] = resp['from'] self.xmlstream.send(presence) else: presence = domish.Element((None, 'presence')) presence['type'] = 'denying' presence['to'] = resp['from'] self.xmlstream.send(presence) elif resp['type'] == 'unsubscribed': if jid in self.users: print('subscription failed: %s' % resp['from']) return for child in resp.elements(): if child.name == 'ConfigIdCloud': print('Found UPnP Cloud device : %s type is: %s' % ( jid, res)) # if jid == self._jid: # return info = IQ(self.xmlstream, 'get') info['to'] = resp ['from'] query = domish.Element( ('urn:schemas-upnp-org:cloud-1-0', 'query')) query['type'] = 'description' query['name'] = ':'.join(res.split(':')[-2:]) info.addChild(query) info.addCallback(self.on_description) info.send()
def on_presence(self, resp): self.log.debug('got presence: %s' % resp.toXml().encode('utf-8')) # print('from :%s' % resp['from']) user, host, res = parse(resp['from']) jid = '@'.join((user, host)) if resp.hasAttribute('type'): if resp['type'] == 'subscribed': if jid in self.users: self.users[jid].update({'state': True}) if 'services' in self.users[jid]: self.users[jid]['services'].append(res) else: self.users[jid].update({'services': [res]}) presence = domish.Element((None, 'presence')) presence['type'] = 'subscribe' presence['to'] = resp['from'] self.xmlstream.send(presence) else: presence = domish.Element((None, 'presence')) presence['type'] = 'denying' presence['to'] = resp['from'] self.xmlstream.send(presence) elif resp['type'] == 'unsubscribed': if jid in self.users: self.log.warn('subscription failed: %s' % resp['from']) return for child in resp.elements(): if child.name == 'ConfigIdCloud': self.log.debug('Found UPnP Cloud device : %s type is: %s' % ( jid, res)) info = IQ(self.xmlstream, 'get') # info['to'] = resp['from'] query = domish.Element( ('urn:schemas-upnp-org:cloud-1-0', 'query')) query['type'] = 'description' query['name'] = ':'.join(res.split(':')[-2:]) info.addChild(query) info.addCallback(self.on_description, res) # info.send() info.send(to=resp['from'])
def unsubscribe_cloud(self, name): def unsubscribed(name, d, res): if res['type'] == 'result': # print('unsubscribed: %s' % name) del self.subscriptions_cloud[name] print('ok') d.callback(None) else: d.errback(Exception(res.toXml())) d = defer.Deferred() iq = IQ(self.xmlstream, 'set') ps = domish.Element(('http://jabber.org/protocol/pubsub', 'pubsub')) unsubscribe = domish.Element((None, 'unsubscribe')) unsubscribe['node'] = name unsubscribe['jid'] = self.jid.full() ps.addChild(unsubscribe) iq.addChild(ps) iq.addCallback(unsubscribed, name, d) iq.send(to='pubsub.' + self.jid.host) return d
def publish(self, event): if len(self.parent.active_controllers) == 0: # self.log.debug('event cancelled') self.parent.registrations = [] return def success(res): # print('event sent') if res['type'] == 'error': self.log.error('Publish Event failed :%s' % res.toXml()) else: if 'Id' in res.children[0].children[0]['node']: self.log.debug('Event Published: %s' % res.toXml()) name, data = event if name == 'Seconds': return iq = IQ(self.parent.xmlstream, 'set') ps = domish.Element(('http://jabber.org/protocol/pubsub', 'pubsub')) publish = domish.Element((None, 'publish')) publish['node'] = '/'.join((self.nodeId, name)) item = domish.Element((None, 'item')) propertyset = domish.Element( ('urn:schemas-upnp-org:event-1-0', 'propertyset'), localPrefixes={'e': 'urn:schemas-upnp-org:event-1-0'}) prop = domish.Element((None, 'e:property')) evt = domish.Element((None, name)) if isinstance(data.value, dict): ev = domish.Element((data.namespace, 'Event')) inst = domish.Element((None, 'InstanceID')) inst['val'] = '0' for k, v in data.value.items: if 'namespace' in v: var = domish.Element((v['namespace'], k)) else: var = domish.Element((None, k)) if 'attrib' in v: attr = v['attrib'] else: attr = {} value = v['value'] if isinstance(value, bool): value = int(value) attr.update( {'val': str(value) .decode('utf-8')}) for attname, attval in attr: var[attname] = attval inst.addChild(var) ev.addChild(inst) evt.addChild(ev) else: # print(str(data.value).decode('utf-8')) if isinstance(data.value, bool): data.value = int(data.value) evt.addContent(str(data.value).decode('utf-8')) prop.addChild(evt) propertyset.addChild(prop) item.addChild(propertyset) publish.addChild(item) ps.addChild(publish) iq.addChild(ps) iq.addCallback(success) iq.send(to=self.addr)
def subscribe_cloud( self, device, svc, var, callback_fct=None, callback_args=()): # print('suscribe to %s' % var) name = device.keys()[0] dev = device[name] if not callback_fct: callback_fct = self.log.debug d = defer.Deferred() def subscribe_failed(err, name): self.parent.remove_device(name.split('_')[0]) def subscribed(node_name, deferred, iq): if iq['type'] == 'result': self.subscriptions_cloud[str(node_name)] = True # print('%s suscribed !' % str(node_name)) # iq = IQ(self.xmlstream, 'get') # ps = domish.Element( # ('http://jabber.org/protocol/pubsub', 'pubsub')) # items = domish.Element((None, 'items')) # items['node'] = node_name # items['max_items'] = '1' # ps.addChild(items) # iq.addChild(ps) # iq.addCallback(self.on_event) # iq.send(to='pubsub.' + self.jid.host) # print(iq.toXml()) deferred.callback(str(node_name)) else: deferred.errback(Exception('subscription to %s failed: %s' % (node_name, iq.toXml()))) if svc in dev['services']: # print('service %s ok' % svc) # print('subscriptions :%s' % self.subscriptions_cloud) if not self.cloud_event_catcher: self.cloud_event_catcher = CloudEventCatcher( {}, {}, logger=self.log) subscription_name = '/'.join((dev['location'], svc, var)) # subscription_service = svc if subscription_name in self.cloud_event_catcher.callbacks: self.cloud_event_catcher.callbacks[subscription_name].update( {var: (callback_fct, callback_args,)}) else: self.cloud_event_catcher.callbacks.update( {subscription_name: {var: (callback_fct, callback_args,)}}) # if var in self.cloud_event_catcher.callbacks: # self.cloud_event_catcher.callbacks[var].update( # {var: (callback_fct, callback_args,)}) # else: # self.cloud_event_catcher.callbacks.update( # {var: {var: (callback_fct, callback_args,)}}) # log.error(self.event_catcher.catcher.childs) if subscription_name in self.subscriptions_cloud: if self.subscriptions_cloud[subscription_name]: # print('already subscribed: %s' % subscription_name) for k, value in\ self.cloud_event_catcher.unfiltered_dict.items(): # print('is %s == %s ?' % (k, var)) if k == var: if value == 'False': value = False elif value == 'True': value = True if isinstance(callback_args, str)\ or isinstance(callback_args, bool): callback_fct(value, callback_args) else: callback_fct(value, *callback_args) del self.cloud_event_catcher.unfiltered_dict[k] return defer.succeed(None) self.subscriptions_cloud.update({str(subscription_name): False}) # print(subscription_name) # print(subscription_service) iq = IQ(self.xmlstream, 'set') ps = domish.Element( ('http://jabber.org/protocol/pubsub', 'pubsub')) subscribe = domish.Element((None, 'subscribe')) subscribe['node'] = subscription_name subscribe['jid'] = self.jid.full() ps.addChild(subscribe) iq.addChild(ps) iq.addCallback(subscribed, subscription_name, d) iq.send(to='pubsub.' + self.jid.host) return d return defer.fail(Exception('Service unknow'))
def publish(self, event): if len(self.parent.active_controllers) == 0: # self.log.debug('event cancelled') self.parent.registrations = [] return def success(res): # print('event sent') if res['type'] == 'error': self.log.error('Publish Event failed :%s' % res.toXml()) else: if 'Id' in res.children[0].children[0]['node']: self.log.debug('Event Published: %s' % res.toXml()) name, data = event if name == 'Seconds': return iq = IQ(self.parent.xmlstream, 'set') ps = domish.Element(('http://jabber.org/protocol/pubsub', 'pubsub')) publish = domish.Element((None, 'publish')) publish['node'] = '/'.join((self.nodeId, name)) item = domish.Element((None, 'item')) propertyset = domish.Element( ('urn:schemas-upnp-org:event-1-0', 'propertyset'), localPrefixes={'e': 'urn:schemas-upnp-org:event-1-0'}) prop = domish.Element((None, 'e:property')) evt = domish.Element((None, name)) if isinstance(data.value, dict): ev = domish.Element((data.namespace, 'Event')) inst = domish.Element((None, 'InstanceID')) inst['val'] = '0' for k, v in data.value.items: if 'namespace' in v: var = domish.Element((v['namespace'], k)) else: var = domish.Element((None, k)) if 'attrib' in v: attr = v['attrib'] else: attr = {} value = v['value'] if isinstance(value, bool): value = int(value) attr.update({'val': str(value).decode('utf-8')}) for attname, attval in attr: var[attname] = attval inst.addChild(var) ev.addChild(inst) evt.addChild(ev) else: # print(str(data.value).decode('utf-8')) if isinstance(data.value, bool): data.value = int(data.value) evt.addContent(str(data.value).decode('utf-8')) prop.addChild(evt) propertyset.addChild(prop) item.addChild(propertyset) publish.addChild(item) ps.addChild(publish) iq.addChild(ps) iq.addCallback(success) iq.send(to=self.addr)