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.transport.ucp;
36
37 import java.io.DataInputStream;
38 import java.io.DataOutputStream;
39 import java.io.IOException;
40 import java.net.Socket;
41 import java.util.Properties;
42
43 import org.marre.sms.SmsAddress;
44 import org.marre.sms.SmsConstants;
45 import org.marre.sms.SmsDcs;
46 import org.marre.sms.SmsException;
47 import org.marre.sms.SmsMessage;
48 import org.marre.sms.SmsPdu;
49 import org.marre.sms.SmsPduUtil;
50 import org.marre.sms.transport.SmsTransport;
51 import org.marre.util.StringUtil;
52
53 /***
54 * An SmsTransport that sends the SMS through an UCP SMSC
55 *
56 *
57 *
58 * @author Markus Eriksson
59 * @version $Id: UcpTransport.java,v 1.16 2005/11/26 16:37:14 c95men Exp $
60 */
61 public class UcpTransport implements SmsTransport
62 {
63 private String ucpServerName_;
64 private int ucpServerPort_;
65 private String ucp60Uid_;
66 private String ucp60Pwd_;
67 private boolean doUcp60Login_;
68
69 private Socket ucpSocket_;
70 private DataOutputStream ucpOs_;
71 private DataInputStream ucpIs_;
72
73 public UcpTransport()
74 {
75 }
76
77 /***
78 * Initializes the class with the properties specified
79 *
80 * @param props
81 * <b>smsj.ucp.ip.host </b>: the ip address or dns name of the
82 * UCP server <br>
83 * <b>smsj.ucp.ip.port </b>: the ip port of the UCP server <br>
84 * <b>smsj.ucp.ucp60.uid </b>: the UCP60 user id <br>
85 * <b>smsj.ucp.ucp60.password </b>: the UCP60 password</br>
86 *
87 * @throws SmsException
88 */
89 public void init(Properties props) throws SmsException
90 {
91
92
93
94
95 ucpServerName_ = props.getProperty("smsj.ucp.ip.host");
96 ucpServerPort_ = Integer.parseInt(props.getProperty("smsj.ucp.ip.port"));
97 ucp60Uid_ = props.getProperty("smsj.ucp.ucp60.uid");
98 ucp60Pwd_ = props.getProperty("smsj.ucp.ucp60.password");
99
100 if (ucp60Uid_ == null || ucp60Pwd_ == null)
101 {
102 doUcp60Login_ = false;
103 }
104 else if ("".equals(ucp60Uid_))
105 {
106 throw new SmsException("UCP Transport: empty UCP60 username");
107 }
108 else
109 {
110 doUcp60Login_ = true;
111 }
112 }
113
114 public void connect() throws SmsException, IOException
115 {
116
117 ucpSocket_ = new Socket(ucpServerName_, ucpServerPort_);
118 ucpOs_ = new DataOutputStream(ucpSocket_.getOutputStream());
119 ucpIs_ = new DataInputStream(ucpSocket_.getInputStream());
120
121
122
123 if (doUcp60Login_)
124 {
125 byte[] loginCmd = buildLogin(ucp60Uid_, ucp60Pwd_);
126 String response = sendUcp(loginCmd);
127 System.err.println("SMSC response: " + response);
128 }
129 }
130
131 public String send(SmsMessage msg, SmsAddress theDest, SmsAddress sender) throws SmsException, IOException
132 {
133 SmsPdu[] msgPdu = null;
134
135 if (theDest.getTypeOfNumber() == SmsConstants.TON_ALPHANUMERIC)
136 {
137 throw new SmsException("Cannot sent SMS to ALPHANUMERIC address");
138 }
139
140 msgPdu = msg.getPdus();
141 for (int i = 0; i < msgPdu.length; i++)
142 {
143 boolean moreToSend = (i < (msgPdu.length - 1));
144 byte[] submitCmd = buildSubmit(msgPdu[i], moreToSend, theDest, sender);
145 String response = sendUcp(submitCmd);
146 System.err.println("SMSC response: " + response);
147 }
148
149 return null;
150 }
151
152 /***
153 * Building the Login Stream
154 *
155 * @author Lorenz Barth
156 * @throws SmsException
157 * @param userid
158 * @param pwd
159 */
160 public byte[] buildLogin(String userid, String pwd) throws SmsException
161 {
162 UCPSeries60 ucplogin = new UCPSeries60(UCPSeries60.OP_OPEN_SESSION);
163
164 ucplogin.setTRN(0x01);
165 ucplogin.setField(UCPSeries60.FIELD_OADC, userid);
166 ucplogin.setField(UCPSeries60.FIELD_OTON, "6");
167 ucplogin.setField(UCPSeries60.FIELD_ONPI, "5");
168 ucplogin.setField(UCPSeries60.FIELD_STYP, "1");
169 ucplogin.setField(UCPSeries60.FIELD_VERS, "0100");
170 ucplogin.setField(UCPSeries60.FIELD_PWD, StringUtil.bytesToHexString(SmsPduUtil.toGsmCharset(pwd)));
171
172 return ucplogin.getCommand();
173 }
174
175 public byte[] buildSubmit(SmsPdu pdu, boolean moreToSend, SmsAddress dest, SmsAddress sender)
176 throws SmsException
177 {
178 String ud;
179 byte[] udhData;
180 UcpSeries50 ucpSubmit = new UcpSeries50(UcpSeries50.OP_SUBMIT_SHORT_MESSAGE);
181
182 byte[] udh = pdu.getUserDataHeaders();
183 boolean isSeptets = (pdu.getDcs().getAlphabet() == SmsDcs.ALPHABET_GSM);
184 int udBits;
185
186
187 ucpSubmit.setTRN(0x01);
188
189
190
191
192
193 if (sender.getTypeOfNumber() == SmsConstants.TON_ALPHANUMERIC)
194 {
195 String addr = sender.getAddress();
196 if (addr.length() > 11)
197 {
198 throw new SmsException("Max alphanumeric Originator Address Code length exceded (11)");
199 }
200
201
202 String codedaddr = StringUtil.bytesToHexString(SmsPduUtil.getSeptets(addr));
203 int x = codedaddr.length();
204 StringBuffer sb = new StringBuffer("00");
205 sb.replace(2 - Integer.toHexString(x).toUpperCase().length(), 2, Integer.toHexString(x).toUpperCase());
206
207 ucpSubmit.setField(UcpSeries50.FIELD_OADC, sb.toString().concat(codedaddr));
208 ucpSubmit.setField(UcpSeries50.FIELD_OTOA, "5039");
209
210 }
211 else
212 {
213 ucpSubmit.setField(UcpSeries50.FIELD_OTOA, "1139");
214 ucpSubmit.setField(UcpSeries50.FIELD_OADC, sender.getAddress());
215 }
216
217
218 ucpSubmit.setField(UcpSeries50.FIELD_ADC, dest.getAddress());
219 if (pdu.getUserDataHeaders() == null)
220 {
221 switch (pdu.getDcs().getAlphabet())
222 {
223 case SmsDcs.ALPHABET_GSM:
224 System.out.println("GSM Message without UDH");
225 ucpSubmit.setField(UcpSeries50.FIELD_MT, "3");
226 String msg = SmsPduUtil.readSeptets(pdu.getUserData().getData(), pdu.getUserData().getLength());
227 ucpSubmit.setField(UcpSeries50.FIELD_MSG, StringUtil.bytesToHexString(SmsPduUtil.toGsmCharset(msg)));
228 System.out.println(msg.length());
229 break;
230 case SmsDcs.ALPHABET_8BIT:
231 throw new SmsException(" 8Bit Messages without UDH are not Supported");
232 case SmsDcs.ALPHABET_UCS2:
233 System.out.println("UCS2 Message without UDH");
234 ud = StringUtil.bytesToHexString(pdu.getUserData().getData());
235 ucpSubmit.setField(UcpSeries50.FIELD_MSG, ud);
236
237 udBits = pdu.getUserData().getLength() * ((isSeptets) ? 7 : 8);
238 ucpSubmit.setField(UcpSeries50.FIELD_NB, StringUtil.intToString(udBits, 4));
239
240 ucpSubmit.setField(UcpSeries50.FIELD_MT, "4");
241 ucpSubmit.clearXSer();
242 ucpSubmit.addXSer(UcpSeries50.XSER_TYPE_DCS, pdu.getDcs().getValue());
243 break;
244 default:
245 throw new SmsException("Unsupported data coding scheme");
246 }
247 }
248 else
249 {
250 switch (pdu.getDcs().getAlphabet())
251 {
252 case SmsDcs.ALPHABET_GSM:
253 throw new SmsException("Cannot send 7 bit encoded messages with UDH");
254 case SmsDcs.ALPHABET_8BIT:
255 ud = StringUtil.bytesToHexString(pdu.getUserData().getData());
256 udhData = pdu.getUserDataHeaders();
257
258 String udhStr = StringUtil.bytesToHexString(new byte[]{(byte) (udhData.length)});
259 udhStr += StringUtil.bytesToHexString(udhData);
260
261 ucpSubmit.setField(UcpSeries50.FIELD_MSG, ud);
262
263 udBits = pdu.getUserData().getLength() * ((isSeptets) ? 7 : 8);
264 ucpSubmit.setField(UcpSeries50.FIELD_NB, StringUtil.intToString(udBits, 4));
265
266 ucpSubmit.setField(UcpSeries50.FIELD_MT, "4");
267
268 ucpSubmit.clearXSer();
269 ucpSubmit.addXSer(UcpSeries50.XSER_TYPE_DCS, pdu.getDcs().getValue());
270 ucpSubmit.addXSer(UcpSeries50.XSER_TYPE_UDH, udhData);
271 break;
272 case SmsDcs.ALPHABET_UCS2:
273 throw new SmsException(" UCS2 Messages are currently not Supportet ");
274 default:
275 throw new SmsException("Unsupported data coding scheme");
276 }
277 }
278
279
280
281
282
283
284
285
286
287
288
289
290
291 if (moreToSend)
292 {
293 ucpSubmit.setField(UcpSeries50.FIELD_MMS, "1");
294 }
295
296 return ucpSubmit.getCommand();
297 }
298
299 public void ping() throws SmsException
300 {
301 }
302
303 /***
304 * Closing Socket and Streams
305 *
306 * @author Lorenz Barth
307 * @throws SmsException
308 *
309 */
310 public void disconnect() throws SmsException, IOException
311 {
312 ucpOs_.close();
313 ucpIs_.close();
314 ucpSocket_.close();
315 }
316
317 /***
318 * This method is sending the Data to over the existing Connection and
319 * recives the answer, the Answer is returned as a String.
320 *
321 * @author Lorenz Barth
322 * @param data
323 * @throws SmsException
324 * @throws IOException
325 */
326 public String sendUcp(byte[] data) throws SmsException, IOException
327 {
328 if (!ucpSocket_.isConnected() || ucpOs_ == null || ucpIs_ == null)
329 {
330 throw new SmsException("Please Connect first");
331 }
332
333 System.out.println("SMSC send: " + new String(data, 0, data.length));
334 StringBuffer strBuf;
335
336 ucpOs_.write(data);
337 ucpOs_.flush();
338
339 byte[] b = new byte[1];
340
341 if ((b[0] = ucpIs_.readByte()) != 2)
342 {
343 System.out.println("SendSMS.send: The SMSC sends a bad reply");
344 throw new SmsException("The SMSC sends a bad reply");
345 }
346
347 strBuf = new StringBuffer();
348
349 while ((b[0] = ucpIs_.readByte()) != 3)
350 {
351 strBuf.append(new String(b));
352 }
353
354
355 return strBuf.toString();
356 }
357 }