1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.marre.sms.siemens;
24
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.util.Random;
29
30 import org.marre.sms.SmsDcs;
31 import org.marre.sms.SmsMessage;
32 import org.marre.sms.SmsConstants;
33 import org.marre.sms.SmsPdu;
34 import org.marre.util.StringUtil;
35
36 /***
37 *
38 * @author Raphael Borg Ellul Vincenti
39 * @version $Id: SiemensOtaMessage.java,v 1.4 2005/05/06 13:55:14 c95men Exp $
40 */
41 public class SiemensOtaMessage implements SmsMessage
42 {
43 protected int myVersion = 1;
44 protected String myName = "";
45 protected String myType = "";
46 protected long myReferenceId;
47 protected int myDataSize;
48 protected int myNumberOfPackets;
49 protected byte[] myContent;
50
51 /***
52 * Creates an SMS containing a Bitmap or a Ringtone
53 *
54 * @param theMessage
55 * The content in bytes
56 */
57 public SiemensOtaMessage(String name, String type, byte[] content)
58 {
59 myName = name;
60 myType = type;
61 myContent = content;
62
63 init();
64 }
65
66 /***
67 * Creates an SMS containing a Bitmap or a Ringtone
68 *
69 * @param theMessage
70 * The content in bytes
71 */
72 public SiemensOtaMessage(int version, String name, String type, byte[] content)
73 {
74 this.myVersion = version;
75 this.myName = name;
76 this.myType = type;
77 this.myContent = content;
78
79 init();
80
81 }
82
83 /***
84 *
85 *
86 */
87 private void init()
88 {
89 this.myReferenceId = (new Random()).nextLong();
90 this.myDataSize = 140 - 22 - myName.length() - myType.length();
91 this.myNumberOfPackets = (int) Math.ceil((float) myContent.length / (float) myDataSize);
92 }
93
94 /***
95 * Returns the userdata header for an SMS
96 *
97 * @return
98 */
99 private byte[] getHeader(int actPacketNumber)
100 {
101 byte[] header = new byte[22 + myName.length() + myType.length()];
102
103
104 header[0] = (byte) 0x2f;
105 header[1] = (byte) 0x2f;
106 header[2] = (byte) 0x53;
107 header[3] = (byte) 0x45;
108 header[4] = (byte) 0x4f;
109
110
111 header[5] = (byte) (myVersion & 0xff);
112
113
114 header[6] = (byte) (myDataSize & 0xff);
115 header[7] = (byte) ((myDataSize >> 8) & 0xff);
116
117
118 header[8] = (byte) (myReferenceId & 0xff);
119 header[9] = (byte) ((myReferenceId >> 8) & 0xff);
120 header[10] = (byte) ((myReferenceId >> 16) & 0xff);
121 header[11] = (byte) ((myReferenceId >> 24) & 0xff);
122
123
124 header[12] = (byte) (actPacketNumber & 0xff);
125 header[13] = (byte) ((actPacketNumber >> 8) & 0xff);
126
127
128 header[14] = (byte) (myNumberOfPackets & 0xff);
129 header[15] = (byte) ((myNumberOfPackets >> 8) & 0xff);
130
131
132 header[16] = (byte) (myContent.length & 0xff);
133 header[17] = (byte) ((myContent.length >> 8) & 0xff);
134 header[18] = (byte) ((myContent.length >> 16) & 0xff);
135 header[19] = (byte) ((myContent.length >> 24) & 0xff);
136
137
138 header[20] = (byte) (myType.length() & 0xff);
139 header[21] = (byte) (myType.charAt(0) & 0xff);
140 header[22] = (byte) (myType.charAt(1) & 0xff);
141 header[23] = (byte) (myType.charAt(2) & 0xff);
142
143
144 header[24] = (byte) (myName.length() & 0xff);
145 for (int i = 0; i < myName.length(); i++)
146 {
147 header[25 + i] = (byte) ((myName.charAt(i)) & 0xff);
148 }
149
150 return header;
151 }
152
153 /***
154 * Converts this message into SmsPdu:s
155 * <p>
156 * If the message is too long to fit in one SmsPdu the message is divided
157 * into many SmsPdu:s with a different packet number
158 *
159 * @return Returns the message as SmsPdu:s
160 */
161 public SmsPdu[] getPdus()
162 {
163 SmsPdu[] smsPdus = new SmsPdu[myNumberOfPackets];
164 SmsDcs dcs = SmsDcs.getGeneralDataCodingDcs(SmsDcs.ALPHABET_8BIT, SmsDcs.MSG_CLASS_1);
165 for (int i = 0; i < myNumberOfPackets; i++)
166 {
167
168 byte[] pdu = new byte[140];
169 byte[] header = getHeader(i + 1);
170
171 System.arraycopy(header, 0, pdu, 0, header.length);
172 int offset = myDataSize * i;
173
174
175 if (i == (myNumberOfPackets - 1))
176 {
177 myDataSize = myContent.length % myDataSize;
178 }
179
180 System.arraycopy(myContent, offset, pdu, header.length, myDataSize);
181
182 SmsPdu smsPdu = new SmsPdu(null, pdu, pdu.length, dcs);
183 smsPdus[i] = smsPdu;
184 }
185
186 return smsPdus;
187 }
188
189
190
191
192 public static byte[] loadFromFile(File file) throws IOException
193 {
194 int n;
195 int nread = 0;
196 int len = (int) file.length();
197
198 FileInputStream fin = new FileInputStream(file);
199
200 byte[] content = new byte[len];
201
202 while (nread < len)
203 {
204
205 if ((n = fin.read(content, nread, len - nread)) == -1)
206 {
207 throw new IOException("Error loading Compound from file");
208 }
209 nread += n;
210 }
211
212 return content;
213 }
214
215 public static void main(String[] args)
216 {
217 String name = "Operator.bmp";
218 String type = "bmp";
219
220 byte[] data = null;
221
222 try
223 {
224 data = loadFromFile(new File(args[0]));
225 }
226 catch (IOException e)
227 {
228 e.printStackTrace();
229 }
230
231 SiemensOtaMessage message = new SiemensOtaMessage(22518750, name, type, data);
232
233 SmsPdu[] pdus = message.getPdus();
234
235 System.out.println("Data : " + StringUtil.bytesToHexString(data));
236
237 for (int i = 0; i < pdus.length; i++)
238 {
239 System.out.println("UD : " + StringUtil.bytesToHexString(pdus[i].getUserData().getData()));
240 }
241 }
242
243 }