1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 package org.marre.sms;
36
37 import java.util.Random;
38
39 /***
40 * Baseclass for messages that needs to be concatenated.
41 * <p>- Only usable for messages that uses the same UDH fields for all message
42 * parts. <br>- This class could be better written. There are several parts
43 * that are copy- pasted. <br>- The septet coding could be a bit optimized.
44 * <br>
45 *
46 * @author Markus Eriksson
47 * @version $Id: SmsConcatMessage.java,v 1.16 2005/05/06 13:55:11 c95men Exp $
48 */
49 public abstract class SmsConcatMessage implements SmsMessage
50 {
51 private static Random myRnd = new Random();
52
53 /***
54 * Creates an empty SmsConcatMessage.
55 */
56 protected SmsConcatMessage()
57 {
58
59 }
60
61 /***
62 * Returns the whole UD
63 *
64 * @return the UD
65 */
66 public abstract SmsUserData getUserData();
67
68 /***
69 * Returns the udh elements
70 * <p>
71 * The returned UDH is the same as specified when the message was created.
72 * No concat headers are added.
73 *
74 * @return the UDH as SmsUdhElements
75 */
76 public abstract SmsUdhElement[] getUdhElements();
77
78 private SmsPdu[] createOctalPdus(SmsUdhElement[] theUdhElements, SmsUserData theUd, int theMaxBytes)
79 {
80 int nMaxChars;
81 int nMaxConcatChars;
82 SmsPdu[] smsPdus = null;
83
84
85 nMaxConcatChars = theMaxBytes - 6;
86 nMaxChars = theMaxBytes;
87
88 if (theUd.getLength() <= nMaxChars)
89 {
90 smsPdus = new SmsPdu[]{new SmsPdu(theUdhElements, theUd)};
91 }
92 else
93 {
94 int refno = myRnd.nextInt(256);
95
96
97 int nSms = theUd.getLength() / nMaxConcatChars;
98 if ((theUd.getLength() % nMaxConcatChars) > 0)
99 {
100 nSms += 1;
101 }
102 smsPdus = new SmsPdu[nSms];
103
104
105 SmsUdhElement[] pduUdhElements = null;
106 if (theUdhElements == null)
107 {
108 pduUdhElements = new SmsUdhElement[1];
109 }
110 else
111 {
112 pduUdhElements = new SmsUdhElement[theUdhElements.length + 1];
113
114
115 for (int j = 0; j < theUdhElements.length; j++)
116 {
117
118 pduUdhElements[j + 1] = theUdhElements[j];
119 }
120 }
121
122
123 for (int i = 0; i < nSms; i++)
124 {
125 byte[] pduUd;
126 int udBytes;
127 int udLength;
128 int udOffset;
129
130
131 pduUdhElements[0] = SmsUdhUtil.get8BitConcatUdh(refno, nSms, i + 1);
132
133
134
135
136 udOffset = nMaxConcatChars * i;
137 udBytes = theUd.getLength() - udOffset;
138 if (udBytes > nMaxConcatChars)
139 {
140 udBytes = nMaxConcatChars;
141 }
142 udLength = udBytes;
143
144 pduUd = new byte[udBytes];
145 SmsPduUtil.arrayCopy(theUd.getData(), udOffset, pduUd, 0, udBytes);
146 smsPdus[i] = new SmsPdu(pduUdhElements, pduUd, udLength, theUd.getDcs());
147 }
148 }
149 return smsPdus;
150 }
151
152 private SmsPdu[] createUnicodePdus(SmsUdhElement[] theUdhElements, SmsUserData theUd, int theMaxBytes)
153 {
154 int nMaxChars;
155 int nMaxConcatChars;
156 SmsPdu[] smsPdus = null;
157
158
159 nMaxConcatChars = (theMaxBytes - 6) / 2;
160 nMaxChars = theMaxBytes / 2;
161
162 if (theUd.getLength() <= nMaxChars)
163 {
164 smsPdus = new SmsPdu[]{new SmsPdu(theUdhElements, theUd)};
165 }
166 else
167 {
168 int refno = myRnd.nextInt(256);
169
170
171 int nSms = (theUd.getLength() / 2) / nMaxConcatChars;
172 if (((theUd.getLength() / 2) % nMaxConcatChars) > 0)
173 {
174 nSms += 1;
175 }
176 smsPdus = new SmsPdu[nSms];
177
178
179 SmsUdhElement[] pduUdhElements = null;
180 if (theUdhElements == null)
181 {
182 pduUdhElements = new SmsUdhElement[1];
183 }
184 else
185 {
186 pduUdhElements = new SmsUdhElement[theUdhElements.length + 1];
187
188
189 for (int j = 0; j < theUdhElements.length; j++)
190 {
191
192 pduUdhElements[j + 1] = theUdhElements[j];
193 }
194 }
195
196
197 for (int i = 0; i < nSms; i++)
198 {
199 byte[] pduUd;
200 int udBytes;
201 int udLength;
202 int udOffset;
203
204
205 pduUdhElements[0] = SmsUdhUtil.get8BitConcatUdh(refno, nSms, i + 1);
206
207
208
209
210 udOffset = nMaxConcatChars * i;
211 udLength = (theUd.getLength() / 2) - udOffset;
212 if (udLength > nMaxConcatChars)
213 {
214 udLength = nMaxConcatChars;
215 }
216 udBytes = udLength * 2;
217
218 pduUd = new byte[udBytes];
219 SmsPduUtil.arrayCopy(theUd.getData(), udOffset * 2, pduUd, 0, udBytes);
220 smsPdus[i] = new SmsPdu(pduUdhElements, pduUd, udBytes, theUd.getDcs());
221 }
222 }
223 return smsPdus;
224 }
225
226 private SmsPdu[] createSeptetPdus(SmsUdhElement[] theUdhElements, SmsUserData theUd, int theMaxBytes)
227 {
228 int nMaxChars;
229 int nMaxConcatChars;
230 SmsPdu[] smsPdus = null;
231
232
233 nMaxConcatChars = ((theMaxBytes - 6) * 8) / 7;
234 nMaxChars = (theMaxBytes * 8) / 7;
235
236 if (theUd.getLength() <= nMaxChars)
237 {
238 smsPdus = new SmsPdu[]{new SmsPdu(theUdhElements, theUd)};
239 }
240 else
241 {
242 int refno = myRnd.nextInt(256);
243
244
245 int nSms = theUd.getLength() / nMaxConcatChars;
246 if ((theUd.getLength() % nMaxConcatChars) > 0)
247 {
248 nSms += 1;
249 }
250 smsPdus = new SmsPdu[nSms];
251
252
253 SmsUdhElement[] pduUdhElements = null;
254 if (theUdhElements == null)
255 {
256 pduUdhElements = new SmsUdhElement[1];
257 }
258 else
259 {
260 pduUdhElements = new SmsUdhElement[theUdhElements.length + 1];
261
262
263 for (int j = 0; j < theUdhElements.length; j++)
264 {
265
266 pduUdhElements[j + 1] = theUdhElements[j];
267 }
268 }
269
270
271 String msg = SmsPduUtil.readSeptets(theUd.getData(), theUd.getLength());
272
273
274 for (int i = 0; i < nSms; i++)
275 {
276 byte[] pduUd;
277 int udOffset;
278 int udLength;
279
280
281 pduUdhElements[0] = SmsUdhUtil.get8BitConcatUdh(refno, nSms, i + 1);
282
283
284
285
286 udOffset = nMaxConcatChars * i;
287 udLength = theUd.getLength() - udOffset;
288 if (udLength > nMaxConcatChars)
289 {
290 udLength = nMaxConcatChars;
291 }
292
293 pduUd = SmsPduUtil.getSeptets(msg.substring(udOffset, udOffset + udLength));
294 smsPdus[i] = new SmsPdu(pduUdhElements, pduUd, udLength, theUd.getDcs());
295 }
296 }
297 return smsPdus;
298 }
299
300 /***
301 * Converts this message into SmsPdu:s
302 * <p>
303 * If the message is too long to fit in one SmsPdu the message is divided
304 * into many SmsPdu:s with a 8-bit concat pdu UDH element.
305 *
306 * @return Returns the message as SmsPdu:s
307 */
308 public SmsPdu[] getPdus()
309 {
310 SmsPdu[] smsPdus;
311 SmsUserData ud = getUserData();
312 SmsUdhElement[] udhElements = getUdhElements();
313 int udhLength = SmsUdhUtil.getTotalSize(udhElements);
314 int nBytesLeft = 140 - udhLength;
315
316 switch (ud.getDcs().getAlphabet())
317 {
318 case SmsDcs.ALPHABET_GSM:
319 smsPdus = createSeptetPdus(udhElements, ud, nBytesLeft);
320 break;
321 case SmsDcs.ALPHABET_UCS2:
322 smsPdus = createUnicodePdus(udhElements, ud, nBytesLeft);
323 break;
324 case SmsDcs.ALPHABET_8BIT:
325 default:
326 smsPdus = createOctalPdus(udhElements, ud, nBytesLeft);
327 break;
328 }
329
330 return smsPdus;
331 }
332 }