package com.eveningoutpost.dexdrip.ShareModels; import android.content.Context; import android.content.SharedPreferences; import android.os.AsyncTask; import android.preference.PreferenceManager; import android.util.Log; import com.eveningoutpost.dexdrip.Models.BgReading; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.squareup.okhttp.OkHttpClient; import java.security.cert.CertificateException; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import retrofit.Callback; import retrofit.RequestInterceptor; import retrofit.RestAdapter; import retrofit.RetrofitError; import retrofit.android.AndroidLog; import retrofit.client.OkClient; import retrofit.client.Response; import retrofit.converter.GsonConverter; import retrofit.mime.TypedByteArray; /** * Created by stephenblack on 12/26/14. */ public class ShareRest { private Context mContext; private String login; private String password; private SharedPreferences prefs; OkClient client; public static Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create(); public ShareRest(Context context) { client = getOkClient(); mContext = context; prefs = PreferenceManager.getDefaultSharedPreferences(context); login = prefs.getString("dexcom_account_name", ""); password = prefs.getString("dexcom_account_password", ""); } public boolean getBgData() { if (prefs.getBoolean("share_poll", false) && login.compareTo("") != 0 && password.compareTo("") != 0) { return loginAndGetData(); } else { return false; } } public boolean sendBgData(BgReading bg) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext); String receiverSn = preferences.getString("share_key", "SM00000000").toUpperCase(); if (prefs.getBoolean("share_upload", false) && login.compareTo("") != 0 && password.compareTo("") != 0 && receiverSn.compareTo("SM00000000") != 0) { return loginAndSendData(bg); } else { return false; } } private boolean loginAndGetData() { try { dexcomShareAuthorizeInterface().getSessionId(new ShareAuthenticationBody(password, login), new Callback() { @Override public void success(Object o, Response response) { Log.d("ShareRest", "Success!! got a response on auth."); String returnedSessionId = new String(((TypedByteArray) response.getBody()).getBytes()).replace("\"", ""); getBgData(returnedSessionId); } @Override public void failure(RetrofitError retrofitError) { Log.e("RETROFIT ERROR: ", ""+retrofitError.toString()); } }); return true; } catch (Exception e) { Log.e("REST CALL ERROR: ", "BOOOO"); return false; } } private boolean loginAndSendData(final BgReading bg) { try { dexcomShareAuthorizeInterface().getSessionId(new ShareAuthenticationBody(password, login), new Callback() { @Override public void success(Object o, Response response) { Log.d("ShareRest", "Success!! got a response on auth."); String returnedSessionId = new String(((TypedByteArray) response.getBody()).getBytes()).replace("\"", ""); sendBgData(returnedSessionId, bg); } @Override public void failure(RetrofitError retrofitError) { Log.e("RETROFIT ERROR: ", ""+retrofitError.toString()); } }); return true; } catch (Exception e) { Log.e("REST CALL ERROR: ", "BOOOO"); return false; } } private void getBgData(String sessionId) { DataFetcher dataFetcher = new DataFetcher(mContext, sessionId); dataFetcher.execute((Void) null); } private void sendBgData(String sessionId, BgReading bg) { DataSender dataSender = new DataSender(mContext, sessionId, bg); dataSender.execute((Void) null); } private DexcomShareInterface dexcomShareAuthorizeInterface() { RestAdapter adapter = authoirizeAdapterBuilder().build(); DexcomShareInterface dexcomShareInterface = adapter.create(DexcomShareInterface.class); return dexcomShareInterface; } private DexcomShareInterface dexcomShareGetBgInterface() { RestAdapter adapter = getBgAdapterBuilder().build(); DexcomShareInterface dexcomShareInterface = adapter.create(DexcomShareInterface.class); return dexcomShareInterface; } private DexcomShareInterface dexcomShareSendBgInterface() { RestAdapter adapter = authoirizeAdapterBuilder().build(); DexcomShareInterface dexcomShareInterface = adapter.create(DexcomShareInterface.class); return dexcomShareInterface; } private DexcomShareInterface checkSessionActive() { RestAdapter adapter = getBgAdapterBuilder().build(); DexcomShareInterface checkSessionActive = adapter.create(DexcomShareInterface.class); return checkSessionActive; } private RestAdapter.Builder authoirizeAdapterBuilder() { RestAdapter.Builder adapterBuilder = new RestAdapter.Builder(); adapterBuilder .setClient(client) .setLogLevel(RestAdapter.LogLevel.FULL).setLog(new AndroidLog("SHAREREST")) .setEndpoint("https://share1.dexcom.com/ShareWebServices/Services") .setRequestInterceptor(authorizationRequestInterceptor) .setConverter(new GsonConverter(new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create())); return adapterBuilder; } private RestAdapter.Builder getBgAdapterBuilder() { RestAdapter.Builder adapterBuilder = new RestAdapter.Builder(); adapterBuilder .setClient(client) .setLogLevel(RestAdapter.LogLevel.FULL).setLog(new AndroidLog("SHAREREST")) .setEndpoint("https://share1.dexcom.com/ShareWebServices/Services") .setRequestInterceptor(getBgRequestInterceptor) .setConverter(new GsonConverter(new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create())); return adapterBuilder; } RequestInterceptor authorizationRequestInterceptor = new RequestInterceptor() { @Override public void intercept(RequestInterceptor.RequestFacade request) { request.addHeader("User-Agent", "Dexcom Share/3.0.2.11 CFNetwork/711.2.23 Darwin/14.0.0"); request.addHeader("Content-Type", "application/json"); request.addHeader("Accept", "application/json"); } }; RequestInterceptor getBgRequestInterceptor = new RequestInterceptor() { @Override public void intercept(RequestInterceptor.RequestFacade request) { request.addHeader("User-Agent", "Dexcom Share/3.0.2.11 CFNetwork/711.2.23 Darwin/14.0.0"); request.addHeader("Content-Type", "application/json"); request.addHeader("Content-Length", "0"); request.addHeader("Accept", "application/json"); } }; public OkHttpClient getOkHttpClient() { try { final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public void checkClientTrusted( java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted( java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } } }; final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setSslSocketFactory(sslSocketFactory); okHttpClient.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); return okHttpClient; } catch (Exception e) { throw new RuntimeException(e); } } public OkClient getOkClient (){ OkHttpClient client1 = getOkHttpClient(); OkClient _client = new OkClient(client1); return _client; } public Map<String, String> queryParamMap(String sessionId) { Map map = new HashMap<String, String>(); map.put("sessionID", sessionId); map.put("minutes", String.valueOf(minutesCount())); map.put("maxCount", String.valueOf(requestCount())); return map; } public class DataFetcher extends AsyncTask<Void, Void, Boolean> { Context mContext; String mSessionId; DataFetcher(Context context, String sessionId) { mContext = context; mSessionId = sessionId; } @Override protected Boolean doInBackground(Void... params) { try { try { final ShareGlucose[] shareGlucoses = dexcomShareGetBgInterface().getShareBg(queryParamMap(mSessionId)); Log.d("REST Success: ", "YAY!"); if(shareGlucoses != null && shareGlucoses.length > 0) { for (ShareGlucose shareGlucose : shareGlucoses) { shareGlucose.processShareData(mContext); } return true; } return false; } catch (Exception e) { Log.d("REST CALL ERROR: ", "BOOOO"); return false; } } catch (RetrofitError e) { Log.d("Retrofit Error: ", "BOOOO"); } catch (Exception ex) { Log.d("Unrecognized Error: ", "BOOOO"); } return false; } } public class DataSender extends AsyncTask<Void, Void, Boolean> { Context mContext; String mSessionId; BgReading mBg; DataSender(Context context, String sessionId, BgReading bg) { mContext = context; mSessionId = sessionId; mBg = bg; } @Override protected Boolean doInBackground(Void... params) { try { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext); String receiverSn = preferences.getString("share_key", "SM00000000").toUpperCase(); dexcomShareSendBgInterface().uploadBGRecords(querySessionMap(mSessionId), new ShareUploadPayload(receiverSn, mBg), new Callback() { @Override public void success(Object o, Response response) { Log.d("ShareRest", "Success!! Uploaded!!"); } @Override public void failure(RetrofitError retrofitError) { Log.e("RETROFIT ERROR: ", ""+retrofitError.toString()); } }); } catch (RetrofitError e) { Log.d("Retrofit Error: ", "BOOOO"); } catch (Exception ex) { Log.d("Unrecognized Error: ", "BOOOO"); } return false; } } public int requestCount() { BgReading bg = BgReading.last(); if(bg != null) { return 20; } else if (bg.timestamp < new Date().getTime()) { return Math.min((int) Math.ceil(((new Date().getTime() - bg.timestamp) / (5 * 1000 * 60))), 10); } else { return 1; } } public int minutesCount() { BgReading bg = BgReading.last(); if(bg != null && bg.timestamp < new Date().getTime()) { return Math.min((int) Math.ceil(((new Date().getTime() - bg.timestamp) / (1000 * 60))), 1440); } else { return 1440; } } public Map<String, String> querySessionMap(String sessionId) { Map map = new HashMap<String, String>(); map.put("sessionID", sessionId); return map; } }