1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.dexterim.oscar;
20
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 import java.util.List;
26
27 import net.sf.dexterim.core.AbstractIMConnection;
28 import net.sf.dexterim.core.Account;
29 import net.sf.dexterim.core.Contact;
30 import net.sf.dexterim.core.ContactList;
31 import net.sf.dexterim.core.Conversation;
32 import net.sf.dexterim.oscar.client.BosRightsRequest;
33 import net.sf.dexterim.oscar.client.BuddyListRightsRequest;
34 import net.sf.dexterim.oscar.client.ClientReadyRequest;
35 import net.sf.dexterim.oscar.client.LocationRightsRequest;
36 import net.sf.dexterim.oscar.client.MessageBuilder;
37 import net.sf.dexterim.oscar.client.PersonalInfoRequest;
38 import net.sf.dexterim.oscar.client.ServiceRequest;
39 import net.sf.dexterim.oscar.client.SetUserInformationRequest;
40 import net.sf.dexterim.oscar.entity.CapabilitiesBuilder;
41 import net.sf.dexterim.oscar.entity.SnacFamiliesVersions;
42 import net.sf.dexterim.oscar.entity.SnacFamily;
43 import net.sf.dexterim.oscar.icbm.ICBMParameterRequest;
44 import net.sf.dexterim.oscar.icbm.SendMessageRequest;
45 import net.sf.dexterim.oscar.io.OscarChannel;
46 import net.sf.dexterim.oscar.io.ParserException;
47 import net.sf.dexterim.oscar.server.CookieResponse;
48 import net.sf.dexterim.oscar.server.MessageOfTheDayResponse;
49 import net.sf.dexterim.oscar.server.RateInfoResponse;
50 import net.sf.dexterim.oscar.server.Response;
51 import net.sf.dexterim.oscar.server.SupportedSnacFamilies;
52
53 import org.apache.commons.logging.Log;
54 import org.apache.commons.logging.LogFactory;
55
56 /***
57 * @author christoph
58 */
59 public class OscarConnection extends AbstractIMConnection {
60
61 private boolean connected;
62
63 private OscarChannel bosChannel;
64
65 private Account account;
66 private Log log = LogFactory.getLog(getClass());
67
68 private List conversations;
69
70 public OscarConnection() {
71 this.conversations = new ArrayList();
72 this.connected = false;
73 }
74
75
76
77
78
79
80 public void connect(Account account) {
81 this.account = account;
82
83 try {
84 InetSocketAddress loginServer = new InetSocketAddress("login.icq.com",
85 5190);
86
87 OscarChannel channel = new OscarChannel();
88 channel.connect(loginServer);
89
90 log.debug("Receiving Welcome Message...");
91 channel.readMessage();
92 log.debug("...Welcome Message Received");
93
94 MessageBuilder builder = new MessageBuilder();
95 byte[] identMessage = builder.buildIdentRequest(account);
96
97 log.debug("Sending Ident Message...");
98 channel.write(identMessage);
99 log.debug("...Ident Message sent");
100
101 log.debug("Receiving Cookie Message...");
102 Response message = channel.readMessage();
103 log.debug("...Cookie Message Received");
104
105 channel.close();
106
107 if (!(message instanceof CookieResponse)) {
108 log.error("message:" + message);
109
110 throw new IllegalStateException("Wrong message type received!");
111 }
112
113 CookieResponse cookieResponse = (CookieResponse) message;
114 InetSocketAddress bosAddress = cookieResponse.getBosAddress();
115
116 bosChannel = new OscarChannel();
117 bosChannel.connect(bosAddress);
118
119 Response m = bosChannel.readMessage();
120
121 if (m != null) {
122 log.debug("Welcome message from BOS received...");
123 log.debug(m.toString());
124 }
125 else {
126 log.debug("Welcome message from BOS received but null!");
127 }
128
129 bosChannel.write(builder.buildCookieRequest(cookieResponse.getCookie()));
130 Response snac = bosChannel.readMessage();
131
132 if (!(snac instanceof SupportedSnacFamilies)) {
133 throw new IllegalStateException("Wrong message type received!");
134 }
135
136 SupportedSnacFamilies families = (SupportedSnacFamilies) snac;
137
138 for (Iterator iter = families.iterator(); iter.hasNext();) {
139 Integer family = (Integer) iter.next();
140 log.debug("Family: " + family);
141 }
142
143 byte[] familyVersionRequest = builder.buildFamilyVersionRequest();
144 bosChannel.write(familyVersionRequest);
145
146 SnacFamiliesVersions versionsResponse = (SnacFamiliesVersions) bosChannel
147 .readMessage();
148
149 for (Iterator iter = versionsResponse.iterator(); iter.hasNext();) {
150 SnacFamily family = (SnacFamily) iter.next();
151
152 log.debug(family.toString());
153 }
154
155 Response motdMessage = bosChannel.readMessage();
156
157 if (motdMessage instanceof MessageOfTheDayResponse) {
158 MessageOfTheDayResponse motd = (MessageOfTheDayResponse) motdMessage;
159
160 log.debug("MOTD: " + motd.toString());
161 }
162
163 log.debug("Sending Rate Request...");
164 bosChannel.write(builder.buildRateRequest());
165 log.debug("Rate Request sent!");
166
167 Response rateResponse = bosChannel.readMessage();
168
169 if (rateResponse instanceof RateInfoResponse) {
170 log.debug("Rate Response from BOS received!");
171 bosChannel.write(builder
172 .buildRateInfoAcknowledge((RateInfoResponse) rateResponse));
173 }
174
175 log.debug("Connected!");
176 this.connected = true;
177
178 bosChannel.write(new ServiceRequest(ServiceRequest.ADVERTISEMENTS));
179 bosChannel.write(new PersonalInfoRequest());
180 bosChannel.write(new LocationRightsRequest());
181 bosChannel.write(new ICBMParameterRequest());
182 bosChannel.write(new BosRightsRequest());
183 bosChannel.write(new BuddyListRightsRequest());
184
185 bosChannel.write(new SetUserInformationRequest(CapabilitiesBuilder
186 .getInstance().buildCapabilities("icq")));
187
188
189
190 bosChannel.write(new ClientReadyRequest(families));
191
192 new Thread("Oscar Message Receiver") {
193 public void run() {
194 Response response = null;
195
196 try {
197 while ((response = bosChannel.readMessage()) != null) {
198 log.debug(response);
199 }
200 }
201 catch (IOException e) {
202
203 }
204 catch (ParserException e) {
205
206 }
207 }
208 }.start();
209
210 }
211 catch (IOException e) {
212 e.printStackTrace();
213 }
214 catch (ParserException pex) {
215 pex.printStackTrace();
216 }
217 }
218
219 /***
220 * @see net.sf.dexterim.core.IMConnection#connectedAs()
221 */
222 public Account connectedAs() {
223 return this.account;
224 }
225
226 /***
227 * @see net.sf.dexterim.core.IMConnection#disconnect()
228 */
229 public void disconnect() {
230 try {
231 if (this.bosChannel != null) {
232 this.bosChannel.close();
233 }
234
235 if (this.bosChannel != null) {
236 this.bosChannel.close();
237 }
238 }
239 catch (IOException e) {
240 e.printStackTrace();
241 }
242
243 connected = false;
244 }
245
246 /***
247 * @see net.sf.dexterim.core.IMConnection#synchronizeContactList(net.sf.dexterim.core.ContactList)
248 */
249 public void synchronizeContactList(ContactList contactList) {
250
251 }
252
253 /***
254 * @see net.sf.dexterim.core.IMConnection#isConnected()
255 */
256 public boolean isConnected() {
257 return connected;
258 }
259
260 /***
261 * @see net.sf.dexterim.core.IMConnection#createConversation()
262 */
263 public Conversation createConversation() {
264 OscarConversation conversation = new OscarConversation(this);
265
266 conversations.add(conversation);
267 return conversation;
268 }
269
270 /***
271 * TODO: Document this
272 * @param conversation
273 */
274 public void closeConversation(Conversation conversation) {
275 this.conversations.remove(conversation);
276 }
277
278 /***
279 * TODO should throw an Exception
280 * @param contact
281 * @param message
282 */
283 public void sendMessage(Contact contact, String message) {
284 try {
285 bosChannel.write(new SendMessageRequest(contact, message, false, true));
286 }
287 catch (IOException e) {
288 e.printStackTrace();
289 }
290 }
291 }