move connectors
[andGMXsms.git] / connectors / gmx / src / de / ub0r / android / websms / connector / gmx / ConnectorGMX.java
blob85531ac609b0858ffccfa653b8113cce1c5aef3d
1 /*
2 * Copyright (C) 2010 Felix Bechstein
3 *
4 * This file is part of WebSMS.
5 *
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
9 * version.
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
14 * details.
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;
24 import java.net.URL;
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;
34 /**
35 * AsyncTask to manage IO to GMX API.
37 * @author flx
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";
55 /** Target host. */
56 private static final String[] TARGET_HOST = { "app0.wr-gmbh.de",
57 "app5.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;
77 /** Result: ok. */
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;
88 /** mail. */
89 private static String mail;
90 /** password. */
91 private static String pw;
93 /** Need to bootstrap? */
94 private static boolean needBootstrap = false;
96 /**
97 * Create a GMX Connector.
99 * @param c
100 * context
102 ConnectorGMX(final Context c) {
103 super(c);
107 * Write key,value to StringBuilder.
109 * @param buffer
110 * buffer
111 * @param key
112 * key
113 * @param value
114 * value
116 private static void writePair(final StringBuilder buffer, final String key,
117 final String value) {
118 buffer.append(key);
119 buffer.append('=');
120 buffer.append(value.replace("\\", "\\\\").replace(">", "\\>").replace(
121 "<", "\\<"));
122 buffer.append("\\p");
126 * Create default data hashtable.
128 * @param packetName
129 * packetName
130 * @param packetVersion
131 * packetVersion
132 * @param addCustomer
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);
145 ret.append("\">");
146 if (addCustomer) {
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, ""));
152 return ret;
156 * Close Buffer.
158 * @param buffer
159 * buffer
160 * @return buffer
162 private static StringBuilder closeBuffer(final StringBuilder buffer) {
163 buffer.append("</WR>");
164 return buffer;
168 * Parse returned packet. Search for name=(.*)\n and return (.*)
170 * @param packet
171 * packet
172 * @param name
173 * parma's name
174 * @return param's value
176 private String getParam(final String packet, final String name) {
177 int i = packet.indexOf(name + '=');
178 if (i < 0) {
179 return null;
181 int j = packet.indexOf("\n", i);
182 if (j < 0) {
183 return packet.substring(i + name.length() + 1);
184 } else {
185 return packet.substring(i + name.length() + 1, j);
190 * Send data.
192 * @param packetData
193 * packetData
194 * @return successful?
195 * @throws WebSMSException
196 * WebSMSException
198 private boolean sendData(final StringBuilder packetData)
199 throws WebSMSException {
200 try {
201 // check connection:
202 // get cluster side
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();
208 // set prefs
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) {
214 // switch hostname
215 gmxHost = (gmxHost + 1) % 2;
216 sp.edit().putInt(PREFS_GMX_HOST, gmxHost).commit();
219 // get Connection
220 c = (HttpURLConnection) (new URL("http://" + TARGET_HOST[gmxHost]
221 + TARGET_PATH)).openConnection();
222 // set prefs
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");
227 c.setDoOutput(true);
228 // push post data
229 OutputStream os = c.getOutputStream();
230 os.write(packetData.toString().getBytes("ISO-8859-15"));
231 os.close();
232 os = null;
234 // send data
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);
240 } else {
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);
247 if (bufsize > 0) {
248 String resultString = stream2str(c.getInputStream());
249 if (resultString.startsWith("The truth")) {
250 // wrong data sent!
251 throw new WebSMSException(this.context,
252 R.string.log_error_server, "" + resultString);
255 // strip packet
256 int resultIndex = resultString.indexOf("rslt=");
257 String outp = resultString.substring(resultIndex).replace(
258 "\\p", "\n");
259 outp = outp.replace("</WR>", "");
261 // get result code
262 String resultValue = this.getParam(outp, "rslt");
263 int rslt;
264 try {
265 rslt = Integer.parseInt(resultValue);
266 } catch (Exception e) {
267 Log.e(TAG, null, e);
268 throw new WebSMSException(e.toString());
270 switch (rslt) {
271 case RSLT_OK: // ok
272 // fetch additional info
273 String p = this.getParam(outp, "free_rem_month");
274 if (p != null) {
275 String b = p;
276 p = this.getParam(outp, "free_max_month");
277 if (p != null) {
278 b += "/" + p;
280 // FIXME: SPECS.setBalance(b);
281 this.pushMessage(WebSMS.MESSAGE_FREECOUNT, null);
283 p = this.getParam(outp, "customer_id");
284 if (p != null) {
285 Editor e = PreferenceManager
286 .getDefaultSharedPreferences(this.context)
287 .edit();
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);
295 e.commit();
296 inBootstrap = false;
298 return true;
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
303 inBootstrap = false;
304 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);
313 default:
314 throw new WebSMSException(outp + " #" + rslt);
316 } else {
317 throw new WebSMSException(this.context,
318 R.string.log_http_header_missing);
320 } catch (IOException e) {
321 Log.e(TAG, null, e);
322 throw new WebSMSException(e.toString());
327 * {@inheritDoc}
329 @Override
330 protected final boolean updateMessages() throws WebSMSException {
331 return this.sendData(closeBuffer(this.openBuffer("GET_SMS_CREDITS",
332 "1.00", true)));
336 * {@inheritDoc}
338 @Override
339 protected final boolean sendMessage() throws WebSMSException {
340 StringBuilder packetData = this.openBuffer("SEND_SMS", "1.01", true);
341 // fill buffer
342 writePair(packetData, "sms_text", this.text);
343 StringBuilder recipients = new StringBuilder();
344 // table: <id>, <name>, <number>
345 int j = 0;
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();
358 recipients = null;
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);
363 } else {
364 writePair(packetData, "sms_sender", this.defSender);
366 if (this.sendLater > 0) {
367 writePair(packetData, "send_date", DateFormat.format(DATEFORMAT,
368 this.sendLater).toString());
370 // push data
371 if (!this.sendData(closeBuffer(packetData))) {
372 // failed!
373 throw new WebSMSException(this.context, R.string.log_error);
375 // result: ok
376 return true;
380 * {@inheritDoc}
382 @Override
383 protected final boolean doBootstrap(final String[] params)
384 throws WebSMSException {
385 if (!needBootstrap) {
386 return true;
388 inBootstrap = true;
389 StringBuilder packetData = this.openBuffer("GET_CUSTOMER", "1.10",
390 false);
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));
400 * {@inheritDoc}
402 @Override
403 protected final boolean supportCustomsender() {
404 return true;
408 * {@inheritDoc}
410 @Override
411 protected final boolean supportSendLater() {
412 return true;