1
2
3
4
5 package net.sf.atmodem4j.core.gsm;
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 import java.util.ArrayList;
36 import java.util.List;
37 import net.sf.atmodem4j.core.gsm.Pdu.Encoding;
38 import net.sf.atmodem4j.core.gsm.Pdu.TimeToLife;
39
40
41
42
43
44 public class PduEncoder {
45
46 private final static int USER_DATA_HEADER_LENGTH = 6;
47 public static final int MAX_USER_PDU_SIZE = 140;
48
49 private List<UserData> data = new ArrayList<UserData>();
50
51 private String receiverPhonenumber;
52 private Encoding encoding;
53 private TimeToLife timeToLife;
54 private int refnumber;
55
56 public PduEncoder() {
57 super();
58 }
59
60 private String getSmscInformationOctet() {
61 return "00";
62 }
63
64 public boolean isMultiSMS() {
65 return data.size() > 1;
66 }
67
68 private String getSmsSubmittOctet() {
69 short result = 0x11;
70 result |= isMultiSMS() ? 0x40 : 0;
71 return UserData.formatOctet(result);
72 }
73
74 private String getTpMessageReferenceOctet() {
75 return "00";
76 }
77
78 private String getAdressOctets() {
79 StringBuilder sb = new StringBuilder();
80 String number = receiverPhonenumber.charAt(0) == '+' ? receiverPhonenumber.substring(1, receiverPhonenumber.length())
81 : receiverPhonenumber;
82 sb.append(UserData.formatOctet(number.length()));
83 if (receiverPhonenumber.charAt(0) == '+') {
84 sb.append("91");
85 } else {
86 sb.append("91");
87 }
88 for (int i = 0; i < number.length() - 1; i += 2) {
89 sb.append(number.charAt(i + 1));
90 sb.append(number.charAt(i));
91 }
92 if (number.length() % 2 != 0) {
93 sb.append("F");
94 sb.append(number.charAt(number.length() - 1));
95 }
96 return sb.toString();
97 }
98
99 private String getTpPidOctet() {
100 return "00";
101 }
102
103 private String getTpDcsOctet() {
104 switch (encoding) {
105 case TEXT_7BIT:
106 return "00";
107 case TEXT_16BIT:
108 return "08";
109 case DATA_8BIT:
110 return "04";
111 default:
112 return "00";
113 }
114 }
115
116 private String getTpValidityPeriodOctet() {
117 return "AA";
118 }
119
120 private String getMultiSMSUserHeader(int length, int index) {
121 StringBuilder sb = new StringBuilder();
122 sb.append("05");
123 sb.append("00");
124 sb.append("03");
125 sb.append(UserData.formatOctet(refnumber++));
126 if (refnumber > 255) {
127 refnumber = 0;
128 }
129 sb.append(UserData.formatOctet(length));
130 sb.append(UserData.formatOctet(index));
131 return sb.toString();
132 }
133
134 public String[] encodePdus() {
135 StringBuilder sb = new StringBuilder();
136 if (isMultiSMS()) {
137
138 String[] result = new String[data.size()];
139 for (int i = 0; i < result.length; i++) {
140 sb.append(getSmscInformationOctet());
141 sb.append(getSmsSubmittOctet());
142 sb.append(getTpMessageReferenceOctet());
143 sb.append(getAdressOctets());
144 sb.append(getTpPidOctet());
145 sb.append(getTpDcsOctet());
146 sb.append(getTpValidityPeriodOctet());
147 sb.append(UserData.formatOctet(data.get(i).getUserDataLength(USER_DATA_HEADER_LENGTH)));
148 sb.append(getMultiSMSUserHeader(data.size(), i +1));
149 sb.append(data.get(i).encodePduData(USER_DATA_HEADER_LENGTH));
150 result[i] = sb.toString();
151 sb.delete(0, sb.length());
152 }
153 return result;
154 } else {
155
156 sb.append(getSmscInformationOctet());
157 sb.append(getSmsSubmittOctet());
158 sb.append(getTpMessageReferenceOctet());
159 sb.append(getAdressOctets());
160 sb.append(getTpPidOctet());
161 sb.append(getTpDcsOctet());
162 sb.append(getTpValidityPeriodOctet());
163 sb.append(UserData.formatOctet(data.get(0).getUserDataLength(0)));
164 sb.append(data.get(0).encodePduData(0));
165 return new String[]{sb.toString()};
166 }
167 }
168
169
170
171
172 public String getMessageText() {
173 return null;
174 }
175
176
177
178
179 public void setMessageText(Encoding enc, String messageText) throws
180 Pdu.EncodingException {
181 this.encoding = enc;
182 switch (encoding) {
183 case TEXT_7BIT:
184 int lastPos = 0;
185 for (int pos : UserData.Text7Bit.getSplitPos(messageText)) {
186 UserData.Text7Bit ud = new UserData.Text7Bit();
187 ud.setText(messageText.substring(lastPos, pos));
188 lastPos = pos;
189 data.add(ud);
190 }
191 break;
192 case TEXT_16BIT:
193 for (UserData ud : UserData.Text16Bit.split(messageText)) {
194 data.add(ud);
195 }
196 break;
197 default:
198 DATA_8BIT:
199 throw new RuntimeException("Cant encode Data as String");
200 }
201 }
202
203
204
205
206 public void setMessageText(String messageText) {
207 try {
208 setMessageText(Encoding.TEXT_7BIT, messageText);
209 } catch (Pdu.EncodingException ex) {
210 try {
211 setMessageText(Encoding.TEXT_16BIT, messageText);
212 } catch (Pdu.EncodingException ex16) {
213 throw new RuntimeException(ex16);
214 }
215 }
216 }
217
218
219
220
221 public String getReceiverPhonenumber() {
222 return receiverPhonenumber;
223 }
224
225
226
227
228 public void setReceiverPhonenumber(String receiverPhonenumber) {
229 this.receiverPhonenumber = receiverPhonenumber;
230 }
231
232
233
234
235 public int getRefnumber() {
236 return refnumber;
237 }
238
239
240
241
242 public void setRefnumber(int refnumber) {
243 this.refnumber = refnumber;
244 }
245 }