Java tutorial
/* * Copyright (C) 2010-2011 Felix Bechstein * * This file is part of WebSMS. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; If not, see <http://www.gnu.org/licenses/>. */ package de.ub0r.android.websms.connector.discotel; import java.io.IOException; import java.net.HttpURLConnection; import java.util.ArrayList; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.message.BasicNameValuePair; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.text.TextUtils; import de.ub0r.android.websms.connector.common.Connector; import de.ub0r.android.websms.connector.common.ConnectorCommand; import de.ub0r.android.websms.connector.common.ConnectorSpec; import de.ub0r.android.websms.connector.common.ConnectorSpec.SubConnectorSpec; import de.ub0r.android.websms.connector.common.Log; import de.ub0r.android.websms.connector.common.Utils; import de.ub0r.android.websms.connector.common.Utils.HttpOptions; import de.ub0r.android.websms.connector.common.WebSMSException; /** * AsyncTask to manage IO to discotel.com API. * * @author flx */ public class ConnectorDiscotel extends Connector { /** Tag for output. */ private static final String TAG = "discotel"; /** Discoplus URL: login. */ private static final String URL_DP_LOGIN = // . "https://service.discoplus.de/frei/LOGIN"; /** Destination for login. */ private static final String LOGIN_DP_DEST = "/discoplus/index3.php"; /** Discoplus URL: send. */ private static final String URL_DP_SEND = // . "https://service.discoplus.de/discoplus/sms-neu.php"; /** Check for login. */ private static final String CHECK_DP_LOGIN = "sms-neu.php"; /** Check for balance. */ private static final String CHECK_DP_BALANCE1 = "prepaid Guthaben:"; /** Check for balance. */ private static final String CHECK_DP_BALANCE2 = " kostenlose SMS "; /** Check for sent. */ private static final String CHECK_DP_SENT = "Ihre SMS wurde versendet"; /** Discotel URL: login. */ private static final String URL_DT_LOGIN = // . "https://lounge.discoplus.de/login"; /** Discotel URL: send. */ private static final String URL_DT_SEND = // . "https://lounge.discoplus.de/sms_service"; /** Check for login. */ private static final String CHECK_DT_LOGIN = "Ihre Kundennummer lautet"; /** Check for balance. */ private static final String CHECK_DT_BALANCE1 = "nnen in diesem Monat noch"; /** Check for sent. */ private static final String CHECK_DT_SENT = // . "Ihre SMS wurde erfolgreich versendet"; /** Max length for discotel sms. */ private static final int MAXLENGTH = 101; /** Number of vars pushed at login. */ private static final int NUM_VARS_LOGIN = 4; /** Number of vars pushed at send. */ private static final int NUM_VARS_SEND = 6; /** HTTP Useragent. */ private static final String TARGET_AGENT = "Mozilla/5.0 (Windows; U; " + "Windows NT 5.1; ko; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 " + "(.NET CLR 3.5.30729)"; /** Used encoding. */ private static final String ENCODING = "ISO-8859-15"; /** Trusted SSL certificates. */ private static final String[] TRUSTED_CERTS = { // . "d6:5c:29:a8:68:dd:c7:72:a1:11:af:5d:6a:84:ad:fc:4f:f0:5b:dc" }; /** * {@inheritDoc} */ @Override public final ConnectorSpec initSpec(final Context context) { final String name = context.getString(R.string.connector_discotel_name); ConnectorSpec c = new ConnectorSpec(name); c.setAuthor(// . context.getString(R.string.connector_discotel_author)); c.setBalance(null); c.setCapabilities(ConnectorSpec.CAPABILITIES_UPDATE | ConnectorSpec.CAPABILITIES_SEND | ConnectorSpec.CAPABILITIES_PREFS); c.addSubConnector("discotel", c.getName(), SubConnectorSpec.FEATURE_NONE); return c; } /** * {@inheritDoc} */ @Override public final ConnectorSpec updateSpec(final Context context, final ConnectorSpec connectorSpec) { final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context); if (p.getBoolean(Preferences.PREFS_ENABLED, false)) { if (p.getString(Preferences.PREFS_PASSWORD, "").length() > 0) { connectorSpec.setReady(); } else { connectorSpec.setStatus(ConnectorSpec.STATUS_ENABLED); } } else { connectorSpec.setStatus(ConnectorSpec.STATUS_INACTIVE); } return connectorSpec; } /** * Login to service.discoplus.de. * * @param context * {@link Context} * @param command * {@link ConnectorCommand} * @throws IOException * IOException */ private void dpDoLogin(final Context context, // . final ConnectorCommand command) throws IOException { Log.d(TAG, "dpDoLogin()"); final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context); ArrayList<BasicNameValuePair> postData = // . new ArrayList<BasicNameValuePair>(NUM_VARS_LOGIN); postData.add(new BasicNameValuePair("destination", LOGIN_DP_DEST)); String genlogin = Utils.getSender(context, command.getDefSender()); Log.d(TAG, "genlogin: " + genlogin); genlogin = Utils.international2national(command.getDefPrefix(), genlogin); Log.d(TAG, "genlogin: " + genlogin); postData.add(new BasicNameValuePair("credential_0", genlogin)); Log.d(TAG, "genlogin: " + genlogin); postData.add(new BasicNameValuePair("credential_1", p.getString(Preferences.PREFS_PASSWORD, ""))); HttpOptions o = new HttpOptions(ENCODING); o.addFormParameter(postData); o.userAgent = TARGET_AGENT; o.trustAll = Preferences.getTrustAll(p); o.knownFingerprints = TRUSTED_CERTS; o.url = URL_DP_LOGIN; HttpResponse response = Utils.getHttpClient(o); postData = null; int resp = response.getStatusLine().getStatusCode(); if (resp != HttpURLConnection.HTTP_OK) { throw new WebSMSException(context, R.string.error_http, "" + resp); } String htmlText = Utils.stream2str(response.getEntity().getContent()); Log.d(TAG, "----HTTP RESPONSE---"); Log.d(TAG, htmlText); Log.d(TAG, "----HTTP RESPONSE---"); if (!htmlText.contains(CHECK_DP_LOGIN)) { Log.e(TAG, "HTTP Status Line: " + response.getStatusLine().toString()); Log.e(TAG, "HTTP Headers:"); for (Header h : response.getAllHeaders()) { Log.e(TAG, h.getName() + ": " + h.getValue()); } Log.e(TAG, "HTTP Body:"); for (String l : htmlText.split("\n")) { Log.e(TAG, l); } Utils.clearCookies(); throw new WebSMSException(context, R.string.error_pw); } // update balance String balance = ""; int i = htmlText.indexOf(CHECK_DP_BALANCE1); if (i > 0) { htmlText = htmlText.substring(i, htmlText.indexOf(" EUR", i)); Log.d(TAG, htmlText); htmlText = htmlText.substring(htmlText.lastIndexOf(">") + 1); balance = htmlText + "\u20ac"; Log.d(TAG, "balance: " + balance); } // update free balance o = new HttpOptions(ENCODING); o.userAgent = TARGET_AGENT; o.trustAll = Preferences.getTrustAll(p); o.knownFingerprints = TRUSTED_CERTS; o.url = URL_DP_SEND; response = Utils.getHttpClient(o); resp = response.getStatusLine().getStatusCode(); if (resp != HttpURLConnection.HTTP_OK) { Log.e(TAG, "HTTP Status Line: " + response.getStatusLine().toString()); Log.e(TAG, "HTTP Headers:"); for (Header h : response.getAllHeaders()) { Log.e(TAG, h.getName() + ": " + h.getValue()); } Log.e(TAG, "HTTP Body:"); for (String l : htmlText.split("\n")) { Log.e(TAG, l); } Utils.clearCookies(); throw new WebSMSException(context, R.string.error_http, "" + resp); } htmlText = Utils.stream2str(response.getEntity().getContent()); Log.d(TAG, "----HTTP RESPONSE---"); Log.d(TAG, htmlText); Log.d(TAG, "----HTTP RESPONSE---"); i = htmlText.indexOf(CHECK_DP_BALANCE2); if (i < 0) { Log.e(TAG, "HTTP Status Line: " + response.getStatusLine().toString()); Log.e(TAG, "HTTP Headers:"); for (Header h : response.getAllHeaders()) { Log.e(TAG, h.getName() + ": " + h.getValue()); } Log.e(TAG, "HTTP Body:"); for (String l : htmlText.split("\n")) { Log.e(TAG, l); } Utils.clearCookies(); throw new WebSMSException(context, R.string.error); } htmlText = htmlText.substring(1, i); Log.d(TAG, "----HTTP RESPONSE---"); Log.d(TAG, htmlText); Log.d(TAG, "----HTTP RESPONSE---"); i = htmlText.lastIndexOf(">"); Log.d(TAG, "i: " + i); ++i; Log.d(TAG, "i: " + i); final int j = htmlText.lastIndexOf(" "); Log.d(TAG, "j: " + j); if (!TextUtils.isEmpty(balance)) { balance += "/"; } if (j < i) { balance += htmlText.substring(i); } else { balance += htmlText.substring(i, j); } Log.d(TAG, "balance: " + balance); this.getSpec(context).setBalance(balance); } /** * Send text via service.discoplus.de. * * @param context * {@link Context} * @param command * {@link ConnectorCommand} * @throws IOException * IOException */ private void dpSendText(final Context context, final ConnectorCommand command) throws IOException { Log.d(TAG, "dpSendText()"); final int cc = Utils.getCookieCount(); if (cc == 0) { this.dpDoLogin(context, command); } String number = Utils.national2international(command.getDefPrefix(), Utils.getRecipientsNumber(command.getRecipients()[0])); Log.d(TAG, "number: " + number); final String prefix = number.substring(0, 6); Log.d(TAG, "prefix: " + prefix); number = number.substring(prefix.length()); Log.d(TAG, "number: " + number); ArrayList<BasicNameValuePair> postData = // . new ArrayList<BasicNameValuePair>(NUM_VARS_SEND); postData.add(new BasicNameValuePair("vorwahl", prefix)); postData.add(new BasicNameValuePair("nummer", number)); postData.add(new BasicNameValuePair("TEXT", command.getText())); postData.add(new BasicNameValuePair("SMSanzahl", "1")); postData.add(new BasicNameValuePair("ZEICHEN", "619")); postData.add(new BasicNameValuePair("sende", "Absenden")); postData.add(new BasicNameValuePair("action", "")); postData.add(new BasicNameValuePair("unteraction", "abschicken")); HttpOptions o = new HttpOptions(ENCODING); o.addFormParameter(postData); o.userAgent = TARGET_AGENT; o.trustAll = Preferences.getTrustAll(context); o.knownFingerprints = TRUSTED_CERTS; o.referer = URL_DP_SEND; o.url = URL_DP_SEND; HttpResponse response = Utils.getHttpClient(o); postData = null; final int resp = response.getStatusLine().getStatusCode(); if (resp != HttpURLConnection.HTTP_OK) { throw new WebSMSException(context, R.string.error_http, "" + resp); } String htmlText = Utils.stream2str(response.getEntity().getContent()); Log.d(TAG, "----HTTP RESPONSE---"); Log.d(TAG, htmlText); Log.d(TAG, "----HTTP RESPONSE---"); final int i = htmlText.indexOf(CHECK_DP_SENT); if (i < 0) { Log.e(TAG, "failed to send message, response following:"); Log.e(TAG, "HTTP Status Line: " + response.getStatusLine().toString()); Log.e(TAG, "HTTP Headers:"); for (Header h : response.getAllHeaders()) { Log.e(TAG, h.getName() + ": " + h.getValue()); } Log.e(TAG, "HTTP Body:"); for (String l : htmlText.split("\n")) { Log.e(TAG, l); } throw new WebSMSException(context, R.string.error); } } /** * Login to lounge.discoplus.de. * * @param context * {@link Context} * @param command * {@link ConnectorCommand} * @throws IOException * IOException */ private void dtDoLogin(final Context context, // . final ConnectorCommand command) throws IOException { Log.d(TAG, "dtDoLogin()"); final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context); ArrayList<BasicNameValuePair> postData = // . new ArrayList<BasicNameValuePair>(NUM_VARS_LOGIN); postData.add(new BasicNameValuePair("do", "login")); postData.add(new BasicNameValuePair("goto", "")); postData.add(new BasicNameValuePair("loginname", p.getString(Preferences.PREFS_USERNAME, ""))); postData.add(new BasicNameValuePair("password", p.getString(Preferences.PREFS_PASSWORD, ""))); HttpOptions o = new HttpOptions(ENCODING); o.addFormParameter(postData); o.userAgent = TARGET_AGENT; o.trustAll = Preferences.getTrustAll(p); o.knownFingerprints = TRUSTED_CERTS; o.referer = URL_DT_LOGIN; o.url = URL_DT_LOGIN; HttpResponse response = Utils.getHttpClient(o); postData = null; int resp = response.getStatusLine().getStatusCode(); if (resp != HttpURLConnection.HTTP_OK) { throw new WebSMSException(context, R.string.error_http, "" + resp); } String htmlText = Utils.stream2str(response.getEntity().getContent()); Log.d(TAG, "----HTTP RESPONSE---"); Log.d(TAG, htmlText); Log.d(TAG, "----HTTP RESPONSE---"); if (!htmlText.contains(CHECK_DT_LOGIN)) { Log.e(TAG, "HTTP Status Line: " + response.getStatusLine().toString()); Log.e(TAG, "HTTP Headers:"); for (Header h : response.getAllHeaders()) { Log.e(TAG, h.getName() + ": " + h.getValue()); } Log.e(TAG, "HTTP Body:"); for (String l : htmlText.split("\n")) { Log.e(TAG, l); } Utils.clearCookies(); throw new WebSMSException(context, R.string.error_pw); } // update balance String balance = ""; int i = htmlText.indexOf(CHECK_DT_BALANCE1); if (i > 0) { htmlText = htmlText.substring(i, htmlText.indexOf("SMS", i)); Log.d(TAG, htmlText); htmlText = htmlText.substring(htmlText.indexOf(">") + 1); balance = htmlText.substring(0, htmlText.indexOf("<")); Log.d(TAG, "balance: " + balance); } Log.d(TAG, "balance: " + balance); this.getSpec(context).setBalance(balance); } /** * Send text via service.discoplus.de. * * @param context * {@link Context} * @param command * {@link ConnectorCommand} * @throws IOException * IOException */ private void dtSendText(final Context context, final ConnectorCommand command) throws IOException { Log.d(TAG, "dtSendText()"); if (command.getText().length() > MAXLENGTH) { throw new WebSMSException(context, R.string.error_length_101); } final int cc = Utils.getCookieCount(); if (cc == 0) { this.dtDoLogin(context, command); } String number = Utils.national2international(command.getDefPrefix(), Utils.getRecipientsNumber(command.getRecipients()[0])); Log.d(TAG, "number: " + number); String sender = Utils.getSender(context, command.getDefSender()); Log.d(TAG, "sender: " + sender); ArrayList<BasicNameValuePair> postData = // . new ArrayList<BasicNameValuePair>(NUM_VARS_SEND); postData.add(new BasicNameValuePair("submit_sms", "SMS versenden")); postData.add(new BasicNameValuePair("confirm_agb", "1")); postData.add(new BasicNameValuePair("sender", sender)); postData.add(new BasicNameValuePair("message", command.getText())); postData.add(new BasicNameValuePair("receiver", Utils.cleanRecipient(command.getRecipients()[0]))); HttpOptions o = new HttpOptions(ENCODING); o.addFormParameter(postData); o.userAgent = TARGET_AGENT; o.trustAll = Preferences.getTrustAll(context); o.knownFingerprints = TRUSTED_CERTS; o.referer = URL_DT_SEND; o.url = URL_DT_SEND; HttpResponse response = Utils.getHttpClient(o); postData = null; final int resp = response.getStatusLine().getStatusCode(); if (resp != HttpURLConnection.HTTP_OK) { throw new WebSMSException(context, R.string.error_http, "" + resp); } String htmlText = Utils.stream2str(response.getEntity().getContent()); Log.d(TAG, "----HTTP RESPONSE---"); Log.d(TAG, htmlText); Log.d(TAG, "----HTTP RESPONSE---"); final int i = htmlText.indexOf(CHECK_DT_SENT); if (i < 0) { Log.e(TAG, "failed to send message, response following:"); Log.e(TAG, "HTTP Status Line: " + response.getStatusLine().toString()); Log.e(TAG, "HTTP Headers:"); for (Header h : response.getAllHeaders()) { Log.e(TAG, h.getName() + ": " + h.getValue()); } Log.e(TAG, "HTTP Body:"); for (String l : htmlText.split("\n")) { Log.e(TAG, l); } throw new WebSMSException(context, R.string.error); } } /** * {@inheritDoc} */ @Override protected final void doUpdate(final Context context, final Intent intent) { try { String url = Preferences.getService(context); if (url.contains("service.discoplus.de")) { this.dpDoLogin(context, new ConnectorCommand(intent)); } else { this.dtDoLogin(context, new ConnectorCommand(intent)); } } catch (IOException e) { Log.e(TAG, "login failed", e); throw new WebSMSException(e.toString()); } } /** * {@inheritDoc} */ @Override protected final void doSend(final Context context, final Intent intent) { try { String url = Preferences.getService(context); if (url.contains("service.discoplus.de")) { this.dpSendText(context, new ConnectorCommand(intent)); } else { this.dtSendText(context, new ConnectorCommand(intent)); } } catch (IOException e) { Log.e(TAG, "send failed", e); throw new WebSMSException(e.toString()); } } }