package com.samknows.measurement.net; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.Calendar; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.HTTP; import org.json.JSONException; import org.json.JSONObject; import android.text.format.DateFormat; import android.util.Base64; import android.util.Log; public class Connection { private static final String TAG = Connection.class.getSimpleName(); public static final String USER_AGENT = "SamKnows Android v1.0"; public static final String BASE_URL = "http://txweb2.samknows.com/mobile.php/"; public static final String ALLOWED_UNITS = BASE_URL + "user/getAllowedUnits"; public static final String REPORTS = BASE_URL + "reports/getResults"; public static final String DOWNSTREAM = "downstream_mt"; public static final String UPSTREAM = "upstream_mt"; public static final String LATENCY = "latency"; public static final String PACKETLOSS = "packetloss"; public static final String WWW_LOAD = "www_load"; public static final String START_DATE = "start_date"; public static final String END_DATE = "end_date"; private final String mUsername; private final String mPassword; private String mUnit; private final DefaultHttpClient mClient = new DefaultHttpClient(); /** * Constructor * @param username * @param password */ public Connection(String username, String password){ mUsername = username; mPassword = password; } /** * constructor * @param username * @param password * @param unit */ public Connection(String username, String password, String unit){ mUsername = username; mPassword = password; mUnit = unit; } private String url(){ return REPORTS + "?unit_id=" + mUnit + "&tests=downstream_mt,upstream_mt,latency,packetloss,www_load"; } private String datesToString(Calendar start, Calendar end){ CharSequence format = "yyyy-MM-dd"; CharSequence startStr = DateFormat.format(format, start); CharSequence endStr = DateFormat.format(format, end); return "&start_date=" + startStr + "&end_date=" + endStr; } private String dates(int difference){ Calendar end = Calendar.getInstance(); Calendar start = (Calendar) end.clone(); start.add(Calendar.DATE, - difference); return datesToString(start, end); } private String week(){ return dates(7); } private String month(){ return dates(30); } private String three_months(){ return dates(3 * 30); } private String six_months(){ return dates(6 * 30); } private String year(){ return dates(365); } public JSONObject getRecent() throws ConnectionException { return get(url()); } public JSONObject getWeek() throws ConnectionException { return get(url() + week()); } public JSONObject getMonth() throws ConnectionException{ return get(url() + month()); } public JSONObject getThreeMonths() throws ConnectionException{ return get(url() + three_months()); } public JSONObject getSixMonths() throws ConnectionException{ return get(url() + six_months()); } public JSONObject getYear() throws ConnectionException { return get(url() + year()); } /** Returns the devices * * @return JSONObject * @throws ConnectionException */ public JSONObject getDevices() throws ConnectionException { return get(ALLOWED_UNITS); } /** * Login method * * @return JSONObject */ public JSONObject login() throws LoginException { HttpGet getMethod = getRequest(ALLOWED_UNITS); HttpResponse response; JSONObject result; int statusCode; try{ response = doRequest(getMethod); statusCode = response.getStatusLine().getStatusCode(); }catch (ConnectionException e){ throw new LoginException("Could not connect to host."); } try{ result = responseToJSON(response); }catch(JSONException e){ throw new LoginException("Invalid JSON returned"); } return result; } private HttpGet getRequest(String url){ HttpGet get = new HttpGet(url); get.setHeader("User-Agent", USER_AGENT); get.addHeader("Authorization", "Basic " + getCredentials()); get.addHeader("Accept", "application/json"); return get; } private HttpResponse doRequest(HttpRequestBase request) throws ConnectionException, LoginException { HttpResponse response; try{ Log.i(TAG, request.getURI().toString()); response = mClient.execute(request); }catch(ClientProtocolException e){ throw new ConnectionException(e); }catch (IOException e){ throw new ConnectionException(e); } finally { request.abort(); } if (response.getStatusLine().getStatusCode() != 200){ throw new LoginException("Could not login."); } return response; } private JSONObject responseToJSON(HttpResponse response) throws JSONException{ String content = retrieveInputStream(response.getEntity()); return new JSONObject(content); } /** * Retrieve the input stream from the HTTP connection. * * @param httpEntity * @return String */ private String retrieveInputStream(HttpEntity httpEntity) { int length = (int) httpEntity.getContentLength(); boolean chunked = httpEntity.isChunked(); Log.i(TAG, "Chunked: "+ Boolean.toString(chunked) + " - Length: " + Integer.toString(length)); StringBuilder stringBuffer = new StringBuilder(length); try { InputStreamReader inputStreamReader = new InputStreamReader(httpEntity.getContent(), HTTP.UTF_8); char buffer[] = new char[length]; int count; while ((count = inputStreamReader.read(buffer, 0, length - 1)) > 0) { stringBuffer.append(buffer, 0, count); } } catch (UnsupportedEncodingException e) { Log.e(TAG, e.toString()); } catch (IllegalStateException e) { Log.e(TAG, e.toString()); } catch (IOException e) { Log.e(TAG, e.toString()); } return stringBuffer.toString(); } /** Get the HTTP digest authentication. Uses Base64 to encode credentials. * * @return String */ public String getCredentials(){ return new String(Base64.encode((mUsername + ":" + mPassword).getBytes(), Base64.DEFAULT)); } /** * Execute a GET request against the SamKnows REST API. * * @param url * @return JSONObject */ public JSONObject getData(HttpRequestBase request) throws ConnectionException { try{ return responseToJSON(doRequest(request)); }catch (Exception e){ throw new ConnectionException(e); } } private JSONObject get(String url) throws ConnectionException{ return getData(getRequest(url)); } }