1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.dexterim.oscar.client;
20
21 import net.sf.dexterim.core.Account;
22 import net.sf.dexterim.core.Contact;
23 import net.sf.dexterim.oscar.BufferArray;
24 import net.sf.dexterim.oscar.OscarByteBuffer;
25 import net.sf.dexterim.oscar.entity.DWord;
26 import net.sf.dexterim.oscar.entity.QWord;
27 import net.sf.dexterim.oscar.entity.Snac;
28 import net.sf.dexterim.oscar.entity.TLV;
29 import net.sf.dexterim.oscar.entity.VariableByte;
30 import net.sf.dexterim.oscar.entity.Word;
31
32
33 /***
34 * @author christoph
35 *
36 */
37 public class SendMessageRequest extends Snac {
38 private static final DWord MESSAGE_CHARSET = new DWord(0x0000);
39 private static final DWord MESSAGE_LANGUAGE = new DWord(0xffff);
40
41 public SendMessageRequest(Contact recipient, String message, boolean storeIfOffline, boolean requestAcknowledge) {
42 super(0x0004, 0x0006, 0x0000);
43
44 OscarByteBuffer buffer = OscarByteBuffer.dynamic();
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 buffer.write(new QWord(System.currentTimeMillis()));
60 buffer.write(new Word(0x0001));
61
62 VariableByte screenName = new VariableByte(recipient.getIdentity().toString());
63
64 buffer.write((byte)screenName.getLength());
65 buffer.write(screenName);
66
67 TLV messageData = new TLV(0x0002);
68
69 OscarByteBuffer capsBuffer = createCapabilityFragment();
70 OscarByteBuffer messageBuffer = createTextMessageFragment(message);
71
72 OscarByteBuffer fragmentBuffer = BufferArray.createBufferArray(capsBuffer, messageBuffer);
73
74 messageData.setData(fragmentBuffer.slice());
75
76 buffer.write(OscarByteBuffer.wrap(messageData.toByteArray()));
77
78 if (requestAcknowledge) {
79 TLV requestAckTLV = new TLV(0x03);
80
81 buffer.write(OscarByteBuffer.wrap(requestAckTLV.toByteArray()));
82 }
83
84 if (storeIfOffline) {
85 TLV offlineTLV = new TLV(0x06);
86
87 buffer.write(OscarByteBuffer.wrap(offlineTLV.toByteArray()));
88 }
89
90 setData(buffer.slice());
91 }
92
93 /*** Creates the Capabilities Message Fragment. Only text capability is
94 * created.
95 * 05 byte fragment identifier (array of required capabilities)
96 * 01 byte fragment version
97 * xx xx word Length of rest data
98 *
99 * xx ... array byte array of required capabilities (1 - text)
100 */
101 private OscarByteBuffer createCapabilityFragment() {
102 OscarByteBuffer buffer = OscarByteBuffer.dynamic();
103
104 buffer.write((byte)0x05);
105 buffer.write((byte)0x01);
106
107 buffer.write((byte)0x00);
108 buffer.write((byte)0x01);
109
110 buffer.write((byte)0x01);
111
112 return buffer;
113 }
114
115 /***
116 01 byte fragment identifier (text message)
117 01 byte fragment version
118 xx xx word Length of rest data
119
120 00 00 word Message charset number
121 ff ff word Message language number
122 xx .. string (ascii) Message text string
123 */
124 private OscarByteBuffer createTextMessageFragment(String message) {
125 OscarByteBuffer buffer = OscarByteBuffer.dynamic();
126
127 buffer.write((byte)0x01);
128 buffer.write((byte)0x01);
129
130 VariableByte byteMessage = new VariableByte(message);
131
132 DWord length = new DWord(MESSAGE_CHARSET.getLength() + MESSAGE_LANGUAGE.getLength() + byteMessage.getLength());
133 buffer.write(length);
134
135 buffer.write(MESSAGE_CHARSET);
136 buffer.write(MESSAGE_LANGUAGE);
137 buffer.write(byteMessage);
138
139 return buffer;
140 }
141 }