Source code: fi/kvanttisofta/sms/SmsMsgIncoming.java
1 //
2 // Copyright (c) 2001 Kvanttisofta oy. All rights reserved.
3 //
4 //
5 // SMS PDU message class for incoming messages.
6 // (aspa@users.sourceforge.net).
7 //
8 // $Id: SmsMsgIncoming.java,v 1.1.1.1 2001/04/18 04:19:00 aspa Exp $.
9 //
10 // TODO:
11 // - support other data encoding schemes than GSM 7 bit
12 //
13
14 package fi.kvanttisofta.sms;
15
16 public class SmsMsgIncoming {
17 public final int SMS_MSG_ENCODING_7BIT = 0;
18
19 private int smscAddressLength;
20 private int smscAddressType;
21 private String smscAddress;
22 private int smsDeliverCode;
23 private int senderAddressLength;
24 private int senderAddressType;
25 private String senderAddress;
26 private int tpPid; // protocol identifier.
27 private int tpDcs; // data coding scheme.
28 private String tpScts; // time stamp.
29 private int tpUdl; // message length.
30 private int encMsgLen;
31 private String tpUd; // user message (as sent).
32 private String msg; // user message (decoded).
33
34 public String getSenderNumber() {
35 return senderAddress;
36 }
37
38 public String getMessage() {
39 return msg;
40 }
41
42 public SmsMsgIncoming(String smspdu) throws PduParseException {
43 int pdulen = smspdu.length();
44 String tmpstr;
45 int i = 0;
46
47 try {
48 boolean hasSmscInfo = false;
49
50 String octet1str = smspdu.substring(i, 2);
51 int octet1 = Integer.parseInt(octet1str, 16);
52 i=i+2;
53 String octet2str = smspdu.substring(i, i+2);
54 int octet2 = Integer.parseInt(octet2str, 16);
55 i=i+2;
56
57 // simple heuristic for deducing whether the PDU contains
58 // SMSC info (if second octet is a SMSC type-of-address
59 // field it always has bit 7 set).
60 if (octet2 >= 127)
61 hasSmscInfo = true;
62
63 if( hasSmscInfo ) {
64 // SMSC info included in the PDU.
65
66 // get SMSC address length.
67 smscAddressLength = octet1;
68
69 // get SMSC address type.
70 smscAddressType = octet2;
71
72 // get SMSC address string (minus type len).
73 int smsAddrLastIndex = i + (smscAddressLength*2)-2;
74 tmpstr = smspdu.substring(i, smsAddrLastIndex);
75 smscAddress = SmsPduCodec.swapDigits(tmpstr);
76 if( smscAddress.indexOf('F') != -1 ) // strip trailing F.
77 smscAddress = smscAddress.substring(0,
78 smscAddress.length()-1);
79 if((smscAddressType & 0xf0) == 0x90) // international format.
80 smscAddress = '+' + smscAddress;
81 i=i+(smscAddressLength*2)-2;
82
83 String smsDeliverStr = smspdu.substring(i, i+2);
84 smsDeliverCode = Integer.parseInt(smsDeliverStr, 16);
85 i=i+2;
86
87 // get sender address length.
88 String addressLenStr = smspdu.substring(i, i+2);
89 senderAddressLength = Integer.parseInt(addressLenStr, 16);
90 i=i+2;
91 } else {
92 // no SMSC info in the PDU.
93 smsDeliverCode = octet1;
94 senderAddressLength = octet2;
95 }
96
97 // decode GSM SMS-DELIVER PDU message.
98 if(smsDeliverCode != 0x04)
99 throw new PduParseException("unknown SMS-DELIVER code " +
100 smsDeliverCode);
101
102 // get sender address type.
103 String addressTypeStr = smspdu.substring(i, i+2);
104 senderAddressType = Integer.parseInt(addressTypeStr, 16);
105 i=i+2;
106
107 // get sender address.
108 int senderLastIndex = i+senderAddressLength+senderAddressLength%2;
109 tmpstr = smspdu.substring(i, senderLastIndex);
110 senderAddress = SmsPduCodec.swapDigits(tmpstr);
111 senderAddress = senderAddress.substring(0, senderAddressLength);
112 if( (senderAddressType & 0xf0) == 0x90 ) // 1001xxxx?
113 senderAddress = '+' + senderAddress;
114 i=i+senderAddressLength + senderAddressLength%2;
115
116 // get protocol id.
117 String protocolStr = smspdu.substring(i, i+2);
118 tpPid = Integer.parseInt(protocolStr, 16);
119 if(tpPid != 0x00)
120 throw new PduParseException("unknown protocol ID " + tpPid);
121 i=i+2;
122
123 // get data encoding scheme.
124 String dataEncStr = smspdu.substring(i, i+2);
125 tpDcs = Integer.parseInt(dataEncStr, 16);
126 if(tpDcs != 0x00)
127 throw new PduParseException("unknown data encoding scheme "+
128 tpDcs);
129 i=i+2;
130
131 // get timestamp.
132 tmpstr = smspdu.substring(i, i+7*2);
133 tpScts = SmsPduCodec.swapDigits(tmpstr);
134 i=i+7*2;
135
136 // get message length.
137 String msgLenStr = smspdu.substring(i, i+2);
138 tpUdl = Integer.parseInt(msgLenStr, 16);
139 i=i+2;
140
141 // calculate encoded message length.
142 if(tpDcs == 0x00) {
143 encMsgLen = (tpUdl*7) / 8;
144 if( ((tpUdl*7) % 8) != 0 )
145 encMsgLen++;
146 } else
147 encMsgLen = tpUdl;
148
149 // get message string.
150 tpUd = smspdu.substring(i, i + encMsgLen*2);
151
152 msg = SmsPduCodec.sevenBitDecode(tpUd, tpUdl);
153
154 } catch (IndexOutOfBoundsException e) {
155 throw new PduParseException("SMS PDU too short: " + e);
156 } catch (NumberFormatException e) {
157 throw new PduParseException("Hexadecimal number expected: " + e);
158 }
159
160 if( (i + tpUd.length()) < pdulen )
161 throw new PduParseException("PDU too long");
162
163 }
164
165 public String toString() {
166 StringBuffer sb = new StringBuffer(200);
167 sb.append("\n");
168 sb.append("\t smscAddressLength = 0x" +
169 SmsPduCodec.toHexString(smscAddressLength));
170 sb.append("\n\t smscAddressType = 0x" +
171 SmsPduCodec.toHexString(smscAddressType));
172 sb.append("\n\t smscAddress = " + smscAddress);
173 sb.append("\n\t smsDeliverCode = 0x" +
174 SmsPduCodec.toHexString(smsDeliverCode));
175 sb.append("\n\t senderAddressLength = 0x" +
176 SmsPduCodec.toHexString(senderAddressLength));
177 sb.append("\n\t senderAddressType = 0x" +
178 SmsPduCodec.toHexString(senderAddressType));
179 sb.append("\n\t senderAddress = " + senderAddress);
180 sb.append("\n\t tpPid = 0x" +
181 SmsPduCodec.toHexString(tpPid));
182 sb.append("\n\t tpDcs = 0x" +
183 SmsPduCodec.toHexString(tpDcs));
184 sb.append("\n\t tpScts = " + tpScts);
185 sb.append("\n\t tpUdl = 0x" +
186 SmsPduCodec.toHexString(tpUdl));
187 sb.append("\n\t tpUd = '" + tpUd + "'");
188 sb.append("\n\t msg = '" + msg + "'");
189 sb.append("\n\t msg hex = " + SmsPduCodec.hexDump(msg));
190 return new String(sb);
191 }
192
193 public static void main(String[] args) {
194 String smspdu1 =
195 "07917238010010F5040BC87238880900F100009930925161958003C16010";
196
197 //String smspdu2 = "040C91534850251863000000214061738580665079991EC603DC65BA0E344DBBEB6C7619F47683EAF5791A240FC3DF723A3D0D3A2DD37275D80D4F93DF6E103D3C2F9F5C206A9A1D0E83CC613C28F60AC7626B761A9E77C1C96690BBDE2ECBDF6FB70E04CBE16AB0582E579B01";
198 String smspdu2 = "040C91534850251863000000214061738580665079991EC603DC65BA0E344DBBEB6C7619F47683EAF5791A240FC3DF723A3D0D3A2DD37275D80D4F93DF6E103D3C2F9F5C206A9A1D0E83CC613C28F60AC7626B761A9E77C1C96690BBDE2ECBDF6FB70E04CBE16AB0582E579B01";
199 String smspdu3 = "040C915348502518630000002140618383800FC6B49B0C82D160B59A0C179BD900";
200
201 //String smspdu4 = "040C91534850251863000000212161515480665079991EC603DC65BA0E344DBBEB6C7619F47683EAF5791A240FC3DF723A3D0D3A2DD37275D80D4F93DF6E103D3C2F9F5C206A9A1D0E83CC613C28F60AC7626B761A9E77C1C96690BBDE2ECBDF6FB70E04CBE16AB0582E579B01";
202 String smspdu4 = "040C915348700689440000002121717570801FC6301E44AFB3DFF37918E4AEB7CBF2F7DB0D82E57035582C97ABCD00";
203
204 SmsMsgIncoming sms1 = null;
205 try {
206 sms1 = new SmsMsgIncoming(smspdu1);
207 } catch (PduParseException e) {
208 System.err.println("error in PDU parsing: " + e);
209 }
210 System.err.println("pdu1: " + smspdu1);
211 System.err.println("message1: " + sms1 + "\n\n");
212
213 SmsMsgIncoming sms2 = null;
214 try {
215 sms2 = new SmsMsgIncoming(smspdu2);
216 } catch (PduParseException e) {
217 System.err.println("error in PDU parsing: " + e);
218 }
219 System.err.println("pdu2: " + smspdu2);
220 System.err.println("message2: " + sms2 + "\n\n");
221
222
223 SmsMsgIncoming sms3 = null;
224 try {
225 sms3 = new SmsMsgIncoming(smspdu3);
226 } catch (PduParseException e) {
227 System.err.println("error in PDU parsing: " + e);
228 }
229 System.err.println("pdu3: " + smspdu3);
230 System.err.println("message3: " + sms3 + "\n\n");
231
232
233 SmsMsgIncoming sms4 = null;
234 try {
235 sms4 = new SmsMsgIncoming(smspdu4);
236 } catch (PduParseException e) {
237 System.err.println("error in PDU parsing: " + e);
238 }
239 System.err.println("pdu4: " + smspdu4);
240 System.err.println("message4: " + sms4 + "\n\n");
241 System.err.println("number: '" + sms4.getSenderNumber() + "'");
242 System.err.println("msg: '" + sms4.getMessage() + "'");
243
244 // sms4 hexdump.
245 String str4 = sms4.getMessage();
246 System.err.println("dump: " + SmsPduCodec.hexDump(str4));
247 }
248
249 }