2 * Copyright (C) 2010 Felix Bechstein
4 * This file is part of WebSMS.
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free Software
8 * Foundation; either version 3 of the License, or (at your option) any later
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * You should have received a copy of the GNU General Public License along with
17 * this program; If not, see <http://www.gnu.org/licenses/>.
19 package de
.ub0r
.android
.andGMXsms
;
21 import java
.io
.IOException
;
22 import java
.io
.OutputStream
;
23 import java
.net
.HttpURLConnection
;
26 import android
.content
.Context
;
27 import android
.content
.SharedPreferences
;
28 import android
.content
.SharedPreferences
.Editor
;
29 import android
.preference
.PreferenceManager
;
30 import android
.text
.format
.DateFormat
;
31 import android
.util
.Log
;
32 import de
.ub0r
.android
.websms
.connector
.common
.WebSMSException
;
35 * AsyncTask to manage IO to GMX API.
39 public class ConnectorGMX
extends Connector
{
40 /** Tag for output. */
41 private static final String TAG
= "WebSMS.GMX";
43 /** Preference's name: mail. */
44 static final String PREFS_MAIL
= "gmx_mail";
45 /** Preference's name: username. */
46 static final String PREFS_USER
= "gmx_user";
47 /** Preference's name: user's password - gmx. */
48 static final String PREFS_PASSWORD
= "gmx_password";
49 /** Preference's name: gmx hostname id. */
50 private static final String PREFS_GMX_HOST
= "gmx_host";
52 /** Custom Dateformater. */
53 private static final String DATEFORMAT
= "yyyy-MM-dd kk-mm-00";
56 private static final String
[] TARGET_HOST
= { "app0.wr-gmbh.de",
58 /** Target path on host. */
59 private static final String TARGET_PATH
= "/WRServer/WRServer.dll/WR";
60 /** Target mime encoding. */
61 private static final String TARGET_ENCODING
= "wr-cs";
62 /** Target mime type. */
63 private static final String TARGET_CONTENT
= "text/plain";
64 /** HTTP Useragent. */
65 private static final String TARGET_AGENT
= "Mozilla/3.0 (compatible)";
66 /** Target version of protocol. */
67 private static final String TARGET_PROTOVERSION
= "1.13.03";
69 /** ID of mail in array. */
70 static final int ID_MAIL
= 1;
71 /** ID of password in array. */
72 static final int ID_PW
= 2;
74 /** Number of IDs in array for bootstrap. */
75 static final int IDS_BOOTSTR
= 3;
78 private static final int RSLT_OK
= 0;
79 /** Result: wrong customerid/password. */
80 private static final int RSLT_WRONG_CUSTOMER
= 11;
81 /** Result: wrong mail/password. */
82 private static final int RSLT_WRONG_MAIL
= 25;
83 /** Result: wrong sender. */
84 private static final int RSLT_WRONG_SENDER
= 8;
85 /** Result: sender is unregistered by gmx. */
86 private static final int RSLT_UNREGISTERED_SENDER
= 71;
89 private static String mail
;
91 private static String pw
;
93 /** Need to bootstrap? */
94 private static boolean needBootstrap
= false;
97 * Create a GMX Connector.
102 ConnectorGMX(final Context c
) {
107 * Write key,value to StringBuilder.
116 private static void writePair(final StringBuilder buffer
, final String key
,
117 final String value
) {
120 buffer
.append(value
.replace("\\", "\\\\").replace(">", "\\>").replace(
122 buffer
.append("\\p");
126 * Create default data hashtable.
130 * @param packetVersion
133 * add customer id/password
134 * @return Hashtable filled with customer_id and password.
136 private StringBuilder
openBuffer(final String packetName
,
137 final String packetVersion
, final boolean addCustomer
) {
138 StringBuilder ret
= new StringBuilder();
139 ret
.append("<WR TYPE=\"RQST\" NAME=\"");
140 ret
.append(packetName
);
141 ret
.append("\" VER=\"");
142 ret
.append(packetVersion
);
143 ret
.append("\" PROGVER=\"");
144 ret
.append(TARGET_PROTOVERSION
);
147 SharedPreferences p
= PreferenceManager
148 .getDefaultSharedPreferences(this.context
);
149 writePair(ret
, "customer_id", p
.getString(PREFS_USER
, ""));
150 writePair(ret
, "password", p
.getString(PREFS_PASSWORD
, ""));
162 private static StringBuilder
closeBuffer(final StringBuilder buffer
) {
163 buffer
.append("</WR>");
168 * Parse returned packet. Search for name=(.*)\n and return (.*)
174 * @return param's value
176 private String
getParam(final String packet
, final String name
) {
177 int i
= packet
.indexOf(name
+ '=');
181 int j
= packet
.indexOf("\n", i
);
183 return packet
.substring(i
+ name
.length() + 1);
185 return packet
.substring(i
+ name
.length() + 1, j
);
194 * @return successful?
195 * @throws WebSMSException
198 private boolean sendData(final StringBuilder packetData
)
199 throws WebSMSException
{
203 SharedPreferences sp
= PreferenceManager
204 .getDefaultSharedPreferences(this.context
);
205 int gmxHost
= sp
.getInt(PREFS_GMX_HOST
, 0);
206 HttpURLConnection c
= (HttpURLConnection
) (new URL("http://"
207 + TARGET_HOST
[gmxHost
] + TARGET_PATH
)).openConnection();
209 c
.setRequestProperty("User-Agent", TARGET_AGENT
);
210 c
.setRequestProperty("Content-Encoding", TARGET_ENCODING
);
211 c
.setRequestProperty("Content-Type", TARGET_CONTENT
);
212 int resp
= c
.getResponseCode();
213 if (resp
== HTTP_SERVICE_UNAVAILABLE
) {
215 gmxHost
= (gmxHost
+ 1) % 2;
216 sp
.edit().putInt(PREFS_GMX_HOST
, gmxHost
).commit();
220 c
= (HttpURLConnection
) (new URL("http://" + TARGET_HOST
[gmxHost
]
221 + TARGET_PATH
)).openConnection();
223 c
.setRequestProperty("User-Agent", TARGET_AGENT
);
224 c
.setRequestProperty("Content-Encoding", TARGET_ENCODING
);
225 c
.setRequestProperty("Content-Type", TARGET_CONTENT
);
226 c
.setRequestMethod("POST");
229 OutputStream os
= c
.getOutputStream();
230 os
.write(packetData
.toString().getBytes("ISO-8859-15"));
235 resp
= c
.getResponseCode();
236 if (resp
!= HttpURLConnection
.HTTP_OK
) {
237 if (resp
== HTTP_SERVICE_UNAVAILABLE
) {
238 throw new WebSMSException(this.context
,
239 R
.string
.log_error_service
, "" + resp
);
241 throw new WebSMSException(this.context
,
242 R
.string
.log_error_http
, "" + resp
);
245 // read received data
246 int bufsize
= c
.getHeaderFieldInt("Content-Length", -1);
248 String resultString
= stream2str(c
.getInputStream());
249 if (resultString
.startsWith("The truth")) {
251 throw new WebSMSException(this.context
,
252 R
.string
.log_error_server
, "" + resultString
);
256 int resultIndex
= resultString
.indexOf("rslt=");
257 String outp
= resultString
.substring(resultIndex
).replace(
259 outp
= outp
.replace("</WR>", "");
262 String resultValue
= this.getParam(outp
, "rslt");
265 rslt
= Integer
.parseInt(resultValue
);
266 } catch (Exception e
) {
268 throw new WebSMSException(e
.toString());
272 // fetch additional info
273 String p
= this.getParam(outp
, "free_rem_month");
276 p
= this.getParam(outp
, "free_max_month");
280 // FIXME: SPECS.setBalance(b);
281 this.pushMessage(WebSMS
.MESSAGE_FREECOUNT
, null);
283 p
= this.getParam(outp
, "customer_id");
285 Editor e
= PreferenceManager
286 .getDefaultSharedPreferences(this.context
)
288 e
.putString(PREFS_USER
, p
);
289 if (ConnectorGMX
.pw
!= null) {
290 e
.putString(PREFS_PASSWORD
, ConnectorGMX
.pw
);
292 if (ConnectorGMX
.mail
!= null) {
293 e
.putString(PREFS_MAIL
, ConnectorGMX
.mail
);
299 case RSLT_WRONG_CUSTOMER
: // wrong user/pw
300 throw new WebSMSException(this.context
,
301 R
.string
.log_error_pw
);
302 case RSLT_WRONG_MAIL
: // wrong mail/pw
305 throw new WebSMSException(this.context
,
306 R
.string
.log_error_mail
);
307 case RSLT_WRONG_SENDER
: // wrong sender
308 throw new WebSMSException(this.context
,
309 R
.string
.log_error_sender
);
310 case RSLT_UNREGISTERED_SENDER
: // unregistered sender
311 throw new WebSMSException(this.context
,
312 R
.string
.log_error_sender_unregistered
);
314 throw new WebSMSException(outp
+ " #" + rslt
);
317 throw new WebSMSException(this.context
,
318 R
.string
.log_http_header_missing
);
320 } catch (IOException e
) {
322 throw new WebSMSException(e
.toString());
330 protected final boolean updateMessages() throws WebSMSException
{
331 return this.sendData(closeBuffer(this.openBuffer("GET_SMS_CREDITS",
339 protected final boolean sendMessage() throws WebSMSException
{
340 StringBuilder packetData
= this.openBuffer("SEND_SMS", "1.01", true);
342 writePair(packetData
, "sms_text", this.text
);
343 StringBuilder recipients
= new StringBuilder();
344 // table: <id>, <name>, <number>
346 for (int i
= 0; i
< this.to
.length
; i
++) {
347 if (this.to
[i
] != null && this.to
[i
].length() > 1) {
348 recipients
.append(++j
);
349 recipients
.append("\\;null\\;");
350 recipients
.append(this.to
[i
]);
351 recipients
.append("\\;");
354 recipients
.append("</TBL>");
355 String recipientsString
= "<TBL ROWS=\"" + j
+ "\" COLS=\"3\">"
356 + "receiver_id\\;receiver_name\\;receiver_number\\;"
357 + recipients
.toString();
359 writePair(packetData
, "receivers", recipientsString
);
360 writePair(packetData
, "send_option", "sms");
361 if (this.customSender
!= null && this.customSender
.length() > 0) {
362 writePair(packetData
, "sms_sender", this.customSender
);
364 writePair(packetData
, "sms_sender", this.defSender
);
366 if (this.sendLater
> 0) {
367 writePair(packetData
, "send_date", DateFormat
.format(DATEFORMAT
,
368 this.sendLater
).toString());
371 if (!this.sendData(closeBuffer(packetData
))) {
373 throw new WebSMSException(this.context
, R
.string
.log_error
);
383 protected final boolean doBootstrap(final String
[] params
)
384 throws WebSMSException
{
385 if (!needBootstrap
) {
389 StringBuilder packetData
= this.openBuffer("GET_CUSTOMER", "1.10",
391 SharedPreferences p
= PreferenceManager
392 .getDefaultSharedPreferences(this.context
);
393 writePair(packetData
, "email_address", p
.getString(PREFS_MAIL
, ""));
394 writePair(packetData
, "password", p
.getString(PREFS_PASSWORD
, ""));
395 writePair(packetData
, "gmx", "1");
396 return this.sendData(closeBuffer(packetData
));
403 protected final boolean supportCustomsender() {
411 protected final boolean supportSendLater() {