1 package Thrasher
::Plugin
::EntityCapabilities
;
9 Thrasher::Plugin::EntityCapabilities - add XEP-0115 "Entity
10 Capabilities" support.
14 This plugin adds support for XEP-0115, "Entity Capabilities". This
15 automatically implements support for the capabilities as described
16 by the data in Thrasher::Plugin, and should need no further
17 interaction beyond "use"ing this module if needed. It automatically
18 annotates outgoing presence packets with the appropriate <c> tag.
22 use Thrasher
::Plugin
qw(:all);
23 use Thrasher
::Constants
qw(:all);
24 use Thrasher
::Log
qw(log);
25 use Thrasher
::XML
qw(:all);
26 use Thrasher
::Callbacks
qw(:all);
28 use Digest
::SHA1
qw(sha1_base64);
32 our @EXPORT_OK = qw(has_feature has_identity_category);
33 our %EXPORT_TAGS = (all
=> \
@EXPORT_OK);
37 # set-like hash of features
39 our @SERVER_IDENTITIES;
41 sub has_feature
{ $SERVER_FEATURES{$_[0]}; }
43 sub has_identity_category
{ grep { $_->[0] eq $_[0] } @SERVER_IDENTITIES }
45 # At the time that the plugins are updated, we don't have a component.
46 # Mark that updates are needed, and on the next presence callback
47 # (which will have a component), we'll compute it.
48 my $UPDATE_NEEDED = 1;
50 register_plugin
({features
=> [$NS_CAPS],
53 {entity_caps
=> \
&update_needed
},
55 {entity_caps
=> \
&presence_out
},
57 {entity_caps
=> \
&query_server_capabilities
}}});
59 # This currently has no support for extended service discovery forms
62 my $identity_info = shift;
63 my $supported_features = shift;
65 my $s = join('/', @
$identity_info) . '<';
67 for my $service_discovery_identity (@
$supported_features) {
68 $s .= $service_discovery_identity . '<';
71 return sha1_base64
($s);
75 my $component = shift;
77 Thrasher
::Plugin
::Basic
::component_identity_info
($component);
78 my @supported_features = supported_features
;
79 $CURRENT_CAP_HASH = hash_for_caps
80 (\
@identity_info, \
@supported_features);
88 my $component = shift;
89 update_caps
($component);
93 # Add the caps tag to the presence
95 my $component = shift;
96 my $presence_tag = shift;
99 run_update
($component);
102 my $from = $presence_tag->[1]->{from
};
104 my $c = [[$NS_CAPS, 'c'],
107 'http://developer.berlios.de/projects/thrasher/',
108 ver
=> $CURRENT_CAP_HASH},
110 push @
{$presence_tag->[2]}, $c;
115 # When we connect, query the server for its capabilities, which will
116 # be necessary for other plugins
117 sub query_server_capabilities
{
118 my $component = shift;
120 # Query the server for its capabilities.
121 my $iq_packet = [[$NS_COMPONENT, 'iq'],
123 from
=> $component->{component_name
},
124 to
=> $Thrasher::SERVER_NAME
|| ''}, # blank if testing
125 [[[$NS_DISCO_INFO, 'query'], {}, []]]];
127 $component->iq_query($iq_packet, \
&extract_server_caps
);
130 sub extract_server_caps
{
131 my $component = shift;
132 my $iq_params = shift;
133 my $iq_packet = shift;
135 if ($iq_params->{'type'} eq 'error') {
136 log("extract_server_caps: error from $iq_params->{from}");
137 failed
('server_capabilities_detected');
141 my $query = $iq_params->{query
};
143 my ($identities, $features) = extract_disco_info
($query);
145 @SERVER_IDENTITIES = @
$identities;
146 %SERVER_FEATURES = map { $_ => 1 } @
$features;
148 succeeded
('server_capabilities_detected');