Index: perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.dtd
===================================================================
--- perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.dtd (revision 7a1c90dd56da7730139bf614567192ed49d47108)
+++ perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.dtd (revision 7a1c90dd56da7730139bf614567192ed49d47108)
@@ -0,0 +1,139 @@
+# The top-level structure is a 'define'. This defines either a building-block --
+# a 'struct' which can get pulled into the various SNACs -- or a SNAC. SNACs have
+# family and subtype, and optionally a channel.
+#
+# 'ref' is like #include. There are some basic structures, like userinfo, which appear
+# inside multiple SNACs.
+#
+# Then there are the data types:
+# Numeric types: byte (8-bit), word (16-bit), dword (32-bit).
+# Raw character data: data
+# This can have a 'length prefix' attached to it.
+# The length prefix is a numeric type. The value of the length prefix
+# is the number of bytes of character data. The existence of this
+# length prefix is why it might be useful for data to have sub-data.
+# Data types can have 'counts'. A count of -1 represents an infinite count.
+# Counted data is passed around as a listref. For instance, a capabilities block
+# is a series of 16-byte values, so by attaching count=-1 to that data item,
+# you can pass in a listref with the individual capabilities. There is also
+# fixed-length character data, specified via the length attribute on the data element.
+# Data can be null-terminated and padded. The value for the pad attribute specifies
+# the octet value to use for padding.
+#
+# There are also enums, which are exactly like numeric types except the raw numeric
+# values gets translated into some other values, so if you have a message-type
+# word, you can have 1 => "foo", and you'll get a "foo" when decoding a 1 and a
+# 1 when encoding a "foo".
+#
+# Things that have, or can have, length prefixes, take an optional 'default_generate'
+# attribute. If set to yes, this will give them a default value of "present but empty".
+#
+# Note that if you have counted character data, you will get a listref of hashrefs.
+# For instance:
+#
+#
+#
+#
+# Will give you:
+# [
+# { foo => 1, bar => 2 },
+# { foo => 1, bar => 4 },
+# ]
+#
+# You can also have tlvchains and TLVs...
+#
+# If you attach a name to a TLV, as opposed to elements within that TLV,
+# presence of that name in the data hash will correspond with presence of
+# that TLV in the TLV chain, without regard to the value of said TLV.
+#
+#
+# family=0 is a global fallback SNAC family. That is:
+#
+# will get picked up on for all SNACs of subtype 1 where there is no define for
+# that specific family.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ count_prefix (byte|word|dword) #IMPLIED
+ length_prefix (byte|word|dword) #IMPLIED
+ prefix_order (network|vax) #DEFAULT network
+ length CDATA #IMPLIED
+ default_generate (yes|no) #DEFAULT no
+>
+
+
+
+
+ default_generate (yes|no) #DEFAULT no
+
+ name CDATA #IMPLIED
+
+ count CDATA #IMPLIED
+>
Index: perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.parsed-xml
===================================================================
--- perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.parsed-xml (revision 7a1c90dd56da7730139bf614567192ed49d47108)
+++ perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.parsed-xml (revision 7a1c90dd56da7730139bf614567192ed49d47108)
@@ -0,0 +1,7038 @@
+$xmlparse = [
+ 'oscar',
+ [
+ {},
+ 0,
+ '
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'flap'
+ },
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {},
+ 0,
+ '42'
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'channel'
+ },
+ 0,
+ '2'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'seqno'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'msg',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'snac'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'family'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'subtype'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'flags1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'flags2'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'reqid'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'data'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'TLV'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'type'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'data',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'subtyped_TLV'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'type'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'subtype'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'data',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'userinfo'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'evil'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {
+ 'count_prefix' => 'word'
+ },
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'flags'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'membersince'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'onsince'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'idle'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '13'
+ },
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'length' => '16',
+ 'name' => 'capabilities'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '25'
+ },
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'length' => '2',
+ 'name' => 'shortcaps'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '29'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {
+ 'subtyped' => 'yes'
+ },
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'subtype' => '1',
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'icon_md5sum'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'subtype' => '-1',
+ 'type' => '2'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'extended_status',
+ 'length_prefix' => 'word'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '12'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'invitation_message'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '10001'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {}
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'chat_url',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '15'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'session_length'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '10'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'ip'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'sub_info',
+ 'type' => '512'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '4',
+ 'name' => 'service_request',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'type'
+ }
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'chat',
+ 'type' => '1'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'exchange'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'url',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '1',
+ 'name' => 'error',
+ 'family' => '-1'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'errno'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'error_details'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '5',
+ 'name' => 'service_redirect_response',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '13'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'service_type'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '6'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'auth_cookie'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'server_ip'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '1',
+ 'flags2' => '6',
+ 'name' => 'BOS_signon',
+ 'channel' => '1',
+ 'family' => '0'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'cookie'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'signon',
+ 'family' => '23'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'screenname'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '37'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'auth_response'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '76'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'pass_is_hashed'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'password'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'clistr'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '22'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'supermajor'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '23'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'major'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '24'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'minor'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '25'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'subminor'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '26'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'build'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '20'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'subbuild'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '15'
+ },
+ 'data',
+ [
+ {},
+ 0,
+ 'en'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '14'
+ },
+ 'data',
+ [
+ {},
+ 0,
+ 'us'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '74'
+ },
+ 'byte',
+ [
+ {},
+ 0,
+ '1'
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_signon_request',
+ 'channel' => '1'
+ },
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {},
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'signon'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '6',
+ 'name' => 'initial_signon_request',
+ 'family' => '23'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'screenname'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'default_generate' => 'yes',
+ 'type' => '75'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'default_generate' => 'yes',
+ 'type' => '90'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '7',
+ 'name' => 'authentication_key',
+ 'family' => '23'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'key',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'authorization_response',
+ 'family' => '23'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '8'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'error'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'error_details'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'screenname'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '17'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'email'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '6'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'auth_cookie'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'server_ip'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '19'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'registration_status'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '84'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'password_change_url'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'rate_class_info'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'class_id'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'window_size'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'levels'
+ },
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'clear'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'alert'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'limit'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'disconnect'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'current'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'max'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'last_time'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'current_state'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '7',
+ 'name' => 'rate_info_response',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count_prefix' => 'word',
+ 'name' => 'classes'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'rate_class_info'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'classmembers'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'class_id'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count_prefix' => 'word',
+ 'name' => 'snacs'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'family'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'subtype'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '8',
+ 'name' => 'rate_acknowledgement',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'classes'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '14',
+ 'name' => 'personal_info_request',
+ 'family' => '1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'buddylist_rights_request',
+ 'family' => '19'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '4',
+ 'name' => 'buddylist_request',
+ 'family' => '19'
+ }
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'locate_rights_request',
+ 'family' => '2'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'locate_rights_response',
+ 'family' => '2'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'max_profile_len'
+ },
+ 0,
+ '1024'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'max_capabilities'
+ },
+ 0,
+ '16'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'word',
+ [
+ {},
+ 0,
+ '10'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'word',
+ [
+ {},
+ 0,
+ '4096'
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'buddy_rights_request',
+ 'family' => '3'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'buddy_rights_response',
+ 'family' => '3'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'maxbuddies'
+ },
+ 0,
+ '600'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'maxwatchers'
+ },
+ 0,
+ '750'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'maxnotifies'
+ },
+ 0,
+ '512'
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'IM_parameters'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'channel'
+ },
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'flags'
+ },
+ 0,
+ '3'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'max_size'
+ },
+ 0,
+ '8000'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'max_send_warn'
+ },
+ 0,
+ '999'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'max_recv_warn'
+ },
+ 0,
+ '999'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'min_msg_interval'
+ },
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'add_IM_parameters',
+ 'family' => '4'
+ },
+ 'ref',
+ [
+ {
+ 'name' => 'IM_parameters'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '4',
+ 'name' => 'IM_parameter_request',
+ 'family' => '4'
+ },
+ 'ref',
+ [
+ {
+ 'name' => 'IM_parameters'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '5',
+ 'name' => 'IM_parameter_response',
+ 'family' => '4'
+ },
+ 'ref',
+ [
+ {
+ 'name' => 'IM_parameters'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'BOS_rights_request',
+ 'family' => '9'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'BOS_rights_response',
+ 'family' => '9'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'max_permits'
+ },
+ 0,
+ '200'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'max_denies'
+ },
+ 0,
+ '200'
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '15',
+ 'name' => 'self_information',
+ 'family' => '1'
+ },
+ 'ref',
+ [
+ {
+ 'name' => 'userinfo'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'minimum_report_interval',
+ 'family' => '11'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '19',
+ 'name' => 'MOTD',
+ 'family' => '1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'server_ready',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'families'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '23',
+ 'name' => 'set_service_versions',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'service'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'service_id'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'service_version'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'set_tool_versions',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'service'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'service_id'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'service_version'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'tool_id'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'tool_version'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '6',
+ 'name' => 'rate_info_request',
+ 'family' => '1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '10',
+ 'name' => 'rate_change',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'enum',
+ [
+ {
+ 'name' => 'message_type',
+ 'type' => 'word'
+ },
+ 0,
+ '
+ ',
+ 'edef',
+ [
+ {
+ 'value' => '1',
+ 'name' => 'change'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'edef',
+ [
+ {
+ 'value' => '2',
+ 'name' => 'warning'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'edef',
+ [
+ {
+ 'value' => '3',
+ 'name' => 'alert'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'edef',
+ [
+ {
+ 'value' => '4',
+ 'name' => 'clear'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'rate_class_info'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '8',
+ 'name' => 'outgoing_warning',
+ 'family' => '4'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'is_anonymous'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '16',
+ 'name' => 'incoming_warning',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'new_level'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'userinfo'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '31',
+ 'name' => 'memory_request',
+ 'family' => '1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '24',
+ 'name' => 'host_versions',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'server'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'service_id'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'service_version'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '7',
+ 'name' => 'buddylist_done',
+ 'family' => '19'
+ }
+ ],
+ 0,
+ '
+
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'buddylist_3_response',
+ 'family' => '19'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'word',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'maximums'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'word',
+ [
+ {},
+ 0,
+ '254'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'word',
+ [
+ {},
+ 0,
+ '508'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '6'
+ },
+ 'word',
+ [
+ {},
+ 0,
+ '97'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '7'
+ },
+ 'word',
+ [
+ {},
+ 0,
+ '10'
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '6',
+ 'name' => 'buddylist',
+ 'family' => '19'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'data'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '14',
+ 'name' => 'buddylist_modification_acknowledgement',
+ 'family' => '19'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'error'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '15',
+ 'name' => 'buddylist_error',
+ 'family' => '19'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'data'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'buddylist_modification'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'entry_name',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'group_id'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'buddy_id'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'entry_type'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'entry_data',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '8',
+ 'name' => 'buddylist_add',
+ 'family' => '19'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'mods'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '9',
+ 'name' => 'buddylist_modify',
+ 'family' => '19'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'mods'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '10',
+ 'name' => 'buddylist_delete',
+ 'family' => '19'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'mods'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'buddylist_change'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'changes'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'buddylist_modification'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '17',
+ 'name' => 'start_buddylist_modifications',
+ 'family' => '19'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '18',
+ 'name' => 'end_buddylist_modifications',
+ 'family' => '19'
+ }
+ ],
+ 0,
+ '
+
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '21',
+ 'name' => 'get_info',
+ 'family' => '2'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '21',
+ 'name' => 'get_away',
+ 'family' => '2'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '3'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '6',
+ 'name' => 'incoming_profile',
+ 'family' => '2'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'userinfo'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'profile'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'awaymsg'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '4',
+ 'name' => 'set_info',
+ 'family' => '2'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'profile_mimetype'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'profile'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'awaymsg_mimetype'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'awaymsg'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'length' => '16',
+ 'name' => 'capabilities'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '6'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'word',
+ [
+ {},
+ 0,
+ '2'
+ ]
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '17',
+ 'name' => 'set_idle',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'duration'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '20',
+ 'name' => 'typing_notification',
+ 'family' => '4'
+ },
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'typing_status'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '33',
+ 'name' => 'incoming_extended_information',
+ 'family' => '1'
+ },
+ 0,
+ '
+
+
+ ',
+ 'tlvchain',
+ [
+ {
+ 'subtyped' => 'yes'
+ },
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'subtype' => '65',
+ 'type' => '0'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'upload_checksum'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'subtype' => '65',
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'upload_checksum'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'subtype' => '129',
+ 'type' => '0'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'resend_checksum'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'subtype' => '129',
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'resend_checksum'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'subtype' => '-1',
+ 'type' => '2'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'status_message',
+ 'length_prefix' => 'word'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '30',
+ 'name' => 'set_extended_status',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'status_message',
+ 'type' => '29'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '2'
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {},
+ 0,
+ '4'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'length_prefix' => 'byte'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'message',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'stealth',
+ 'type' => '6'
+ },
+ 0,
+ '
+
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'state'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'icon_upload',
+ 'family' => '16'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'icon'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '11',
+ 'name' => 'buddy_status_update',
+ 'family' => '3'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'userinfo'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '12',
+ 'name' => 'buddy_signoff',
+ 'family' => '3'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'standard_IM_header'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'length' => '8',
+ 'name' => 'cookie'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'channel'
+ },
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'standard_IM_footer'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1281'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '257'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '257'
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '257'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'message'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'is_automatic',
+ 'type' => '4'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'request_server_confirmation',
+ 'type' => '3'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'supports_typing_status',
+ 'type' => '11'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'icon_data',
+ 'type' => '8'
+ },
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'icon_length'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'icon_checksum'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'icon_timestamp'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'rendezvous_IM'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 0,
+ '
+ ',
+ 'enum',
+ [
+ {
+ 'name' => 'status',
+ 'type' => 'word'
+ },
+ 0,
+ '
+ ',
+ 'edef',
+ [
+ {
+ 'value' => '0',
+ 'name' => 'propose'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'edef',
+ [
+ {
+ 'value' => '1',
+ 'name' => 'cancel'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'edef',
+ [
+ {
+ 'value' => '2',
+ 'name' => 'accept'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'data',
+ [
+ {
+ 'length' => '8',
+ 'name' => 'cookie'
+ }
+ ],
+ 0,
+ '
+
+
+ ',
+ 'data',
+ [
+ {
+ 'length' => '16',
+ 'name' => 'capability'
+ }
+ ],
+ 0,
+ '
+
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '10'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'push_pull'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '11'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'error'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'default_generate' => 'yes',
+ 'type' => '15'
+ }
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'client_1_ip'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'client_2_ip'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'client_external_ip'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'port'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '22'
+ },
+ 'dword',
+ [
+ {
+ 'name' => 'proxy_ip'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '12'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'invitation_msg'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '13'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'charset'
+ },
+ 0,
+ 'us-ascii'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '14'
+ },
+ 'byte',
+ [
+ {
+ 'name' => 'language'
+ },
+ 0,
+ '48'
+ ]
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '10001'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'svcdata'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '10002'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'svcdata_charset'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '7',
+ 'name' => 'incoming_IM',
+ 'family' => '4'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'standard_IM_header'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'userinfo'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'message_body'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '6',
+ 'name' => 'outgoing_IM',
+ 'family' => '4'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'standard_IM_header'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'message_body'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '12',
+ 'name' => 'IM_acknowledgement',
+ 'family' => '4'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'length' => '8',
+ 'name' => 'cookie'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'channel'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '4',
+ 'name' => 'chat_invitation_accept',
+ 'family' => '13'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'exchange'
+ },
+ 0,
+ '4'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'url',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {},
+ 0,
+ '2'
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '11',
+ 'name' => 'chat_invitation_decline',
+ 'family' => '4'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'length' => '8',
+ 'name' => 'cookie'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'channel'
+ },
+ 0,
+ '2'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'code'
+ },
+ 0,
+ '1'
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'chat_navigator_rights_request',
+ 'family' => '13'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '8',
+ 'name' => 'chat_navigator_room_create',
+ 'family' => '13'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'chat_room_info'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'chat_data'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {
+ 'count_prefix' => 'word'
+ },
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '106'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'name'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '111'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'occupant_count'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'occupants',
+ 'type' => '115'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'userinfo'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '209'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'max_msg_len'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '211'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'name'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '214'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'charset'
+ },
+ 0,
+ 'us-ascii'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'default_generate' => 'yes',
+ 'type' => '215'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'language'
+ },
+ 0,
+ 'en'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '219'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'encoding'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'chat_room_info'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'exchange'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'url',
+ 'length_prefix' => 'byte'
+ },
+ 0,
+ 'create'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'instance'
+ },
+ 0,
+ '65535'
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'detail_level'
+ },
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'chat_data'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {}
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'length_prefix' => 'byte'
+ },
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {}
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'name'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {}
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'detail_level'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {
+ 'count_prefix' => 'word'
+ },
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '111'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'occupant_count'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '115'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'occupants'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'userinfo'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '9',
+ 'name' => 'chat_navigator_response',
+ 'family' => '13'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'byte',
+ [
+ {
+ 'name' => 'max_concurrent_rooms'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'exchange',
+ 'type' => '3'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'exchange'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'chat_data'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+ ',
+ 'tlv',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'room',
+ 'type' => '4'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'chat_room_info'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'chat_room_status',
+ 'family' => '14'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'chat_room_info'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'chat_buddy_arrival',
+ 'family' => '14'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'arrivals'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'userinfo'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '4',
+ 'name' => 'chat_buddy_departure',
+ 'family' => '14'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'departures',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'chat_IM'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'length' => '8',
+ 'name' => 'cookie'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '3'
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'default_generate' => 'yes',
+ 'type' => '1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'sender',
+ 'length_prefix' => 'byte'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'reflect',
+ 'type' => '6'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'name' => 'is_automatic',
+ 'type' => '7'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'type'
+ },
+ 0,
+ 'text/x-aolrtf'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'charset'
+ },
+ 0,
+ 'us-ascii'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'language'
+ },
+ 0,
+ 'en'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 'data',
+ [
+ {},
+ 0,
+ 'binary'
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'message'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '5',
+ 'name' => 'outgoing_chat_IM',
+ 'family' => '14'
+ },
+ 'ref',
+ [
+ {
+ 'name' => 'chat_IM'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '6',
+ 'name' => 'incoming_chat_IM',
+ 'family' => '14'
+ },
+ 'ref',
+ [
+ {
+ 'name' => 'chat_IM'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '5',
+ 'name' => 'admin_request_response',
+ 'family' => '7'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'request_type'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {
+ 'count_prefix' => 'word'
+ },
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'new_screenname'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '17'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'new_email'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '8'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'error_code'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '4'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'error_url'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '3'
+ },
+ 'word',
+ [
+ {
+ 'name' => 'subrequest'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'buddy_icon_uploaded',
+ 'family' => '16'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '4',
+ 'name' => 'buddy_icon_download',
+ 'family' => '16'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {},
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {},
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'md5sum',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '5',
+ 'name' => 'buddy_icon_downloaded',
+ 'family' => '16'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'flags'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'number'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'checksum',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'icon',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '6',
+ 'name' => 'confirm_account_request',
+ 'family' => '7'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '7',
+ 'name' => 'confirm_account_response',
+ 'family' => '7'
+ },
+ 0,
+ '
+
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'status'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '4',
+ 'name' => 'change_account_info',
+ 'family' => '7'
+ },
+ 0,
+ '
+
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'new_screenname'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '17'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'new_email'
+ }
+ ]
+ ],
+ 0,
+ '
+
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '2'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'newpass'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '18'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'oldpass'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta'
+ },
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'prefix_order' => 'vax',
+ 'length_prefix' => 'word'
+ },
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'our_uin'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'type'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'seqno'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'typedata'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '2',
+ 'name' => 'ICQ_meta_request',
+ 'family' => '21'
+ },
+ 'ref',
+ [
+ {
+ 'name' => 'ICQ_meta'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '3',
+ 'name' => 'ICQ_meta_response',
+ 'family' => '21'
+ },
+ 'ref',
+ [
+ {
+ 'name' => 'ICQ_meta'
+ }
+ ]
+ ],
+ 0,
+ '
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_request'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'subtype'
+ },
+ 0,
+ '1202'
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'uin'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'subtype'
+ }
+ ],
+ 0,
+ '
+
+
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'status'
+ }
+ ],
+ 0,
+ '
+
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'response_data'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response:_basic'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'nickname',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'firstname',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'lastname',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'email',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'home'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'city',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'state',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'phone_num',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'fax_num',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'address',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'cell_phone_num',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'zip_code',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'country_code'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'gmt_offset'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'authorization'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'web_aware'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'direct_connect_permissions'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'publish_primary_email'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response:_office'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'city',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'state',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'phone_num',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'fax_num',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'address',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'zip_code',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'country_code'
+ }
+ ],
+ 0,
+ '
+
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'company',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'department',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'position',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'occupation'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'office_website',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response:_background'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'age'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'gender'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'homepage',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'birth_year'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'birth_month'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'bith_day'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'language_1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'language_2'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'language_3'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {}
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'origin_city',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'origin_state',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'origin_country'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'marital_status'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response:_notes'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'notes',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response:_email'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count_prefix' => 'byte',
+ 'name' => 'addresses'
+ },
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'publish'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'address',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response:_interests'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count_prefix' => 'byte',
+ 'name' => 'interests'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'category'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'interest',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response:_affiliations'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count_prefix' => 'byte',
+ 'name' => 'past_affiliations'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'category'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'keyword',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count_prefix' => 'byte',
+ 'name' => 'affiliations'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'category'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'keyword',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'ICQ_meta_info_response:_homepage'
+ },
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'enabled'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'order' => 'vax',
+ 'name' => 'category'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'null_terminated' => 'yes',
+ 'prefix_order' => 'vax',
+ 'name' => 'keywords',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {}
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'chat_invite_rendezvous_data'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'exchange'
+ },
+ 0,
+ '4'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'url',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'file_transfer_rendezvous_data'
+ },
+ 0,
+ '
+
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'file_count_status'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'file_count'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'size'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'null_terminated' => 'yes',
+ 'name' => 'files'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'buddy_list_transfer_rendezvous_data'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'group'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'name',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'count_prefix' => 'word',
+ 'name' => 'buddies'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'name',
+ 'length_prefix' => 'word'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'file_transfer_header'
+ },
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'length' => '4'
+ },
+ 0,
+ 'OFT2'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'header_length'
+ },
+ 0,
+ '256'
+ ],
+ 0,
+ '
+
+
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'type'
+ }
+ ],
+ 0,
+ '
+
+ ',
+ 'data',
+ [
+ {
+ 'length' => '8',
+ 'name' => 'cookie'
+ }
+ ],
+ 0,
+ '
+
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'encrypt'
+ },
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'compress'
+ },
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'file_count'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'files_left'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'part_count'
+ },
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'parts_left'
+ },
+ 0,
+ '1'
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'byte_count'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'bytes_left'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'mtime'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'checksum'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'received_initial_checksum'
+ },
+ 0,
+ '4294901760'
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'received_size'
+ },
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'ctime'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'initial_checksum'
+ },
+ 0,
+ '4294901760'
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'bytes_received'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'received_checksum'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'pad' => '0',
+ 'length' => '32',
+ 'name' => 'client_id'
+ },
+ 0,
+ 'Cool FileXfer'
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'flags'
+ },
+ 0,
+ '32'
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'name_offset'
+ },
+ 0,
+ '28'
+ ],
+ 0,
+ '
+ ',
+ 'byte',
+ [
+ {
+ 'name' => 'size_offset'
+ },
+ 0,
+ '17'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'pad' => '0',
+ 'length' => '69'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'pad' => '0',
+ 'length' => '16',
+ 'name' => 'mac_file_info'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'encoding'
+ },
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'language'
+ },
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'pad' => '0',
+ 'length' => '64',
+ 'name' => 'filename'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '11',
+ 'name' => 'pause',
+ 'family' => '1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '12',
+ 'name' => 'pause_ack',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'count' => '-1',
+ 'name' => 'families'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '13',
+ 'name' => 'unpause',
+ 'family' => '1'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'subtype' => '18',
+ 'name' => 'migrate',
+ 'family' => '1'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'count_prefix' => 'word',
+ 'name' => 'families'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '5'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'peer'
+ }
+ ]
+ ],
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '6'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'cookie'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+
+
+
+
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'direct_connect_proxy_hdr'
+ },
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'magic'
+ },
+ 0,
+ '1098'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'msg_type'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'data'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'direct_connect_proxy_init'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'direct_connect_proxy_hdr'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '0'
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'name' => 'screenname',
+ 'length_prefix' => 'byte'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'data',
+ [
+ {
+ 'length' => '8',
+ 'name' => 'cookie'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'tlvchain',
+ [
+ {},
+ 0,
+ '
+ ',
+ 'tlv',
+ [
+ {
+ 'type' => '1'
+ },
+ 'data',
+ [
+ {
+ 'name' => 'capability'
+ }
+ ]
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+ ',
+ 'define',
+ [
+ {
+ 'name' => 'direct_connect_proxy_reply'
+ },
+ 0,
+ '
+ ',
+ 'ref',
+ [
+ {
+ 'name' => 'direct_connect_proxy_hdr'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {},
+ 0,
+ '544'
+ ],
+ 0,
+ '
+ ',
+ 'word',
+ [
+ {
+ 'name' => 'port'
+ }
+ ],
+ 0,
+ '
+ ',
+ 'dword',
+ [
+ {
+ 'name' => 'ip'
+ }
+ ],
+ 0,
+ '
+ '
+ ],
+ 0,
+ '
+'
+ ]
+ ];
Index: perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.xml
===================================================================
--- perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.xml (revision 7a1c90dd56da7730139bf614567192ed49d47108)
+++ perl/modules/AIM/lib/Net/OSCAR/XML/Protocol.xml (revision 7a1c90dd56da7730139bf614567192ed49d47108)
@@ -0,0 +1,928 @@
+
+
+
+
+
+
+
+
+ 42
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ en
+ us
+ 1
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1024
+ 16
+ 10
+ 4096
+
+
+
+
+
+
+ 600
+ 750
+ 512
+
+
+
+
+ 0
+ 3
+ 8000
+ 999
+ 999
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 200
+ 200
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 254
+ 508
+ 0
+ 97
+ 10
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 1
+
+
+
+ 0
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ 4
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+ 257
+ 257
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ us-ascii
+ 48
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+ 0
+ 2
+
+
+
+ 2
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ us-ascii
+ en
+
+
+
+
+
+ create
+ 65535
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+
+ text/x-aolrtf
+ us-ascii
+ en
+ binary
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1202
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OFT2
+ 256
+
+
+
+
+
+
+ 0
+ 0
+
+
+ 1
+ 1
+
+
+
+
+ 4294901760
+ 0
+
+ 4294901760
+
+
+ Cool FileXfer
+ 32
+ 28
+ 17
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1098
+
+ 0
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+ 544
+
+
+
+
+
Index: perl/modules/AIM/lib/Net/OSCAR/XML/Template.pm
===================================================================
--- perl/modules/AIM/lib/Net/OSCAR/XML/Template.pm (revision 7a1c90dd56da7730139bf614567192ed49d47108)
+++ perl/modules/AIM/lib/Net/OSCAR/XML/Template.pm (revision 7a1c90dd56da7730139bf614567192ed49d47108)
@@ -0,0 +1,485 @@
+# These objects, initialized with an "OSCAR protocol template" from Net::OSCAR::XML::protoparse,
+# pack and unpack data according to the specification of that template.
+
+package Net::OSCAR::XML::Template;
+
+use strict;
+use warnings;
+
+use Net::OSCAR::XML;
+use Net::OSCAR::Common qw(:loglevels);
+use Net::OSCAR::Utility qw(hexdump);
+use Net::OSCAR::TLV;
+use Data::Dumper;
+use Carp;
+
+sub new($@) {
+ my $class = shift;
+ my $package = ref($class) || $class || "Net::OSCAR::XML::Template";
+ my $self = {template => $_[0]};
+ $self->{oscar} = $class->{oscar} if ref($class) and $class->{oscar};
+ bless $self, $package;
+ return $self;
+}
+
+# Net::OSCAR::XML caches Template objects that don't have an associated OSCAR,
+# so that the same Template can be reused with multiple OSCAR objects.
+# Before returning a Template to the user, it calls set_oscar, so here we clone
+# ourself with the new OSCAR.
+#
+sub set_oscar($$) {
+ my($self, $oscar) = @_;
+ my $clone = $self->new($self->{template});
+ $clone->{oscar} = $oscar;
+ return $clone;
+}
+
+
+# If given a scalar ref instead of a scalar as the second argument,
+# we will modify the packet in-place.
+sub unpack($$) {
+ my ($self, $x_packet) = @_;
+ my $oscar = $self->{oscar};
+ my $template = $self->{template};
+ my $packet = ref($x_packet) ? $$x_packet : $x_packet;
+
+ my %data = ();
+
+ $oscar->log_print_cond(OSCAR_DBG_XML, sub { "Decoding:\n", hexdump($packet), "\n according to: ", Data::Dumper::Dumper($template) });
+
+ assert(ref($template) eq "ARRAY");
+ foreach my $datum (@$template) {
+ # In TLV chains, count refers to number of TLVs, not number of repetitions of the datum, so it defaults to infinite.
+ my $count = $datum->{count} || ($datum->{type} eq "tlvchain" ? -1 : 1);
+ my @results;
+
+
+ ## Figure out how much input data this datum is dealing with
+
+ if($datum->{prefix} and $datum->{prefix} eq "count") {
+ ($count) = unpack($datum->{prefix_packlet}, substr($packet, 0, $datum->{prefix_len}, "")) || 0;
+ }
+
+ my $size = undef;
+ if($datum->{type} eq "num") {
+ if($count != -1) {
+ $size = $datum->{len} * $count;
+ } else {
+ $size = length($packet);
+ }
+ } else {
+ if($datum->{prefix} and $datum->{prefix} eq "length") {
+ ($size) = unpack($datum->{prefix_packlet}, substr($packet, 0, $datum->{prefix_len}, ""));
+ } elsif(exists($datum->{len})) {
+ # In TLV chains, count is the number of TLVs, not a repeat
+ # count for the datum.
+ if($datum->{type} eq "tlvchain") {
+ $size = $datum->{len};
+ } else {
+ if($count == -1) {
+ $size = length($packet);
+ } else {
+ $size = $datum->{len} * $count;
+ }
+ }
+ }
+ }
+
+ my $input;
+ if(defined($size)) {
+ $input = substr($packet, 0, $size, "");
+ } else {
+ $input = $packet;
+ }
+
+
+ ## Okay, we have our input data -- act on it
+
+ if($datum->{type} eq "num") {
+ for(my $i = 0; ($input ne "") and ($count == -1 or $i < $count); $i++) {
+ push @results, unpack($datum->{packlet}, substr($input, 0, $datum->{len}, ""));
+
+ if(exists($datum->{enum_byval}) and exists($datum->{enum_byval}->{$results[-1]})) {
+ $results[-1] = $datum->{enum_byval}->{$results[-1]};
+ }
+ }
+ } elsif($datum->{type} eq "data" or $datum->{type} eq "ref") {
+ # If we just have simple, no preset length, no subitems, raw data, it can't have a repeat count, since the first repetition will gobble up everything
+ assert($datum->{type} ne "data" or ($datum->{items} and @{$datum->{items}}) or defined($size) or $count == 1 or $datum->{null_terminated});
+
+ # We want:
+ #
+ # to be empty string, not undefined, when length==0.
+ if(!$input and $count == 1 and defined($size)) {
+ push @results, "";
+ }
+
+ for(my $i = 0; $input and ($count == -1 or $i < $count); $i++) {
+ # So, consider the structure:
+ #
+ #
+ #
+ #
+ # We don't know the size of 'foo' in advance.
+ # Thus, we pass a reference to the actual packet into protopack.
+ # subpacket will be modified to be the packet minus the bits that the contents of the data consumed.
+
+ my %tmp;
+ if($datum->{type} eq "data") {
+ my $subinput;
+ if($datum->{len}) {
+ $subinput = substr($input, 0, $datum->{len}, "");
+ } elsif($datum->{null_terminated}) {
+ $input =~ s/^(.*?)\0//;
+ $subinput = $1;
+ } else {
+ $subinput = $input;
+ $input = "";
+ }
+
+ if(exists($datum->{pad})) {
+ my $pad = chr($datum->{pad});
+ $subinput =~ s/$pad*$//;
+ }
+
+ if($datum->{items} and @{$datum->{items}}) {
+ assert(!$datum->{null_terminated});
+ (%tmp) = $self->new($datum->{items})->unpack(\$subinput);
+ $input = $subinput unless $datum->{len};
+ } else {
+ $subinput =~ s/\0$// if $datum->{null_terminated};
+
+ # The simple case -- raw
+ push @results, $subinput if $datum->{name};
+ }
+ } elsif($datum->{type} eq "ref") {
+ (%tmp) = protoparse($oscar, $datum->{name})->unpack(\$input);
+ }
+
+ push @results, \%tmp if %tmp;
+ }
+ } elsif($datum->{type} eq "tlvchain") {
+ my @unknown;
+
+ ## First set up a hash to store the data for each TLV, grouped by (sub)type
+ ##
+ my $tlvmap = tlv();
+ if($datum->{subtyped}) {
+ foreach (@{$datum->{items}}) {
+ $tlvmap->{$_->{num}} ||= tlv();
+ $tlvmap->{$_->{num}}->{$_->{subtype} || -1} = {%$_};
+ }
+ } else {
+ $tlvmap->{$_->{num}} = {%$_} foreach (@{$datum->{items}});
+ }
+
+ ## Now, go through the chain and split the data into TLVs.
+ ##
+ for(my $i = 0; $input and ($count == -1 or $i < $count); $i++) {
+ my %tlv;
+ if($datum->{subtyped}) {
+ (%tlv) = protoparse($oscar, "subtyped_TLV")->unpack(\$input);
+ } else {
+ (%tlv) = protoparse($oscar, "TLV")->unpack(\$input);
+ }
+
+ my $unknown = 0;
+ if(!exists($tlvmap->{$tlv{type}})) {
+ $tlvmap->{$tlv{type}} = $datum->{subtyped} ? tlv() : {};
+ $unknown = 1;
+ }
+
+ assert(!exists($tlv{name})) if exists($tlv{count});
+ if($datum->{subtyped}) {
+ assert(exists($tlv{subtype}));
+
+ if(!exists($tlvmap->{$tlv{type}}->{$tlv{subtype}})) {
+ if(exists($tlvmap->{$tlv{type}}->{-1})) {
+ $tlv{subtype} = -1;
+ } else {
+ $tlvmap->{$tlv{type}}->{$tlv{subtype}} = {};
+ $unknown = 1;
+ }
+ }
+
+ if(!$unknown) {
+ my $type = $tlv{type};
+ my $subtype = $tlv{subtype};
+ $tlvmap->{$type}->{$subtype}->{data} ||= [];
+ $tlvmap->{$type}->{$subtype}->{outdata} ||= [];
+
+ $tlv{data} = "" if !defined($tlv{data});
+ push @{$tlvmap->{$type}->{$subtype}->{data}}, $tlv{data};
+ } else {
+ push @unknown, {
+ type => $tlv{type},
+ subtype => $tlv{subtype},
+ data => $tlv{data}
+ };
+ }
+ } else {
+ if(!$unknown) {
+ my $type = $tlv{type};
+ $tlvmap->{$type}->{data} ||= [];
+ $tlvmap->{$type}->{outdata} ||= [];
+
+ $tlv{data} = "" if !defined($tlv{data});
+ push @{$tlvmap->{$tlv{type}}->{data}}, $tlv{data};
+ } else {
+ push @unknown, {
+ type => $tlv{type},
+ data => $tlv{data}
+ };
+ }
+ }
+ }
+
+ ## Almost done! Go back through the hash we made earlier, which now has the
+ ## data in it, and figure out which TLVs we want to emit.
+ ##
+ my @outvals;
+ while(my($num, $val) = each %$tlvmap) {
+ if($datum->{subtyped}) {
+ while(my($subtype, $subval) = each %$val) {
+ push @outvals, $subval if exists($subval->{data});
+ }
+ } else {
+ push @outvals, $val if exists($val->{data});
+ }
+ }
+
+
+ ## Okay, now take the TLVs to emit, and structure the output correctly
+ ## for each thing-to-emit. We'll need to do one last phase of postprocessing
+ ## so that we can group counted TLVs correctly.
+ ##
+ foreach my $val (@outvals) {
+ foreach (@{$val->{data}}) {
+ next unless exists($val->{items});
+ my(%tmp) = $self->new($val->{items})->unpack($_);
+ # We want:
+ #
+ # to give x => "" when TLV 1 is present but empty,
+ # not x => undef.
+ if(@{$val->{items}} == 1 and $val->{items}->[0]->{name}) {
+ my $name = $val->{items}->[0]->{name};
+ $tmp{$name} = "" if !defined($tmp{$name});
+ }
+
+ if(@{$val->{items}}) {
+ push @{$val->{outdata}}, \%tmp;
+ } else {
+ push @{$val->{outdata}}, "";
+ }
+ }
+ }
+
+
+ ## Okay, we've stashed the output (formatted data structures) for each TLV.
+ ## Now we need to merge these into results.
+ ## This is normally just pushing everything out to results, as a hashref
+ ## under the TLVs name for named TLVs, but counted TLVs also need to
+ ## be layered into an array.
+ ##
+ foreach my $val (@outvals) {
+ if(exists($val->{count})) {
+ if(exists($val->{name})) {
+ push @results, {
+ $val->{name} => $val->{outdata}
+ };
+ } else {
+ push @results, $val->{outdata}->[0];
+ }
+ } else {
+ if(exists($val->{name})) {
+ push @results, {
+ $val->{name} => $val->{outdata}->[0]
+ };
+ } else {
+ push @results, $val->{outdata}->[0];
+ }
+ }
+ }
+
+ push @results, {__UNKNOWN => [@unknown]} if @unknown;
+ }
+
+
+ # If we didn't know the length of the datum in advance,
+ # we've been modifying the entire packet in-place.
+ $packet = $input if !defined($size);
+
+
+ ## Okay, we have the results from this datum, store them away.
+
+ if($datum->{name}) {
+ if($datum->{count} or ($datum->{prefix} and $datum->{prefix} eq "count")) {
+ $data{$datum->{name}} = \@results;
+ } elsif(
+ $datum->{type} eq "ref" or
+ (ref($datum->{items}) and @{$datum->{items}})
+ ) {
+ $data{$_} = $results[0]->{$_} foreach keys %{$results[0]};
+ } else {
+ $data{$datum->{name}} = $results[0];
+ }
+ } elsif(@results) {
+ foreach my $result(@results) {
+ next unless ref($result);
+ $data{$_} = $result->{$_} foreach keys %$result;
+ }
+ }
+ }
+
+ $oscar->log_print_cond(OSCAR_DBG_XML, sub { "Decoded:\n", join("\n", map { "\t$_ => ".(defined($data{$_}) ? hexdump($data{$_}) : 'undef') } keys %data) });
+
+ # Remember, passing in a ref to packet in place of actual packet data == in-place editing...
+ $$x_packet = $packet if ref($x_packet);
+
+ return %data;
+}
+
+
+sub pack($%) {
+ my($self, %data) = @_;
+ my $packet = "";
+ my $oscar = $self->{oscar};
+ my $template = $self->{template};
+
+ $oscar->log_print_cond(OSCAR_DBG_XML, sub { "Encoding:\n", join("\n", map { "\t$_ => ".(defined($data{$_}) ? hexdump($data{$_}) : 'undef') } keys %data), "\n according to: ", Data::Dumper::Dumper($template) });
+
+ assert(ref($template) eq "ARRAY");
+ foreach my $datum (@$template) {
+ my $output = undef;
+
+ ## Figure out what we're packing
+ my $value = undef;
+ $value = $data{$datum->{name}} if $datum->{name};
+ $value = $datum->{value} if !defined($value);
+ my @valarray = ref($value) eq "ARRAY" ? @$value : ($value); # Don't modify $value in-place!
+
+ $datum->{count} = @valarray if $datum->{prefix} and $datum->{prefix} eq "count";
+ my $max_count = exists($datum->{count}) ? $datum->{count} : 1;
+ my $count = 0;
+
+ assert($max_count == -1 or @valarray <= $max_count);
+
+
+ ## Pack it
+ if($datum->{type} eq "num") {
+ next unless defined($value);
+
+ for($count = 0; ($max_count == -1 or $count < $max_count) and @valarray; $count++) {
+ my $val = shift @valarray;
+ if(exists($datum->{enum_byname}) and exists($datum->{enum_byname}->{$val})) {
+ $val = $datum->{enum_byname}->{$val};
+ }
+
+ $output .= pack($datum->{packlet}, $val);
+ }
+ } elsif($datum->{type} eq "data" or $datum->{type} eq "ref") {
+ for($count = 0; ($max_count == -1 or $count < $max_count) and @valarray; $count++) {
+ my $val = shift @valarray;
+
+ if($datum->{items} and @{$datum->{items}}) {
+ $output .= $self->new($datum->{items})->pack(ref($val) ? %$val : %data);
+ } elsif($datum->{type} eq "ref") {
+ assert($max_count == 1 or (ref($val) and ref($val) eq "HASH"));
+ $output .= protoparse($oscar, $datum->{name})->pack(ref($val) ? %$val : %data);
+ } else {
+ $output .= $val if defined($val);
+ }
+
+ $output .= chr(0) if $datum->{null_terminated};
+ if(exists($datum->{pad})) {
+ assert(exists($datum->{len}) and exists($datum->{pad}));
+
+ my $outlen = defined($output) ? length($output) : 0;
+ my $pad_needed = $datum->{len} - $outlen;
+ $output .= chr($datum->{pad}) x $pad_needed if $pad_needed;
+ }
+ }
+ } elsif($datum->{type} eq "tlvchain") {
+ foreach my $tlv (@{$datum->{items}}) {
+ my $tlvdata = undef;
+
+ if(exists($tlv->{name})) {
+ if(exists($data{$tlv->{name}})) {
+ if(@{$tlv->{items}}) {
+ assert(ref($data{$tlv->{name}}) eq "HASH" or ref($data{$tlv->{name}}) eq "ARRAY");
+ if(ref($data{$tlv->{name}}) eq "ARRAY") {
+ $tlvdata = [];
+ push @$tlvdata, $self->new($tlv->{items})->pack(%$_) foreach @{$data{$tlv->{name}}};
+ } else {
+ $tlvdata = [$self->new($tlv->{items})->pack(%{$data{$tlv->{name}}})];
+ }
+ } else {
+ $tlvdata = [""] if defined($data{$tlv->{name}});
+ }
+ } elsif(exists($tlv->{value}) and !@{$tlv->{items}}) {
+ $tlvdata = [$tlv->{value}];
+ }
+ } else {
+ my $tmp = $self->new($tlv->{items})->pack(%data);
+
+ # If TLV has no name and only one element, do special handling for "present but empty" value.
+ if($tmp ne "") {
+ $tlvdata = [$tmp];
+ } elsif(@{$tlv->{items}} == 1 and $tlv->{items}->[0]->{name} and exists($data{$tlv->{items}->[0]->{name}})) {
+ $tlvdata = [""];
+ } elsif(!@{$tlv->{items}} and exists($tlv->{value})) {
+ $tlvdata = [$tlv->{value}];
+ }
+ }
+
+ assert($tlv->{num});
+ next unless defined($tlvdata);
+
+ $count++;
+ if($datum->{subtyped}) {
+ my $subtype = 0;
+ assert(exists($tlv->{subtype}));
+ $subtype = $tlv->{subtype} if $tlv->{subtype} != -1;
+
+ $output .= protoparse($oscar, "subtyped_TLV")->pack(
+ type => $tlv->{num},
+ subtype => $subtype,
+ data => $_
+ ) foreach @$tlvdata;
+ } else {
+ $output .= protoparse($oscar, "TLV")->pack(
+ type => $tlv->{num},
+ data => $_
+ ) foreach @$tlvdata;
+ }
+ }
+ }
+
+
+ ## Handle any prefixes
+ if($datum->{prefix} and defined($output)) {
+ if($datum->{prefix} eq "count") {
+ $packet .= pack($datum->{prefix_packlet}, $count);
+ } else {
+ $packet .= pack($datum->{prefix_packlet}, length($output));
+ }
+ }
+
+ $packet .= $output if defined($output);
+ }
+
+ $oscar->log_print_cond(OSCAR_DBG_XML, sub { "Encoded:\n", hexdump($packet) });
+ return $packet;
+}
+
+
+sub assert($) {
+ my $test = shift;
+ return if $test;
+ confess("Net::OSCAR internal error");
+}
+
+# Why isn't this imported properly??
+sub protoparse { Net::OSCAR::XML::protoparse(@_); }
+
+1;