View Javadoc
1   // ////////////////////////////////////////////////////////////////////////////
2   // dexterIM - Instant Messaging Framework
3   // Copyright (C) 2003 Christoph Walcher
4   //
5   // This program is free software; you can redistribute it and/or modify
6   // it under the terms of the GNU General Public License as published by
7   // the Free Software Foundation; either version 2 of the License, or
8   // (at your option) any later version.
9   //
10  // This program is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  // GNU General Public License for more details.
14  //
15  // You should have received a copy of the GNU General Public License
16  // along with this program; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  //////////////////////////////////////////////////////////////////////////////
19  package net.sf.dexterim.oscar.icbm;
20  
21  import net.sf.dexterim.core.Contact;
22  import net.sf.dexterim.oscar.BufferArray;
23  import net.sf.dexterim.oscar.OscarByteBuffer;
24  import net.sf.dexterim.oscar.entity.DWord;
25  import net.sf.dexterim.oscar.entity.Snac;
26  import net.sf.dexterim.oscar.entity.TLV;
27  import net.sf.dexterim.oscar.entity.VariableByte;
28  import net.sf.dexterim.oscar.entity.Word;
29  
30  
31  /***
32   * @author christoph
33   *
34   */
35  public class SendMessageRequest extends Snac {
36  	private static final Word MESSAGE_CHARSET = new Word(0x0000);
37  	private static final Word MESSAGE_LANGUAGE = new Word(0xffff);
38  	
39  	public SendMessageRequest(Contact recipient, String message, boolean storeIfOffline, boolean requestAcknowledge) {
40  		super(0x0004, 0x0006, 0x0000);
41  		
42  		OscarByteBuffer buffer = OscarByteBuffer.dynamic();
43  		
44  		/*
45  		00 04   word   SNAC family 
46  		00 06   word   SNAC subtype 
47  		00 00   word   SNAC flags 
48  		xx xx xx xx   dword   SNAC request-id 
49  		 
50  		xx xx xx xx
51  		xx xx xx xx   qword   msg-id cookie 
52  		xx xx   word   message channel (see table below) 
53  		xx   byte   screenname string length 
54  		xx ..   string   screenname string 
55  		 
56  		*/
57  		buffer.write(new DWord((int)System.currentTimeMillis()));
58  		buffer.write(new DWord(0x0000));
59  		buffer.write(new Word(0x0001));
60  		
61  		VariableByte screenName = new VariableByte(recipient.getIdentity().toString());
62  		
63  		buffer.write((byte)screenName.getLength());
64  		buffer.write(screenName);
65  		
66  		TLV messageData = new TLV(0x0002);
67  
68  		OscarByteBuffer capsBuffer = createCapabilityFragment();
69  		OscarByteBuffer messageBuffer = createTextMessageFragment(message);
70  		
71  		OscarByteBuffer fragmentBuffer = BufferArray.createBufferArray(capsBuffer, messageBuffer);
72  		
73  		messageData.setData(fragmentBuffer.slice());
74  
75  		buffer.write(OscarByteBuffer.wrap(messageData.toByteArray()));
76  		
77  		if (requestAcknowledge) {
78  			TLV requestAckTLV = new TLV(0x03);
79  			
80  			buffer.write(OscarByteBuffer.wrap(requestAckTLV.toByteArray()));
81  		}
82  		
83  		if (storeIfOffline) {
84  			TLV offlineTLV = new TLV(0x06);
85  			
86  			buffer.write(OscarByteBuffer.wrap(offlineTLV.toByteArray()));
87  		}
88  		
89  		setData(buffer.slice());
90  	}
91  	
92  	/*** Creates the Capabilities Message Fragment. Only text capability is
93  	 * created.
94  	 * 05   byte   fragment identifier (array of required capabilities) 
95  	 * 01   byte   fragment version 
96  	 * xx xx   word   Length of rest data 
97  	 *
98  	 * xx ...   array   byte array of required capabilities (1 - text) 
99  	 */
100 	private OscarByteBuffer createCapabilityFragment() {
101 		OscarByteBuffer buffer = OscarByteBuffer.dynamic();
102 
103 		buffer.write((byte)0x05);
104 		buffer.write((byte)0x01);
105 		
106 		buffer.write((byte)0x00);
107 		buffer.write((byte)0x01);
108 		
109 		buffer.write((byte)0x01);
110 		
111 		return buffer;
112 	}
113 	
114 	/***
115 	 01   byte   fragment identifier (text message) 
116 	 01   byte   fragment version 
117 	 xx xx   word   Length of rest data 
118 	 
119 	 00 00   word   Message charset number 
120 	 ff ff   word   Message language number 
121 	 xx ..   string (ascii)   Message text string 
122 	 */
123 	private OscarByteBuffer createTextMessageFragment(String message) {
124 		OscarByteBuffer buffer = OscarByteBuffer.dynamic();
125 
126 		buffer.write((byte)0x01);
127 		buffer.write((byte)0x01);
128 		
129 		VariableByte byteMessage = new VariableByte(message);
130 		
131 		Word length = new Word(MESSAGE_CHARSET.getLength() + MESSAGE_LANGUAGE.getLength() + byteMessage.getLength());
132 		buffer.write(length);
133 		
134 		buffer.write(MESSAGE_CHARSET);
135 		buffer.write(MESSAGE_LANGUAGE);
136 		buffer.write(byteMessage);
137 		
138 		return buffer;
139 	}
140 }