diff --git a/.gitignore b/.gitignore
index 65a246ab8800c50e8872cd12c0d7c03f0c3e5979..2cf6323a20955eddc2f8eb2ffdb03ed7c294a46d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,60 +1,60 @@
-#built application files
-*.apk
-*.ap_
-
-#files for the dex VM
-*.dex
-
-#Java class files
-*.class
-
-#generated files
-bin/
-gen/
-out/
-build/
-captures/
-
-#Local configuration files (sdk path, etc)
-local.properties
-
-#Window thumbnail db
-Thumbs.db
-
-#OSX files
-.DS_Store
-
-#Eclipse project files
-.classpath
-.project
-
-#Android Studio
-*.iml
-.idea
-
-#Android Studio Navigation editor temp files
-.navigation/
-
-#old-style IDEA project files
-*.ipr
-*.iws
-
-#Local IDEA workspace
-.idea/workspace.xml
-
-#Local IDEA Libraries
-.idea/libraries
-
-#Gradel cache
-.gradle
-
-#Sandbox stuff
-_sandbox
-
-#NDK
-obj/
-
-#Illustrator Files
-*.ai
-
-
+#built application files
+*.apk
+*.ap_
+
+#files for the dex VM
+*.dex
+
+#Java class files
+*.class
+
+#generated files
+bin/
+gen/
+out/
+build/
+captures/
+
+#Local configuration files (sdk path, etc)
+local.properties
+
+#Window thumbnail db
+Thumbs.db
+
+#OSX files
+.DS_Store
+
+#Eclipse project files
+.classpath
+.project
+
+#Android Studio
+*.iml
+.idea
+
+#Android Studio Navigation editor temp files
+.navigation/
+
+#old-style IDEA project files
+*.ipr
+*.iws
+
+#Local IDEA workspace
+.idea/workspace.xml
+
+#Local IDEA Libraries
+.idea/libraries
+
+#Gradel cache
+.gradle
+
+#Sandbox stuff
+_sandbox
+
+#NDK
+obj/
+
+#Illustrator Files
+*.ai
+
+
diff --git a/README.md b/README.md
index 70f1cc8be01bace86836abaaaa0c6bd7aa425520..1006e70f8286b7e384e0334fab73cae382dfc604 100644
--- a/README.md
+++ b/README.md
@@ -1,43 +1,43 @@
-# Mobile Group Project: Investigating Broadcom & Internet of Things
-
-## Author
-
-Jeffrey Martin, Brandon Rodriguez
-
-## Description
-
-An attempt to learn about "Internet of Things" concepts with hands-on development, using Broadcom's "WICED SMART"" pre-made mobile application as a base.
-
-Broadcam's sensor associated with the application can detect a number of things including: Device orientation, speed, compass direction, air pressure, humidity, and temperature.
-
-### Core Function and Minimum Implementation
-
-Our goal is to learn how the program connects to the device (including finding out how the bluetooth conectivity works, if time allows). From there, we will create our own UI, showcasing that we understand how to read the sensor information and accurately display it in real time.
-
-### Additional functionality, should time allow
-
-Determine a way to store up to a week's worth of data within the app. We will average out the information so that we only store the hourly-average per data type. Any hours with no sensory information will display as "NA" or some equivalent. This data will then be displayed to a clean and easy to read UI. This UI will display both "current data" plus have a tab to show specifics of each data catagory.
-
-Should we accomplish this, we can take it a step further by showing something along the lines of "change this week." For example, we could do "Total distance traveled" or "Highest Temperature Vs Lowest Temperature" type displays.
-
-### Notes
-
-It might be beneficial to look into a few resources before we start any actual work.
-
-For example, we might want to consider some practices for commenting and organization:
-* Javadocs  http://www.oracle.com/technetwork/articles/java/index-137868.html
-* Use of regions  http://stackoverflow.com/questions/2344524/java-equivalent-to-region-in-c-sharp
-
-
-We could also investigate how to properly create commit messages and decide on a standard:
-* http://chris.beams.io/posts/git-commit/
-* https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message
-
-
-## Outside Resources Used
-
-
-
-## Known Problems, Issues, And/Or Errors in the Program
-
-
+# Mobile Group Project: Investigating Broadcom & Internet of Things
+
+## Author
+
+Jeffrey Martin, Brandon Rodriguez
+
+## Description
+
+An attempt to learn about "Internet of Things" concepts with hands-on development, using Broadcom's "WICED SMART"" pre-made mobile application as a base.
+
+Broadcam's sensor associated with the application can detect a number of things including: Device orientation, speed, compass direction, air pressure, humidity, and temperature.
+
+### Core Function and Minimum Implementation
+
+Our goal is to learn how the program connects to the device (including finding out how the bluetooth conectivity works, if time allows). From there, we will create our own UI, showcasing that we understand how to read the sensor information and accurately display it in real time.
+
+### Additional functionality, should time allow
+
+Determine a way to store up to a week's worth of data within the app. We will average out the information so that we only store the hourly-average per data type. Any hours with no sensory information will display as "NA" or some equivalent. This data will then be displayed to a clean and easy to read UI. This UI will display both "current data" plus have a tab to show specifics of each data catagory.
+
+Should we accomplish this, we can take it a step further by showing something along the lines of "change this week." For example, we could do "Total distance traveled" or "Highest Temperature Vs Lowest Temperature" type displays.
+
+### Notes
+
+It might be beneficial to look into a few resources before we start any actual work.
+
+For example, we might want to consider some practices for commenting and organization:
+* Javadocs  http://www.oracle.com/technetwork/articles/java/index-137868.html
+* Use of regions  http://stackoverflow.com/questions/2344524/java-equivalent-to-region-in-c-sharp
+
+
+We could also investigate how to properly create commit messages and decide on a standard:
+* http://chris.beams.io/posts/git-commit/
+* https://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message
+
+
+## Outside Resources Used
+
+
+
+## Known Problems, Issues, And/Or Errors in the Program
+
+
diff --git a/WicedSense/app/build.gradle b/WicedSense/app/build.gradle
index fbf93be31ada73f290f842992f0cfa1ca6910712..0d8c3d09d5cb3a220bc773d72fa69f819c8a71dd 100644
--- a/WicedSense/app/build.gradle
+++ b/WicedSense/app/build.gradle
@@ -1,22 +1,22 @@
-apply plugin: 'com.android.application'
-android {
-    compileSdkVersion 18
-    buildToolsVersion "23.0.1"
-
-    defaultConfig {
-        applicationId "com.broadcom.app.wicedsense"
-        minSdkVersion 18
-        targetSdkVersion 19
-    }
-
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
-        }
-    }
-}
-
-dependencies {
-    compile 'com.android.support:support-v4:23.0.1'
+apply plugin: 'com.android.application'
+android {
+    compileSdkVersion 18
+    buildToolsVersion "23.0.1"
+
+    defaultConfig {
+        applicationId "com.broadcom.app.wicedsense"
+        minSdkVersion 18
+        targetSdkVersion 19
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+        }
+    }
+}
+
+dependencies {
+    compile 'com.android.support:support-v4:23.0.1'
 }
\ No newline at end of file
diff --git a/WicedSense/app/lint.xml b/WicedSense/app/lint.xml
index 8423c0ef9c4d15f948aee03637204d97e5ce7c44..993e7be6d3ee72d01a4522d90768cb07e068de2b 100644
--- a/WicedSense/app/lint.xml
+++ b/WicedSense/app/lint.xml
@@ -1,3 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
-<lint>
+<?xml version="1.0" encoding="utf-8"?>
+<lint>
 </lint>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/AndroidManifest.xml b/WicedSense/app/src/main/AndroidManifest.xml
index 83b9d627fec3e6ff81dc82e5f389eb2e327c73a4..1621b1a29d8651e937cb95a089e7f860193551e2 100644
--- a/WicedSense/app/src/main/AndroidManifest.xml
+++ b/WicedSense/app/src/main/AndroidManifest.xml
@@ -1,57 +1,57 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.broadcom.app.wicedsense"
-    android:versionCode="108"
-    android:versionName="1.08" >
-
-    <uses-permission android:name="android.permission.BLUETOOTH" />
-    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-sdk
-        android:minSdkVersion="18"
-        android:targetSdkVersion="19" />
-
-    <uses-feature
-        android:name="android.hardware.bluetooth"
-        android:required="true" />
-    <uses-feature
-        android:name="android.hardware.bluetooth_le"
-        android:required="true" />
-
-    <application
-        android:allowBackup="false"
-        android:hardwareAccelerated="true"
-        android:icon="@drawable/ic_launcher"
-        android:label="@string/app_name"
-        android:largeHeap="true"
-        android:logo="@drawable/ic_launcher"
-        android:theme="@style/AppTheme" >
-        <activity
-            android:name="com.broadcom.app.wicedsense.MainActivity"
-            android:label="@string/title_activity_compass" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-        <activity
-            android:name="com.broadcom.app.ledevicepicker.DevicePickerActivity"
-            android:excludeFromRecents="true"
-            android:label="@string/app_name"
-            android:launchMode="singleInstance"
-            android:theme="@style/DevicePickerDialogTheme" >
-        </activity>
-        <activity
-            android:name="com.broadcom.app.wicedsense.SettingsActivity"
-            android:excludeFromRecents="true"
-            android:label="@string/app_name"
-            android:launchMode="singleInstance" />
-
-        <service android:name="com.broadcom.app.wicedsense.SenseManager" >
-        </service>
-
-    </application>
-
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.broadcom.app.wicedsense"
+    android:versionCode="108"
+    android:versionName="1.08" >
+
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-sdk
+        android:minSdkVersion="18"
+        android:targetSdkVersion="19" />
+
+    <uses-feature
+        android:name="android.hardware.bluetooth"
+        android:required="true" />
+    <uses-feature
+        android:name="android.hardware.bluetooth_le"
+        android:required="true" />
+
+    <application
+        android:allowBackup="false"
+        android:hardwareAccelerated="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:largeHeap="true"
+        android:logo="@drawable/ic_launcher"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.broadcom.app.wicedsense.MainActivity"
+            android:label="@string/title_activity_compass" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name="com.broadcom.app.ledevicepicker.DevicePickerActivity"
+            android:excludeFromRecents="true"
+            android:label="@string/app_name"
+            android:launchMode="singleInstance"
+            android:theme="@style/DevicePickerDialogTheme" >
+        </activity>
+        <activity
+            android:name="com.broadcom.app.wicedsense.SettingsActivity"
+            android:excludeFromRecents="true"
+            android:label="@string/app_name"
+            android:launchMode="singleInstance" />
+
+        <service android:name="com.broadcom.app.wicedsense.SenseManager" >
+        </service>
+
+    </application>
+
 </manifest>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/assets/license.html b/WicedSense/app/src/main/assets/license.html
index de33b5018b82aab22a6fe2134555a013e9ae4ea9..f0a136b554906889681820a45e89666adc25638a 100644
--- a/WicedSense/app/src/main/assets/license.html
+++ b/WicedSense/app/src/main/assets/license.html
@@ -1,33 +1,33 @@
-<b>IMPORTANT:</b> BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE APPLICATION (“SOFTWARE”), YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS LICENSE AGREEMENT (“AGREEMENT”). IF YOU DO NOT AGREE WITH THE TERMS OF THIS AGREEMENT, DO NOT DOWNLOAD, INSTALL OR USE THE SOFTWARE AND PROMPTLY DELETE THE SOFTWARE FROM YOUR COMPUTER OR DEVICE.  IF YOU AGREE WITH AND ACCEPT THE TERMS AND CONDITIONS OF THIS AGREEMENT, IT SHALL BECOME A LEGALLY BINDING AGREEMENT BETWEEN YOU AND BROADCOM CORPORATION (“BROADCOM”), AND YOU MAY PROCEED TO DOWNLOAD, INSTALL, AND USE THE SOFTWARE IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF THIS AGREEMENT.  WHERE WE REFER TO “YOU” IN THIS AGREEMENT, WE ARE REFERRING TO THE PARTY THAT HAS DOWNLOADED AND INSTALLED OR IS USING THE SOFTWARE.  IF AN INDIVIDUAL HAS DONE SO ON BEHALF OF A CORPORATION OR SIMILAR ENTITY, SUCH INDIVIDUAL REPRESENTS AND WARRANTS THAT HE OR HSE HAS THE LEGAL AUTHORITY TO AGREE TO ACT ON BEHALF OF SUCH ENTITY AND LEGALLY BIND SUCH ENTITY TO THIS AGREEMENT.  IN SUCH CASES, WHERE USED HEREIN, “YOU” SHALL REFER TO THE ENTITY.
-
-<p>1. <b>GRANT OF LICENSE</b> Subject to the terms and conditions of this Agreement, BROADCOM grants You a limited, revocable, non-exclusive, non-transferable personal license to use the Software and any accompanying documentation (“Documentation”) solely for Your individual use and for the intended purposes of the Software. You do not have the right to modify or create derivate works from the Software.  You do not have the right to sublicense the Software to third parties.</p>
-
-<p>2. <b>THIRD PARTY SOFTWARE</b> The Software may include software which is owned or controlled and provided by third parties (“Third Party Software”). Such Third Party Software may be subject to third party licenses.  You agree to acknowledge and comply with the terms and conditions of any applicable third party licenses.  BROADCOM is not responsible for the use of Third Party Software, whether or not it is included in or distributed with the Software.  If the Software contains Third Party Software, You can find a list of Third Party Software under the “About” item in the menu.</p>
-
-<p>3. <b>PROPRIETARY RIGHTS</b> The Software and the Documentation are the intellectual property of BROADCOM. BROADCOM or its licensors retain sole and exclusive ownership of the Software, Documentation and intellectual property rights relating thereto or arising therefrom. Except as provided in Section 1 above, You have no right, title or interest in the Software or the Documentation.  You hereby covenant that You will not assert any claim that the Software or Documentation (or any derivative works thereof created by or for BROADCOM) infringe any intellectual property right owned or controlled by You.</p>
-
-<p>4. <b>RESTRICTIONS</b> The Software is licensed, not sold. You may not use the Software for any purpose other than its intended purpose. You may not use the Software or Documentation in connection with the development of products competitive to BROADCOM’s products, including this Software, BROADCOM’s other software products or its integrated circuit products.  You may not attempt to obtain the source code for the Software (except for the source code provided) by any means, and You many not reverse engineer, decompile, disassemble, translate or similarly manipulate the Software, unless and only to the extent that applicable law in Your jurisdiction specifically gives You the right to do any of the foregoing in spite of this contractual prohibition.  Except as expressly permitted in Section 1, You may not publish, modify, create derivative works of, distribute, sell, assign, pledge, sublicense, lease, deliver or otherwise transfer the Software or any portion thereof in any form, and You may not cause or permit anyone else to do any of the foregoing. You may not alter, obscure, or remove any BROADCOM or third party trademark, trade name, logo, patent or copyright notice, or other notice or marking on the Software or Documentation or add any notices or markings to the Software or Documentation. Without limiting the foregoing restriction, except as otherwise permitted in Section 1, You may not provide access to others on a service bureau basis or otherwise. You shall not use the Software or other material provided in the Software in violation of any applicable law or regulation, including but not limited to any regulatory agency.  You may not use the Software in connection with any unauthorized snooping, hacking, intrusion or similar activities. This Agreement shall automatically terminate upon Your failure to comply with any of the terms of this Agreement. In such event, You will destroy all copies of the Software and Documentation.</p>
-
-<p>5. <b>DANGEROUS APPLICATIONS</b>  The Software is not designed, intended, or certified for use in components of systems intended for the operation of weapons, weapons systems, nuclear installations, means of mass transportation, aviation, medical devices, life-support computers or equipment (including resuscitation equipment and surgical implants), pollution control, hazardous substances management, safety or security equipment, or for any other uses or applications in which the failure of the Software could create a situation where personal injury or death may occur. You understand that use of the Software in such applications is fully at Your own risk and BROADCOM shall have no liability in respect thereof to You or any third party.</p>
-
-<p>6. <b>EXPORT COMPLIANCE</b> You hereby acknowledge that You are not a national of, nor located in, a country designated in Country Group E of Supplement Number 1 to Part 740 of the Export Administration Regulations, 15 CFR Parts 730-774 (“EAR”), which includes as of the date this license agreement was first published, but may not be limited to, Cuba, Iran, North Korea, Sudan, and Syria. Further, You acknowledge that these items were exported from the United States in accordance with the EAR. Diversion of these items contrary to U.S. law is prohibited and You agree that, notwithstanding other provisions of U.S. law, You acknowledge that transfer or re-export to any country, entity, or person subject to U.S. sanctions, a denial order, or identified in Country Group E, requires prior authorization from the U.S. Government.  Without limiting any other rights or remedies that BROADCOM may have, You agree to indemnify, defend and hold harmless BROADCOM and its affiliates, employees, directors, representatives and agents for any and all liabilities, losses, damages, costs and expenses (including attorneys’ fees and costs) arising from or relating to Your failure to comply with any such law or regulation or to obtain any such license, permit or approval.</p>
-
-<p>7. <b>LIMITED WARRANTY</b> THE SOFTWARE IS OFFERED “AS IS,” AND BROADCOM PROVIDES AND GRANTS AND YOU RECEIVE NO SUPPORT AND NO WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR CONDUCT WITH LICENSEE, OR OTHERWISE. BROADCOM SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A SPECIFIC PURPOSE, OR NONINFRINGEMENT CONCERNING THE SOFTWARE OR ANY UPGRADES TO OR DOCUMENTATION FOR THE SOFTWARE. WITHOUT LIMITATION OF THE ABOVE, BROADCOM GRANTS NO WARRANTY THAT THE SOFTWARE IS ERROR-FREE OR WILL OPERATE WITHOUT INTERRUPTION, AND GRANTS NO WARRANTY REGARDING ITS USE OR THE RESULTS THEREFROM INCLUDING, WITHOUT LIMITATION, ITS CORRECTNESS, ACCURACY, OR RELIABILITY.</p>
-
-<p>8. <b>LIMITATION ON LIABILITY</b> TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ANY OF ITS LICENSORS HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR OTHER DAMAGES, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER FOR BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, ARISING OUT OF THIS AGREEMENT OR USE, REPRODUCTION, OR DISTRIBUTION OF THE SOFTWARE, INCLUDING BUT NOT LIMITED TO LOSS OF DATA AND LOSS OF PROFITS, EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDYTO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW.  IF THE FOREGOING LIMITATION OF LIABILITY IS DEEMED INVALID FOR ANY REASON IN ANY JURISDICTION, THEN BROADCOM’S MAXIMUM AGGREGATE LIABILITY UNDER THIS AGREEMENT SHALL NOT EXCEED THE GREATER OF US$100 OR THE AMOUNT OF THE LICENSE FEE PAID BY YOU TO BROADCOM  FOR USE OF THE SOFTWARE.</p>
-
-<p>9. <b>INDEMNIFICATION</b> You agree to indemnify, defend and hold harmless BROADCOM and its affiliates, employees, directors, representatives and agents for any and all liabilities, losses, damages, costs and expenses (including attorneys’ fees and costs) arising from or relating to (1) Your use, reproduction or distribution of the Software or Documentation, (2) Your breach or non-compliance of any terms or conditions of this Agreement, (3) any warranties, liabilities or other obligations You make or incur to third parties or end users, or (4) allegations that Your use, reproduction or distribution of the Software or Documentation infringes the intellectual property rights of any third party; provided that the Indemnified Parties shall give You written notice of any such claim, suit or proceeding within a reasonable time and You shall be entitled to control the defense thereof.  Settlement of the indemnified matter shall require BROADCOM’s prior written consent, which consent shall not be unreasonably withheld or denied.</p>
-
-<p>10. <b>SUPPORT</b> Nothing in this Agreement shall obligate BROADCOM to provide any support for the Software. BROADCOM may, but shall be under no obligation to, correct any defects in the Software and/or provide updates or upgrades to the Software. You shall make reasonable efforts to promptly report to BROADCOM any defects You find in the Software. In the event that BROADCOM elects to provide such updates or upgrades to the Software and Documentation, such updated and upgrades shall be included within the definition of Software and Documentation and shall be provided subject to the rights and restrictions set forth in this Agreement. BROADCOM makes no representation or warranty that it support, or continue to support the Software and may cease distribution, maintenance, updates, upgrades and support of the Software at any time.</p>
-
-<p>11. <b>END USER SUPPORT</b>  You shall, at Your own expense, be solely responsible for providing technical support and training to Your customers and end users, and BROADCOM shall have no obligation with respect thereto. You shall be solely responsible for, and You shall ensure that BROADCOM has no obligation or liability to honor, any warranties that You provide to Your customers or end users with respect to the Software or Documentation.</p>
-
-<p>12. <b>CONFIDENTIALITY</b> The Software and Documentation contains proprietary and confidential technology and information of BROADCOM. Accordingly, during the term of this Agreement and thereafter, You must limit access to the Software and Documentation to those of Your employees who need to use the Software for purposes permitted hereunder, and You must treat the Software and Documentation as confidential and use the same care to protect it from unauthorized use, access or disclosure as You use to protect Your own confidential and proprietary information, but never less than the care a reasonable person would use under similar circumstances. Any breach of this Section 12 would cause irreparable injury to BROADCOM for which no adequate remedy at law exists. Therefore, in addition to any monetary damages or other remedies available to BROADCOM, You agree that equitable remedies, including injunctive relief and specific performance, are appropriate remedies to redress any breach or threatened breach of this Section.</p>
-
-<p>13. <b>TERMINATION</b> This Agreement shall terminate immediately without notice if You breach any term or condition of this Agreement.  You may terminate this Agreement at any time by destroying all copies of the Software and Documentation, and ceasing any use, reproduction or distribution of the Software and Documentation.  The following Sections shall survive any termination or expiration of this Agreement: Section 3-9 and 12-16, and any other terms and conditions which by their nature must survive termination.</p>
-
-<p>14. <b>U.S. GOVERNMENT RESTRICTED RIGHTS</b> The Software and Documentation are commercial products, developed at private expense, and provided with restricted rights. Use, reproduction, release, modification or disclosure of the Software or Documentation, or any part thereof, including technical data, by the Government is restricted in accordance with Federal Acquisition Regulation (“FAR”) 12.212 for civilian agencies and Defense (“DFARS”) 227.7202 for military agencies. The Software and Documentation are “commercial items,” as that term is defined in 48 C.F.R. 2.101, consisting of “commercial computer software” and “commercial computer software documentation,” as such terms are used in 48 C.F.R. 12.212. Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4, all U.S. Government End Users acquire Software and Documentation with only those rights set forth in this Agreement.</p>
-
-<p>15. <b>MISCELLANEOUS</b> This Agreement shall be governed by the laws of California without regard to any conflict-of-laws rules, and the United Nations Convention on Contracts for the International Sale of Goods is hereby excluded. The sole jurisdiction and venue for actions related to the subject matter hereof shall be the state and federal courts located in the County of Orange, California, USA and both parties hereby consent to such jurisdiction and exclusive venue. This Agreement shall inure to the benefit of BROADCOM, its successors, administrators, heirs and assigns. In any legal proceeding arising out of or regarding this Agreement, the prevailing party shall be entitled to receive, in addition to any other relief, reimbursement of its attorneys' fees and expenses and costs of suit. If one or more of the provisions contained in this Agreement shall be unenforceable, then such provision shall be considered inoperative to the extent of such enforceability and the remainder of this Agreement shall continue in full force and effect. The parties hereto agree to replace any such invalid or unenforceable provision with a new provision that has the most nearly similar permissible economic or other effect. You may not assign, delegate or otherwise transfer, whether by agreement, operation of law or otherwise, any right or obligation hereunder without the express prior written consent of BROADCOM, and any attempted assignment, delegation or transfer without such consent shall be void.  This Agreement supersedes all prior or contemporaneous proposals, representations, warranties, promises and other communications, whether oral or written, relating to the Software and Documentation. This Agreement may not be amended or modified, except by a formal written amendment signed by an authorized officer of each party. Any term or condition in any purchase order, invoice, e-mail or other document between You and BROADCOM will have no legal effect.</p>
-
+<b>IMPORTANT:</b> BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE APPLICATION (“SOFTWARE”), YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS LICENSE AGREEMENT (“AGREEMENT”). IF YOU DO NOT AGREE WITH THE TERMS OF THIS AGREEMENT, DO NOT DOWNLOAD, INSTALL OR USE THE SOFTWARE AND PROMPTLY DELETE THE SOFTWARE FROM YOUR COMPUTER OR DEVICE.  IF YOU AGREE WITH AND ACCEPT THE TERMS AND CONDITIONS OF THIS AGREEMENT, IT SHALL BECOME A LEGALLY BINDING AGREEMENT BETWEEN YOU AND BROADCOM CORPORATION (“BROADCOM”), AND YOU MAY PROCEED TO DOWNLOAD, INSTALL, AND USE THE SOFTWARE IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF THIS AGREEMENT.  WHERE WE REFER TO “YOU” IN THIS AGREEMENT, WE ARE REFERRING TO THE PARTY THAT HAS DOWNLOADED AND INSTALLED OR IS USING THE SOFTWARE.  IF AN INDIVIDUAL HAS DONE SO ON BEHALF OF A CORPORATION OR SIMILAR ENTITY, SUCH INDIVIDUAL REPRESENTS AND WARRANTS THAT HE OR HSE HAS THE LEGAL AUTHORITY TO AGREE TO ACT ON BEHALF OF SUCH ENTITY AND LEGALLY BIND SUCH ENTITY TO THIS AGREEMENT.  IN SUCH CASES, WHERE USED HEREIN, “YOU” SHALL REFER TO THE ENTITY.
+
+<p>1. <b>GRANT OF LICENSE</b> Subject to the terms and conditions of this Agreement, BROADCOM grants You a limited, revocable, non-exclusive, non-transferable personal license to use the Software and any accompanying documentation (“Documentation”) solely for Your individual use and for the intended purposes of the Software. You do not have the right to modify or create derivate works from the Software.  You do not have the right to sublicense the Software to third parties.</p>
+
+<p>2. <b>THIRD PARTY SOFTWARE</b> The Software may include software which is owned or controlled and provided by third parties (“Third Party Software”). Such Third Party Software may be subject to third party licenses.  You agree to acknowledge and comply with the terms and conditions of any applicable third party licenses.  BROADCOM is not responsible for the use of Third Party Software, whether or not it is included in or distributed with the Software.  If the Software contains Third Party Software, You can find a list of Third Party Software under the “About” item in the menu.</p>
+
+<p>3. <b>PROPRIETARY RIGHTS</b> The Software and the Documentation are the intellectual property of BROADCOM. BROADCOM or its licensors retain sole and exclusive ownership of the Software, Documentation and intellectual property rights relating thereto or arising therefrom. Except as provided in Section 1 above, You have no right, title or interest in the Software or the Documentation.  You hereby covenant that You will not assert any claim that the Software or Documentation (or any derivative works thereof created by or for BROADCOM) infringe any intellectual property right owned or controlled by You.</p>
+
+<p>4. <b>RESTRICTIONS</b> The Software is licensed, not sold. You may not use the Software for any purpose other than its intended purpose. You may not use the Software or Documentation in connection with the development of products competitive to BROADCOM’s products, including this Software, BROADCOM’s other software products or its integrated circuit products.  You may not attempt to obtain the source code for the Software (except for the source code provided) by any means, and You many not reverse engineer, decompile, disassemble, translate or similarly manipulate the Software, unless and only to the extent that applicable law in Your jurisdiction specifically gives You the right to do any of the foregoing in spite of this contractual prohibition.  Except as expressly permitted in Section 1, You may not publish, modify, create derivative works of, distribute, sell, assign, pledge, sublicense, lease, deliver or otherwise transfer the Software or any portion thereof in any form, and You may not cause or permit anyone else to do any of the foregoing. You may not alter, obscure, or remove any BROADCOM or third party trademark, trade name, logo, patent or copyright notice, or other notice or marking on the Software or Documentation or add any notices or markings to the Software or Documentation. Without limiting the foregoing restriction, except as otherwise permitted in Section 1, You may not provide access to others on a service bureau basis or otherwise. You shall not use the Software or other material provided in the Software in violation of any applicable law or regulation, including but not limited to any regulatory agency.  You may not use the Software in connection with any unauthorized snooping, hacking, intrusion or similar activities. This Agreement shall automatically terminate upon Your failure to comply with any of the terms of this Agreement. In such event, You will destroy all copies of the Software and Documentation.</p>
+
+<p>5. <b>DANGEROUS APPLICATIONS</b>  The Software is not designed, intended, or certified for use in components of systems intended for the operation of weapons, weapons systems, nuclear installations, means of mass transportation, aviation, medical devices, life-support computers or equipment (including resuscitation equipment and surgical implants), pollution control, hazardous substances management, safety or security equipment, or for any other uses or applications in which the failure of the Software could create a situation where personal injury or death may occur. You understand that use of the Software in such applications is fully at Your own risk and BROADCOM shall have no liability in respect thereof to You or any third party.</p>
+
+<p>6. <b>EXPORT COMPLIANCE</b> You hereby acknowledge that You are not a national of, nor located in, a country designated in Country Group E of Supplement Number 1 to Part 740 of the Export Administration Regulations, 15 CFR Parts 730-774 (“EAR”), which includes as of the date this license agreement was first published, but may not be limited to, Cuba, Iran, North Korea, Sudan, and Syria. Further, You acknowledge that these items were exported from the United States in accordance with the EAR. Diversion of these items contrary to U.S. law is prohibited and You agree that, notwithstanding other provisions of U.S. law, You acknowledge that transfer or re-export to any country, entity, or person subject to U.S. sanctions, a denial order, or identified in Country Group E, requires prior authorization from the U.S. Government.  Without limiting any other rights or remedies that BROADCOM may have, You agree to indemnify, defend and hold harmless BROADCOM and its affiliates, employees, directors, representatives and agents for any and all liabilities, losses, damages, costs and expenses (including attorneys’ fees and costs) arising from or relating to Your failure to comply with any such law or regulation or to obtain any such license, permit or approval.</p>
+
+<p>7. <b>LIMITED WARRANTY</b> THE SOFTWARE IS OFFERED “AS IS,” AND BROADCOM PROVIDES AND GRANTS AND YOU RECEIVE NO SUPPORT AND NO WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR CONDUCT WITH LICENSEE, OR OTHERWISE. BROADCOM SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A SPECIFIC PURPOSE, OR NONINFRINGEMENT CONCERNING THE SOFTWARE OR ANY UPGRADES TO OR DOCUMENTATION FOR THE SOFTWARE. WITHOUT LIMITATION OF THE ABOVE, BROADCOM GRANTS NO WARRANTY THAT THE SOFTWARE IS ERROR-FREE OR WILL OPERATE WITHOUT INTERRUPTION, AND GRANTS NO WARRANTY REGARDING ITS USE OR THE RESULTS THEREFROM INCLUDING, WITHOUT LIMITATION, ITS CORRECTNESS, ACCURACY, OR RELIABILITY.</p>
+
+<p>8. <b>LIMITATION ON LIABILITY</b> TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ANY OF ITS LICENSORS HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR OTHER DAMAGES, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER FOR BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR OTHERWISE, ARISING OUT OF THIS AGREEMENT OR USE, REPRODUCTION, OR DISTRIBUTION OF THE SOFTWARE, INCLUDING BUT NOT LIMITED TO LOSS OF DATA AND LOSS OF PROFITS, EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDYTO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW.  IF THE FOREGOING LIMITATION OF LIABILITY IS DEEMED INVALID FOR ANY REASON IN ANY JURISDICTION, THEN BROADCOM’S MAXIMUM AGGREGATE LIABILITY UNDER THIS AGREEMENT SHALL NOT EXCEED THE GREATER OF US$100 OR THE AMOUNT OF THE LICENSE FEE PAID BY YOU TO BROADCOM  FOR USE OF THE SOFTWARE.</p>
+
+<p>9. <b>INDEMNIFICATION</b> You agree to indemnify, defend and hold harmless BROADCOM and its affiliates, employees, directors, representatives and agents for any and all liabilities, losses, damages, costs and expenses (including attorneys’ fees and costs) arising from or relating to (1) Your use, reproduction or distribution of the Software or Documentation, (2) Your breach or non-compliance of any terms or conditions of this Agreement, (3) any warranties, liabilities or other obligations You make or incur to third parties or end users, or (4) allegations that Your use, reproduction or distribution of the Software or Documentation infringes the intellectual property rights of any third party; provided that the Indemnified Parties shall give You written notice of any such claim, suit or proceeding within a reasonable time and You shall be entitled to control the defense thereof.  Settlement of the indemnified matter shall require BROADCOM’s prior written consent, which consent shall not be unreasonably withheld or denied.</p>
+
+<p>10. <b>SUPPORT</b> Nothing in this Agreement shall obligate BROADCOM to provide any support for the Software. BROADCOM may, but shall be under no obligation to, correct any defects in the Software and/or provide updates or upgrades to the Software. You shall make reasonable efforts to promptly report to BROADCOM any defects You find in the Software. In the event that BROADCOM elects to provide such updates or upgrades to the Software and Documentation, such updated and upgrades shall be included within the definition of Software and Documentation and shall be provided subject to the rights and restrictions set forth in this Agreement. BROADCOM makes no representation or warranty that it support, or continue to support the Software and may cease distribution, maintenance, updates, upgrades and support of the Software at any time.</p>
+
+<p>11. <b>END USER SUPPORT</b>  You shall, at Your own expense, be solely responsible for providing technical support and training to Your customers and end users, and BROADCOM shall have no obligation with respect thereto. You shall be solely responsible for, and You shall ensure that BROADCOM has no obligation or liability to honor, any warranties that You provide to Your customers or end users with respect to the Software or Documentation.</p>
+
+<p>12. <b>CONFIDENTIALITY</b> The Software and Documentation contains proprietary and confidential technology and information of BROADCOM. Accordingly, during the term of this Agreement and thereafter, You must limit access to the Software and Documentation to those of Your employees who need to use the Software for purposes permitted hereunder, and You must treat the Software and Documentation as confidential and use the same care to protect it from unauthorized use, access or disclosure as You use to protect Your own confidential and proprietary information, but never less than the care a reasonable person would use under similar circumstances. Any breach of this Section 12 would cause irreparable injury to BROADCOM for which no adequate remedy at law exists. Therefore, in addition to any monetary damages or other remedies available to BROADCOM, You agree that equitable remedies, including injunctive relief and specific performance, are appropriate remedies to redress any breach or threatened breach of this Section.</p>
+
+<p>13. <b>TERMINATION</b> This Agreement shall terminate immediately without notice if You breach any term or condition of this Agreement.  You may terminate this Agreement at any time by destroying all copies of the Software and Documentation, and ceasing any use, reproduction or distribution of the Software and Documentation.  The following Sections shall survive any termination or expiration of this Agreement: Section 3-9 and 12-16, and any other terms and conditions which by their nature must survive termination.</p>
+
+<p>14. <b>U.S. GOVERNMENT RESTRICTED RIGHTS</b> The Software and Documentation are commercial products, developed at private expense, and provided with restricted rights. Use, reproduction, release, modification or disclosure of the Software or Documentation, or any part thereof, including technical data, by the Government is restricted in accordance with Federal Acquisition Regulation (“FAR”) 12.212 for civilian agencies and Defense (“DFARS”) 227.7202 for military agencies. The Software and Documentation are “commercial items,” as that term is defined in 48 C.F.R. 2.101, consisting of “commercial computer software” and “commercial computer software documentation,” as such terms are used in 48 C.F.R. 12.212. Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4, all U.S. Government End Users acquire Software and Documentation with only those rights set forth in this Agreement.</p>
+
+<p>15. <b>MISCELLANEOUS</b> This Agreement shall be governed by the laws of California without regard to any conflict-of-laws rules, and the United Nations Convention on Contracts for the International Sale of Goods is hereby excluded. The sole jurisdiction and venue for actions related to the subject matter hereof shall be the state and federal courts located in the County of Orange, California, USA and both parties hereby consent to such jurisdiction and exclusive venue. This Agreement shall inure to the benefit of BROADCOM, its successors, administrators, heirs and assigns. In any legal proceeding arising out of or regarding this Agreement, the prevailing party shall be entitled to receive, in addition to any other relief, reimbursement of its attorneys' fees and expenses and costs of suit. If one or more of the provisions contained in this Agreement shall be unenforceable, then such provision shall be considered inoperative to the extent of such enforceability and the remainder of this Agreement shall continue in full force and effect. The parties hereto agree to replace any such invalid or unenforceable provision with a new provision that has the most nearly similar permissible economic or other effect. You may not assign, delegate or otherwise transfer, whether by agreement, operation of law or otherwise, any right or obligation hereunder without the express prior written consent of BROADCOM, and any attempted assignment, delegation or transfer without such consent shall be void.  This Agreement supersedes all prior or contemporaneous proposals, representations, warranties, promises and other communications, whether oral or written, relating to the Software and Documentation. This Agreement may not be amended or modified, except by a formal written amendment signed by an authorized officer of each party. Any term or condition in any purchase order, invoice, e-mail or other document between You and BROADCOM will have no legal effect.</p>
+
 <p>16. <b>ACKNOWLEDGMENT</b> You acknowledge that You have read this Agreement, understand it, and agree to its terms and conditions. You also agree that this Agreement covers any merged or partial copies of the Software and Documentation, and all future versions thereof.</p>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DeviceAdapter.java b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DeviceAdapter.java
index a1b57d3ff4e3025b85ec667335c5b9dbf21753f2..af36752f99464ae5cdccaf0ed256c158e204514f 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DeviceAdapter.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DeviceAdapter.java
@@ -1,223 +1,223 @@
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.ledevicepicker;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application
- * Also, make sure you include the following resources
- * layout/devicepicker_activity.xml
- * layout/devicepicker_fragment.xml
- * layout/devicepicker_listitem.xml
- * values/strings_devicepicker.xml
- * values-v11/styles_devicepicker.xml
- * values-v14/styles_devicepicker.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import android.app.Activity;
-import android.bluetooth.BluetoothDevice;
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-/**
- * Helper class used by the device picker to render the state of the device
- *
- */
-class DeviceAdapter extends BaseAdapter {
-    class DeviceRecord {
-        public BluetoothDevice device;
-        public int rssi;
-        public Long last_scanned;
-        public int state;
-
-        public DeviceRecord(BluetoothDevice device, int rssi, int state) {
-            this.device = device;
-            this.rssi = rssi;
-            this.state = state;
-            last_scanned = System.currentTimeMillis() / 1000;
-        }
-    }
-
-    public static final int DEVICE_SOURCE_SCAN = 0;
-    public static final int DEVICE_SOURCE_BONDED = 1;
-    public static final int DEVICE_SOURCE_CONNECTED = 2;
-
-    public static final int STATE_BONDED = 1;
-    public static final int STATE_CONNECTED = 2;
-    public static final int STATE_NONE = 0;
-
-    private long mLastUpdate = 0;
-
-    private final Context mContext;
-    private final ArrayList<DeviceRecord> mDevices;
-    private final LayoutInflater mInflater;
-
-    public DeviceAdapter(Context context) {
-        mContext = context;
-
-        mInflater = LayoutInflater.from(context);
-        mDevices = new ArrayList<DeviceRecord>();
-    }
-
-    public void addDevice(BluetoothDevice device, int rssi, int state) {
-        synchronized (mDevices) {
-            for (DeviceRecord rec : mDevices) {
-                if (rec.device.equals(device)) {
-                    rec.rssi = rssi;
-                    rec.last_scanned = System.currentTimeMillis() / 1000;
-                    updateUi(false);
-                    return;
-                }
-            }
-
-            mDevices.add(new DeviceRecord(device, rssi, state));
-            updateUi(true);
-        }
-    }
-
-    public void removeDevice(BluetoothDevice device) {
-        synchronized (mDevices) {
-            for (DeviceRecord rec : mDevices) {
-                if (rec.device.equals(device)) {
-                    mDevices.remove(rec);
-                    updateUi(true);
-                    break;
-                }
-            }
-        }
-    }
-
-    public void clear() {
-        synchronized (mDevices) {
-            mDevices.clear();
-            updateUi(true);
-        }
-    }
-
-    public BluetoothDevice getDevice(int position) {
-        if (position < mDevices.size())
-            return mDevices.get(position).device;
-        return null;
-    }
-
-    public String getName(int position) {
-        if (position < mDevices.size())
-            return mDevices.get(position).device.getName();
-        return null;
-    }
-
-    public String getAddress(int position) {
-        if (position < mDevices.size())
-            return mDevices.get(position).device.getAddress();
-        return null;
-    }
-
-    @Override
-    public int getCount() {
-        return mDevices.size();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return mDevices.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        ViewHolder holder;
-
-        if (convertView == null || convertView.findViewById(R.id.device_name) == null) {
-            convertView = mInflater.inflate(R.layout.devicepicker_listitem, null);
-            holder = new ViewHolder();
-            holder.device_name = (TextView) convertView.findViewById(R.id.device_name);
-            holder.device_addr = (TextView) convertView.findViewById(R.id.device_addr);
-            holder.device_rssi = (ProgressBar) convertView.findViewById(R.id.device_rssi);
-            convertView.setTag(holder);
-        } else {
-            holder = (ViewHolder) convertView.getTag();
-        }
-
-        DeviceRecord rec = mDevices.get(position);
-        holder.device_rssi.setProgress(normaliseRssi(rec.rssi));
-
-        String deviceName = rec.device.getName();
-        if (deviceName != null && deviceName.length() > 0) {
-            holder.device_name.setText(rec.device.getName());
-            holder.device_addr.setText(rec.device.getAddress());
-        } else {
-            holder.device_name.setText(rec.device.getAddress());
-            holder.device_addr.setText(mContext.getResources().getString(R.string.unknown_device));
-        }
-
-        return convertView;
-    }
-
-    static class ViewHolder {
-        TextView device_name;
-        TextView device_addr;
-        ProgressBar device_rssi;
-    }
-
-    private void updateUi(boolean force) {
-        Long ts = System.currentTimeMillis() / 1000;
-        if (force || ((ts - mLastUpdate) >= 1)) {
-            removeOutdated();
-            ((Activity) mContext).runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    notifyDataSetChanged();
-                }
-            });
-        }
-
-        mLastUpdate = ts;
-    }
-
-    private void removeOutdated() {
-        Long ts = System.currentTimeMillis() / 1000;
-        synchronized (mDevices) {
-            for (Iterator<DeviceRecord> it = mDevices.iterator(); it.hasNext();) {
-                DeviceRecord rec = it.next();
-                if ((ts - rec.last_scanned) > 3 && rec.state == DEVICE_SOURCE_SCAN) {
-                    it.remove();
-                }
-            }
-        }
-    }
-
-    private int normaliseRssi(int rssi) {
-        // Expected input range is -127 -> 20
-        // Output range is 0 -> 100
-        final int RSSI_RANGE = 147;
-        final int RSSI_MAX = 20;
-
-        return (RSSI_RANGE + (rssi - RSSI_MAX)) * 100 / RSSI_RANGE;
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.ledevicepicker;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application
+ * Also, make sure you include the following resources
+ * layout/devicepicker_activity.xml
+ * layout/devicepicker_fragment.xml
+ * layout/devicepicker_listitem.xml
+ * values/strings_devicepicker.xml
+ * values-v11/styles_devicepicker.xml
+ * values-v14/styles_devicepicker.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import android.app.Activity;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+/**
+ * Helper class used by the device picker to render the state of the device
+ *
+ */
+class DeviceAdapter extends BaseAdapter {
+    class DeviceRecord {
+        public BluetoothDevice device;
+        public int rssi;
+        public Long last_scanned;
+        public int state;
+
+        public DeviceRecord(BluetoothDevice device, int rssi, int state) {
+            this.device = device;
+            this.rssi = rssi;
+            this.state = state;
+            last_scanned = System.currentTimeMillis() / 1000;
+        }
+    }
+
+    public static final int DEVICE_SOURCE_SCAN = 0;
+    public static final int DEVICE_SOURCE_BONDED = 1;
+    public static final int DEVICE_SOURCE_CONNECTED = 2;
+
+    public static final int STATE_BONDED = 1;
+    public static final int STATE_CONNECTED = 2;
+    public static final int STATE_NONE = 0;
+
+    private long mLastUpdate = 0;
+
+    private final Context mContext;
+    private final ArrayList<DeviceRecord> mDevices;
+    private final LayoutInflater mInflater;
+
+    public DeviceAdapter(Context context) {
+        mContext = context;
+
+        mInflater = LayoutInflater.from(context);
+        mDevices = new ArrayList<DeviceRecord>();
+    }
+
+    public void addDevice(BluetoothDevice device, int rssi, int state) {
+        synchronized (mDevices) {
+            for (DeviceRecord rec : mDevices) {
+                if (rec.device.equals(device)) {
+                    rec.rssi = rssi;
+                    rec.last_scanned = System.currentTimeMillis() / 1000;
+                    updateUi(false);
+                    return;
+                }
+            }
+
+            mDevices.add(new DeviceRecord(device, rssi, state));
+            updateUi(true);
+        }
+    }
+
+    public void removeDevice(BluetoothDevice device) {
+        synchronized (mDevices) {
+            for (DeviceRecord rec : mDevices) {
+                if (rec.device.equals(device)) {
+                    mDevices.remove(rec);
+                    updateUi(true);
+                    break;
+                }
+            }
+        }
+    }
+
+    public void clear() {
+        synchronized (mDevices) {
+            mDevices.clear();
+            updateUi(true);
+        }
+    }
+
+    public BluetoothDevice getDevice(int position) {
+        if (position < mDevices.size())
+            return mDevices.get(position).device;
+        return null;
+    }
+
+    public String getName(int position) {
+        if (position < mDevices.size())
+            return mDevices.get(position).device.getName();
+        return null;
+    }
+
+    public String getAddress(int position) {
+        if (position < mDevices.size())
+            return mDevices.get(position).device.getAddress();
+        return null;
+    }
+
+    @Override
+    public int getCount() {
+        return mDevices.size();
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return mDevices.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ViewHolder holder;
+
+        if (convertView == null || convertView.findViewById(R.id.device_name) == null) {
+            convertView = mInflater.inflate(R.layout.devicepicker_listitem, null);
+            holder = new ViewHolder();
+            holder.device_name = (TextView) convertView.findViewById(R.id.device_name);
+            holder.device_addr = (TextView) convertView.findViewById(R.id.device_addr);
+            holder.device_rssi = (ProgressBar) convertView.findViewById(R.id.device_rssi);
+            convertView.setTag(holder);
+        } else {
+            holder = (ViewHolder) convertView.getTag();
+        }
+
+        DeviceRecord rec = mDevices.get(position);
+        holder.device_rssi.setProgress(normaliseRssi(rec.rssi));
+
+        String deviceName = rec.device.getName();
+        if (deviceName != null && deviceName.length() > 0) {
+            holder.device_name.setText(rec.device.getName());
+            holder.device_addr.setText(rec.device.getAddress());
+        } else {
+            holder.device_name.setText(rec.device.getAddress());
+            holder.device_addr.setText(mContext.getResources().getString(R.string.unknown_device));
+        }
+
+        return convertView;
+    }
+
+    static class ViewHolder {
+        TextView device_name;
+        TextView device_addr;
+        ProgressBar device_rssi;
+    }
+
+    private void updateUi(boolean force) {
+        Long ts = System.currentTimeMillis() / 1000;
+        if (force || ((ts - mLastUpdate) >= 1)) {
+            removeOutdated();
+            ((Activity) mContext).runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    notifyDataSetChanged();
+                }
+            });
+        }
+
+        mLastUpdate = ts;
+    }
+
+    private void removeOutdated() {
+        Long ts = System.currentTimeMillis() / 1000;
+        synchronized (mDevices) {
+            for (Iterator<DeviceRecord> it = mDevices.iterator(); it.hasNext();) {
+                DeviceRecord rec = it.next();
+                if ((ts - rec.last_scanned) > 3 && rec.state == DEVICE_SOURCE_SCAN) {
+                    it.remove();
+                }
+            }
+        }
+    }
+
+    private int normaliseRssi(int rssi) {
+        // Expected input range is -127 -> 20
+        // Output range is 0 -> 100
+        final int RSSI_RANGE = 147;
+        final int RSSI_MAX = 20;
+
+        return (RSSI_RANGE + (rssi - RSSI_MAX)) * 100 / RSSI_RANGE;
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DeviceListFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DeviceListFragment.java
index b226c1fe85a9893c384354c34731eb8436000b8d..0b95d87cda445b05e03ede68ac808b6faba3bc45 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DeviceListFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DeviceListFragment.java
@@ -1,165 +1,165 @@
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.ledevicepicker;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-import android.app.Activity;
-import android.app.ListFragment;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.bluetooth.BluetoothProfile;
-import android.content.Context;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.ListView;
-
-/**
- * Displays a list of Bluetooth GATT device
- *
- */
-public class DeviceListFragment extends ListFragment implements BluetoothAdapter.LeScanCallback {
-    private static final String TAG = DevicePickerSettings.TAG_PREFIX + "DeviceListFragment";
-
-    public interface Callback {
-        public boolean canAddDevice(BluetoothDevice device);
-
-        public void onDevicePicked(BluetoothDevice device);
-
-        public void onError();
-    }
-
-    private DeviceAdapter mDeviceAdapter;
-    private BluetoothAdapter mBluetoothAdapter = null;
-    private Callback mCallback;
-
-    @Override
-    public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
-        getActivity().runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                if (mCallback != null && mCallback.canAddDevice(device)) {
-                    mDeviceAdapter.addDevice(device, rssi, DeviceAdapter.DEVICE_SOURCE_SCAN);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        Activity activity = getActivity();
-        mDeviceAdapter = new DeviceAdapter(activity);
-        setListAdapter(mDeviceAdapter);
-        BluetoothManager bluetoothManager = (BluetoothManager) activity
-                .getSystemService(Context.BLUETOOTH_SERVICE);
-        if (bluetoothManager == null) {
-            if (mCallback != null) {
-                mCallback.onError();
-                return;
-            }
-        }
-        mBluetoothAdapter = bluetoothManager.getAdapter();
-    }
-
-    @Override
-    public void onListItemClick(ListView list, View view, int position, long id) {
-        BluetoothDevice device = mDeviceAdapter.getDevice(position);
-        if (device != null && mCallback != null) {
-            mCallback.onDevicePicked(device);
-        }
-    }
-
-    UUID[] mServiceFilters;
-
-    public void setServiceFilter(String[] filters) {
-        if (filters == null || filters.length == 0) {
-            mServiceFilters = null;
-        } else {
-            ArrayList<UUID> f = new ArrayList<UUID>();
-            mServiceFilters = new UUID[filters.length];
-            for (int i = 0; i < mServiceFilters.length; i++) {
-                try {
-                    f.add(UUID.fromString(filters[i]));
-                } catch (Throwable t) {
-                    Log.e(TAG, "setServiceFilter: error", t);
-                }
-            }
-            if (f.size() == 0) {
-                mServiceFilters = null;
-            } else {
-                mServiceFilters = new UUID[f.size()];
-                f.toArray(mServiceFilters);
-            }
-        }
-    }
-
-    public void scan(boolean enable) {
-        if (mBluetoothAdapter == null)
-            return;
-
-        if (enable) {
-
-            addDevices();
-            if (mServiceFilters == null || mServiceFilters.length == 0) {
-                mBluetoothAdapter.startLeScan(this);
-            } else {
-                mBluetoothAdapter.startLeScan(mServiceFilters, this);
-            }
-        } else {
-            mBluetoothAdapter.stopLeScan(this);
-        }
-
-        getActivity().invalidateOptionsMenu();
-    }
-
-    private void addDevices() {
-        BluetoothManager btManager = null;
-
-        if (mBluetoothAdapter != null) {
-            btManager = (BluetoothManager) getActivity()
-                    .getSystemService(Context.BLUETOOTH_SERVICE);
-        }
-        if (btManager == null) {
-            if (mCallback != null) {
-                mCallback.onError();
-            }
-            return;
-        }
-
-        List<BluetoothDevice> devices = btManager.getDevicesMatchingConnectionStates(
-                BluetoothProfile.GATT_SERVER, new int[] { BluetoothProfile.STATE_CONNECTED,
-                        BluetoothProfile.STATE_DISCONNECTED });
-        for (BluetoothDevice device : devices) {
-            if (mCallback != null && mCallback.canAddDevice(device)) {
-                mDeviceAdapter.addDevice(device, 0, DeviceAdapter.DEVICE_SOURCE_CONNECTED);
-            }
-        }
-    }
-
-    // ---------------------Public APIs--------------------------
-
-    public void setCallback(Callback cb) {
-        mCallback = cb;
-    }
-
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.ledevicepicker;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import android.app.Activity;
+import android.app.ListFragment;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+/**
+ * Displays a list of Bluetooth GATT device
+ *
+ */
+public class DeviceListFragment extends ListFragment implements BluetoothAdapter.LeScanCallback {
+    private static final String TAG = DevicePickerSettings.TAG_PREFIX + "DeviceListFragment";
+
+    public interface Callback {
+        public boolean canAddDevice(BluetoothDevice device);
+
+        public void onDevicePicked(BluetoothDevice device);
+
+        public void onError();
+    }
+
+    private DeviceAdapter mDeviceAdapter;
+    private BluetoothAdapter mBluetoothAdapter = null;
+    private Callback mCallback;
+
+    @Override
+    public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                if (mCallback != null && mCallback.canAddDevice(device)) {
+                    mDeviceAdapter.addDevice(device, rssi, DeviceAdapter.DEVICE_SOURCE_SCAN);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Activity activity = getActivity();
+        mDeviceAdapter = new DeviceAdapter(activity);
+        setListAdapter(mDeviceAdapter);
+        BluetoothManager bluetoothManager = (BluetoothManager) activity
+                .getSystemService(Context.BLUETOOTH_SERVICE);
+        if (bluetoothManager == null) {
+            if (mCallback != null) {
+                mCallback.onError();
+                return;
+            }
+        }
+        mBluetoothAdapter = bluetoothManager.getAdapter();
+    }
+
+    @Override
+    public void onListItemClick(ListView list, View view, int position, long id) {
+        BluetoothDevice device = mDeviceAdapter.getDevice(position);
+        if (device != null && mCallback != null) {
+            mCallback.onDevicePicked(device);
+        }
+    }
+
+    UUID[] mServiceFilters;
+
+    public void setServiceFilter(String[] filters) {
+        if (filters == null || filters.length == 0) {
+            mServiceFilters = null;
+        } else {
+            ArrayList<UUID> f = new ArrayList<UUID>();
+            mServiceFilters = new UUID[filters.length];
+            for (int i = 0; i < mServiceFilters.length; i++) {
+                try {
+                    f.add(UUID.fromString(filters[i]));
+                } catch (Throwable t) {
+                    Log.e(TAG, "setServiceFilter: error", t);
+                }
+            }
+            if (f.size() == 0) {
+                mServiceFilters = null;
+            } else {
+                mServiceFilters = new UUID[f.size()];
+                f.toArray(mServiceFilters);
+            }
+        }
+    }
+
+    public void scan(boolean enable) {
+        if (mBluetoothAdapter == null)
+            return;
+
+        if (enable) {
+
+            addDevices();
+            if (mServiceFilters == null || mServiceFilters.length == 0) {
+                mBluetoothAdapter.startLeScan(this);
+            } else {
+                mBluetoothAdapter.startLeScan(mServiceFilters, this);
+            }
+        } else {
+            mBluetoothAdapter.stopLeScan(this);
+        }
+
+        getActivity().invalidateOptionsMenu();
+    }
+
+    private void addDevices() {
+        BluetoothManager btManager = null;
+
+        if (mBluetoothAdapter != null) {
+            btManager = (BluetoothManager) getActivity()
+                    .getSystemService(Context.BLUETOOTH_SERVICE);
+        }
+        if (btManager == null) {
+            if (mCallback != null) {
+                mCallback.onError();
+            }
+            return;
+        }
+
+        List<BluetoothDevice> devices = btManager.getDevicesMatchingConnectionStates(
+                BluetoothProfile.GATT_SERVER, new int[] { BluetoothProfile.STATE_CONNECTED,
+                        BluetoothProfile.STATE_DISCONNECTED });
+        for (BluetoothDevice device : devices) {
+            if (mCallback != null && mCallback.canAddDevice(device)) {
+                mDeviceAdapter.addDevice(device, 0, DeviceAdapter.DEVICE_SOURCE_CONNECTED);
+            }
+        }
+    }
+
+    // ---------------------Public APIs--------------------------
+
+    public void setCallback(Callback cb) {
+        mCallback = cb;
+    }
+
 }
\ No newline at end of file
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePicker.java b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePicker.java
index d7a56a4d7ec5c4a676674997a54594e1a7275979..c05d8826cddc7be327739ff23eb96a503e9f9685 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePicker.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePicker.java
@@ -1,315 +1,315 @@
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.ledevicepicker;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.PatternMatcher;
-import android.util.Log;
-
-/**
- * Helper class to show a device picker dialog and obtain the device selected by
- * the user.
- *
- *
- */
-public class DevicePicker {
-    private static final String TAG = DevicePickerSettings.TAG_PREFIX + "DevicePicker";
-
-    /*
-     * Intent action when someone wants to select a BLE device from a pick list
-     */
-    public static final String ACTION_LAUNCH = "com.broadcom.app.ledevicepicker.action.LAUNCH";
-    /**
-     * The target package to call when the device is picked
-     */
-
-    public static final String EXTRA_START_SCANNING = "START_SCANNING";
-
-    public static final String EXTRA_DATA = "DATA";
-
-    public static final String EXTRA_LAUNCH_PACKAGE = "LAUNCH_PACKAGE";
-    /**
-     * The target class to call when the device is picked
-     */
-    public static final String EXTRA_LAUNCH_CLASS = "LAUNCH_CLASS";
-
-    public static final String EXTRA_TITLE = "TITLE";
-
-    public static final String EXTRA_DEVICE_FILTERS = "DEVICE_FILTERS";
-
-    public static final String EXTRA_SERVICE_FILTERS = "SERVICE_FILTERS";
-    /**
-     * Broadcast intent when a BLE device is selected from the BLE device picker
-     * screen
-     */
-    public static final String ACTION_DEVICE_SELECTED = "com.broadcom.app.ledevicepicker.action.DEVICE_SELECTED";
-
-    public static final String ACTION_CANCELLED = "com.broadcom.app.ledevicepicker.action.CANCELED";
-    /**
-     * Extra field containing the picked BluetoothDevice
-     */
-    public static final String EXTRA_DEVICE = BluetoothDevice.EXTRA_DEVICE;
-
-    /**
-     * Callback to receive device picked event
-     *
-     * @author fredc
-     *
-     */
-    public interface Callback {
-        public void onDevicePicked(BluetoothDevice device);
-
-        public void onDevicePickCancelled();
-    }
-
-    public static Intent createLaunchIntent(String title, String launchAction, String packageName,
-            String className, String[] deviceFilters) {
-        Intent intent = new Intent(launchAction);
-        intent.putExtra(EXTRA_LAUNCH_PACKAGE, packageName);
-        intent.putExtra(EXTRA_LAUNCH_CLASS, className);
-        intent.putExtra(EXTRA_TITLE, title);
-        intent.putExtra(EXTRA_DEVICE_FILTERS, deviceFilters);
-        return intent;
-    }
-
-    /**
-     * Create a Device Picker Launch Intent
-     *
-     * @param title
-     * @param dataUri
-     * @return
-     */
-    public static Intent createLaunchIntent(String title, String launchAction, Uri dataUri,
-            String[] deviceFilters) {
-        Intent intent = new Intent(launchAction);
-        if (dataUri != null) {
-            intent.putExtra(EXTRA_DATA, dataUri.toString());
-        }
-        intent.putExtra(EXTRA_TITLE, title);
-        if (deviceFilters != null && deviceFilters.length > 0) {
-            intent.putExtra(EXTRA_DEVICE_FILTERS, deviceFilters);
-        }
-        return intent;
-    }
-
-    public static Intent createLaunchIntent(String title, String launchPackageName,
-            String launchClassName, String resultPackageName, String resultClassName,
-            String[] deviceFilters, String[] serviceUuids) {
-        Intent intent = new Intent();
-        intent.setClassName(launchPackageName, launchClassName);
-        intent.putExtra(EXTRA_LAUNCH_PACKAGE, resultPackageName);
-        intent.putExtra(EXTRA_LAUNCH_CLASS, resultClassName);
-        intent.putExtra(EXTRA_TITLE, title);
-        if (deviceFilters != null && deviceFilters.length > 0) {
-            intent.putExtra(EXTRA_DEVICE_FILTERS, deviceFilters);
-        }
-        if (serviceUuids != null && serviceUuids.length > 0) {
-            intent.putExtra(EXTRA_SERVICE_FILTERS, serviceUuids);
-        }
-        return intent;
-    }
-
-    /**
-     * Create a Device Picker Launch Intent
-     *
-     * @param title
-     * @param dataUri
-     * @return
-     */
-    public static Intent createLaunchIntent(String title, String launchPackageName,
-            String launchClassName, Uri dataUri, String[] deviceFilters, String[] serviceUuids) {
-        Intent intent = new Intent();
-        intent.setClassName(launchPackageName, launchClassName);
-        if (dataUri != null) {
-            intent.putExtra(EXTRA_DATA, dataUri.toString());
-        }
-        intent.putExtra(EXTRA_TITLE, title);
-        if (deviceFilters != null && deviceFilters.length > 0) {
-            intent.putExtra(EXTRA_DEVICE_FILTERS, deviceFilters);
-        }
-        if (serviceUuids != null && serviceUuids.length > 0) {
-            intent.putExtra(EXTRA_SERVICE_FILTERS, serviceUuids);
-        }
-
-        return intent;
-    }
-
-    /**
-     * Create a Device Picker Broadcast Receiver filter that filters for the
-     * data uri
-     *
-     * @param filterUri
-     * @return
-     */
-    public static IntentFilter createResultIntentFilter(Uri filterUri) {
-        IntentFilter filter = new IntentFilter(ACTION_DEVICE_SELECTED);
-        filter.addAction(ACTION_CANCELLED);
-        if (filterUri != null) {
-            String scheme = filterUri.getScheme();
-            String host = filterUri.getHost();
-            int port = filterUri.getPort();
-            String path = filterUri.getPath();
-            filter.addDataScheme(scheme);
-            filter.addDataAuthority(host, port == -1 ? null : String.valueOf(port));
-            if (path != null) {
-                filter.addDataPath(path, PatternMatcher.PATTERN_LITERAL);
-            }
-        }
-        return filter;
-    }
-
-    private final Context mCtx;
-    private final Uri mDevicePickerDataUri;
-    private final IntentFilter mDevicePickFilter;
-    private final Callback mCallback;
-    private final String mlaunchPackageName;
-    private final String mlaunchClassName;
-    private final String mBroadcastPackageName;
-    private final String mBroadcastClassName;
-    private final BroadcastReceiver mDevicePickerReceiver;
-
-    private class DevicePickerBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (mCallback != null) {
-                String action = intent.getAction();
-                if (ACTION_DEVICE_SELECTED.equals(action)) {
-                    final BluetoothDevice device = intent.getParcelableExtra(EXTRA_DEVICE);
-                    if (device != null) {
-                        try {
-                            mCallback.onDevicePicked(device);
-                        } catch (Throwable t) {
-                        }
-                        return;
-                    }
-
-                }
-                try {
-                    mCallback.onDevicePickCancelled();
-                } catch (Throwable t) {
-                }
-            }
-        }
-    };
-
-    /**
-     * Create a DevicePicker, and broadcast an intent to the specificed
-     * package/class receiver specified
-     *
-     * @param ctx
-     * @param broadcastPackageName
-     * @param broadcastClassName
-     */
-    public DevicePicker(Context ctx, String launchPackageName, String launchClassName,
-            String broadcastPackageName, String broadcastClassName) {
-        mCtx = ctx;
-        mlaunchPackageName = launchPackageName;
-        mlaunchClassName = launchClassName;
-        mDevicePickerDataUri = null;
-        mDevicePickFilter = createResultIntentFilter(null);
-        mCallback = null;
-        mDevicePickerReceiver = null;
-        mBroadcastPackageName = broadcastPackageName;
-        mBroadcastClassName = broadcastClassName;
-    }
-
-    /**
-     * Create a DevicePicker, automatically register a broadcast receiver, and
-     * invoke the callback when the device is picked
-     *
-     * @param ctx
-     * @param devicePickerDataFilterUri
-     * @param cb
-     */
-    public DevicePicker(Context ctx, String launchPackageName, String launchClassName, Callback cb,
-            Uri devicePickerDataFilterUri) {
-        mCtx = ctx;
-        mlaunchPackageName = launchPackageName;
-        mlaunchClassName = launchClassName;
-        mDevicePickerDataUri = devicePickerDataFilterUri;
-        mDevicePickFilter = createResultIntentFilter(mDevicePickerDataUri);
-        mCallback = cb;
-        mDevicePickerReceiver = new DevicePickerBroadcastReceiver();
-        mBroadcastPackageName = null;
-        mBroadcastClassName = null;
-    }
-
-    boolean mDevicePickerReceiverRegistered;
-
-    /**
-     * Initializes device picker resources
-     */
-    public boolean init() {
-        if (mCallback != null && !mDevicePickerReceiverRegistered) {
-            try {
-                mCtx.registerReceiver(mDevicePickerReceiver, mDevicePickFilter);
-                mDevicePickerReceiverRegistered = true;
-                return true;
-            } catch (Throwable t) {
-                Log.e(TAG, "init(): error", t);
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Cleanup device picker resources
-     */
-    public void cleanup() {
-        Log.d(TAG, "cleanup");
-        if (mDevicePickerReceiverRegistered) {
-            try {
-                mCtx.unregisterReceiver(mDevicePickerReceiver);
-                mDevicePickerReceiverRegistered = false;
-            } catch (Throwable t) {
-                Log.e(TAG, "init(): error", t);
-            }
-        }
-    }
-
-    /**
-     * Launches the device picker. Returns false if Bluetooth is not available
-     */
-    public boolean launch(String title, String[] deviceFilters, String[] serviceUuids) {
-        if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
-            return false;
-        }
-        Intent intent = null;
-        if (mCallback != null) {
-            intent = createLaunchIntent(title, mlaunchPackageName, mlaunchClassName,
-                    mDevicePickerDataUri, deviceFilters, serviceUuids);
-        } else {
-            intent = createLaunchIntent(title, mlaunchPackageName, mlaunchClassName,
-                    mBroadcastPackageName, mBroadcastClassName, deviceFilters, serviceUuids);
-        }
-        try {
-            mCtx.startActivity(intent);
-
-        } catch (Throwable t) {
-            Log.e(TAG, "launch(): error", t);
-        }
-        return false;
-    }
-
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.ledevicepicker;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.PatternMatcher;
+import android.util.Log;
+
+/**
+ * Helper class to show a device picker dialog and obtain the device selected by
+ * the user.
+ *
+ *
+ */
+public class DevicePicker {
+    private static final String TAG = DevicePickerSettings.TAG_PREFIX + "DevicePicker";
+
+    /*
+     * Intent action when someone wants to select a BLE device from a pick list
+     */
+    public static final String ACTION_LAUNCH = "com.broadcom.app.ledevicepicker.action.LAUNCH";
+    /**
+     * The target package to call when the device is picked
+     */
+
+    public static final String EXTRA_START_SCANNING = "START_SCANNING";
+
+    public static final String EXTRA_DATA = "DATA";
+
+    public static final String EXTRA_LAUNCH_PACKAGE = "LAUNCH_PACKAGE";
+    /**
+     * The target class to call when the device is picked
+     */
+    public static final String EXTRA_LAUNCH_CLASS = "LAUNCH_CLASS";
+
+    public static final String EXTRA_TITLE = "TITLE";
+
+    public static final String EXTRA_DEVICE_FILTERS = "DEVICE_FILTERS";
+
+    public static final String EXTRA_SERVICE_FILTERS = "SERVICE_FILTERS";
+    /**
+     * Broadcast intent when a BLE device is selected from the BLE device picker
+     * screen
+     */
+    public static final String ACTION_DEVICE_SELECTED = "com.broadcom.app.ledevicepicker.action.DEVICE_SELECTED";
+
+    public static final String ACTION_CANCELLED = "com.broadcom.app.ledevicepicker.action.CANCELED";
+    /**
+     * Extra field containing the picked BluetoothDevice
+     */
+    public static final String EXTRA_DEVICE = BluetoothDevice.EXTRA_DEVICE;
+
+    /**
+     * Callback to receive device picked event
+     *
+     * @author fredc
+     *
+     */
+    public interface Callback {
+        public void onDevicePicked(BluetoothDevice device);
+
+        public void onDevicePickCancelled();
+    }
+
+    public static Intent createLaunchIntent(String title, String launchAction, String packageName,
+            String className, String[] deviceFilters) {
+        Intent intent = new Intent(launchAction);
+        intent.putExtra(EXTRA_LAUNCH_PACKAGE, packageName);
+        intent.putExtra(EXTRA_LAUNCH_CLASS, className);
+        intent.putExtra(EXTRA_TITLE, title);
+        intent.putExtra(EXTRA_DEVICE_FILTERS, deviceFilters);
+        return intent;
+    }
+
+    /**
+     * Create a Device Picker Launch Intent
+     *
+     * @param title
+     * @param dataUri
+     * @return
+     */
+    public static Intent createLaunchIntent(String title, String launchAction, Uri dataUri,
+            String[] deviceFilters) {
+        Intent intent = new Intent(launchAction);
+        if (dataUri != null) {
+            intent.putExtra(EXTRA_DATA, dataUri.toString());
+        }
+        intent.putExtra(EXTRA_TITLE, title);
+        if (deviceFilters != null && deviceFilters.length > 0) {
+            intent.putExtra(EXTRA_DEVICE_FILTERS, deviceFilters);
+        }
+        return intent;
+    }
+
+    public static Intent createLaunchIntent(String title, String launchPackageName,
+            String launchClassName, String resultPackageName, String resultClassName,
+            String[] deviceFilters, String[] serviceUuids) {
+        Intent intent = new Intent();
+        intent.setClassName(launchPackageName, launchClassName);
+        intent.putExtra(EXTRA_LAUNCH_PACKAGE, resultPackageName);
+        intent.putExtra(EXTRA_LAUNCH_CLASS, resultClassName);
+        intent.putExtra(EXTRA_TITLE, title);
+        if (deviceFilters != null && deviceFilters.length > 0) {
+            intent.putExtra(EXTRA_DEVICE_FILTERS, deviceFilters);
+        }
+        if (serviceUuids != null && serviceUuids.length > 0) {
+            intent.putExtra(EXTRA_SERVICE_FILTERS, serviceUuids);
+        }
+        return intent;
+    }
+
+    /**
+     * Create a Device Picker Launch Intent
+     *
+     * @param title
+     * @param dataUri
+     * @return
+     */
+    public static Intent createLaunchIntent(String title, String launchPackageName,
+            String launchClassName, Uri dataUri, String[] deviceFilters, String[] serviceUuids) {
+        Intent intent = new Intent();
+        intent.setClassName(launchPackageName, launchClassName);
+        if (dataUri != null) {
+            intent.putExtra(EXTRA_DATA, dataUri.toString());
+        }
+        intent.putExtra(EXTRA_TITLE, title);
+        if (deviceFilters != null && deviceFilters.length > 0) {
+            intent.putExtra(EXTRA_DEVICE_FILTERS, deviceFilters);
+        }
+        if (serviceUuids != null && serviceUuids.length > 0) {
+            intent.putExtra(EXTRA_SERVICE_FILTERS, serviceUuids);
+        }
+
+        return intent;
+    }
+
+    /**
+     * Create a Device Picker Broadcast Receiver filter that filters for the
+     * data uri
+     *
+     * @param filterUri
+     * @return
+     */
+    public static IntentFilter createResultIntentFilter(Uri filterUri) {
+        IntentFilter filter = new IntentFilter(ACTION_DEVICE_SELECTED);
+        filter.addAction(ACTION_CANCELLED);
+        if (filterUri != null) {
+            String scheme = filterUri.getScheme();
+            String host = filterUri.getHost();
+            int port = filterUri.getPort();
+            String path = filterUri.getPath();
+            filter.addDataScheme(scheme);
+            filter.addDataAuthority(host, port == -1 ? null : String.valueOf(port));
+            if (path != null) {
+                filter.addDataPath(path, PatternMatcher.PATTERN_LITERAL);
+            }
+        }
+        return filter;
+    }
+
+    private final Context mCtx;
+    private final Uri mDevicePickerDataUri;
+    private final IntentFilter mDevicePickFilter;
+    private final Callback mCallback;
+    private final String mlaunchPackageName;
+    private final String mlaunchClassName;
+    private final String mBroadcastPackageName;
+    private final String mBroadcastClassName;
+    private final BroadcastReceiver mDevicePickerReceiver;
+
+    private class DevicePickerBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (mCallback != null) {
+                String action = intent.getAction();
+                if (ACTION_DEVICE_SELECTED.equals(action)) {
+                    final BluetoothDevice device = intent.getParcelableExtra(EXTRA_DEVICE);
+                    if (device != null) {
+                        try {
+                            mCallback.onDevicePicked(device);
+                        } catch (Throwable t) {
+                        }
+                        return;
+                    }
+
+                }
+                try {
+                    mCallback.onDevicePickCancelled();
+                } catch (Throwable t) {
+                }
+            }
+        }
+    };
+
+    /**
+     * Create a DevicePicker, and broadcast an intent to the specificed
+     * package/class receiver specified
+     *
+     * @param ctx
+     * @param broadcastPackageName
+     * @param broadcastClassName
+     */
+    public DevicePicker(Context ctx, String launchPackageName, String launchClassName,
+            String broadcastPackageName, String broadcastClassName) {
+        mCtx = ctx;
+        mlaunchPackageName = launchPackageName;
+        mlaunchClassName = launchClassName;
+        mDevicePickerDataUri = null;
+        mDevicePickFilter = createResultIntentFilter(null);
+        mCallback = null;
+        mDevicePickerReceiver = null;
+        mBroadcastPackageName = broadcastPackageName;
+        mBroadcastClassName = broadcastClassName;
+    }
+
+    /**
+     * Create a DevicePicker, automatically register a broadcast receiver, and
+     * invoke the callback when the device is picked
+     *
+     * @param ctx
+     * @param devicePickerDataFilterUri
+     * @param cb
+     */
+    public DevicePicker(Context ctx, String launchPackageName, String launchClassName, Callback cb,
+            Uri devicePickerDataFilterUri) {
+        mCtx = ctx;
+        mlaunchPackageName = launchPackageName;
+        mlaunchClassName = launchClassName;
+        mDevicePickerDataUri = devicePickerDataFilterUri;
+        mDevicePickFilter = createResultIntentFilter(mDevicePickerDataUri);
+        mCallback = cb;
+        mDevicePickerReceiver = new DevicePickerBroadcastReceiver();
+        mBroadcastPackageName = null;
+        mBroadcastClassName = null;
+    }
+
+    boolean mDevicePickerReceiverRegistered;
+
+    /**
+     * Initializes device picker resources
+     */
+    public boolean init() {
+        if (mCallback != null && !mDevicePickerReceiverRegistered) {
+            try {
+                mCtx.registerReceiver(mDevicePickerReceiver, mDevicePickFilter);
+                mDevicePickerReceiverRegistered = true;
+                return true;
+            } catch (Throwable t) {
+                Log.e(TAG, "init(): error", t);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Cleanup device picker resources
+     */
+    public void cleanup() {
+        Log.d(TAG, "cleanup");
+        if (mDevicePickerReceiverRegistered) {
+            try {
+                mCtx.unregisterReceiver(mDevicePickerReceiver);
+                mDevicePickerReceiverRegistered = false;
+            } catch (Throwable t) {
+                Log.e(TAG, "init(): error", t);
+            }
+        }
+    }
+
+    /**
+     * Launches the device picker. Returns false if Bluetooth is not available
+     */
+    public boolean launch(String title, String[] deviceFilters, String[] serviceUuids) {
+        if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
+            return false;
+        }
+        Intent intent = null;
+        if (mCallback != null) {
+            intent = createLaunchIntent(title, mlaunchPackageName, mlaunchClassName,
+                    mDevicePickerDataUri, deviceFilters, serviceUuids);
+        } else {
+            intent = createLaunchIntent(title, mlaunchPackageName, mlaunchClassName,
+                    mBroadcastPackageName, mBroadcastClassName, deviceFilters, serviceUuids);
+        }
+        try {
+            mCtx.startActivity(intent);
+
+        } catch (Throwable t) {
+            Log.e(TAG, "launch(): error", t);
+        }
+        return false;
+    }
+
 }
\ No newline at end of file
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerActivity.java b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerActivity.java
index 5daa7d28727f18f987eb9543a624ec5f7221bd8d..5bf9f1c70f32a738b5176c952196f08d73441afa 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerActivity.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerActivity.java
@@ -1,204 +1,204 @@
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.ledevicepicker;
-/**
- * NOTE: replace "R.class" with your R.class declared in your application
- * Also, make sure you include the following resources
- * layout/devicepicker_activity.xml
- * layout/devicepicker_fragment.xml
- * layout/devicepicker_listitem.xml
- * values/strings_devicepicker.xml
- * values-v11/styles_devicepicker.xml
- * values-v14/styles_devicepicker.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import com.broadcom.app.ledevicepicker.DevicePicker;
-import android.app.Activity;
-import android.bluetooth.BluetoothDevice;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.Toast;
-
-/**
- * Container activity used to display the device picker
- * @author fredc
- *
- */
-public class DevicePickerActivity extends Activity implements DeviceListFragment.Callback,
-        OnClickListener {
-    private static final String TAG = DevicePickerSettings.TAG_PREFIX + "DevicePickerActivity";
-
-    private String mDataUri;
-    private String mLaunchPackage;
-    private String mLaunchClass;
-    private String mTitle;
-    private Button mScanButton;
-    private boolean mIsScanning;
-    private boolean mStartScanning;
-    private DeviceListFragment mDevicePickerFragment;
-    private String[] mDeviceFilters;
-    private String[] mServiceFilters;
-    private boolean mDevicePicked;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.devicepicker_activity);
-        Intent intent = getIntent();
-        mDataUri = intent.getStringExtra(DevicePicker.EXTRA_DATA);
-        mLaunchPackage = intent.getStringExtra(DevicePicker.EXTRA_LAUNCH_PACKAGE);
-        mLaunchClass = intent.getStringExtra(DevicePicker.EXTRA_LAUNCH_CLASS);
-        mTitle = intent.getStringExtra(DevicePicker.EXTRA_TITLE);
-        mStartScanning = intent.getBooleanExtra(DevicePicker.EXTRA_START_SCANNING, true);
-        mDeviceFilters = intent.getStringArrayExtra(DevicePicker.EXTRA_DEVICE_FILTERS);
-        mServiceFilters = intent.getStringArrayExtra(DevicePicker.EXTRA_SERVICE_FILTERS);
-
-        if (mTitle != null) {
-            setTitle(mTitle);
-        } else {
-            setTitle(R.string.default_title);
-        }
-
-        mDevicePickerFragment = (DeviceListFragment) getFragmentManager().findFragmentByTag(
-                "device_picker_id");
-        if (mDevicePickerFragment != null) {
-            mDevicePickerFragment.setCallback(this);
-            mDevicePickerFragment.setServiceFilter(mServiceFilters);
-        }
-
-        mScanButton = (Button) findViewById(R.id.scan_button);
-        mScanButton.setOnClickListener(this);
-
-    }
-
-    private void setScanState(boolean isScanning) {
-        if (isScanning) {
-            mScanButton.setText(R.string.menu_stop);
-        } else {
-            mScanButton.setText(R.string.menu_scan);
-        }
-        mIsScanning = isScanning;
-
-    }
-
-    @Override
-    protected void onResume() {
-        if (mStartScanning) {
-            mStartScanning = false;
-            setScanState(true);
-            mDevicePickerFragment.scan(true);
-        } else {
-            setScanState(false);
-        }
-        super.onResume();
-    }
-
-    @Override
-    protected void onPause() {
-        if (mIsScanning) {
-            mDevicePickerFragment.scan(false);
-            mIsScanning = false;
-        }
-        super.onPause();
-    }
-
-    @Override
-    protected void onDestroy() {
-        if (!mDevicePicked) {
-            Intent intent = new Intent();
-            intent.setAction(DevicePicker.ACTION_CANCELLED);
-            if (mDataUri != null) {
-                Uri uri = null;
-                try {
-                    uri = Uri.parse(mDataUri);
-                } catch (Exception e) {
-                    Log.e(TAG, "Error parsing uri", e);
-                }
-                if (uri != null) {
-                    intent.setData(uri);
-                }
-            }
-            sendBroadcast(intent);
-        }
-        super.onDestroy();
-    }
-
-
-    @Override
-    public void onDevicePicked(BluetoothDevice device) {
-        if (device != null) {
-            mDevicePicked = true;
-            Intent intent = new Intent();
-            intent.setAction(DevicePicker.ACTION_DEVICE_SELECTED);
-            intent.putExtra(DevicePicker.EXTRA_DEVICE, device);
-
-            if (mLaunchPackage != null && mLaunchClass != null) {
-                intent.setClassName(mLaunchPackage, mLaunchClass);
-            }
-            if (mDataUri != null) {
-                Uri uri = null;
-                try {
-                    uri = Uri.parse(mDataUri);
-                } catch (Exception e) {
-                    Log.e(TAG, "Error parsing uri", e);
-                }
-                if (uri != null) {
-                    intent.setData(uri);
-                }
-            }
-            finish();
-            sendBroadcast(intent);
-        }
-
-    }
-
-    @Override
-    public void onError() {
-        Toast.makeText(getApplicationContext(), R.string.error_internal, Toast.LENGTH_SHORT).show();
-        finish();
-    }
-
-    @Override
-    public void onClick(View v) {
-        boolean isScanning = !mIsScanning;
-        setScanState(isScanning);
-        mDevicePickerFragment.scan(isScanning);
-    }
-
-    @Override
-    public boolean canAddDevice(BluetoothDevice device) {
-        if (mDeviceFilters == null || mDeviceFilters.length == 0) {
-            return true;
-        }
-        String address = device.getAddress();
-        for (int i = 0; i < mDeviceFilters.length; i++) {
-            if (mDeviceFilters[i].equals(address)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.ledevicepicker;
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application
+ * Also, make sure you include the following resources
+ * layout/devicepicker_activity.xml
+ * layout/devicepicker_fragment.xml
+ * layout/devicepicker_listitem.xml
+ * values/strings_devicepicker.xml
+ * values-v11/styles_devicepicker.xml
+ * values-v14/styles_devicepicker.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import com.broadcom.app.ledevicepicker.DevicePicker;
+import android.app.Activity;
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+/**
+ * Container activity used to display the device picker
+ * @author fredc
+ *
+ */
+public class DevicePickerActivity extends Activity implements DeviceListFragment.Callback,
+        OnClickListener {
+    private static final String TAG = DevicePickerSettings.TAG_PREFIX + "DevicePickerActivity";
+
+    private String mDataUri;
+    private String mLaunchPackage;
+    private String mLaunchClass;
+    private String mTitle;
+    private Button mScanButton;
+    private boolean mIsScanning;
+    private boolean mStartScanning;
+    private DeviceListFragment mDevicePickerFragment;
+    private String[] mDeviceFilters;
+    private String[] mServiceFilters;
+    private boolean mDevicePicked;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.devicepicker_activity);
+        Intent intent = getIntent();
+        mDataUri = intent.getStringExtra(DevicePicker.EXTRA_DATA);
+        mLaunchPackage = intent.getStringExtra(DevicePicker.EXTRA_LAUNCH_PACKAGE);
+        mLaunchClass = intent.getStringExtra(DevicePicker.EXTRA_LAUNCH_CLASS);
+        mTitle = intent.getStringExtra(DevicePicker.EXTRA_TITLE);
+        mStartScanning = intent.getBooleanExtra(DevicePicker.EXTRA_START_SCANNING, true);
+        mDeviceFilters = intent.getStringArrayExtra(DevicePicker.EXTRA_DEVICE_FILTERS);
+        mServiceFilters = intent.getStringArrayExtra(DevicePicker.EXTRA_SERVICE_FILTERS);
+
+        if (mTitle != null) {
+            setTitle(mTitle);
+        } else {
+            setTitle(R.string.default_title);
+        }
+
+        mDevicePickerFragment = (DeviceListFragment) getFragmentManager().findFragmentByTag(
+                "device_picker_id");
+        if (mDevicePickerFragment != null) {
+            mDevicePickerFragment.setCallback(this);
+            mDevicePickerFragment.setServiceFilter(mServiceFilters);
+        }
+
+        mScanButton = (Button) findViewById(R.id.scan_button);
+        mScanButton.setOnClickListener(this);
+
+    }
+
+    private void setScanState(boolean isScanning) {
+        if (isScanning) {
+            mScanButton.setText(R.string.menu_stop);
+        } else {
+            mScanButton.setText(R.string.menu_scan);
+        }
+        mIsScanning = isScanning;
+
+    }
+
+    @Override
+    protected void onResume() {
+        if (mStartScanning) {
+            mStartScanning = false;
+            setScanState(true);
+            mDevicePickerFragment.scan(true);
+        } else {
+            setScanState(false);
+        }
+        super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        if (mIsScanning) {
+            mDevicePickerFragment.scan(false);
+            mIsScanning = false;
+        }
+        super.onPause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (!mDevicePicked) {
+            Intent intent = new Intent();
+            intent.setAction(DevicePicker.ACTION_CANCELLED);
+            if (mDataUri != null) {
+                Uri uri = null;
+                try {
+                    uri = Uri.parse(mDataUri);
+                } catch (Exception e) {
+                    Log.e(TAG, "Error parsing uri", e);
+                }
+                if (uri != null) {
+                    intent.setData(uri);
+                }
+            }
+            sendBroadcast(intent);
+        }
+        super.onDestroy();
+    }
+
+
+    @Override
+    public void onDevicePicked(BluetoothDevice device) {
+        if (device != null) {
+            mDevicePicked = true;
+            Intent intent = new Intent();
+            intent.setAction(DevicePicker.ACTION_DEVICE_SELECTED);
+            intent.putExtra(DevicePicker.EXTRA_DEVICE, device);
+
+            if (mLaunchPackage != null && mLaunchClass != null) {
+                intent.setClassName(mLaunchPackage, mLaunchClass);
+            }
+            if (mDataUri != null) {
+                Uri uri = null;
+                try {
+                    uri = Uri.parse(mDataUri);
+                } catch (Exception e) {
+                    Log.e(TAG, "Error parsing uri", e);
+                }
+                if (uri != null) {
+                    intent.setData(uri);
+                }
+            }
+            finish();
+            sendBroadcast(intent);
+        }
+
+    }
+
+    @Override
+    public void onError() {
+        Toast.makeText(getApplicationContext(), R.string.error_internal, Toast.LENGTH_SHORT).show();
+        finish();
+    }
+
+    @Override
+    public void onClick(View v) {
+        boolean isScanning = !mIsScanning;
+        setScanState(isScanning);
+        mDevicePickerFragment.scan(isScanning);
+    }
+
+    @Override
+    public boolean canAddDevice(BluetoothDevice device) {
+        if (mDeviceFilters == null || mDeviceFilters.length == 0) {
+            return true;
+        }
+        String address = device.getAddress();
+        for (int i = 0; i < mDeviceFilters.length; i++) {
+            if (mDeviceFilters[i].equals(address)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerFragment.java
index 41c64f53ee85a598b52f83c27aa64161804f1735..1990bcb486fc6d63e8ccf4af7c89257d15216a2e 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerFragment.java
@@ -1,158 +1,158 @@
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.ledevicepicker;
-/**
- * NOTE: replace "R.class" with your R.class declared in your application
- * Also, make sure you include the following resources
- * layout/devicepicker_activity.xml
- * layout/devicepicker_fragment.xml
- * layout/devicepicker_listitem.xml
- * values/strings_devicepicker.xml
- * values-v11/styles_devicepicker.xml
- * values-v14/styles_devicepicker.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import com.broadcom.app.ledevicepicker.DeviceListFragment;
-import com.broadcom.app.ledevicepicker.DeviceListFragment.Callback;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.bluetooth.BluetoothDevice;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnShowListener;
-import android.view.View.OnClickListener;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-
-/**
- * Not used
- *
- * @deprecated
- * @author fredc
- *
- */
-@Deprecated
-public class DevicePickerFragment extends DialogFragment implements OnClickListener,
-        OnShowListener, Callback {
-    private String mTitle;
-    private Button mScanButton;
-    private boolean mIsScanning;
-    private boolean mStartScanning;
-    private DeviceListFragment mDevicePickerFragment;
-    private String[] mDeviceFilters;
-    private String[] mServiceFilters;
-
-    // private boolean mDevicePicked;
-
-    public static DevicePickerFragment createDialog(String title, String[] deviceFilters,
-            String[] serviceFilters, boolean startScanning) {
-        DevicePickerFragment f = new DevicePickerFragment();
-        f.mTitle = title;
-        f.mDeviceFilters = deviceFilters;
-        f.mServiceFilters = serviceFilters;
-        f.mStartScanning = startScanning;
-        return f;
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        Log.d("DevicePickerFragment", "onCreateDialog()");
-        AlertDialog.Builder b = new AlertDialog.Builder(getActivity(),
-                R.style.DevicePickerDialogTheme);
-        b.setTitle(mTitle == null ? getString(R.string.devicepicker_pick) : mTitle)
-                .setPositiveButton(R.string.menu_scan, null);
-        View v = getActivity().getLayoutInflater().inflate(R.layout.devicepicker_fragment, null);
-        b.setView(v);
-        AlertDialog d = b.create();
-        d.setOnShowListener(this);
-
-        return d;
-    }
-
-    @Override
-    public void onShow(DialogInterface dialog) {
-        mScanButton = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
-        mScanButton.setOnClickListener(this);
-        mDevicePickerFragment = (DeviceListFragment) getFragmentManager().findFragmentById(
-                R.id.device_picker_id);
-        if (mDevicePickerFragment != null) {
-            mDevicePickerFragment.setCallback(this);
-            mDevicePickerFragment.setServiceFilter(mServiceFilters);
-        }
-
-        Log.d("Wiced", "Fragment =" + mDevicePickerFragment);
-        if (mStartScanning) {
-            mStartScanning = false;
-            setScanState(true);
-            if (mDevicePickerFragment != null) {
-                mDevicePickerFragment.scan(true);
-            }
-        } else {
-            setScanState(false);
-        }
-    }
-
-    @Override
-    public void onClick(View v) {
-        boolean isScanning = !mIsScanning;
-        setScanState(isScanning);
-        if (mDevicePickerFragment != null) {
-            mDevicePickerFragment.scan(isScanning);
-        }
-    }
-
-    public void setScanState(boolean isScanning) {
-        if (mScanButton != null) {
-            if (isScanning) {
-                mScanButton.setText(R.string.menu_stop);
-            } else {
-                mScanButton.setText(R.string.menu_scan);
-            }
-            mIsScanning = isScanning;
-        }
-    }
-
-    @Override
-    public boolean canAddDevice(BluetoothDevice device) {
-        if (mDeviceFilters == null || mDeviceFilters.length == 0) {
-            return true;
-        }
-        String address = device.getAddress();
-        for (int i = 0; i < mDeviceFilters.length; i++) {
-            if (mDeviceFilters[i].equals(address)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void onDevicePicked(BluetoothDevice device) {
-
-    }
-
-    @Override
-    public void onError() {
-        // TODO Auto-generated method stub
-
-    }
-
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.ledevicepicker;
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application
+ * Also, make sure you include the following resources
+ * layout/devicepicker_activity.xml
+ * layout/devicepicker_fragment.xml
+ * layout/devicepicker_listitem.xml
+ * values/strings_devicepicker.xml
+ * values-v11/styles_devicepicker.xml
+ * values-v14/styles_devicepicker.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import com.broadcom.app.ledevicepicker.DeviceListFragment;
+import com.broadcom.app.ledevicepicker.DeviceListFragment.Callback;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.bluetooth.BluetoothDevice;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnShowListener;
+import android.view.View.OnClickListener;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+
+/**
+ * Not used
+ *
+ * @deprecated
+ * @author fredc
+ *
+ */
+@Deprecated
+public class DevicePickerFragment extends DialogFragment implements OnClickListener,
+        OnShowListener, Callback {
+    private String mTitle;
+    private Button mScanButton;
+    private boolean mIsScanning;
+    private boolean mStartScanning;
+    private DeviceListFragment mDevicePickerFragment;
+    private String[] mDeviceFilters;
+    private String[] mServiceFilters;
+
+    // private boolean mDevicePicked;
+
+    public static DevicePickerFragment createDialog(String title, String[] deviceFilters,
+            String[] serviceFilters, boolean startScanning) {
+        DevicePickerFragment f = new DevicePickerFragment();
+        f.mTitle = title;
+        f.mDeviceFilters = deviceFilters;
+        f.mServiceFilters = serviceFilters;
+        f.mStartScanning = startScanning;
+        return f;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Log.d("DevicePickerFragment", "onCreateDialog()");
+        AlertDialog.Builder b = new AlertDialog.Builder(getActivity(),
+                R.style.DevicePickerDialogTheme);
+        b.setTitle(mTitle == null ? getString(R.string.devicepicker_pick) : mTitle)
+                .setPositiveButton(R.string.menu_scan, null);
+        View v = getActivity().getLayoutInflater().inflate(R.layout.devicepicker_fragment, null);
+        b.setView(v);
+        AlertDialog d = b.create();
+        d.setOnShowListener(this);
+
+        return d;
+    }
+
+    @Override
+    public void onShow(DialogInterface dialog) {
+        mScanButton = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
+        mScanButton.setOnClickListener(this);
+        mDevicePickerFragment = (DeviceListFragment) getFragmentManager().findFragmentById(
+                R.id.device_picker_id);
+        if (mDevicePickerFragment != null) {
+            mDevicePickerFragment.setCallback(this);
+            mDevicePickerFragment.setServiceFilter(mServiceFilters);
+        }
+
+        Log.d("Wiced", "Fragment =" + mDevicePickerFragment);
+        if (mStartScanning) {
+            mStartScanning = false;
+            setScanState(true);
+            if (mDevicePickerFragment != null) {
+                mDevicePickerFragment.scan(true);
+            }
+        } else {
+            setScanState(false);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        boolean isScanning = !mIsScanning;
+        setScanState(isScanning);
+        if (mDevicePickerFragment != null) {
+            mDevicePickerFragment.scan(isScanning);
+        }
+    }
+
+    public void setScanState(boolean isScanning) {
+        if (mScanButton != null) {
+            if (isScanning) {
+                mScanButton.setText(R.string.menu_stop);
+            } else {
+                mScanButton.setText(R.string.menu_scan);
+            }
+            mIsScanning = isScanning;
+        }
+    }
+
+    @Override
+    public boolean canAddDevice(BluetoothDevice device) {
+        if (mDeviceFilters == null || mDeviceFilters.length == 0) {
+            return true;
+        }
+        String address = device.getAddress();
+        for (int i = 0; i < mDeviceFilters.length; i++) {
+            if (mDeviceFilters[i].equals(address)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void onDevicePicked(BluetoothDevice device) {
+
+    }
+
+    @Override
+    public void onError() {
+        // TODO Auto-generated method stub
+
+    }
+
 }
\ No newline at end of file
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerSettings.java b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerSettings.java
index 244fdb3b9643e2b228959f1cce035677c321ba78..ffb285995a025c366527e22e1eb3b2e6ec539673 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerSettings.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/ledevicepicker/DevicePickerSettings.java
@@ -1,28 +1,28 @@
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.ledevicepicker;
-
-/**
- * Configurable settings for the device picker
- * @author fredc
- *
- */
-class DevicePickerSettings {
-    static final String TAG_PREFIX="DevicePicker.";
-    static final boolean DBG= false;
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.ledevicepicker;
+
+/**
+ * Configurable settings for the device picker
+ * @author fredc
+ *
+ */
+class DevicePickerSettings {
+    static final String TAG_PREFIX="DevicePicker.";
+    static final boolean DBG= false;
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/license/LicenseDialog.java b/WicedSense/app/src/main/java/com/broadcom/app/license/LicenseDialog.java
index d5d01a55f948e79cb78e27cfd1f999d3bd3c3573..5e0417a57aa2a68dc8662cbe50a0436e46f6c921 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/license/LicenseDialog.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/license/LicenseDialog.java
@@ -1,111 +1,111 @@
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.license;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application
- * Also, make sure you include the following resources
- * assets/license.html
- * layout/dialog_license.xml
- * values/strings_license.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import android.app.DialogFragment;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.text.Html;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TextView;
-
-/**
- * Dialog that displays the license's terms and conditions
- *
- */
-public class LicenseDialog extends DialogFragment implements OnClickListener {
-    public interface OnLicenseAcceptListener {
-        public abstract void onLicenseAccepted(boolean accepted);
-    }
-
-    private OnLicenseAcceptListener listener = null;
-    private boolean mLicenseAccepted;
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        View view = inflater.inflate(R.layout.dialog_license, container);
-        TextView tv = (TextView) view.findViewById(R.id.license_text);
-
-        Button btn = (Button) view.findViewById(R.id.btnAccept);
-        btn.setOnClickListener(this);
-
-        try {
-            StringBuilder sb = new StringBuilder();
-            String str;
-
-            InputStream is = getActivity().getAssets().open("license.html");
-            BufferedReader br = new BufferedReader(new InputStreamReader(is));
-
-            while ((str = br.readLine()) != null) {
-                sb.append(str);
-            }
-            br.close();
-
-            tv.setText(Html.fromHtml(sb.toString()));
-        } catch (IOException ex) {
-        }
-
-        getDialog().setTitle(R.string.title_license);
-
-        return view;
-    }
-
-    @Override
-    public void onCancel(DialogInterface dialog) {
-        mLicenseAccepted = false;
-        if (listener != null)
-            listener.onLicenseAccepted(false);
-        super.onCancel(dialog);
-    }
-
-    @Override
-    public void onClick(View view) {
-        mLicenseAccepted = true;
-        if (listener != null)
-            listener.onLicenseAccepted(true);
-        dismiss();
-    }
-
-
-    //---------------------Public APIs--------------------------
-    public void setListener(OnLicenseAcceptListener listener) {
-        this.listener = listener;
-    }
-
-    public boolean isLicenseAccepted() {
-        return mLicenseAccepted;
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.license;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application
+ * Also, make sure you include the following resources
+ * assets/license.html
+ * layout/dialog_license.xml
+ * values/strings_license.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Dialog that displays the license's terms and conditions
+ *
+ */
+public class LicenseDialog extends DialogFragment implements OnClickListener {
+    public interface OnLicenseAcceptListener {
+        public abstract void onLicenseAccepted(boolean accepted);
+    }
+
+    private OnLicenseAcceptListener listener = null;
+    private boolean mLicenseAccepted;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.dialog_license, container);
+        TextView tv = (TextView) view.findViewById(R.id.license_text);
+
+        Button btn = (Button) view.findViewById(R.id.btnAccept);
+        btn.setOnClickListener(this);
+
+        try {
+            StringBuilder sb = new StringBuilder();
+            String str;
+
+            InputStream is = getActivity().getAssets().open("license.html");
+            BufferedReader br = new BufferedReader(new InputStreamReader(is));
+
+            while ((str = br.readLine()) != null) {
+                sb.append(str);
+            }
+            br.close();
+
+            tv.setText(Html.fromHtml(sb.toString()));
+        } catch (IOException ex) {
+        }
+
+        getDialog().setTitle(R.string.title_license);
+
+        return view;
+    }
+
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        mLicenseAccepted = false;
+        if (listener != null)
+            listener.onLicenseAccepted(false);
+        super.onCancel(dialog);
+    }
+
+    @Override
+    public void onClick(View view) {
+        mLicenseAccepted = true;
+        if (listener != null)
+            listener.onLicenseAccepted(true);
+        dismiss();
+    }
+
+
+    //---------------------Public APIs--------------------------
+    public void setListener(OnLicenseAcceptListener listener) {
+        this.listener = listener;
+    }
+
+    public boolean isLicenseAccepted() {
+        return mLicenseAccepted;
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/license/LicenseUtils.java b/WicedSense/app/src/main/java/com/broadcom/app/license/LicenseUtils.java
index bb9d9d3fe1bdc8b27752607f989d3ce895844c6c..3adfe8afd62e453c01e57155ef900b8d07b97600 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/license/LicenseUtils.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/license/LicenseUtils.java
@@ -1,85 +1,85 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.license;
-
-import com.broadcom.app.license.LicenseDialog.OnLicenseAcceptListener;
-
-import android.app.FragmentManager;
-import android.content.Context;
-import android.content.SharedPreferences;
-
-/**
- * Helper class to show the license dialog and saves the user's selection
- */
-public class LicenseUtils implements OnLicenseAcceptListener {
-    private static final String PREFS_ID = "LicensePrefs";
-    private static final Integer PREFS_SET = 0;
-    private static final String PREFS_HAS_ACCEPTED = "HasAccepted";
-    private Context mContext;
-    private boolean mHasAccepted;
-    private LicenseDialog.OnLicenseAcceptListener mListener;
-    private LicenseDialog mDialog;
-
-    @Override
-    public void onLicenseAccepted(boolean accepted) {
-        mDialog = null;
-        if (mListener != null) {
-            mListener.onLicenseAccepted(accepted);
-        }
-    }
-
-    public LicenseUtils(Context ctx, LicenseDialog.OnLicenseAcceptListener listener) {
-        mContext = ctx;
-        mListener = listener;
-        SharedPreferences prefs = ctx.getSharedPreferences(PREFS_ID, PREFS_SET);
-        if (prefs == null)
-            return;
-        mHasAccepted = prefs.getBoolean(PREFS_HAS_ACCEPTED, false);
-    }
-
-    public void setAccepted(boolean accepted) {
-        mHasAccepted = accepted;
-        SharedPreferences prefs = mContext.getSharedPreferences(PREFS_ID, PREFS_SET);
-        SharedPreferences.Editor edit = prefs.edit();
-        if (edit == null)
-            return;
-
-        edit.putBoolean(PREFS_HAS_ACCEPTED, mHasAccepted);
-        edit.commit();
-    }
-
-    public boolean checkLicenseAccepted(FragmentManager mgr) {
-        if (!mHasAccepted) {
-            if (mDialog == null) {
-                mDialog = new LicenseDialog();
-                mDialog.setListener(this);
-                mDialog.show(mgr, null);
-            }
-            return false;
-        }
-        return true;
-    }
-
-    public void dismiss() {
-        if (mDialog != null) {
-            mDialog.setListener(null);
-            mDialog.dismiss();
-            mDialog = null;
-        }
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.license;
+
+import com.broadcom.app.license.LicenseDialog.OnLicenseAcceptListener;
+
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+
+/**
+ * Helper class to show the license dialog and saves the user's selection
+ */
+public class LicenseUtils implements OnLicenseAcceptListener {
+    private static final String PREFS_ID = "LicensePrefs";
+    private static final Integer PREFS_SET = 0;
+    private static final String PREFS_HAS_ACCEPTED = "HasAccepted";
+    private Context mContext;
+    private boolean mHasAccepted;
+    private LicenseDialog.OnLicenseAcceptListener mListener;
+    private LicenseDialog mDialog;
+
+    @Override
+    public void onLicenseAccepted(boolean accepted) {
+        mDialog = null;
+        if (mListener != null) {
+            mListener.onLicenseAccepted(accepted);
+        }
+    }
+
+    public LicenseUtils(Context ctx, LicenseDialog.OnLicenseAcceptListener listener) {
+        mContext = ctx;
+        mListener = listener;
+        SharedPreferences prefs = ctx.getSharedPreferences(PREFS_ID, PREFS_SET);
+        if (prefs == null)
+            return;
+        mHasAccepted = prefs.getBoolean(PREFS_HAS_ACCEPTED, false);
+    }
+
+    public void setAccepted(boolean accepted) {
+        mHasAccepted = accepted;
+        SharedPreferences prefs = mContext.getSharedPreferences(PREFS_ID, PREFS_SET);
+        SharedPreferences.Editor edit = prefs.edit();
+        if (edit == null)
+            return;
+
+        edit.putBoolean(PREFS_HAS_ACCEPTED, mHasAccepted);
+        edit.commit();
+    }
+
+    public boolean checkLicenseAccepted(FragmentManager mgr) {
+        if (!mHasAccepted) {
+            if (mDialog == null) {
+                mDialog = new LicenseDialog();
+                mDialog.setListener(this);
+                mDialog.show(mgr, null);
+            }
+            return false;
+        }
+        return true;
+    }
+
+    public void dismiss() {
+        if (mDialog != null) {
+            mDialog.setListener(null);
+            mDialog.dismiss();
+            mDialog = null;
+        }
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/AccelerometerFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/AccelerometerFragment.java
index 634d4f9e9469901bb0eafc9234975a43227a2e11..c661265ff83cc017490ba91835a916ad1e6b30a3 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/AccelerometerFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/AccelerometerFragment.java
@@ -1,356 +1,356 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import java.util.List;
-
-import com.broadcom.app.wicedsense.AnimationManager.Animated;
-
-import android.animation.PropertyValuesHolder;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-/**
- * Our Implimentation of (speed) AccelerometerFragment.
- * Will attempt to closely resemble practices done in class/assignments.
- */
-public class AccelerometerFragment extends Fragment {
-
-    //region Variables
-
-    private TextView mCurrent;
-    private TextView mMin;
-    private TextView mMax;
-    private TextView mAvg;
-
-    //endregion
-
-
-
-    //region Static information to summon Fragment.
-    private static final String ARG_ACCELEROMETER_ID= "accelerometer_id";
-
-    private static AccelerometerFragment newInstance() {
-        // Provided in case bundle is required in the future.
-        Bundle args = new Bundle();
-
-        // Make and return new fragment.
-        AccelerometerFragment fragment = new AccelerometerFragment();
-        fragment.setArguments(args);
-        return fragment;
-    }
-
-    //endregion
-
-
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Nullable
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        // Use inflater to get view from layout.
-        View view = inflater.inflate(R.layout.speed_fragment, container, false);
-
-        // Set class level vars to appropriate xml attributes.
-        mCurrent = (TextView) view.findViewById(R.id.speed_current);
-        mMin = (TextView) view.findViewById(R.id.speed_min);
-        mMax = (TextView) view.findViewById(R.id.speed_max);
-        mAvg = (TextView) view.findViewById(R.id.speed_avg);
-
-        // Read in from database and set values here?
-
-        return view;
-    }
-}
-
-
-/**
- * WICEDSENCE default stuff.
- * Commenting out instead of removing in case we need to reference it to get the program running.
- *
- *
- *
- *
- * Fragment to display the Accelerometer data. This view consists of
- *
- * 1. A "bubble" view that displays the X and Y data as the position of a
- * bubble.
- *
- * 2. A hidden text view that displays the X,Y,Z raw data that is shown when the
- * user taps on this fragment.
- *
- *//*
-public class AccelerometerFragment extends Fragment implements OnClickListener,
-        AnimatorUpdateListener, Animated {
-    private static final int mMaxValue = SensorDataParser.SENSOR_ACCEL_MAX;
-    private static final int mMinValue = SensorDataParser.SENSOR_ACCEL_MIN;
-    private static final float mValueLength = (mMaxValue - mMinValue);
-
-    private ImageView mBubble;
-    private TextView mRawX;
-    private TextView mRawY;
-    private TextView mRawZ;
-    private View mClickablePanel;
-    private boolean mRangeInited;
-    private View mRange;
-    private float mAccelMaxWidth;
-    private float mAccelMaxHeight;
-
-    // Current x,y,z values of accelerometer
-    private float mX;
-    private float mY;
-    private float mZ;
-
-    // Variables used for animation
-    private float mPreviousX;
-    private float mPreviousY;
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        View v = inflater.inflate(R.layout.accelerometer_fragment, null);
-        return v;
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        mBubble = (ImageView) view.findViewById(R.id.bubble);
-        mRange = view.findViewById(R.id.range);
-        mClickablePanel = view.findViewById(R.id.clickable_panel);
-        mClickablePanel.setOnClickListener(this);
-        mRawX = (TextView) view.findViewById(R.id.raw_x);
-        mRawY = (TextView) view.findViewById(R.id.raw_y);
-        mRawZ = (TextView) view.findViewById(R.id.raw_z);
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        // Restore saved values if we are returning from being paused
-        if (savedInstanceState != null && savedInstanceState.getBoolean("s", false)) {
-            mX = savedInstanceState.getFloat("x", 0);
-            mY = savedInstanceState.getFloat("y", 0);
-            mZ = savedInstanceState.getFloat("z", 0);
-            setValue(null, mX, mY, mZ);
-            return;
-
-        }
-        reset();
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        // Save values if we pause
-        outState.putBoolean("s", true);
-        outState.putFloat("x", mX);
-        outState.putFloat("y", mY);
-        outState.putFloat("z", mZ);
-    }
-
-    /**
-     * Get the horizontal and vertical boundaries that the bubble can travel
-     * dynamically, based on the current screen size
-     *//*
-    private void initGaugeRange() {
-        if (!mRangeInited) {
-            int rangeWidth = mRange.getWidth();
-            int rangeHeight = mRange.getHeight();
-            if (rangeWidth == 0 || rangeHeight == 0) {
-                return;
-            }
-            mAccelMaxWidth = rangeWidth - rangeWidth / 5;
-            mAccelMaxHeight = rangeHeight - rangeHeight / 5;
-            mRangeInited = true;
-        }
-
-    }
-
-    /**
-     * Limit the accelerometer value to the bounded range of accepted values
-     *
-     * @param value
-     * @return
-     *//*
-    private float getBoundedValue(float value) {
-        if (value > mMaxValue) {
-            value = mMaxValue;
-        }
-        if (value < mMinValue) {
-            value = mMinValue;
-        }
-        return value;
-    }
-
-    /**
-     * Set the accelerometer gauge NOTE: currently only x and y are displayed (z
-     * is not displayed in the bubble view)
-     *
-     * @param x
-     * @param y
-     *//*
-    private void setGauge(float x, float y) {
-        // scale x translation
-        mBubble.setTranslationX(x * mAccelMaxWidth / mValueLength);
-
-        // scale y translation
-        mBubble.setTranslationY(y * mAccelMaxHeight / mValueLength);
-    }
-
-    /**
-     * Update the text widgets that show x,y,z
-     *//*
-    private void updateTextWidgets() {
-        mRawX.setText(getString(R.string.raw_x, String.format("%.1f", mX)));
-        mRawY.setText(getString(R.string.raw_y, String.format("%.1f", mY)));
-        mRawZ.setText(getString(R.string.raw_z, String.format("%.1f", mZ)));
-    }
-
-    /**
-     * Store the accelerator values x,y,z, and if animation is enabled, prepare
-     * the view for animation..Otherwise, if animation is not enabled, update
-     * the bubble view instantaneously.
-     *
-     * @param animation
-     * @param x
-     * @param y
-     * @param z
-     *//*
-    public void setValue(AnimationManager animation, float x, float y, float z) {
-
-        initGaugeRange();
-        mX = getBoundedValue(x);
-        mY = getBoundedValue(y);
-        mZ = getBoundedValue(z);
-        if (!hasAnimatedValuesChanged()) {
-            return;
-        }
-        if (animation != null && animation.useAnimation()) {
-            animation.prepareAnimated(this);
-        } else {
-            saveAnimatedValues();
-            setGauge(mX, mY);
-        }
-        updateTextWidgets();
-    }
-
-    /**
-     * Callback invoked when the user clicks on the accelerometer view. Toggles
-     * showing/hiddening the raw x,y,z values
-     *//*
-    @Override
-    public void onClick(View v) {
-        int visibility = mRawX.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE;
-        mRawX.setVisibility(visibility);
-        mRawY.setVisibility(visibility);
-        mRawZ.setVisibility(visibility);
-    }
-
-    /**
-     * Reset all UI components and values to initial conditions
-     *//*
-    public void reset() {
-        mRawX.setText("");
-        mRawY.setText("");
-        mRawZ.setText("");
-        mX = 0;
-        mY = 0;
-        mZ = 0;
-    }
-
-    /**
-     * Called by the animation manager to display the first value used in the
-     * animation.
-     *//*
-    @Override
-    public void showFirstAnimatedValues() {
-        setGauge(mX, mY);
-
-    }
-
-    /**
-     * Called by the animation manager to determine if values have changed that
-     * need to be animated
-     *//*
-    @Override
-    public boolean hasAnimatedValuesChanged() {
-        return mPreviousX != mX || mPreviousY != mY;
-    }
-
-    /**
-     * Called by the animation manager to save the current values for the next
-     * interaction of animation
-     *//*
-    @Override
-    public void saveAnimatedValues() {
-        mPreviousX = mX;
-        mPreviousY = mY;
-    }
-
-    /**
-     * Called by the animation manager to prepare the values to animate
-     *//*
-    @Override
-    public void prepareAnimatedValues(List<PropertyValuesHolder> values) {
-        values.add(PropertyValuesHolder.ofFloat("accel.x", mPreviousX, mX));
-        values.add(PropertyValuesHolder.ofFloat("accel.y", mPreviousY, mY));
-    }
-
-    /**
-     * Called by the animation manager to update the UI with the currently
-     * specified values
-     *//*
-    @Override
-    public void onAnimationUpdate(ValueAnimator animation) {
-        Object x = animation.getAnimatedValue("accel.x");
-        Object y = animation.getAnimatedValue("accel.y");
-        if (x != null && y != null) {
-            setGauge((Float) x, (Float) y);
-        }
-    }
-
-    public void setEnabled(boolean enabled) {
-        if (enabled) {
-            mRange.setVisibility(View.VISIBLE);
-            mBubble.setVisibility(View.VISIBLE);
-            mClickablePanel.setOnClickListener(this);
-        } else {
-            mRange.setVisibility(View.INVISIBLE);
-            mBubble.setVisibility(View.INVISIBLE);
-            mRawX.setVisibility(View.INVISIBLE);
-            mRawY.setVisibility(View.INVISIBLE);
-            mRawZ.setVisibility(View.INVISIBLE);
-            mClickablePanel.setOnClickListener(null);
-        }
-
-    }
-} */
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import java.util.List;
+
+import com.broadcom.app.wicedsense.AnimationManager.Animated;
+
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * Our Implimentation of (speed) AccelerometerFragment.
+ * Will attempt to closely resemble practices done in class/assignments.
+ */
+public class AccelerometerFragment extends Fragment {
+
+    //region Variables
+
+    private TextView mCurrent;
+    private TextView mMin;
+    private TextView mMax;
+    private TextView mAvg;
+
+    //endregion
+
+
+
+    //region Static information to summon Fragment.
+    private static final String ARG_ACCELEROMETER_ID= "accelerometer_id";
+
+    private static AccelerometerFragment newInstance() {
+        // Provided in case bundle is required in the future.
+        Bundle args = new Bundle();
+
+        // Make and return new fragment.
+        AccelerometerFragment fragment = new AccelerometerFragment();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    //endregion
+
+
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        // Use inflater to get view from layout.
+        View view = inflater.inflate(R.layout.speed_fragment, container, false);
+
+        // Set class level vars to appropriate xml attributes.
+        mCurrent = (TextView) view.findViewById(R.id.speed_current);
+        mMin = (TextView) view.findViewById(R.id.speed_min);
+        mMax = (TextView) view.findViewById(R.id.speed_max);
+        mAvg = (TextView) view.findViewById(R.id.speed_avg);
+
+        // Read in from database and set values here?
+
+        return view;
+    }
+}
+
+
+/**
+ * WICEDSENCE default stuff.
+ * Commenting out instead of removing in case we need to reference it to get the program running.
+ *
+ *
+ *
+ *
+ * Fragment to display the Accelerometer data. This view consists of
+ *
+ * 1. A "bubble" view that displays the X and Y data as the position of a
+ * bubble.
+ *
+ * 2. A hidden text view that displays the X,Y,Z raw data that is shown when the
+ * user taps on this fragment.
+ *
+ *//*
+public class AccelerometerFragment extends Fragment implements OnClickListener,
+        AnimatorUpdateListener, Animated {
+    private static final int mMaxValue = SensorDataParser.SENSOR_ACCEL_MAX;
+    private static final int mMinValue = SensorDataParser.SENSOR_ACCEL_MIN;
+    private static final float mValueLength = (mMaxValue - mMinValue);
+
+    private ImageView mBubble;
+    private TextView mRawX;
+    private TextView mRawY;
+    private TextView mRawZ;
+    private View mClickablePanel;
+    private boolean mRangeInited;
+    private View mRange;
+    private float mAccelMaxWidth;
+    private float mAccelMaxHeight;
+
+    // Current x,y,z values of accelerometer
+    private float mX;
+    private float mY;
+    private float mZ;
+
+    // Variables used for animation
+    private float mPreviousX;
+    private float mPreviousY;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.accelerometer_fragment, null);
+        return v;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        mBubble = (ImageView) view.findViewById(R.id.bubble);
+        mRange = view.findViewById(R.id.range);
+        mClickablePanel = view.findViewById(R.id.clickable_panel);
+        mClickablePanel.setOnClickListener(this);
+        mRawX = (TextView) view.findViewById(R.id.raw_x);
+        mRawY = (TextView) view.findViewById(R.id.raw_y);
+        mRawZ = (TextView) view.findViewById(R.id.raw_z);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        // Restore saved values if we are returning from being paused
+        if (savedInstanceState != null && savedInstanceState.getBoolean("s", false)) {
+            mX = savedInstanceState.getFloat("x", 0);
+            mY = savedInstanceState.getFloat("y", 0);
+            mZ = savedInstanceState.getFloat("z", 0);
+            setValue(null, mX, mY, mZ);
+            return;
+
+        }
+        reset();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        // Save values if we pause
+        outState.putBoolean("s", true);
+        outState.putFloat("x", mX);
+        outState.putFloat("y", mY);
+        outState.putFloat("z", mZ);
+    }
+
+    /**
+     * Get the horizontal and vertical boundaries that the bubble can travel
+     * dynamically, based on the current screen size
+     *//*
+    private void initGaugeRange() {
+        if (!mRangeInited) {
+            int rangeWidth = mRange.getWidth();
+            int rangeHeight = mRange.getHeight();
+            if (rangeWidth == 0 || rangeHeight == 0) {
+                return;
+            }
+            mAccelMaxWidth = rangeWidth - rangeWidth / 5;
+            mAccelMaxHeight = rangeHeight - rangeHeight / 5;
+            mRangeInited = true;
+        }
+
+    }
+
+    /**
+     * Limit the accelerometer value to the bounded range of accepted values
+     *
+     * @param value
+     * @return
+     *//*
+    private float getBoundedValue(float value) {
+        if (value > mMaxValue) {
+            value = mMaxValue;
+        }
+        if (value < mMinValue) {
+            value = mMinValue;
+        }
+        return value;
+    }
+
+    /**
+     * Set the accelerometer gauge NOTE: currently only x and y are displayed (z
+     * is not displayed in the bubble view)
+     *
+     * @param x
+     * @param y
+     *//*
+    private void setGauge(float x, float y) {
+        // scale x translation
+        mBubble.setTranslationX(x * mAccelMaxWidth / mValueLength);
+
+        // scale y translation
+        mBubble.setTranslationY(y * mAccelMaxHeight / mValueLength);
+    }
+
+    /**
+     * Update the text widgets that show x,y,z
+     *//*
+    private void updateTextWidgets() {
+        mRawX.setText(getString(R.string.raw_x, String.format("%.1f", mX)));
+        mRawY.setText(getString(R.string.raw_y, String.format("%.1f", mY)));
+        mRawZ.setText(getString(R.string.raw_z, String.format("%.1f", mZ)));
+    }
+
+    /**
+     * Store the accelerator values x,y,z, and if animation is enabled, prepare
+     * the view for animation..Otherwise, if animation is not enabled, update
+     * the bubble view instantaneously.
+     *
+     * @param animation
+     * @param x
+     * @param y
+     * @param z
+     *//*
+    public void setValue(AnimationManager animation, float x, float y, float z) {
+
+        initGaugeRange();
+        mX = getBoundedValue(x);
+        mY = getBoundedValue(y);
+        mZ = getBoundedValue(z);
+        if (!hasAnimatedValuesChanged()) {
+            return;
+        }
+        if (animation != null && animation.useAnimation()) {
+            animation.prepareAnimated(this);
+        } else {
+            saveAnimatedValues();
+            setGauge(mX, mY);
+        }
+        updateTextWidgets();
+    }
+
+    /**
+     * Callback invoked when the user clicks on the accelerometer view. Toggles
+     * showing/hiddening the raw x,y,z values
+     *//*
+    @Override
+    public void onClick(View v) {
+        int visibility = mRawX.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE;
+        mRawX.setVisibility(visibility);
+        mRawY.setVisibility(visibility);
+        mRawZ.setVisibility(visibility);
+    }
+
+    /**
+     * Reset all UI components and values to initial conditions
+     *//*
+    public void reset() {
+        mRawX.setText("");
+        mRawY.setText("");
+        mRawZ.setText("");
+        mX = 0;
+        mY = 0;
+        mZ = 0;
+    }
+
+    /**
+     * Called by the animation manager to display the first value used in the
+     * animation.
+     *//*
+    @Override
+    public void showFirstAnimatedValues() {
+        setGauge(mX, mY);
+
+    }
+
+    /**
+     * Called by the animation manager to determine if values have changed that
+     * need to be animated
+     *//*
+    @Override
+    public boolean hasAnimatedValuesChanged() {
+        return mPreviousX != mX || mPreviousY != mY;
+    }
+
+    /**
+     * Called by the animation manager to save the current values for the next
+     * interaction of animation
+     *//*
+    @Override
+    public void saveAnimatedValues() {
+        mPreviousX = mX;
+        mPreviousY = mY;
+    }
+
+    /**
+     * Called by the animation manager to prepare the values to animate
+     *//*
+    @Override
+    public void prepareAnimatedValues(List<PropertyValuesHolder> values) {
+        values.add(PropertyValuesHolder.ofFloat("accel.x", mPreviousX, mX));
+        values.add(PropertyValuesHolder.ofFloat("accel.y", mPreviousY, mY));
+    }
+
+    /**
+     * Called by the animation manager to update the UI with the currently
+     * specified values
+     *//*
+    @Override
+    public void onAnimationUpdate(ValueAnimator animation) {
+        Object x = animation.getAnimatedValue("accel.x");
+        Object y = animation.getAnimatedValue("accel.y");
+        if (x != null && y != null) {
+            setGauge((Float) x, (Float) y);
+        }
+    }
+
+    public void setEnabled(boolean enabled) {
+        if (enabled) {
+            mRange.setVisibility(View.VISIBLE);
+            mBubble.setVisibility(View.VISIBLE);
+            mClickablePanel.setOnClickListener(this);
+        } else {
+            mRange.setVisibility(View.INVISIBLE);
+            mBubble.setVisibility(View.INVISIBLE);
+            mRawX.setVisibility(View.INVISIBLE);
+            mRawY.setVisibility(View.INVISIBLE);
+            mRawZ.setVisibility(View.INVISIBLE);
+            mClickablePanel.setOnClickListener(null);
+        }
+
+    }
+} */
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/AnimationManager.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/AnimationManager.java
index 81b50d56958e58231ca9c714e43438cb8cfe4a69..df3e46d51f279fee0f5f5f235c4a6a72a97a0df5 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/AnimationManager.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/AnimationManager.java
@@ -1,132 +1,132 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.animation.Animator;
-import android.animation.PropertyValuesHolder;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.view.animation.LinearInterpolator;
-
-/**
- * Manages and coordinates multiple "Animated" objects
- *
- */
-public class AnimationManager {
-
-    public interface Animated extends AnimatorUpdateListener {
-        public void showFirstAnimatedValues();
-
-        public boolean hasAnimatedValuesChanged();
-
-        public void saveAnimatedValues();
-
-        public void prepareAnimatedValues(List<PropertyValuesHolder> values);
-    }
-
-    private final int mFrameDelayMs;
-    private final int mAnimateIntervalMs;
-    private final ValueAnimator mAnimator;
-    private long mLastTime;
-    private long mCurrentTime;
-    private boolean mIsReady;
-    private final ArrayList<PropertyValuesHolder> mPropertyValues;
-
-    public AnimationManager(int frameDelayMs, int animateIntervalMs) {
-        mAnimator = new ValueAnimator();
-        mAnimator.setInterpolator(new LinearInterpolator());
-        mFrameDelayMs = frameDelayMs;
-        mAnimateIntervalMs = animateIntervalMs;
-        ValueAnimator.setFrameDelay(mFrameDelayMs);
-
-        mLastTime = 0;
-        mCurrentTime = 0;
-        mPropertyValues = new ArrayList<PropertyValuesHolder>();
-    }
-
-    public boolean useAnimation() {
-        return Settings.animate();
-    }
-
-    public void addAnimated(Animated a) {
-        ArrayList<Animator.AnimatorListener> l = mAnimator.getListeners();
-        if (l == null || !l.contains(a)) {
-            mAnimator.addUpdateListener(a);
-        }
-    }
-
-    public void removeAnimated(Animated a) {
-        mAnimator.removeUpdateListener(a);
-    }
-
-    public void init() {
-        mCurrentTime = System.currentTimeMillis();
-
-        long duration = mCurrentTime - mLastTime;
-        if (duration < mAnimateIntervalMs) {
-            mIsReady = false;
-            return;
-        }
-
-        if (mAnimator.isRunning()) {
-            // mAnimator.end();
-            mIsReady = false;
-            return;
-        }
-
-        mIsReady = true;
-    }
-
-    public void prepareAnimated(Animated a) {
-        if (!mIsReady) {
-            return;
-        }
-
-        // Check if this is the first values: don't animate first value
-        if (mLastTime == 0) {
-            a.showFirstAnimatedValues();
-            a.saveAnimatedValues();
-            mLastTime = mCurrentTime;
-            return;
-        }
-
-        if (a.hasAnimatedValuesChanged()) {
-            a.prepareAnimatedValues(mPropertyValues);
-            a.saveAnimatedValues();
-        } else {
-
-        }
-    }
-
-    public void animate() {
-        if (mPropertyValues.size() > 0) {
-            PropertyValuesHolder[] values = new PropertyValuesHolder[mPropertyValues.size()];
-            mPropertyValues.toArray(values);
-            mAnimator.setValues(values);
-            mAnimator.setDuration(mAnimateIntervalMs);
-            mAnimator.start();
-            mLastTime = mCurrentTime;
-            mPropertyValues.clear();
-            mIsReady = false;
-        }
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.animation.Animator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.view.animation.LinearInterpolator;
+
+/**
+ * Manages and coordinates multiple "Animated" objects
+ *
+ */
+public class AnimationManager {
+
+    public interface Animated extends AnimatorUpdateListener {
+        public void showFirstAnimatedValues();
+
+        public boolean hasAnimatedValuesChanged();
+
+        public void saveAnimatedValues();
+
+        public void prepareAnimatedValues(List<PropertyValuesHolder> values);
+    }
+
+    private final int mFrameDelayMs;
+    private final int mAnimateIntervalMs;
+    private final ValueAnimator mAnimator;
+    private long mLastTime;
+    private long mCurrentTime;
+    private boolean mIsReady;
+    private final ArrayList<PropertyValuesHolder> mPropertyValues;
+
+    public AnimationManager(int frameDelayMs, int animateIntervalMs) {
+        mAnimator = new ValueAnimator();
+        mAnimator.setInterpolator(new LinearInterpolator());
+        mFrameDelayMs = frameDelayMs;
+        mAnimateIntervalMs = animateIntervalMs;
+        ValueAnimator.setFrameDelay(mFrameDelayMs);
+
+        mLastTime = 0;
+        mCurrentTime = 0;
+        mPropertyValues = new ArrayList<PropertyValuesHolder>();
+    }
+
+    public boolean useAnimation() {
+        return Settings.animate();
+    }
+
+    public void addAnimated(Animated a) {
+        ArrayList<Animator.AnimatorListener> l = mAnimator.getListeners();
+        if (l == null || !l.contains(a)) {
+            mAnimator.addUpdateListener(a);
+        }
+    }
+
+    public void removeAnimated(Animated a) {
+        mAnimator.removeUpdateListener(a);
+    }
+
+    public void init() {
+        mCurrentTime = System.currentTimeMillis();
+
+        long duration = mCurrentTime - mLastTime;
+        if (duration < mAnimateIntervalMs) {
+            mIsReady = false;
+            return;
+        }
+
+        if (mAnimator.isRunning()) {
+            // mAnimator.end();
+            mIsReady = false;
+            return;
+        }
+
+        mIsReady = true;
+    }
+
+    public void prepareAnimated(Animated a) {
+        if (!mIsReady) {
+            return;
+        }
+
+        // Check if this is the first values: don't animate first value
+        if (mLastTime == 0) {
+            a.showFirstAnimatedValues();
+            a.saveAnimatedValues();
+            mLastTime = mCurrentTime;
+            return;
+        }
+
+        if (a.hasAnimatedValuesChanged()) {
+            a.prepareAnimatedValues(mPropertyValues);
+            a.saveAnimatedValues();
+        } else {
+
+        }
+    }
+
+    public void animate() {
+        if (mPropertyValues.size() > 0) {
+            PropertyValuesHolder[] values = new PropertyValuesHolder[mPropertyValues.size()];
+            mPropertyValues.toArray(values);
+            mAnimator.setValues(values);
+            mAnimator.setDuration(mAnimateIntervalMs);
+            mAnimator.start();
+            mLastTime = mCurrentTime;
+            mPropertyValues.clear();
+            mIsReady = false;
+        }
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/BaseThermoFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/BaseThermoFragment.java
index bd0e4cb88715852ea8a501a0e07bea51d1c30110..4ecf5645f1c75e4684f00833f9e71d785d41b7b7 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/BaseThermoFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/BaseThermoFragment.java
@@ -1,243 +1,243 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-
-package com.broadcom.app.wicedsense;
-
-import java.util.List;
-
-import com.broadcom.app.wicedsense.AnimationManager.Animated;
-
-import android.animation.PropertyValuesHolder;
-import android.animation.ValueAnimator;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.view.View;
-import android.view.View.OnLayoutChangeListener;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-/**
- * Base class used for the thermometer, pressure, humidity
- *
- */
-public abstract class BaseThermoFragment extends Fragment implements OnLayoutChangeListener,
-        Animated {
-    private static final int LEVEL_WIDTH_PX = 17;
-    private static final int LEVEL_FRAME_WIDTH_PX = 110;
-
-    private static final int RANGE_TOP_PAD_PX = 49;
-    private static final int RANGE_BOTTOM_PAD_PX = 98;
-    private static final int RANGE_HEIGHT_PX = 788;
-
-    protected float mMaxValue;
-    protected float mMinValue;
-    protected float mValueRange;
-
-    protected TextView mGaugeValue;
-    protected View mGaugeBg;
-    protected View mGaugeLevelFrame;
-    protected View mGaugeLevel;
-    protected View mGaugeRange;
-    protected View mGaugeLabel;
-
-    private boolean mGaugeAdjusted;
-
-    protected float mPreviousValue;
-    protected float mValue;
-    protected boolean mValueSet;
-
-    public BaseThermoFragment() {
-        super();
-        initRange();
-    }
-
-    protected void initRange() {
-        initRangeValues();
-        mValueRange = mMaxValue - mMinValue;
-        mValue = mMinValue;
-    }
-
-    public void setInitialValue(float value) {
-        if (value > mMaxValue) {
-            value = mMaxValue;
-        }
-        if (value < mMinValue) {
-            value = mMinValue;
-        }
-        mValue = value;
-        mValueSet = true;
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        mGaugeBg = view.findViewById(R.id.gauge_bg);
-        mGaugeLabel = view.findViewById(R.id.gauge_label);
-
-        mGaugeLevelFrame = view.findViewById(R.id.gauge_level_frame);
-        mGaugeLevelFrame.addOnLayoutChangeListener(this);
-        mGaugeLevel = view.findViewById(R.id.gauge_level);
-        mGaugeLevel.setVisibility(View.INVISIBLE);
-        mGaugeValue = (TextView) view.findViewById(R.id.gauge_value);
-        mGaugeRange = view.findViewById(R.id.gauge_range);
-
-        if (mValueSet) {
-            setValue(null, mValue);
-        }
-    }
-
-    @Override
-    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
-            int oldTop, int oldRight, int oldBottom) {
-        if (v == mGaugeLevelFrame) {
-            if (!mGaugeAdjusted) {
-                setGauge(mValue);
-                adjustGaugeLevel();
-                return;
-            }
-            if (mGaugeLevel.getVisibility() != View.VISIBLE) {
-                mGaugeLevel.setVisibility(View.VISIBLE);
-            }
-        }
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        if (savedInstanceState != null && savedInstanceState.getBoolean("s", false)) {
-            mValue = savedInstanceState.getFloat("v", mMinValue - 1);
-            if (mValue >= mMinValue) {
-                setValue(null, mValue);
-                return;
-            }
-        }
-        reset();
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean("s", mValueSet);
-        outState.putFloat("v", mValue);
-    }
-
-    private void adjustGaugeLevel() {
-        if (mGaugeAdjusted) {
-            return;
-        }
-        int gaugeBgWidth = mGaugeBg.getWidth();
-        int gaugeBgHeight = mGaugeBg.getHeight();
-
-        if (gaugeBgWidth == 0 || gaugeBgHeight == 0) {
-            return;
-        }
-
-        RelativeLayout.LayoutParams lpGaugeFrame = (RelativeLayout.LayoutParams) mGaugeLevelFrame
-                .getLayoutParams();
-
-        int newGaugeLevelWidth = (int) (gaugeBgWidth * LEVEL_WIDTH_PX / LEVEL_FRAME_WIDTH_PX);
-        lpGaugeFrame.width = newGaugeLevelWidth;
-        int newGaugeTopMargin = gaugeBgHeight * RANGE_TOP_PAD_PX / RANGE_HEIGHT_PX;
-        int newGaugeBottomMargin = gaugeBgHeight * RANGE_BOTTOM_PAD_PX / RANGE_HEIGHT_PX;
-        lpGaugeFrame.topMargin = newGaugeTopMargin;
-        lpGaugeFrame.bottomMargin = newGaugeBottomMargin;
-        mGaugeLevelFrame.setLayoutParams(lpGaugeFrame);
-        mGaugeAdjusted = true;
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        adjustGaugeLevel();
-    }
-
-    public void setValue(AnimationManager animation, float value) {
-        if (value > mMaxValue) {
-            value = mMaxValue;
-        }
-        if (value < mMinValue) {
-            value = mMinValue;
-        }
-        mValue = value;
-        mValueSet = true;
-        if (!hasAnimatedValuesChanged()) {
-            return;
-        }
-        if (animation != null && animation.useAnimation()) {
-            animation.prepareAnimated(this);
-        } else {
-            saveAnimatedValues();
-            setGauge(mValue);
-        }
-        updateTextWidgets();
-    }
-
-    private void updateTextWidgets() {
-        setGaugeText(mValue);
-    }
-
-    public void reset() {
-        mGaugeValue.setText("");
-        setGauge(mMinValue);
-        mGaugeLevel.setVisibility(View.INVISIBLE);
-    }
-
-    protected void setGauge(float value) {
-        if (mGaugeLevel == null) {
-            return;
-        }
-        float gaugeOffset = ((mMaxValue - value) / mValueRange) * mGaugeLevel.getHeight();
-        float newY = mGaugeRange.getY() + gaugeOffset;
-        mGaugeLevel.setY(newY);
-    }
-
-    @Override
-    public void showFirstAnimatedValues() {
-        setGauge(mValue);
-    }
-
-    @Override
-    public boolean hasAnimatedValuesChanged() {
-        return mPreviousValue != mValue;
-    }
-
-    @Override
-    public void saveAnimatedValues() {
-        mPreviousValue = mValue;
-    }
-
-    @Override
-    public void prepareAnimatedValues(List<PropertyValuesHolder> values) {
-        values.add(PropertyValuesHolder.ofFloat(getPropertyName(), mPreviousValue, mValue));
-    }
-
-    @Override
-    public void onAnimationUpdate(ValueAnimator animator) {
-        Object value = animator.getAnimatedValue(getPropertyName());
-        if (value != null) {
-            setGauge((Float) value);
-        }
-    }
-
-    protected abstract void initRangeValues();
-
-    protected abstract void setGaugeText(float value);
-
-    protected abstract String getPropertyName();
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+package com.broadcom.app.wicedsense;
+
+import java.util.List;
+
+import com.broadcom.app.wicedsense.AnimationManager.Animated;
+
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnLayoutChangeListener;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+/**
+ * Base class used for the thermometer, pressure, humidity
+ *
+ */
+public abstract class BaseThermoFragment extends Fragment implements OnLayoutChangeListener,
+        Animated {
+    private static final int LEVEL_WIDTH_PX = 17;
+    private static final int LEVEL_FRAME_WIDTH_PX = 110;
+
+    private static final int RANGE_TOP_PAD_PX = 49;
+    private static final int RANGE_BOTTOM_PAD_PX = 98;
+    private static final int RANGE_HEIGHT_PX = 788;
+
+    protected float mMaxValue;
+    protected float mMinValue;
+    protected float mValueRange;
+
+    protected TextView mGaugeValue;
+    protected View mGaugeBg;
+    protected View mGaugeLevelFrame;
+    protected View mGaugeLevel;
+    protected View mGaugeRange;
+    protected View mGaugeLabel;
+
+    private boolean mGaugeAdjusted;
+
+    protected float mPreviousValue;
+    protected float mValue;
+    protected boolean mValueSet;
+
+    public BaseThermoFragment() {
+        super();
+        initRange();
+    }
+
+    protected void initRange() {
+        initRangeValues();
+        mValueRange = mMaxValue - mMinValue;
+        mValue = mMinValue;
+    }
+
+    public void setInitialValue(float value) {
+        if (value > mMaxValue) {
+            value = mMaxValue;
+        }
+        if (value < mMinValue) {
+            value = mMinValue;
+        }
+        mValue = value;
+        mValueSet = true;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        mGaugeBg = view.findViewById(R.id.gauge_bg);
+        mGaugeLabel = view.findViewById(R.id.gauge_label);
+
+        mGaugeLevelFrame = view.findViewById(R.id.gauge_level_frame);
+        mGaugeLevelFrame.addOnLayoutChangeListener(this);
+        mGaugeLevel = view.findViewById(R.id.gauge_level);
+        mGaugeLevel.setVisibility(View.INVISIBLE);
+        mGaugeValue = (TextView) view.findViewById(R.id.gauge_value);
+        mGaugeRange = view.findViewById(R.id.gauge_range);
+
+        if (mValueSet) {
+            setValue(null, mValue);
+        }
+    }
+
+    @Override
+    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+            int oldTop, int oldRight, int oldBottom) {
+        if (v == mGaugeLevelFrame) {
+            if (!mGaugeAdjusted) {
+                setGauge(mValue);
+                adjustGaugeLevel();
+                return;
+            }
+            if (mGaugeLevel.getVisibility() != View.VISIBLE) {
+                mGaugeLevel.setVisibility(View.VISIBLE);
+            }
+        }
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        if (savedInstanceState != null && savedInstanceState.getBoolean("s", false)) {
+            mValue = savedInstanceState.getFloat("v", mMinValue - 1);
+            if (mValue >= mMinValue) {
+                setValue(null, mValue);
+                return;
+            }
+        }
+        reset();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean("s", mValueSet);
+        outState.putFloat("v", mValue);
+    }
+
+    private void adjustGaugeLevel() {
+        if (mGaugeAdjusted) {
+            return;
+        }
+        int gaugeBgWidth = mGaugeBg.getWidth();
+        int gaugeBgHeight = mGaugeBg.getHeight();
+
+        if (gaugeBgWidth == 0 || gaugeBgHeight == 0) {
+            return;
+        }
+
+        RelativeLayout.LayoutParams lpGaugeFrame = (RelativeLayout.LayoutParams) mGaugeLevelFrame
+                .getLayoutParams();
+
+        int newGaugeLevelWidth = (int) (gaugeBgWidth * LEVEL_WIDTH_PX / LEVEL_FRAME_WIDTH_PX);
+        lpGaugeFrame.width = newGaugeLevelWidth;
+        int newGaugeTopMargin = gaugeBgHeight * RANGE_TOP_PAD_PX / RANGE_HEIGHT_PX;
+        int newGaugeBottomMargin = gaugeBgHeight * RANGE_BOTTOM_PAD_PX / RANGE_HEIGHT_PX;
+        lpGaugeFrame.topMargin = newGaugeTopMargin;
+        lpGaugeFrame.bottomMargin = newGaugeBottomMargin;
+        mGaugeLevelFrame.setLayoutParams(lpGaugeFrame);
+        mGaugeAdjusted = true;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        adjustGaugeLevel();
+    }
+
+    public void setValue(AnimationManager animation, float value) {
+        if (value > mMaxValue) {
+            value = mMaxValue;
+        }
+        if (value < mMinValue) {
+            value = mMinValue;
+        }
+        mValue = value;
+        mValueSet = true;
+        if (!hasAnimatedValuesChanged()) {
+            return;
+        }
+        if (animation != null && animation.useAnimation()) {
+            animation.prepareAnimated(this);
+        } else {
+            saveAnimatedValues();
+            setGauge(mValue);
+        }
+        updateTextWidgets();
+    }
+
+    private void updateTextWidgets() {
+        setGaugeText(mValue);
+    }
+
+    public void reset() {
+        mGaugeValue.setText("");
+        setGauge(mMinValue);
+        mGaugeLevel.setVisibility(View.INVISIBLE);
+    }
+
+    protected void setGauge(float value) {
+        if (mGaugeLevel == null) {
+            return;
+        }
+        float gaugeOffset = ((mMaxValue - value) / mValueRange) * mGaugeLevel.getHeight();
+        float newY = mGaugeRange.getY() + gaugeOffset;
+        mGaugeLevel.setY(newY);
+    }
+
+    @Override
+    public void showFirstAnimatedValues() {
+        setGauge(mValue);
+    }
+
+    @Override
+    public boolean hasAnimatedValuesChanged() {
+        return mPreviousValue != mValue;
+    }
+
+    @Override
+    public void saveAnimatedValues() {
+        mPreviousValue = mValue;
+    }
+
+    @Override
+    public void prepareAnimatedValues(List<PropertyValuesHolder> values) {
+        values.add(PropertyValuesHolder.ofFloat(getPropertyName(), mPreviousValue, mValue));
+    }
+
+    @Override
+    public void onAnimationUpdate(ValueAnimator animator) {
+        Object value = animator.getAnimatedValue(getPropertyName());
+        if (value != null) {
+            setGauge((Float) value);
+        }
+    }
+
+    protected abstract void initRangeValues();
+
+    protected abstract void setGaugeText(float value);
+
+    protected abstract String getPropertyName();
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/CompassFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/CompassFragment.java
index 1a988f3e455a4bcd15f5ea6772a04c7071a7265a..4ea0ad89e688a92ed34ee2a480b06ccaf8ae85a1 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/CompassFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/CompassFragment.java
@@ -1,203 +1,203 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import java.util.List;
-
-import com.broadcom.app.wicedsense.AnimationManager.Animated;
-
-import android.animation.PropertyValuesHolder;
-import android.animation.ValueAnimator;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-public class CompassFragment extends Fragment implements OnClickListener, Animated {
-    private ImageView mNeedle;
-    private TextView mRawX;
-    private TextView mRawY;
-    private TextView mRawZ;
-    private TextView mRawAngle;
-    private View mClickablePanel;
-
-    private float mX;
-    private float mY;
-    private float mZ;
-    private float mAngle;
-
-    private float mPreviousAngle;
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        View v = inflater.inflate(R.layout.compass_fragment, null);
-        return v;
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        mNeedle = (ImageView) view.findViewById(R.id.needle);
-
-        mClickablePanel = view.findViewById(R.id.clickable_panel);
-        mClickablePanel.setOnClickListener(this);
-        mRawX = (TextView) view.findViewById(R.id.raw_x);
-        mRawY = (TextView) view.findViewById(R.id.raw_y);
-        mRawZ = (TextView) view.findViewById(R.id.raw_z);
-        mRawAngle = (TextView) view.findViewById(R.id.raw_angle);
-    }
-
-    public void setValue(AnimationManager animation, float angle, float x, float y, float z) {
-
-
-        if (angle >= 360) {
-            angle -= 360;
-        }
-        if (angle < 0) {
-            angle += 360;
-        }
-
-        mX = x;
-        mY = y;
-        mZ = z;
-        mAngle = angle;
-        if (!hasAnimatedValuesChanged()) {
-            return;
-        }
-        if (animation != null && animation.useAnimation()) {
-            animation.prepareAnimated(this);
-        } else {
-            saveAnimatedValues();
-            mNeedle.setRotation(mAngle);
-        }
-        updateTextWidgets();
-    }
-
-    private void updateTextWidgets() {
-        mRawX.setText(getString(R.string.raw_x, String.format("%.1f", mX)));
-        mRawY.setText(getString(R.string.raw_y, String.format("%.1f", mY)));
-        mRawZ.setText(getString(R.string.raw_z, String.format("%.1f", mZ)));
-        mRawAngle.setText(getString(R.string.compass_raw_angle, String.format("%.1f", mAngle)));
-    }
-
-    @Override
-    public void onClick(View v) {
-        int visibility = mRawX.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE;
-        mRawX.setVisibility(visibility);
-        mRawY.setVisibility(visibility);
-        mRawZ.setVisibility(visibility);
-        mRawAngle.setVisibility(visibility);
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        if (savedInstanceState != null && savedInstanceState.getBoolean("s", false)) {
-            mX = savedInstanceState.getFloat("x", 0);
-            mY = savedInstanceState.getFloat("y", 0);
-            mZ = savedInstanceState.getFloat("z", 0);
-            mAngle = savedInstanceState.getFloat("a", 0);
-            setValue(null, mAngle, mX, mY, mZ);
-            return;
-        }
-        reset();
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean("s", true);
-        outState.putFloat("x", mX);
-        outState.putFloat("y", mY);
-        outState.putFloat("z", mZ);
-        outState.putFloat("a", mAngle);
-    }
-
-    public void reset() {
-        mRawX.setText("");
-        mRawY.setText("");
-        mRawZ.setText("");
-        mRawAngle.setText("");
-        mX = 0;
-        mY = 0;
-        mZ = 0;
-        mAngle = 0;
-    }
-
-    @Override
-    public void showFirstAnimatedValues() {
-        mNeedle.setRotation(mAngle);
-    }
-
-    @Override
-    public boolean hasAnimatedValuesChanged() {
-        return mPreviousAngle != mAngle;
-    }
-
-    @Override
-    public void saveAnimatedValues() {
-        mPreviousAngle = mAngle;
-    }
-
-    @Override
-    public void prepareAnimatedValues(List<PropertyValuesHolder> values) {
-        PropertyValuesHolder v = null;
-
-        float angleChange = mAngle - mPreviousAngle;
-        if (angleChange > -180 && angleChange < 180) {
-            v = PropertyValuesHolder.ofFloat("compass.angle", mPreviousAngle, mAngle);
-        } else {
-            // we jumped more than +-180 degrees==>crossing 0 mark
-            if (mAngle < mPreviousAngle) {
-                // Example: 350->10 CW
-                v = PropertyValuesHolder.ofFloat("compass.angle", mPreviousAngle, mAngle + 360);
-            } else {
-                // Example 10 >350 CCW
-                v = PropertyValuesHolder.ofFloat("compass.angle", mPreviousAngle + 360, mAngle);
-            }
-        }
-        values.add(v);
-    }
-
-    @Override
-    public void onAnimationUpdate(ValueAnimator a) {
-        Object angle = a.getAnimatedValue("compass.angle");
-        if (angle != null) {
-            mNeedle.setRotation((Float) angle);
-        }
-    }
-
-
-    public void setEnabled(boolean enabled) {
-        if (enabled) {
-            mNeedle.setVisibility(View.VISIBLE);
-            mClickablePanel.setOnClickListener(this);
-        } else {
-            mNeedle.setVisibility(View.INVISIBLE);
-            mRawX.setVisibility(View.INVISIBLE);
-            mRawY.setVisibility(View.INVISIBLE);
-            mRawZ.setVisibility(View.INVISIBLE);
-            mRawAngle.setVisibility(View.INVISIBLE);
-            mClickablePanel.setOnClickListener(null);
-        }
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import java.util.List;
+
+import com.broadcom.app.wicedsense.AnimationManager.Animated;
+
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class CompassFragment extends Fragment implements OnClickListener, Animated {
+    private ImageView mNeedle;
+    private TextView mRawX;
+    private TextView mRawY;
+    private TextView mRawZ;
+    private TextView mRawAngle;
+    private View mClickablePanel;
+
+    private float mX;
+    private float mY;
+    private float mZ;
+    private float mAngle;
+
+    private float mPreviousAngle;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.compass_fragment, null);
+        return v;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        mNeedle = (ImageView) view.findViewById(R.id.needle);
+
+        mClickablePanel = view.findViewById(R.id.clickable_panel);
+        mClickablePanel.setOnClickListener(this);
+        mRawX = (TextView) view.findViewById(R.id.raw_x);
+        mRawY = (TextView) view.findViewById(R.id.raw_y);
+        mRawZ = (TextView) view.findViewById(R.id.raw_z);
+        mRawAngle = (TextView) view.findViewById(R.id.raw_angle);
+    }
+
+    public void setValue(AnimationManager animation, float angle, float x, float y, float z) {
+
+
+        if (angle >= 360) {
+            angle -= 360;
+        }
+        if (angle < 0) {
+            angle += 360;
+        }
+
+        mX = x;
+        mY = y;
+        mZ = z;
+        mAngle = angle;
+        if (!hasAnimatedValuesChanged()) {
+            return;
+        }
+        if (animation != null && animation.useAnimation()) {
+            animation.prepareAnimated(this);
+        } else {
+            saveAnimatedValues();
+            mNeedle.setRotation(mAngle);
+        }
+        updateTextWidgets();
+    }
+
+    private void updateTextWidgets() {
+        mRawX.setText(getString(R.string.raw_x, String.format("%.1f", mX)));
+        mRawY.setText(getString(R.string.raw_y, String.format("%.1f", mY)));
+        mRawZ.setText(getString(R.string.raw_z, String.format("%.1f", mZ)));
+        mRawAngle.setText(getString(R.string.compass_raw_angle, String.format("%.1f", mAngle)));
+    }
+
+    @Override
+    public void onClick(View v) {
+        int visibility = mRawX.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE;
+        mRawX.setVisibility(visibility);
+        mRawY.setVisibility(visibility);
+        mRawZ.setVisibility(visibility);
+        mRawAngle.setVisibility(visibility);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        if (savedInstanceState != null && savedInstanceState.getBoolean("s", false)) {
+            mX = savedInstanceState.getFloat("x", 0);
+            mY = savedInstanceState.getFloat("y", 0);
+            mZ = savedInstanceState.getFloat("z", 0);
+            mAngle = savedInstanceState.getFloat("a", 0);
+            setValue(null, mAngle, mX, mY, mZ);
+            return;
+        }
+        reset();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean("s", true);
+        outState.putFloat("x", mX);
+        outState.putFloat("y", mY);
+        outState.putFloat("z", mZ);
+        outState.putFloat("a", mAngle);
+    }
+
+    public void reset() {
+        mRawX.setText("");
+        mRawY.setText("");
+        mRawZ.setText("");
+        mRawAngle.setText("");
+        mX = 0;
+        mY = 0;
+        mZ = 0;
+        mAngle = 0;
+    }
+
+    @Override
+    public void showFirstAnimatedValues() {
+        mNeedle.setRotation(mAngle);
+    }
+
+    @Override
+    public boolean hasAnimatedValuesChanged() {
+        return mPreviousAngle != mAngle;
+    }
+
+    @Override
+    public void saveAnimatedValues() {
+        mPreviousAngle = mAngle;
+    }
+
+    @Override
+    public void prepareAnimatedValues(List<PropertyValuesHolder> values) {
+        PropertyValuesHolder v = null;
+
+        float angleChange = mAngle - mPreviousAngle;
+        if (angleChange > -180 && angleChange < 180) {
+            v = PropertyValuesHolder.ofFloat("compass.angle", mPreviousAngle, mAngle);
+        } else {
+            // we jumped more than +-180 degrees==>crossing 0 mark
+            if (mAngle < mPreviousAngle) {
+                // Example: 350->10 CW
+                v = PropertyValuesHolder.ofFloat("compass.angle", mPreviousAngle, mAngle + 360);
+            } else {
+                // Example 10 >350 CCW
+                v = PropertyValuesHolder.ofFloat("compass.angle", mPreviousAngle + 360, mAngle);
+            }
+        }
+        values.add(v);
+    }
+
+    @Override
+    public void onAnimationUpdate(ValueAnimator a) {
+        Object angle = a.getAnimatedValue("compass.angle");
+        if (angle != null) {
+            mNeedle.setRotation((Float) angle);
+        }
+    }
+
+
+    public void setEnabled(boolean enabled) {
+        if (enabled) {
+            mNeedle.setVisibility(View.VISIBLE);
+            mClickablePanel.setOnClickListener(this);
+        } else {
+            mNeedle.setVisibility(View.INVISIBLE);
+            mRawX.setVisibility(View.INVISIBLE);
+            mRawY.setVisibility(View.INVISIBLE);
+            mRawZ.setVisibility(View.INVISIBLE);
+            mRawAngle.setVisibility(View.INVISIBLE);
+            mClickablePanel.setOnClickListener(null);
+        }
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/GyroFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/GyroFragment.java
index 26f3985c727882415e2fd7a8c50dc5d6fe6696ef..8882d7d73152740c4702aa19f9e2e64bfe59f393 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/GyroFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/GyroFragment.java
@@ -1,230 +1,230 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import java.util.List;
-
-import com.broadcom.app.wicedsense.AnimationManager.Animated;
-
-import android.animation.PropertyValuesHolder;
-import android.animation.ValueAnimator;
-import android.app.Fragment;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-public class GyroFragment extends Fragment implements OnClickListener, Animated {
-    public static final String TAG = Settings.TAG_PREFIX + ".GyroFragment";
-    private static final float mMaxValue = SensorDataParser.SENSOR_GYRO_MAX;
-    private static final float mMinValue = SensorDataParser.SENSOR_GYRO_MIN;
-    private static final float GAUGE_MAX_ANGLE = 120;
-    private static final float GAUGE_MIN_ANGLE = -120;
-
-    private ImageView mNeedleX;
-    private ImageView mNeedleY;
-    private ImageView mNeedleZ;
-    private TextView mRawX;
-    private TextView mRawY;
-    private TextView mRawZ;
-    private View mClickablePanel;
-
-    private float mX;
-    private float mY;
-    private float mZ;
-
-    private float mPreviousX;
-    private float mPreviousY;
-    private float mPreviousZ;
-
-    private float getGaugeScaledAngle(float gyroValue) {
-        float a = GAUGE_MIN_ANGLE
-                + ((GAUGE_MAX_ANGLE - GAUGE_MIN_ANGLE) * (gyroValue - mMinValue) / (mMaxValue - mMinValue));
-        return a;
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        View v = inflater.inflate(R.layout.gyro_fragment, null);
-        return v;
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        mNeedleX = (ImageView) view.findViewById(R.id.needle_x);
-        mNeedleY = (ImageView) view.findViewById(R.id.needle_y);
-        mNeedleZ = (ImageView) view.findViewById(R.id.needle_z);
-
-        mClickablePanel = view.findViewById(R.id.clickable_panel);
-        mClickablePanel.setOnClickListener(this);
-        mRawX = (TextView) view.findViewById(R.id.raw_x);
-        mRawY = (TextView) view.findViewById(R.id.raw_y);
-        mRawZ = (TextView) view.findViewById(R.id.raw_z);
-    }
-
-    public boolean mPivotSet = false;
-
-    public void setValue(AnimationManager animation, float x, float y, float z) {
-
-        mX = x;
-        mY = y;
-        mZ = z;
-        if (!hasAnimatedValuesChanged()) {
-            return;
-        }
-        if (animation != null && animation.useAnimation()) {
-            animation.prepareAnimated(this);
-        } else {
-            saveAnimatedValues();
-            setGauge(x, y, z);
-        }
-        updateTextWidgets();
-    }
-
-    private void updateTextWidgets() {
-        mRawX.setText(getString(R.string.raw_x, String.format("%.1f", mX)));
-        mRawY.setText(getString(R.string.raw_y, String.format("%.1f", mY)));
-        mRawZ.setText(getString(R.string.raw_z, String.format("%.1f", mZ)));
-    }
-
-    private void setGauge(float x, float y, float z) {
-        setNeedle(mNeedleX, x);
-        setNeedle(mNeedleY, y);
-        setNeedle(mNeedleZ, z);
-    }
-
-    private void setNeedle(ImageView mNeedleView, float value) {
-
-        if (value < mMinValue) {
-            value = mMinValue;
-        }
-        if (value > mMaxValue) {
-            value = mMaxValue;
-        }
-
-        float rotAngle = getGaugeScaledAngle(value);
-        float curAngle = mNeedleView.getRotation();
-
-        float rotationDist = Math.abs(curAngle - rotAngle);
-        if (rotationDist < 180.0) {
-            // Rotate normally
-            mNeedleView.setRotation(rotAngle);
-        } else {
-            // Rotate in 2 steps
-            float rotDir = (rotAngle > curAngle) ? 1.0f : -1.0f;
-            float rot1 = curAngle + ((rotationDist / 2.0f) * rotDir);
-            float rot2 = rotAngle;
-            mNeedleView.setRotation(rot1);
-            mNeedleView.setRotation(rot2);
-        }
-    }
-
-    @Override
-    public void onClick(View v) {
-        int visibility = mRawX.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE;
-        mRawX.setVisibility(visibility);
-        mRawY.setVisibility(visibility);
-        mRawZ.setVisibility(visibility);
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        if (savedInstanceState != null && savedInstanceState.getBoolean("s", false)) {
-            mX = savedInstanceState.getFloat("x", 0);
-            mY = savedInstanceState.getFloat("y", 0);
-            mZ = savedInstanceState.getFloat("z", 0);
-            setValue(null, mX, mY, mZ);
-            return;
-        }
-        reset();
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean("s", true);
-        outState.putFloat("x", mX);
-        outState.putFloat("y", mY);
-        outState.putFloat("z", mZ);
-    }
-
-    public void reset() {
-        mRawX.setText("");
-        mRawY.setText("");
-        mRawZ.setText("");
-        mX = 0;
-        mY = 0;
-        mZ = 0;
-    }
-
-    @Override
-    public boolean hasAnimatedValuesChanged() {
-        return mPreviousX != mX || mPreviousY != mY || mPreviousZ != mZ;
-    }
-
-    @Override
-    public void saveAnimatedValues() {
-        mPreviousX = mX;
-        mPreviousY = mY;
-        mPreviousZ = mZ;
-    }
-
-    @Override
-    public void showFirstAnimatedValues() {
-        setGauge(mX, mY, mZ);
-    }
-
-    @Override
-    public void prepareAnimatedValues(List<PropertyValuesHolder> values) {
-        values.add(PropertyValuesHolder.ofFloat("gyro.x", mPreviousX, mX));
-        values.add(PropertyValuesHolder.ofFloat("gyro.y", mPreviousY, mY));
-        values.add(PropertyValuesHolder.ofFloat("gyro.z", mPreviousY, mZ));
-    }
-
-    @Override
-    public void onAnimationUpdate(ValueAnimator animation) {
-        Object x = animation.getAnimatedValue("gyro.x");
-        Object y = animation.getAnimatedValue("gyro.y");
-        Object z = animation.getAnimatedValue("gyro.z");
-        if (x != null && y != null && z != null) {
-            setGauge((Float) x, (Float) y, (Float) z);
-        }
-    }
-
-    public void setEnabled(boolean enabled) {
-        if (enabled) {
-            mNeedleX.setVisibility(View.VISIBLE);
-            mNeedleY.setVisibility(View.VISIBLE);
-            mNeedleZ.setVisibility(View.VISIBLE);
-            mClickablePanel.setOnClickListener(this);
-        } else {
-            mNeedleX.setVisibility(View.INVISIBLE);
-            mNeedleY.setVisibility(View.INVISIBLE);
-            mNeedleZ.setVisibility(View.INVISIBLE);
-            mRawX.setVisibility(View.INVISIBLE);
-            mRawY.setVisibility(View.INVISIBLE);
-            mRawZ.setVisibility(View.INVISIBLE);
-            mClickablePanel.setOnClickListener(null);
-        }
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import java.util.List;
+
+import com.broadcom.app.wicedsense.AnimationManager.Animated;
+
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class GyroFragment extends Fragment implements OnClickListener, Animated {
+    public static final String TAG = Settings.TAG_PREFIX + ".GyroFragment";
+    private static final float mMaxValue = SensorDataParser.SENSOR_GYRO_MAX;
+    private static final float mMinValue = SensorDataParser.SENSOR_GYRO_MIN;
+    private static final float GAUGE_MAX_ANGLE = 120;
+    private static final float GAUGE_MIN_ANGLE = -120;
+
+    private ImageView mNeedleX;
+    private ImageView mNeedleY;
+    private ImageView mNeedleZ;
+    private TextView mRawX;
+    private TextView mRawY;
+    private TextView mRawZ;
+    private View mClickablePanel;
+
+    private float mX;
+    private float mY;
+    private float mZ;
+
+    private float mPreviousX;
+    private float mPreviousY;
+    private float mPreviousZ;
+
+    private float getGaugeScaledAngle(float gyroValue) {
+        float a = GAUGE_MIN_ANGLE
+                + ((GAUGE_MAX_ANGLE - GAUGE_MIN_ANGLE) * (gyroValue - mMinValue) / (mMaxValue - mMinValue));
+        return a;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.gyro_fragment, null);
+        return v;
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        mNeedleX = (ImageView) view.findViewById(R.id.needle_x);
+        mNeedleY = (ImageView) view.findViewById(R.id.needle_y);
+        mNeedleZ = (ImageView) view.findViewById(R.id.needle_z);
+
+        mClickablePanel = view.findViewById(R.id.clickable_panel);
+        mClickablePanel.setOnClickListener(this);
+        mRawX = (TextView) view.findViewById(R.id.raw_x);
+        mRawY = (TextView) view.findViewById(R.id.raw_y);
+        mRawZ = (TextView) view.findViewById(R.id.raw_z);
+    }
+
+    public boolean mPivotSet = false;
+
+    public void setValue(AnimationManager animation, float x, float y, float z) {
+
+        mX = x;
+        mY = y;
+        mZ = z;
+        if (!hasAnimatedValuesChanged()) {
+            return;
+        }
+        if (animation != null && animation.useAnimation()) {
+            animation.prepareAnimated(this);
+        } else {
+            saveAnimatedValues();
+            setGauge(x, y, z);
+        }
+        updateTextWidgets();
+    }
+
+    private void updateTextWidgets() {
+        mRawX.setText(getString(R.string.raw_x, String.format("%.1f", mX)));
+        mRawY.setText(getString(R.string.raw_y, String.format("%.1f", mY)));
+        mRawZ.setText(getString(R.string.raw_z, String.format("%.1f", mZ)));
+    }
+
+    private void setGauge(float x, float y, float z) {
+        setNeedle(mNeedleX, x);
+        setNeedle(mNeedleY, y);
+        setNeedle(mNeedleZ, z);
+    }
+
+    private void setNeedle(ImageView mNeedleView, float value) {
+
+        if (value < mMinValue) {
+            value = mMinValue;
+        }
+        if (value > mMaxValue) {
+            value = mMaxValue;
+        }
+
+        float rotAngle = getGaugeScaledAngle(value);
+        float curAngle = mNeedleView.getRotation();
+
+        float rotationDist = Math.abs(curAngle - rotAngle);
+        if (rotationDist < 180.0) {
+            // Rotate normally
+            mNeedleView.setRotation(rotAngle);
+        } else {
+            // Rotate in 2 steps
+            float rotDir = (rotAngle > curAngle) ? 1.0f : -1.0f;
+            float rot1 = curAngle + ((rotationDist / 2.0f) * rotDir);
+            float rot2 = rotAngle;
+            mNeedleView.setRotation(rot1);
+            mNeedleView.setRotation(rot2);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        int visibility = mRawX.getVisibility() == View.VISIBLE ? View.INVISIBLE : View.VISIBLE;
+        mRawX.setVisibility(visibility);
+        mRawY.setVisibility(visibility);
+        mRawZ.setVisibility(visibility);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        if (savedInstanceState != null && savedInstanceState.getBoolean("s", false)) {
+            mX = savedInstanceState.getFloat("x", 0);
+            mY = savedInstanceState.getFloat("y", 0);
+            mZ = savedInstanceState.getFloat("z", 0);
+            setValue(null, mX, mY, mZ);
+            return;
+        }
+        reset();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean("s", true);
+        outState.putFloat("x", mX);
+        outState.putFloat("y", mY);
+        outState.putFloat("z", mZ);
+    }
+
+    public void reset() {
+        mRawX.setText("");
+        mRawY.setText("");
+        mRawZ.setText("");
+        mX = 0;
+        mY = 0;
+        mZ = 0;
+    }
+
+    @Override
+    public boolean hasAnimatedValuesChanged() {
+        return mPreviousX != mX || mPreviousY != mY || mPreviousZ != mZ;
+    }
+
+    @Override
+    public void saveAnimatedValues() {
+        mPreviousX = mX;
+        mPreviousY = mY;
+        mPreviousZ = mZ;
+    }
+
+    @Override
+    public void showFirstAnimatedValues() {
+        setGauge(mX, mY, mZ);
+    }
+
+    @Override
+    public void prepareAnimatedValues(List<PropertyValuesHolder> values) {
+        values.add(PropertyValuesHolder.ofFloat("gyro.x", mPreviousX, mX));
+        values.add(PropertyValuesHolder.ofFloat("gyro.y", mPreviousY, mY));
+        values.add(PropertyValuesHolder.ofFloat("gyro.z", mPreviousY, mZ));
+    }
+
+    @Override
+    public void onAnimationUpdate(ValueAnimator animation) {
+        Object x = animation.getAnimatedValue("gyro.x");
+        Object y = animation.getAnimatedValue("gyro.y");
+        Object z = animation.getAnimatedValue("gyro.z");
+        if (x != null && y != null && z != null) {
+            setGauge((Float) x, (Float) y, (Float) z);
+        }
+    }
+
+    public void setEnabled(boolean enabled) {
+        if (enabled) {
+            mNeedleX.setVisibility(View.VISIBLE);
+            mNeedleY.setVisibility(View.VISIBLE);
+            mNeedleZ.setVisibility(View.VISIBLE);
+            mClickablePanel.setOnClickListener(this);
+        } else {
+            mNeedleX.setVisibility(View.INVISIBLE);
+            mNeedleY.setVisibility(View.INVISIBLE);
+            mNeedleZ.setVisibility(View.INVISIBLE);
+            mRawX.setVisibility(View.INVISIBLE);
+            mRawY.setVisibility(View.INVISIBLE);
+            mRawZ.setVisibility(View.INVISIBLE);
+            mClickablePanel.setOnClickListener(null);
+        }
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/HumidityFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/HumidityFragment.java
index 58245c16479d71d9d2f997dfcf845dbb108bb026..abdad537cbfa1cc2b3527ecd13a48da54d2f389d 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/HumidityFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/HumidityFragment.java
@@ -1,120 +1,120 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-/**
- * Our Implimentation of HumidityFragment.
- * Will attempt to closely resemble practices done in class/assignments.
- */
-public class HumidityFragment extends Fragment {
-
-//region Variables
-
-    private TextView mCurrent;
-    private TextView mMin;
-    private TextView mMax;
-    private TextView mAvg;
-
-    //endregion
-
-
-
-    //region Static information to summon Fragment.
-    private static final String ARG_HUMIDITY_ID= "humidity_id";
-
-    private static HumidityFragment newInstance() {
-        // Provided in case bundle is required in the future.
-        Bundle args = new Bundle();
-
-        // Make and return new fragment.
-        HumidityFragment fragment = new HumidityFragment();
-        fragment.setArguments(args);
-        return fragment;
-    }
-
-    //endregion
-
-
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Nullable
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        // Use inflater to get view from layout.
-        View view = inflater.inflate(R.layout.humidity_fragment, container, false);
-
-        // Set class level vars to appropriate xml attributes.
-        mCurrent = (TextView) view.findViewById(R.id.humidity_current);
-        mMin = (TextView) view.findViewById(R.id.humidity_min);
-        mMax = (TextView) view.findViewById(R.id.humidity_max);
-        mAvg = (TextView) view.findViewById(R.id.humidity_avg);
-
-        // Read in from database and set values here?
-
-        return view;
-    }
-}
-
-/**
- * WICEDSENCE default stuff.
- * Commenting out instead of removing in case we need to reference it to get the program running.
- *
- *
- *
- *
- */ /*
-public class HumidityFragment extends BaseThermoFragment {
-
-    @Override
-    protected void initRangeValues() {
-        mMaxValue = SensorDataParser.SENSOR_HUMIDITY_MAX;
-        mMinValue = SensorDataParser.SENSOR_HUMIDITY_MIN;
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        View v = inflater.inflate(R.layout.humidity_fragment, null);
-        return v;
-    }
-
-    @Override
-    protected void setGaugeText(float value) {
-        if (mGaugeLevel == null) {
-            return;
-        }
-        //mGaugeValue.setText(getString(R.string.humidity_value, String.format("%.1f", value)));
-    }
-
-    @Override
-    protected String getPropertyName() {
-        return "humd";
-    }
-
-} */
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Our Implimentation of HumidityFragment.
+ * Will attempt to closely resemble practices done in class/assignments.
+ */
+public class HumidityFragment extends Fragment {
+
+//region Variables
+
+    private TextView mCurrent;
+    private TextView mMin;
+    private TextView mMax;
+    private TextView mAvg;
+
+    //endregion
+
+
+
+    //region Static information to summon Fragment.
+    private static final String ARG_HUMIDITY_ID= "humidity_id";
+
+    private static HumidityFragment newInstance() {
+        // Provided in case bundle is required in the future.
+        Bundle args = new Bundle();
+
+        // Make and return new fragment.
+        HumidityFragment fragment = new HumidityFragment();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    //endregion
+
+
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        // Use inflater to get view from layout.
+        View view = inflater.inflate(R.layout.humidity_fragment, container, false);
+
+        // Set class level vars to appropriate xml attributes.
+        mCurrent = (TextView) view.findViewById(R.id.humidity_current);
+        mMin = (TextView) view.findViewById(R.id.humidity_min);
+        mMax = (TextView) view.findViewById(R.id.humidity_max);
+        mAvg = (TextView) view.findViewById(R.id.humidity_avg);
+
+        // Read in from database and set values here?
+
+        return view;
+    }
+}
+
+/**
+ * WICEDSENCE default stuff.
+ * Commenting out instead of removing in case we need to reference it to get the program running.
+ *
+ *
+ *
+ *
+ */ /*
+public class HumidityFragment extends BaseThermoFragment {
+
+    @Override
+    protected void initRangeValues() {
+        mMaxValue = SensorDataParser.SENSOR_HUMIDITY_MAX;
+        mMinValue = SensorDataParser.SENSOR_HUMIDITY_MIN;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.humidity_fragment, null);
+        return v;
+    }
+
+    @Override
+    protected void setGaugeText(float value) {
+        if (mGaugeLevel == null) {
+            return;
+        }
+        //mGaugeValue.setText(getString(R.string.humidity_value, String.format("%.1f", value)));
+    }
+
+    @Override
+    protected String getPropertyName() {
+        return "humd";
+    }
+
+} */
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/MainActivity.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/MainActivity.java
index 1b4f3a6af2384e228f7944a6b71501f6a31c4e4a..da73879c5ad9d2c65955591cba582d896f5eee1a 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/MainActivity.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/MainActivity.java
@@ -1,1218 +1,1218 @@
-/******************************************************************************
- *
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import com.broadcom.app.ledevicepicker.DevicePicker;
-import com.broadcom.app.ledevicepicker.DevicePickerActivity;
-import com.broadcom.app.license.LicenseUtils;
-import com.broadcom.app.license.LicenseDialog.OnLicenseAcceptListener;
-import com.broadcom.app.wicedsense.Settings.SettingChangeListener;
-import com.broadcom.app.wicedsmart.ota.OtaAppInfo;
-import com.broadcom.app.wicedsmart.ota.ui.OtaAppInfoFragment;
-import com.broadcom.app.wicedsmart.ota.ui.OtaResource;
-import com.broadcom.app.wicedsmart.ota.ui.OtaUiHelper;
-import com.broadcom.app.wicedsmart.ota.ui.OtaUiHelper.OtaUiCallback;
-import com.broadcom.ui.BluetoothEnabler;
-import com.broadcom.ui.ExitConfirmUtils;
-import com.broadcom.ui.ExitConfirmFragment.ExitConfirmCallback;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.content.BroadcastReceiver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.support.v4.app.FragmentActivity;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-import android.text.format.Time;
-
-/**
- * Manaages the main view and gauges for each sensor
- *
- */
-public class MainActivity extends FragmentActivity implements OnLicenseAcceptListener,
-        DevicePicker.Callback, android.os.Handler.Callback, OnClickListener, ExitConfirmCallback,
-        OtaUiCallback, SettingChangeListener {
-
-    //region Variables
-
-    //region Static Variables
-    private static final String TAG = Settings.TAG_PREFIX + "MainActivity";
-    private static final String JEFF_TAG = "Jeff_Tag";
-    private static final boolean DBG_LIFECYCLE = true;
-    private static final boolean DBG = Settings.DBG;
-
-    private static final int COMPLETE_INIT = 800;
-    private static final int PROCESS_SENSOR_DATA_ON_UI = 801;
-    private static final int PROCESS_BATTERY_STATUS_UI = 802;
-    private static final int PROCESS_EVENT_DEVICE_UNSUPPORTED = 803;
-    private static final int PROCESS_CONNECTION_STATE_CHANGE_UI = 804;
-
-    // Keys to send data to/from activities for fragments.
-    private static final String FRAGMENT_TEMPERATURE = "edu.kvcc.cis298.fragment_temp";
-    private static final String FRAGMENT_HUMIDITY = "edu.kvcc.cis298.fragment_humd";
-    private static final String FRAGMENT_PRESSURE = "edu.kvcc.cis298.fragment_pres";
-    private static final String FRAGMENT_GYRO = "edu.kvcc.cis298.fragment_gyro";
-    private static final String FRAGMENT_COMPASS = "edu.kvcc.cis298.fragment_compass";
-    private static final String FRAGMENT_ACCELEROMETER = "edu.kvcc.cis298.fragment_accelerometer";
-
-    //endregion
-
-    private Button mButtonConnectDisconnect;
-    private TemperatureFragment mTemperatureFrag;
-    private HumidityFragment mHumidityFrag;
-    private PressureFragment mPressureFrag;
-    private GyroFragment mGyroFrag;
-    private CompassFragment mCompassFrag;
-    private AccelerometerFragment mAccelerometerFrag;
-    private ImageView mBatteryStatusIcon;
-    private TextView mBatteryStatusText;
-    private View mBatteryStatusView;
-    private DevicePicker mDevicePicker;
-    private String mDevicePickerTitle;
-    private int mLastBatteryStatus = -1;
-    private boolean mConnectDisconnectPending;
-    private SenseManager mSenseManager;
-    private Handler mUiHandler;
-    private final BluetoothStateReceiver mBtStateReceiver = new BluetoothStateReceiver();
-    private LicenseUtils mLicense;
-    private ExitConfirmUtils mExitConfirm;
-    private int mInitState;
-    private Handler mSensorDataEventHandler;
-    private HandlerThread mSensorDataEventThread;
-    private final AnimationManager mAnimation = new AnimationManager(
-            Settings.ANIMATION_FRAME_DELAY_MS, Settings.ANIMATE_TIME_INTERVAL_MS);
-    private final AnimationManager mAnimationSlower = new AnimationManager(
-            Settings.ANIMATION_FRAME_DELAY_MS, Settings.ANIMATE_TIME_INTERVAL_MS);
-    private final OtaUiHelper mOtaUiHelper = new OtaUiHelper();
-    private boolean mShowAppInfoDialog;
-    private boolean mFirmwareUpdateCheckPending;
-    private boolean mCanAskForFirmwareUpdate;
-    private boolean mMandatoryUpdateRequired;
-    private boolean mIsTempScaleF = false;
-    private long mLastRefreshTimeMs;
-    private long mLastRefreshSlowerTimeMs;
-
-    //endregion
-
-
-
-    //region Our Methods
-
-    /**
-     * Create an intent for MainActivity.
-     * @param packageContext Context.
-     * @return Properly formatted intent for MainActivity.
-     */
-    public static Intent newIntent(Context packageContext) {
-        // Make new intent.
-        Intent intent = new Intent(packageContext, MainActivity.class);
-        return intent;
-    }
-
-
-    //region Database Methods
-    //************************************  This is to open the database - JEFF  Added******************
-
-    private Context mContext;
-    private SQLiteDatabase mDatabase;
-
-    private String mHumidityValue;
-    private String mPressureValue;
-    private String mTemperatureValue;
-
-    public void StartDatabase(Context context){
-        mContext = context.getApplicationContext();
-        mDatabase = new ThermoBaseHelper(mContext).getReadableDatabase();
-        Toast.makeText(this, "Main Activity", Toast.LENGTH_SHORT).show();
-    }
-
-    private ContentValues getContentValues(){ // To place values in the database  ????? What am I passing in?   see page 325
-
-        Time now = new Time();
-        now.setToNow();
-        String time = now.format("%Y_%m_%d_%H_%M_%S");
-
-        ContentValues values = new ContentValues();
-        values.put(WicedDBSchema.ThermoTable.Cols.TIME, time);
-        Log.d(JEFF_TAG, "Put time into ContentValues = " + time);
-        values.put(WicedDBSchema.ThermoTable.Cols.HUMIDITY, mHumidityValue);
-        Log.d(JEFF_TAG, "Put Humidty into ContentValues = " + mHumidityValue);
-        values.put(WicedDBSchema.ThermoTable.Cols.PRESSURE, mPressureValue);
-        Log.d(JEFF_TAG, "Put Pressure into ContentValues = " + mPressureValue);
-        values.put(WicedDBSchema.ThermoTable.Cols.TEMPERATURE, mTemperatureValue);
-        Log.d(JEFF_TAG, "Put Temperature into ContentValues = " + mTemperatureValue);
-
-        return values;
-    }
-
-    public  void addThermoData () {//  Add a row of data????????????What am I passing in?    see page 326
-        Log.d(JEFF_TAG, "adding data");
-        ContentValues values = getContentValues();
-        mDatabase.insert(WicedDBSchema.ThermoTable.NAME, null, values);
-    }
-
-    public void DataDump(){
-        Log.d(JEFF_TAG, "Place data dump in ExitConfirmFragment.java");
-    }
-
-    //endregion
-
-
-    //endregion
-
-
-
-    //region Override Methods
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        if (DBG_LIFECYCLE) {
-            Log.d(TAG, "onCreate " + this);
-        }
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main_activity);
-
-
-        //region Broadcom Stuff
-        // Initialize dialogs
-        initDevicePicker();
-        initLicenseUtils();
-        initExitConfirm();
-
-        mInitState = 0;
-
-        // Register bluetooth state receiver
-        registerReceiver(mBtStateReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
-
-        // Start event handler thread
-        mSensorDataEventThread = new HandlerThread("WicedSenseEventHandlerThread");
-        mSensorDataEventThread.start();
-        mSensorDataEventHandler = new Handler(mSensorDataEventThread.getLooper(), this);
-
-        // Start ui handler
-        mUiHandler = new Handler(new UiHandlerCallback());
-
-        //endregion
-
-
-        Toast.makeText(this,"About to StartDatabase", Toast.LENGTH_SHORT);
-        StartDatabase(this);
-
-        /**
-         * Shouldn't need since it's provided in abstract class.
-         * Written by Broadcom so kept as comment for reference.
-         *
-        FragmentManager fMgr = getFragmentManager();
-        mHumidityFrag = (HumidityFragment) fMgr.findFragmentByTag(FRAGMENT_HUMDITY);
-        mPressureFrag = (PressureFragment) fMgr.findFragmentByTag(FRAGMENT_PRESSURE);
-        mGyroFrag = (GyroFragment) fMgr.findFragmentByTag(FRAGMENT_GYRO);
-        mCompassFrag = (CompassFragment) fMgr.findFragmentByTag(FRAGMENT_COMPASS);
-
-        mButtonConnectDisconnect = (Button) findViewById(R.id.connection_state);
-        if (mButtonConnectDisconnect != null) {
-            mButtonConnectDisconnect.setOnClickListener(this);
-            mButtonConnectDisconnect.setEnabled(false);
-        } else {
-            // large screen sizes do not have button in the main layout. Instead
-            // it's an action button in the menu button
-        }
-        mAccelerometerFrag = (AccelerometerFragment) fMgr.findFragmentByTag(FRAGMENT_ACCELEROMETER);
-
-
-        // Register components for frequent animation
-        mAnimation.addAnimated(mAccelerometerFrag);
-        mAnimation.addAnimated(mCompassFrag);
-        mAnimation.addAnimated(mGyroFrag);
-
-        // Refresh temp,humid,press gauges using a slower animation to conserve
-        // UI resources
-        // for devices that cannot handle refresh of many widgets at the same
-        // time (IE Galaxy S4)
-        mAnimationSlower.addAnimated(mHumidityFrag);
-        mAnimationSlower.addAnimated(mPressureFrag);
-
-        updateTemperatureScaleType();
-         */
-    }
-
-    @Override
-    protected void onResume() {
-        if (DBG_LIFECYCLE) {
-            Log.d(TAG, "onResume " + this);
-        }
-        super.onResume();
-        initResourcesAndResume();
-    }
-
-    @Override
-    protected void onPause() {
-        if (DBG_LIFECYCLE) {
-            Log.d(TAG, "onPause " + this);
-        }
-        mLicense.dismiss();
-        mExitConfirm.dismiss();
-
-        Settings.removeChangeListener(this);
-
-        // Disable notifications if the application is backgrounded, but don't
-        // disconnect from the device
-        if (mSenseManager != null) {
-            if (mSenseManager.isConnectedAndAvailable()) {
-                mSenseManager.enableNotifications(false);
-            }
-            mSenseManager.unregisterEventCallbackHandler(mSensorDataEventHandler);
-        }
-        super.onPause();
-    }
-
-    @Override
-    protected void onDestroy() {
-        if (DBG_LIFECYCLE) {
-            Log.d(TAG, "onDestroy " + this);
-        }
-
-        mSensorDataEventThread.quit();
-        cleanupDevicePicker();
-        unregisterReceiver(mBtStateReceiver);
-        super.onDestroy();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.main, menu);
-        MenuItem item = menu.findItem(R.id.action_battery_status);
-        if (item == null) {
-            return true;
-        }
-
-        // ActionViews must have an explicit onClickListener registered
-        mBatteryStatusView = item.getActionView();
-        mBatteryStatusIcon = (ImageView) mBatteryStatusView.findViewById(R.id.battery_status_icon);
-        mBatteryStatusText = (TextView) mBatteryStatusView.findViewById(R.id.battery_status);
-        mBatteryStatusView.setOnClickListener(this);
-        return true;
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
-
-        boolean isDeviceSelected = (mSenseManager != null && mSenseManager.getDevice() != null);
-        boolean isDeviceConnected = isDeviceSelected && mSenseManager.isConnectedAndAvailable();
-
-        // Check if we are in landscape mode. If so, update the state of the
-        // connect/disconnect action
-        if (mButtonConnectDisconnect == null) {
-            // Get Connect/disconnect button
-            MenuItem menuConnectDisconnect = menu.findItem(R.id.action_connectdisconnect);
-            if (menuConnectDisconnect != null) {
-                // Landscape mode
-                if (!isDeviceSelected) {
-                    // No device selected: hide connect/disconnect button
-                    // menuConnectDisconnect.setVisible(false);
-                    menuConnectDisconnect.setEnabled(false);
-
-                } else {
-                    menuConnectDisconnect.setEnabled(!mConnectDisconnectPending);
-                    if (isDeviceConnected) {
-                        menuConnectDisconnect.setTitle(R.string.disconnect);
-                    } else {
-                        menuConnectDisconnect.setTitle(R.string.connect);
-                    }
-                }
-            }
-        }
-        // Update the battery icon
-        if (mBatteryStatusView != null && mBatteryStatusIcon != null && mBatteryStatusText != null) {
-            int batteryStatus = mLastBatteryStatus;
-            if (!isDeviceConnected) {
-                mBatteryStatusIcon.setImageResource(getBatteryStatusIcon(-1));
-                mBatteryStatusText.setText(getString(R.string.battery_status, "??"));
-            } else {
-                mBatteryStatusView.setEnabled(true);
-                mBatteryStatusIcon.setImageResource(getBatteryStatusIcon(batteryStatus));
-                mBatteryStatusText.setText(getString(R.string.battery_status, batteryStatus < 0 ? 0
-                        : batteryStatus));
-            }
-        }
-
-        // Update the update firmware button
-        MenuItem updateFw = menu.findItem(R.id.update_fw);
-        if (updateFw != null) {
-            updateFw.setEnabled(isDeviceSelected);
-        }
-
-        // Update the get firmware info button
-        MenuItem getFwInfo = menu.findItem(R.id.get_fw_info);
-        if (getFwInfo != null) {
-            getFwInfo.setEnabled(isDeviceConnected);
-        }
-
-        // Update the pick device menu: only allow a pick device from the
-        // disconnected state
-        MenuItem pick = menu.findItem(R.id.action_pick);
-        if (pick != null) {
-            pick.setEnabled(!isDeviceConnected);
-        }
-
-        return super.onPrepareOptionsMenu(menu);
-    }
-
-    /**
-     * Invoked when a menu option is picked
-     */
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        boolean isDeviceSelected = (mSenseManager != null && mSenseManager.getDevice() != null);
-        boolean isDeviceConnected = isDeviceSelected && mSenseManager.isConnectedAndAvailable();
-        switch (item.getItemId()) {
-            case R.id.action_connectdisconnect:
-                mConnectDisconnectPending = true;
-                invalidateOptionsMenu();
-                doConnectDisconnect();
-                return true;
-            case R.id.action_pick:
-                launchDevicePicker();
-                return true;
-            case R.id.data_dump:
-                if (isDeviceConnected){
-                    Toast.makeText(this,R.string.disconnect_message, Toast.LENGTH_SHORT).show();
-                }else {
-                    DataDump();
-                }
-
-                return true;
-            case R.id.get_fw_info:
-                getFirmwareInfo();
-                return true;
-            case R.id.action_settings:
-                // Launch setttings menu
-                Intent i = new Intent(this, SettingsActivity.class);
-                startActivity(i);
-                return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * Callback invoked when the user finishes with the license agreement dialog
-     */
-    @Override
-    public void onLicenseAccepted(boolean accepted) {
-        if (!accepted) {
-            exitApp();
-            return;
-        }
-        mLicense.setAccepted(true);
-        initResourcesAndResume();
-    }
-
-    /**
-     * Callback invoked when a device is selected from the device picker
-     */
-    @Override
-    public void onDevicePicked(BluetoothDevice device) {
-        if (DBG_LIFECYCLE) {
-            Log.d(TAG, "onDevicePicked");
-        }
-        if (Settings.CHECK_FOR_UPDATES_ON_CONNECT) {
-            mCanAskForFirmwareUpdate = true;
-        } else {
-            mCanAskForFirmwareUpdate = false;
-        }
-        mSenseManager.setDevice(device);
-        updateConnectionStateWidgets();
-    }
-
-    /**
-     * Callback invoked when the user aborts picking a device from the device
-     * picker
-     */
-    @Override
-    public void onDevicePickCancelled() {
-        if (DBG_LIFECYCLE) {
-            Log.d(TAG, "onDevicePickCancelled");
-        }
-        updateConnectionStateWidgets();
-    }
-
-    /**
-     * Handler callback used for two purposes
-     *
-     * 1. This callback is invoked by the event handler loop when the
-     * SenseManager service sends a event from the sensor tag using the
-     * mEventHandler object. The event handler loop runs in a child thread, so
-     * that it can queue up events and allow the SenseManager (and Bluetooth
-     * callbacks) to return asynchronously before the UI processes the event.
-     * The event handler loop reposts the event to the main UI handler loop via
-     * the mUiHandler Handler
-     *
-     * 2. This callback is invoked by the mEventHandler object to run a UI
-     * operation in the main event loop of the application
-     *
-     *
-     */
-    @Override
-    public boolean handleMessage(Message msg) {
-        switch (msg.what) {
-            case SenseManager.EVENT_DEVICE_UNSUPPORTED:
-                mUiHandler.sendEmptyMessage(PROCESS_EVENT_DEVICE_UNSUPPORTED);
-                break;
-            case SenseManager.EVENT_CONNECTED:
-                mUiHandler.sendEmptyMessage(PROCESS_CONNECTION_STATE_CHANGE_UI);
-                onConnected();
-                break;
-            case SenseManager.EVENT_DISCONNECTED:
-                mUiHandler.sendEmptyMessage(PROCESS_CONNECTION_STATE_CHANGE_UI);
-                break;
-            case SenseManager.EVENT_BATTERY_STATUS:
-                mUiHandler.sendMessage(mUiHandler.obtainMessage(PROCESS_BATTERY_STATUS_UI, msg.arg1,
-                        msg.arg1));
-                break;
-            case SenseManager.EVENT_SENSOR_DATA:
-                mUiHandler.sendMessage(mUiHandler.obtainMessage(PROCESS_SENSOR_DATA_ON_UI, msg.obj));
-                break;
-            case SenseManager.EVENT_APP_INFO:
-                boolean success = msg.arg1 == 1;
-                OtaAppInfo appInfo = (OtaAppInfo) msg.obj;
-                if (DBG) {
-                    Log.d(TAG, "EVENT_APP_INFO: success=" + success + ",otaAppInfo=" + appInfo);
-                }
-                if (mFirmwareUpdateCheckPending) {
-                    mFirmwareUpdateCheckPending = false;
-                    checkForFirmwareUpdate(appInfo);
-                    break;
-                }
-
-                if (mShowAppInfoDialog) {
-                    mShowAppInfoDialog = false;
-                    if (success) {
-                        OtaAppInfoFragment mOtaAppInfoFragment = OtaAppInfoFragment.createDialog(
-                                mSenseManager.getDevice(), appInfo);
-                        mOtaAppInfoFragment.show(getFragmentManager(), null);
-                    }
-                }
-                break;
-        }
-        return true;
-    }
-
-    /**
-     * Callback invoked when the connect/disconnect button is clicked or the
-     * battery status button is clicked
-     */
-    @Override
-    public void onClick(View v) {
-
-        // Process connect/disconnect request
-        if (v == mButtonConnectDisconnect) {
-            // Temporary disable the button while a connect/disconnect is
-            // pending
-            mConnectDisconnectPending = true;
-            mButtonConnectDisconnect.setEnabled(false);
-            doConnectDisconnect();
-        }
-
-        // Process battery status request
-        else if (v == mBatteryStatusView) {
-            if (mSenseManager != null) {
-                mSenseManager.getBatteryStatus();
-            }
-        }
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == BluetoothEnabler.REQUEST_ENABLE_BT) {
-            if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
-                exitApp();
-                return;
-            }
-            initResourcesAndResume();
-        }
-    }
-
-    /**
-     * Show exit confirmation dialog if user presses the button
-     */
-    @Override
-    public void onBackPressed() {
-        mExitConfirm.show(getFragmentManager());
-    }
-
-    /**
-     * Callback invoked when the user selects "ok" from the exit confirmation
-     * dialog
-     */
-    @Override
-    public void onExit() {
-        exitApp();
-    }
-
-    /**
-     * Callback invoked when the user cancels exitting the application.
-     */
-    @Override
-    public void onExitCancelled() {
-    }
-
-    /**
-     * Callback invoked when the OTA firmware update has completed
-     *
-     * @param completed
-     *            : if true, OTA upgrade was successful, false otherwise.
-     */
-    @Override
-    public void onOtaFinished(boolean completed) {
-        if (DBG_LIFECYCLE) {
-            Log.d(TAG, "onOtaFinished");
-        }
-
-        // If OTA did not complete and the patch was mandatory, disconnect
-        if (!completed && mMandatoryUpdateRequired) {
-            if (mSenseManager != null) {
-                mSenseManager.disconnect();
-            }
-            return;
-        }
-
-        // Enable notifications
-        if (mSenseManager != null) {
-            mSenseManager.setOtaUpdateMode(false);
-        }
-    }
-
-    @Override
-    public void onSettingsChanged(String settingName) {
-        if (Settings.SETTINGS_KEY_TEMPERATURE_SCALE_TYPE.equals(settingName)) {
-            //updateTemperatureScaleType();
-        }
-    }
-
-    //endregion
-
-
-
-    //region Broadcom's Pre-provided methods.
-
-    // Int which changes based on battery level? Seems pointless to have in this kind of app but okay.
-    private static int getBatteryStatusIcon(int batteryLevel) {
-        if (batteryLevel <= 0) {
-            return R.drawable.battery_charge_background;
-        } else if (batteryLevel < 25) {
-            return R.drawable.battery_charge_25;
-        } else if (batteryLevel < 50) {
-            return R.drawable.battery_charge_50;
-        } else if (batteryLevel < 75) {
-            return R.drawable.battery_charge_75;
-        } else {
-            return R.drawable.battery_charge_full;
-        }
-
-    }
-
-    /**
-     * Handles Bluetooth on/off events. If Bluetooth is turned off, exit this
-     * app
-     *
-     * @author Fred Chen
-     *
-     */
-    private class BluetoothStateReceiver extends BroadcastReceiver {
-
-        @Override
-        public void onReceive(final Context context, final Intent intent) {
-            mSensorDataEventHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    int btState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                            BluetoothAdapter.ERROR);
-                    switch (btState) {
-
-                        case BluetoothAdapter.STATE_TURNING_OFF:
-                            exitApp();
-                            break;
-                    }
-                }
-            });
-        }
-    }
-
-    private class UiHandlerCallback implements Handler.Callback {
-
-        @Override
-        public boolean handleMessage(Message msg) {
-            switch (msg.what) {
-
-                // These events run on the mUiHandler on the UI Main Thread
-                case COMPLETE_INIT:
-                    initResourcesAndResume();
-                    break;
-                case PROCESS_EVENT_DEVICE_UNSUPPORTED:
-                    Toast.makeText(getApplicationContext(), R.string.error_unsupported_device,
-                            Toast.LENGTH_SHORT).show();
-                    break;
-                case PROCESS_CONNECTION_STATE_CHANGE_UI:
-                    updateConnectionStateWidgets();
-                    break;
-                case PROCESS_BATTERY_STATUS_UI:
-                    updateBatteryLevelWidget(msg.arg1);
-                    break;
-                case PROCESS_SENSOR_DATA_ON_UI:
-                    processSensorData((byte[]) msg.obj);
-                    break;
-            }
-            return true;
-        }
-    };
-
-
-    /**
-     * Initialize async resources in series
-     *
-     * @return
-     */
-    private boolean initResourcesAndResume() {
-        switch (mInitState) {
-            case 0:
-                // Check if license accepted. If not, prompt user
-                if (!mLicense.checkLicenseAccepted(getFragmentManager())) {
-                    return false;
-                }
-                mInitState++;
-            case 1:
-                // Check if BT is on, If not, prompt user
-                if (!BluetoothEnabler.checkBluetoothOn(this)) {
-                    return false;
-                }
-                mInitState++;
-                SenseManager.init(this);
-            case 2:
-                // Check if sense manager initialized. If not, keep waiting
-                if (waitForSenseManager()) {
-                    return false;
-                }
-                mInitState = -1;
-                checkDevicePicked();
-        }
-        mSenseManager.registerEventCallbackHandler(mSensorDataEventHandler);
-
-        if (mSenseManager.isConnectedAndAvailable()) {
-            mSenseManager.enableNotifications(true);
-        }
-        updateConnectionStateWidgets();
-        //updateTemperatureScaleType();
-        //updateGyroState();
-        //updateAccelerometerState();
-        //updateCompassState();
-        Settings.addChangeListener(this);
-        return true;
-    }
-
-    /**
-     * Acquire reference to the SenseManager serivce....This is asynchronous
-     *
-     * @return
-     */
-    private boolean waitForSenseManager() {
-        // Check if the SenseManager is available. If not, keep retrying
-        mSenseManager = SenseManager.getInstance();
-        if (mSenseManager == null) {
-            mUiHandler.sendEmptyMessageDelayed(COMPLETE_INIT, Settings.SERVICE_INIT_TIMEOUT_MS);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Exit the application and cleanup resources
-     */
-    protected void exitApp() {
-        if (DBG_LIFECYCLE) {
-            Log.d(TAG, "exitApp");
-        }
-        SenseManager.destroy();
-        finish();
-    }
-
-    /**
-     * Update the battery level UI widgets
-     *
-     * @param batteryLevel
-     */
-    private void updateBatteryLevelWidget(int batteryLevel) {
-        mLastBatteryStatus = batteryLevel;
-        invalidateOptionsMenu();
-    }
-
-
-    //region License Stuff
-
-    /**
-     * Initialize the license agreement dialog
-     */
-    private void initLicenseUtils() {
-        mLicense = new LicenseUtils(this, this);
-    }
-
-    /**
-     * Initialize the exit confirmation dialog
-     */
-    private void initExitConfirm() {
-        mExitConfirm = new ExitConfirmUtils(this);
-    }
-
-    //endregion
-
-
-    //region Device Selection/Connection
-
-    /**
-     * Update all UI components related to the connection state
-     */
-    private void updateConnectionStateWidgets() {
-        mConnectDisconnectPending = false;
-        if (mButtonConnectDisconnect != null) {
-            if (mSenseManager.getDevice() == null) {
-                mButtonConnectDisconnect.setEnabled(false);
-                mButtonConnectDisconnect.setText(R.string.no_device);
-                return;
-            }
-            if (!mButtonConnectDisconnect.isEnabled()) {
-                mButtonConnectDisconnect.setEnabled(true);
-            }
-            if (mSenseManager.isConnectedAndAvailable()) {
-                mButtonConnectDisconnect.setText(R.string.disconnect);
-            } else {
-                mButtonConnectDisconnect.setText(R.string.connect);
-            }
-            mButtonConnectDisconnect.setEnabled(true);
-        }
-        invalidateOptionsMenu();
-    }
-
-    /*
-     * Initialize the device picker
-     *
-     * @return
-     */
-    private void initDevicePicker() {
-        mDevicePickerTitle = getString(R.string.title_devicepicker);
-        mDevicePicker = new DevicePicker(this, Settings.PACKAGE_NAME,
-                DevicePickerActivity.class.getName(), this,
-                Uri.parse("content://com.brodcom.app.wicedsense/device/pick"));
-        mDevicePicker.init();
-    }
-
-    /**
-     * Launch the device picker
-     */
-    private void launchDevicePicker() {
-        mDevicePicker.launch(mDevicePickerTitle, null, null);
-    }
-
-    /**
-     * Cleanup the device picker
-     */
-    private void cleanupDevicePicker() {
-        if (mDevicePicker != null) {
-            mDevicePicker.cleanup();
-            mDevicePicker = null;
-        }
-    }
-
-    /**
-     * Check if a device has been picked, and launch the device picker if not...
-     *
-     * @return
-     */
-    private boolean checkDevicePicked() {
-        if (mSenseManager != null && mSenseManager.getDevice() != null) {
-            return true;
-        }
-        // Launch device picker
-        launchDevicePicker();
-        return false;
-    }
-
-    /**
-     * Start the connect or disconnect, based on the current state of the device
-     */
-    private void doConnectDisconnect() {
-        if (!mSenseManager.isConnectedAndAvailable()) {
-            if (!mSenseManager.connect()) {
-                updateConnectionStateWidgets();
-            }
-        } else {
-            if (!mSenseManager.disconnect()) {
-                updateConnectionStateWidgets();
-            }
-        }
-    }
-
-    //endregion
-
-
-    /**
-     * Parses the sensor data bytes and updates the corresponding sensor(s) UI
-     * component
-     *
-     * @param sensorData
-     */
-    private void processSensorData(byte[] sensorData) {
-        if (mAnimation != null && mAnimation.useAnimation()) {
-            mAnimation.init();
-        }
-
-        if (mAnimationSlower != null && mAnimationSlower.useAnimation()) {
-            mAnimationSlower.init();
-        }
-
-        int maskField = sensorData[0];
-        int offset = 0;
-        int[] values = new int[3];
-        boolean updateView = false;
-        long currentTimeMs = System.currentTimeMillis();
-        switch (sensorData.length) {
-            case 19:
-                if (currentTimeMs - mLastRefreshTimeMs < Settings.REFRESH_INTERVAL_MS) {
-                    return;
-                } else {
-                    mLastRefreshTimeMs = currentTimeMs;
-                }
-
-                // packet type specifying accelerometer, gyro, magno
-                offset = 1;
-                if (SensorDataParser.accelerometerHasChanged(maskField)) {
-                    if (Settings.accelerometerEnabled() && mAccelerometerFrag.isVisible()) {
-                        SensorDataParser.getAccelorometerData(sensorData, offset, values);
-                        //mAccelerometerFrag.setValue(mAnimation, values[0], values[1], values[2]);
-                        updateView = true;
-                    }
-                    offset += SensorDataParser.SENSOR_ACCEL_DATA_SIZE;
-                }
-
-                if (SensorDataParser.gyroHasChanged(maskField)) {
-                    if (Settings.gyroEnabled() && mGyroFrag.isVisible()) {
-                        SensorDataParser.getGyroData(sensorData, offset, values);
-                        mGyroFrag.setValue(mAnimation, values[0], values[1], values[2]);
-                        updateView = true;
-                    }
-                    offset += SensorDataParser.SENSOR_GYRO_DATA_SIZE;
-                }
-
-                if (SensorDataParser.magnetometerHasChanged(maskField)) {
-                    if (Settings.compassEnabled() && mCompassFrag.isVisible()) {
-                        SensorDataParser.getMagnometerData(sensorData, offset, values);
-                        float angle = SensorDataParser.getCompassAngleDegrees(values);
-                        mCompassFrag.setValue(mAnimation, angle, values[0], values[1], values[2]);
-                        updateView = true;
-                    }
-                    offset += SensorDataParser.SENSOR_MAGNO_DATA_SIZE;
-                }
-
-                if (updateView && mAnimation != null) {
-                    mAnimation.animate();
-                }
-                break;
-            case 7:
-
-                if (currentTimeMs - mLastRefreshSlowerTimeMs < Settings.REFRESH_INTERVAL_SLOWER_MS) {
-                    return;
-                } else {
-                    mLastRefreshSlowerTimeMs = currentTimeMs;
-                }
-
-                // packet type specifying temp, humid, press
-                offset = 1;
-                float value = 0;
-                if (mHumidityFrag.isVisible() && SensorDataParser.humidityHasChanged(maskField)) {
-                    value = SensorDataParser.getHumidityPercent(sensorData, offset);
-                    mHumidityValue = Float.toString(value);
-                    Log.d(JEFF_TAG,"Humidity = " + mHumidityValue);
-                    offset += SensorDataParser.SENSOR_HUMD_DATA_SIZE;
-                    //mHumidityFrag.setValue(mAnimationSlower, value);
-                    updateView = true;
-                }
-                if (mPressureFrag.isVisible() && SensorDataParser.pressureHasChanged(maskField)) {
-                    value = SensorDataParser.getPressureMBar(sensorData, offset);
-                    mPressureValue = Float.toString(value);
-                    Log.d(JEFF_TAG, "Pressure = " + mPressureValue);
-                    offset += SensorDataParser.SENSOR_PRES_DATA_SIZE;
-                    //mPressureFrag.setValue(mAnimationSlower, value);
-                    updateView = true;
-                }
-
-                if (mTemperatureFrag.isVisible() && SensorDataParser.temperatureHasChanged(maskField)) {
-                    if (mIsTempScaleF) {
-                        value = SensorDataParser.getTemperatureF(sensorData, offset);
-                    } else {
-                        value = SensorDataParser.getTemperatureC(sensorData, offset);
-                    }
-                    mTemperatureValue = Float.toString(value);
-                    Log.d(JEFF_TAG, "Temperature = "+mTemperatureValue);
-                    offset += SensorDataParser.SENSOR_TEMP_DATA_SIZE;
-                    //mTemperatureFrag.setValue(mAnimationSlower, value);
-                    updateView = true;
-                }
-                if (updateView && mAnimationSlower != null) {
-                    mAnimationSlower.animate();
-                    addThermoData();
-                    //***********************************************************************************************************************
-                }
-                break;
-        }
-
-        // If animation is enabled, call animate...
-    }
-
-
-    //region Firmware section. Is this for the fab thing you connect to?
-
-    /**
-     * Start a request to read application id, major version,minor version of a
-     * connected WICED Sense tag...
-     */
-    private void getFirmwareInfo() {
-        if (mSenseManager != null) {
-            mShowAppInfoDialog = true;
-            mSenseManager.getAppInfo();
-        }
-    }
-
-    /**
-     * Check for firmware update, if the user allows it or if there is a
-     * mandatory update. The connection is assumed to be up
-     */
-    private void checkForFirmwareUpdate() {
-        if (mSenseManager == null) {
-            return;
-        }
-        // Check if we are connected
-        if (!mSenseManager.isConnectedAndAvailable()) {
-            mCanAskForFirmwareUpdate = true;
-            boolean success = mSenseManager.connect();
-            if (!success) {
-                mCanAskForFirmwareUpdate = false;
-            }
-        } else {
-            mCanAskForFirmwareUpdate = true;
-            checkForFirmwareUpdateIfAllowed();
-        }
-    }
-
-    /**
-     * Check for firmware update, if the user allows it. The connection is
-     * assumed to be up
-     *
-     * @return
-     */
-    private boolean checkForFirmwareUpdateIfAllowed() {
-        if (!mCanAskForFirmwareUpdate && !Settings.hasMandatoryUpdate()) {
-            if (DBG) {
-                Log.d(TAG, "firmwareUpdateCheck(): user opted out...skipping..");
-            }
-            return false;
-        }
-        mFirmwareUpdateCheckPending = true;
-        if (!mSenseManager.getAppInfo()) {
-            mFirmwareUpdateCheckPending = false;
-            if (DBG) {
-                Log.d(TAG, "checkForFirmwareUpdates(): unable to get app info");
-            }
-            return false;
-        }
-        if (DBG) {
-            Log.d(TAG, "firmwareUpdateCheck(): getting app info");
-        }
-        return true;
-    }
-
-    private void onConnected() {
-        if (checkForFirmwareUpdateIfAllowed()) {
-            // Wait for firmware check...
-            if (DBG) {
-                Log.d(TAG, "onConnected:Checking for firmware updates..");
-            }
-        } else {
-            if (DBG) {
-                Log.d(TAG, "onConnected: enabling notifications");
-            }
-            if (mSenseManager != null) {
-                mSenseManager.enableNotifications(true);
-            }
-        }
-    }
-
-    private boolean canUpdateToFirmware(OtaAppInfo appInfo, OtaResource otaResource) {
-        if (otaResource == null || appInfo == null) {
-            return false;
-        }
-        if (otaResource.getMajor() <= 0) {
-            return true;
-        }
-        if (appInfo.mMajorVersion < otaResource.getMajor()) {
-            return true;
-        } else if (appInfo.mMajorVersion == otaResource.getMajor()
-                && appInfo.mMinorVersion < otaResource.getMinor()) {
-            return true;
-        }
-        return false;
-    }
-
-    private void checkForFirmwareUpdate(OtaAppInfo appInfo) {
-        mCanAskForFirmwareUpdate = false;
-        mMandatoryUpdateRequired = false;
-
-        ArrayList<OtaResource> otaResources = new ArrayList<OtaResource>();
-        OtaResource defaultResource = Settings.getDefaultOtaResource();
-        if (defaultResource != null && canUpdateToFirmware(appInfo, defaultResource)) {
-            mMandatoryUpdateRequired = defaultResource.isMandatory();
-            otaResources.add(defaultResource);
-        }
-        if (!mMandatoryUpdateRequired) {
-            OtaUiHelper.createOtaResources(Settings.getOtaDirectory(), Settings.getOtaFileFilter(),
-                    otaResources);
-            Iterator<OtaResource> i = otaResources.iterator();
-            while (i.hasNext()) {
-                OtaResource otaResource = i.next();
-                if (!canUpdateToFirmware(appInfo, otaResource)) {
-                    if (DBG) {
-                        Log.d(TAG, "Skipping OTA firmware " + otaResource.getName());
-                    }
-                    i.remove();
-                }
-            }
-        }
-        if (otaResources.size() > 0) {
-            mSenseManager.setOtaUpdateMode(true);
-            mOtaUiHelper.startUpdate(getApplicationContext(), mSenseManager.getDevice(),
-                    mSenseManager.getGattManager(), getFragmentManager(), otaResources, this, true);
-        } else {
-            mSenseManager.setOtaUpdateMode(false);
-            mSenseManager.enableNotifications(true);
-        }
-    }
-
-    //endregion
-
-
-    //region Code which we probably don't need. Commented out and kept here in case we desire to reference
-    /*
-
-
-
-    //region Update data display states? Not needed?
-
-    private void updateGyroState() {
-        if (mGyroFrag != null) {
-            mGyroFrag.setEnabled(Settings.gyroEnabled());
-        }
-    }
-
-    private void updateAccelerometerState() {
-        if (mAccelerometerFrag != null) {
-            mAccelerometerFrag.setEnabled(Settings.accelerometerEnabled());
-        }
-
-    }
-
-    private void updateCompassState() {
-        if (mCompassFrag != null) {
-            mCompassFrag.setEnabled(Settings.compassEnabled());
-        }
-    }
-
-    //endregion
-
-
-
-
-    /**
-     * Update the temperature gauge by dynamically replacing the gauge with the
-     * correct temperature type scale
-     *
-    private void updateTemperatureScaleType() {
-        // Get the old temperatureType
-        String tempScaleType = Settings.getTemperatureeScaleType();
-        mIsTempScaleF = Settings.TEMPERATURE_SCALE_TYPE_F.equals(tempScaleType);
-
-        // Check if this is a new temperature fragment
-        if (mTemperatureFrag == null) {
-            TemperatureFragment f = new TemperatureFragment();
-            f.setScaleType(mIsTempScaleF ? TemperatureFragment.SCALE_F
-                    : TemperatureFragment.SCALE_C);
-            FragmentTransaction ft = getFragmentManager().beginTransaction();
-            ft.replace(R.id.fragment_temp, f, FRAGMENT_TEMPERATURE);
-            ft.commit();
-            mTemperatureFrag = f;
-            mAnimationSlower.addAnimated(f);
-            return;
-        }
-
-        // This is a refresh. Check if the temp scale has changed
-        boolean isLastScaleF = TemperatureFragment.SCALE_F == mTemperatureFrag.getScaleType();
-        if (mIsTempScaleF == isLastScaleF) {
-            // No change. exit
-            return;
-        }
-
-        float lastTempValue = mTemperatureFrag.getLastValue();
-        TemperatureFragment f = new TemperatureFragment();
-        f.setScaleType(mIsTempScaleF ? TemperatureFragment.SCALE_F : TemperatureFragment.SCALE_C);
-        FragmentTransaction ft = getFragmentManager().beginTransaction();
-        ft.replace(R.id.fragment_temp, f, FRAGMENT_TEMPERATURE);
-        if (mIsTempScaleF) {
-            // Convert last temp C to F
-            f.setInitialValue(SensorDataParser.tempCtoF(lastTempValue));
-        } else {
-            // Convert last temp F to C
-            f.setInitialValue(SensorDataParser.tempFtoC(lastTempValue));
-        }
-        ft.commit();
-        mAnimationSlower.removeAnimated(mTemperatureFrag);
-        mAnimationSlower.addAnimated(f);
-
-        mTemperatureFrag = f;
-    }
-    */
-
-    //endregion
-
-
-    //endregion
-
-}
+/******************************************************************************
+ *
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import com.broadcom.app.ledevicepicker.DevicePicker;
+import com.broadcom.app.ledevicepicker.DevicePickerActivity;
+import com.broadcom.app.license.LicenseUtils;
+import com.broadcom.app.license.LicenseDialog.OnLicenseAcceptListener;
+import com.broadcom.app.wicedsense.Settings.SettingChangeListener;
+import com.broadcom.app.wicedsmart.ota.OtaAppInfo;
+import com.broadcom.app.wicedsmart.ota.ui.OtaAppInfoFragment;
+import com.broadcom.app.wicedsmart.ota.ui.OtaResource;
+import com.broadcom.app.wicedsmart.ota.ui.OtaUiHelper;
+import com.broadcom.app.wicedsmart.ota.ui.OtaUiHelper.OtaUiCallback;
+import com.broadcom.ui.BluetoothEnabler;
+import com.broadcom.ui.ExitConfirmUtils;
+import com.broadcom.ui.ExitConfirmFragment.ExitConfirmCallback;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.support.v4.app.FragmentActivity;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.text.format.Time;
+
+/**
+ * Manaages the main view and gauges for each sensor
+ *
+ */
+public class MainActivity extends FragmentActivity implements OnLicenseAcceptListener,
+        DevicePicker.Callback, android.os.Handler.Callback, OnClickListener, ExitConfirmCallback,
+        OtaUiCallback, SettingChangeListener {
+
+    //region Variables
+
+    //region Static Variables
+    private static final String TAG = Settings.TAG_PREFIX + "MainActivity";
+    private static final String JEFF_TAG = "Jeff_Tag";
+    private static final boolean DBG_LIFECYCLE = true;
+    private static final boolean DBG = Settings.DBG;
+
+    private static final int COMPLETE_INIT = 800;
+    private static final int PROCESS_SENSOR_DATA_ON_UI = 801;
+    private static final int PROCESS_BATTERY_STATUS_UI = 802;
+    private static final int PROCESS_EVENT_DEVICE_UNSUPPORTED = 803;
+    private static final int PROCESS_CONNECTION_STATE_CHANGE_UI = 804;
+
+    // Keys to send data to/from activities for fragments.
+    private static final String FRAGMENT_TEMPERATURE = "edu.kvcc.cis298.fragment_temp";
+    private static final String FRAGMENT_HUMIDITY = "edu.kvcc.cis298.fragment_humd";
+    private static final String FRAGMENT_PRESSURE = "edu.kvcc.cis298.fragment_pres";
+    private static final String FRAGMENT_GYRO = "edu.kvcc.cis298.fragment_gyro";
+    private static final String FRAGMENT_COMPASS = "edu.kvcc.cis298.fragment_compass";
+    private static final String FRAGMENT_ACCELEROMETER = "edu.kvcc.cis298.fragment_accelerometer";
+
+    //endregion
+
+    private Button mButtonConnectDisconnect;
+    private TemperatureFragment mTemperatureFrag;
+    private HumidityFragment mHumidityFrag;
+    private PressureFragment mPressureFrag;
+    private GyroFragment mGyroFrag;
+    private CompassFragment mCompassFrag;
+    private AccelerometerFragment mAccelerometerFrag;
+    private ImageView mBatteryStatusIcon;
+    private TextView mBatteryStatusText;
+    private View mBatteryStatusView;
+    private DevicePicker mDevicePicker;
+    private String mDevicePickerTitle;
+    private int mLastBatteryStatus = -1;
+    private boolean mConnectDisconnectPending;
+    private SenseManager mSenseManager;
+    private Handler mUiHandler;
+    private final BluetoothStateReceiver mBtStateReceiver = new BluetoothStateReceiver();
+    private LicenseUtils mLicense;
+    private ExitConfirmUtils mExitConfirm;
+    private int mInitState;
+    private Handler mSensorDataEventHandler;
+    private HandlerThread mSensorDataEventThread;
+    private final AnimationManager mAnimation = new AnimationManager(
+            Settings.ANIMATION_FRAME_DELAY_MS, Settings.ANIMATE_TIME_INTERVAL_MS);
+    private final AnimationManager mAnimationSlower = new AnimationManager(
+            Settings.ANIMATION_FRAME_DELAY_MS, Settings.ANIMATE_TIME_INTERVAL_MS);
+    private final OtaUiHelper mOtaUiHelper = new OtaUiHelper();
+    private boolean mShowAppInfoDialog;
+    private boolean mFirmwareUpdateCheckPending;
+    private boolean mCanAskForFirmwareUpdate;
+    private boolean mMandatoryUpdateRequired;
+    private boolean mIsTempScaleF = false;
+    private long mLastRefreshTimeMs;
+    private long mLastRefreshSlowerTimeMs;
+
+    //endregion
+
+
+
+    //region Our Methods
+
+    /**
+     * Create an intent for MainActivity.
+     * @param packageContext Context.
+     * @return Properly formatted intent for MainActivity.
+     */
+    public static Intent newIntent(Context packageContext) {
+        // Make new intent.
+        Intent intent = new Intent(packageContext, MainActivity.class);
+        return intent;
+    }
+
+
+    //region Database Methods
+    //************************************  This is to open the database - JEFF  Added******************
+
+    private Context mContext;
+    private SQLiteDatabase mDatabase;
+
+    private String mHumidityValue;
+    private String mPressureValue;
+    private String mTemperatureValue;
+
+    public void StartDatabase(Context context){
+        mContext = context.getApplicationContext();
+        mDatabase = new ThermoBaseHelper(mContext).getReadableDatabase();
+        Toast.makeText(this, "Main Activity", Toast.LENGTH_SHORT).show();
+    }
+
+    private ContentValues getContentValues(){ // To place values in the database  ????? What am I passing in?   see page 325
+
+        Time now = new Time();
+        now.setToNow();
+        String time = now.format("%Y_%m_%d_%H_%M_%S");
+
+        ContentValues values = new ContentValues();
+        values.put(WicedDBSchema.ThermoTable.Cols.TIME, time);
+        Log.d(JEFF_TAG, "Put time into ContentValues = " + time);
+        values.put(WicedDBSchema.ThermoTable.Cols.HUMIDITY, mHumidityValue);
+        Log.d(JEFF_TAG, "Put Humidty into ContentValues = " + mHumidityValue);
+        values.put(WicedDBSchema.ThermoTable.Cols.PRESSURE, mPressureValue);
+        Log.d(JEFF_TAG, "Put Pressure into ContentValues = " + mPressureValue);
+        values.put(WicedDBSchema.ThermoTable.Cols.TEMPERATURE, mTemperatureValue);
+        Log.d(JEFF_TAG, "Put Temperature into ContentValues = " + mTemperatureValue);
+
+        return values;
+    }
+
+    public  void addThermoData () {//  Add a row of data????????????What am I passing in?    see page 326
+        Log.d(JEFF_TAG, "adding data");
+        ContentValues values = getContentValues();
+        mDatabase.insert(WicedDBSchema.ThermoTable.NAME, null, values);
+    }
+
+    public void DataDump(){
+        Log.d(JEFF_TAG, "Place data dump in ExitConfirmFragment.java");
+    }
+
+    //endregion
+
+
+    //endregion
+
+
+
+    //region Override Methods
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        if (DBG_LIFECYCLE) {
+            Log.d(TAG, "onCreate " + this);
+        }
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main_activity);
+
+
+        //region Broadcom Stuff
+        // Initialize dialogs
+        initDevicePicker();
+        initLicenseUtils();
+        initExitConfirm();
+
+        mInitState = 0;
+
+        // Register bluetooth state receiver
+        registerReceiver(mBtStateReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
+
+        // Start event handler thread
+        mSensorDataEventThread = new HandlerThread("WicedSenseEventHandlerThread");
+        mSensorDataEventThread.start();
+        mSensorDataEventHandler = new Handler(mSensorDataEventThread.getLooper(), this);
+
+        // Start ui handler
+        mUiHandler = new Handler(new UiHandlerCallback());
+
+        //endregion
+
+
+        Toast.makeText(this,"About to StartDatabase", Toast.LENGTH_SHORT);
+        StartDatabase(this);
+
+        /**
+         * Shouldn't need since it's provided in abstract class.
+         * Written by Broadcom so kept as comment for reference.
+         *
+        FragmentManager fMgr = getFragmentManager();
+        mHumidityFrag = (HumidityFragment) fMgr.findFragmentByTag(FRAGMENT_HUMDITY);
+        mPressureFrag = (PressureFragment) fMgr.findFragmentByTag(FRAGMENT_PRESSURE);
+        mGyroFrag = (GyroFragment) fMgr.findFragmentByTag(FRAGMENT_GYRO);
+        mCompassFrag = (CompassFragment) fMgr.findFragmentByTag(FRAGMENT_COMPASS);
+
+        mButtonConnectDisconnect = (Button) findViewById(R.id.connection_state);
+        if (mButtonConnectDisconnect != null) {
+            mButtonConnectDisconnect.setOnClickListener(this);
+            mButtonConnectDisconnect.setEnabled(false);
+        } else {
+            // large screen sizes do not have button in the main layout. Instead
+            // it's an action button in the menu button
+        }
+        mAccelerometerFrag = (AccelerometerFragment) fMgr.findFragmentByTag(FRAGMENT_ACCELEROMETER);
+
+
+        // Register components for frequent animation
+        mAnimation.addAnimated(mAccelerometerFrag);
+        mAnimation.addAnimated(mCompassFrag);
+        mAnimation.addAnimated(mGyroFrag);
+
+        // Refresh temp,humid,press gauges using a slower animation to conserve
+        // UI resources
+        // for devices that cannot handle refresh of many widgets at the same
+        // time (IE Galaxy S4)
+        mAnimationSlower.addAnimated(mHumidityFrag);
+        mAnimationSlower.addAnimated(mPressureFrag);
+
+        updateTemperatureScaleType();
+         */
+    }
+
+    @Override
+    protected void onResume() {
+        if (DBG_LIFECYCLE) {
+            Log.d(TAG, "onResume " + this);
+        }
+        super.onResume();
+        initResourcesAndResume();
+    }
+
+    @Override
+    protected void onPause() {
+        if (DBG_LIFECYCLE) {
+            Log.d(TAG, "onPause " + this);
+        }
+        mLicense.dismiss();
+        mExitConfirm.dismiss();
+
+        Settings.removeChangeListener(this);
+
+        // Disable notifications if the application is backgrounded, but don't
+        // disconnect from the device
+        if (mSenseManager != null) {
+            if (mSenseManager.isConnectedAndAvailable()) {
+                mSenseManager.enableNotifications(false);
+            }
+            mSenseManager.unregisterEventCallbackHandler(mSensorDataEventHandler);
+        }
+        super.onPause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (DBG_LIFECYCLE) {
+            Log.d(TAG, "onDestroy " + this);
+        }
+
+        mSensorDataEventThread.quit();
+        cleanupDevicePicker();
+        unregisterReceiver(mBtStateReceiver);
+        super.onDestroy();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.main, menu);
+        MenuItem item = menu.findItem(R.id.action_battery_status);
+        if (item == null) {
+            return true;
+        }
+
+        // ActionViews must have an explicit onClickListener registered
+        mBatteryStatusView = item.getActionView();
+        mBatteryStatusIcon = (ImageView) mBatteryStatusView.findViewById(R.id.battery_status_icon);
+        mBatteryStatusText = (TextView) mBatteryStatusView.findViewById(R.id.battery_status);
+        mBatteryStatusView.setOnClickListener(this);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+
+        boolean isDeviceSelected = (mSenseManager != null && mSenseManager.getDevice() != null);
+        boolean isDeviceConnected = isDeviceSelected && mSenseManager.isConnectedAndAvailable();
+
+        // Check if we are in landscape mode. If so, update the state of the
+        // connect/disconnect action
+        if (mButtonConnectDisconnect == null) {
+            // Get Connect/disconnect button
+            MenuItem menuConnectDisconnect = menu.findItem(R.id.action_connectdisconnect);
+            if (menuConnectDisconnect != null) {
+                // Landscape mode
+                if (!isDeviceSelected) {
+                    // No device selected: hide connect/disconnect button
+                    // menuConnectDisconnect.setVisible(false);
+                    menuConnectDisconnect.setEnabled(false);
+
+                } else {
+                    menuConnectDisconnect.setEnabled(!mConnectDisconnectPending);
+                    if (isDeviceConnected) {
+                        menuConnectDisconnect.setTitle(R.string.disconnect);
+                    } else {
+                        menuConnectDisconnect.setTitle(R.string.connect);
+                    }
+                }
+            }
+        }
+        // Update the battery icon
+        if (mBatteryStatusView != null && mBatteryStatusIcon != null && mBatteryStatusText != null) {
+            int batteryStatus = mLastBatteryStatus;
+            if (!isDeviceConnected) {
+                mBatteryStatusIcon.setImageResource(getBatteryStatusIcon(-1));
+                mBatteryStatusText.setText(getString(R.string.battery_status, "??"));
+            } else {
+                mBatteryStatusView.setEnabled(true);
+                mBatteryStatusIcon.setImageResource(getBatteryStatusIcon(batteryStatus));
+                mBatteryStatusText.setText(getString(R.string.battery_status, batteryStatus < 0 ? 0
+                        : batteryStatus));
+            }
+        }
+
+        // Update the update firmware button
+        MenuItem updateFw = menu.findItem(R.id.update_fw);
+        if (updateFw != null) {
+            updateFw.setEnabled(isDeviceSelected);
+        }
+
+        // Update the get firmware info button
+        MenuItem getFwInfo = menu.findItem(R.id.get_fw_info);
+        if (getFwInfo != null) {
+            getFwInfo.setEnabled(isDeviceConnected);
+        }
+
+        // Update the pick device menu: only allow a pick device from the
+        // disconnected state
+        MenuItem pick = menu.findItem(R.id.action_pick);
+        if (pick != null) {
+            pick.setEnabled(!isDeviceConnected);
+        }
+
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    /**
+     * Invoked when a menu option is picked
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        boolean isDeviceSelected = (mSenseManager != null && mSenseManager.getDevice() != null);
+        boolean isDeviceConnected = isDeviceSelected && mSenseManager.isConnectedAndAvailable();
+        switch (item.getItemId()) {
+            case R.id.action_connectdisconnect:
+                mConnectDisconnectPending = true;
+                invalidateOptionsMenu();
+                doConnectDisconnect();
+                return true;
+            case R.id.action_pick:
+                launchDevicePicker();
+                return true;
+            case R.id.data_dump:
+                if (isDeviceConnected){
+                    Toast.makeText(this,R.string.disconnect_message, Toast.LENGTH_SHORT).show();
+                }else {
+                    DataDump();
+                }
+
+                return true;
+            case R.id.get_fw_info:
+                getFirmwareInfo();
+                return true;
+            case R.id.action_settings:
+                // Launch setttings menu
+                Intent i = new Intent(this, SettingsActivity.class);
+                startActivity(i);
+                return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Callback invoked when the user finishes with the license agreement dialog
+     */
+    @Override
+    public void onLicenseAccepted(boolean accepted) {
+        if (!accepted) {
+            exitApp();
+            return;
+        }
+        mLicense.setAccepted(true);
+        initResourcesAndResume();
+    }
+
+    /**
+     * Callback invoked when a device is selected from the device picker
+     */
+    @Override
+    public void onDevicePicked(BluetoothDevice device) {
+        if (DBG_LIFECYCLE) {
+            Log.d(TAG, "onDevicePicked");
+        }
+        if (Settings.CHECK_FOR_UPDATES_ON_CONNECT) {
+            mCanAskForFirmwareUpdate = true;
+        } else {
+            mCanAskForFirmwareUpdate = false;
+        }
+        mSenseManager.setDevice(device);
+        updateConnectionStateWidgets();
+    }
+
+    /**
+     * Callback invoked when the user aborts picking a device from the device
+     * picker
+     */
+    @Override
+    public void onDevicePickCancelled() {
+        if (DBG_LIFECYCLE) {
+            Log.d(TAG, "onDevicePickCancelled");
+        }
+        updateConnectionStateWidgets();
+    }
+
+    /**
+     * Handler callback used for two purposes
+     *
+     * 1. This callback is invoked by the event handler loop when the
+     * SenseManager service sends a event from the sensor tag using the
+     * mEventHandler object. The event handler loop runs in a child thread, so
+     * that it can queue up events and allow the SenseManager (and Bluetooth
+     * callbacks) to return asynchronously before the UI processes the event.
+     * The event handler loop reposts the event to the main UI handler loop via
+     * the mUiHandler Handler
+     *
+     * 2. This callback is invoked by the mEventHandler object to run a UI
+     * operation in the main event loop of the application
+     *
+     *
+     */
+    @Override
+    public boolean handleMessage(Message msg) {
+        switch (msg.what) {
+            case SenseManager.EVENT_DEVICE_UNSUPPORTED:
+                mUiHandler.sendEmptyMessage(PROCESS_EVENT_DEVICE_UNSUPPORTED);
+                break;
+            case SenseManager.EVENT_CONNECTED:
+                mUiHandler.sendEmptyMessage(PROCESS_CONNECTION_STATE_CHANGE_UI);
+                onConnected();
+                break;
+            case SenseManager.EVENT_DISCONNECTED:
+                mUiHandler.sendEmptyMessage(PROCESS_CONNECTION_STATE_CHANGE_UI);
+                break;
+            case SenseManager.EVENT_BATTERY_STATUS:
+                mUiHandler.sendMessage(mUiHandler.obtainMessage(PROCESS_BATTERY_STATUS_UI, msg.arg1,
+                        msg.arg1));
+                break;
+            case SenseManager.EVENT_SENSOR_DATA:
+                mUiHandler.sendMessage(mUiHandler.obtainMessage(PROCESS_SENSOR_DATA_ON_UI, msg.obj));
+                break;
+            case SenseManager.EVENT_APP_INFO:
+                boolean success = msg.arg1 == 1;
+                OtaAppInfo appInfo = (OtaAppInfo) msg.obj;
+                if (DBG) {
+                    Log.d(TAG, "EVENT_APP_INFO: success=" + success + ",otaAppInfo=" + appInfo);
+                }
+                if (mFirmwareUpdateCheckPending) {
+                    mFirmwareUpdateCheckPending = false;
+                    checkForFirmwareUpdate(appInfo);
+                    break;
+                }
+
+                if (mShowAppInfoDialog) {
+                    mShowAppInfoDialog = false;
+                    if (success) {
+                        OtaAppInfoFragment mOtaAppInfoFragment = OtaAppInfoFragment.createDialog(
+                                mSenseManager.getDevice(), appInfo);
+                        mOtaAppInfoFragment.show(getFragmentManager(), null);
+                    }
+                }
+                break;
+        }
+        return true;
+    }
+
+    /**
+     * Callback invoked when the connect/disconnect button is clicked or the
+     * battery status button is clicked
+     */
+    @Override
+    public void onClick(View v) {
+
+        // Process connect/disconnect request
+        if (v == mButtonConnectDisconnect) {
+            // Temporary disable the button while a connect/disconnect is
+            // pending
+            mConnectDisconnectPending = true;
+            mButtonConnectDisconnect.setEnabled(false);
+            doConnectDisconnect();
+        }
+
+        // Process battery status request
+        else if (v == mBatteryStatusView) {
+            if (mSenseManager != null) {
+                mSenseManager.getBatteryStatus();
+            }
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (requestCode == BluetoothEnabler.REQUEST_ENABLE_BT) {
+            if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) {
+                exitApp();
+                return;
+            }
+            initResourcesAndResume();
+        }
+    }
+
+    /**
+     * Show exit confirmation dialog if user presses the button
+     */
+    @Override
+    public void onBackPressed() {
+        mExitConfirm.show(getFragmentManager());
+    }
+
+    /**
+     * Callback invoked when the user selects "ok" from the exit confirmation
+     * dialog
+     */
+    @Override
+    public void onExit() {
+        exitApp();
+    }
+
+    /**
+     * Callback invoked when the user cancels exitting the application.
+     */
+    @Override
+    public void onExitCancelled() {
+    }
+
+    /**
+     * Callback invoked when the OTA firmware update has completed
+     *
+     * @param completed
+     *            : if true, OTA upgrade was successful, false otherwise.
+     */
+    @Override
+    public void onOtaFinished(boolean completed) {
+        if (DBG_LIFECYCLE) {
+            Log.d(TAG, "onOtaFinished");
+        }
+
+        // If OTA did not complete and the patch was mandatory, disconnect
+        if (!completed && mMandatoryUpdateRequired) {
+            if (mSenseManager != null) {
+                mSenseManager.disconnect();
+            }
+            return;
+        }
+
+        // Enable notifications
+        if (mSenseManager != null) {
+            mSenseManager.setOtaUpdateMode(false);
+        }
+    }
+
+    @Override
+    public void onSettingsChanged(String settingName) {
+        if (Settings.SETTINGS_KEY_TEMPERATURE_SCALE_TYPE.equals(settingName)) {
+            //updateTemperatureScaleType();
+        }
+    }
+
+    //endregion
+
+
+
+    //region Broadcom's Pre-provided methods.
+
+    // Int which changes based on battery level? Seems pointless to have in this kind of app but okay.
+    private static int getBatteryStatusIcon(int batteryLevel) {
+        if (batteryLevel <= 0) {
+            return R.drawable.battery_charge_background;
+        } else if (batteryLevel < 25) {
+            return R.drawable.battery_charge_25;
+        } else if (batteryLevel < 50) {
+            return R.drawable.battery_charge_50;
+        } else if (batteryLevel < 75) {
+            return R.drawable.battery_charge_75;
+        } else {
+            return R.drawable.battery_charge_full;
+        }
+
+    }
+
+    /**
+     * Handles Bluetooth on/off events. If Bluetooth is turned off, exit this
+     * app
+     *
+     * @author Fred Chen
+     *
+     */
+    private class BluetoothStateReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(final Context context, final Intent intent) {
+            mSensorDataEventHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    int btState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                            BluetoothAdapter.ERROR);
+                    switch (btState) {
+
+                        case BluetoothAdapter.STATE_TURNING_OFF:
+                            exitApp();
+                            break;
+                    }
+                }
+            });
+        }
+    }
+
+    private class UiHandlerCallback implements Handler.Callback {
+
+        @Override
+        public boolean handleMessage(Message msg) {
+            switch (msg.what) {
+
+                // These events run on the mUiHandler on the UI Main Thread
+                case COMPLETE_INIT:
+                    initResourcesAndResume();
+                    break;
+                case PROCESS_EVENT_DEVICE_UNSUPPORTED:
+                    Toast.makeText(getApplicationContext(), R.string.error_unsupported_device,
+                            Toast.LENGTH_SHORT).show();
+                    break;
+                case PROCESS_CONNECTION_STATE_CHANGE_UI:
+                    updateConnectionStateWidgets();
+                    break;
+                case PROCESS_BATTERY_STATUS_UI:
+                    updateBatteryLevelWidget(msg.arg1);
+                    break;
+                case PROCESS_SENSOR_DATA_ON_UI:
+                    processSensorData((byte[]) msg.obj);
+                    break;
+            }
+            return true;
+        }
+    };
+
+
+    /**
+     * Initialize async resources in series
+     *
+     * @return
+     */
+    private boolean initResourcesAndResume() {
+        switch (mInitState) {
+            case 0:
+                // Check if license accepted. If not, prompt user
+                if (!mLicense.checkLicenseAccepted(getFragmentManager())) {
+                    return false;
+                }
+                mInitState++;
+            case 1:
+                // Check if BT is on, If not, prompt user
+                if (!BluetoothEnabler.checkBluetoothOn(this)) {
+                    return false;
+                }
+                mInitState++;
+                SenseManager.init(this);
+            case 2:
+                // Check if sense manager initialized. If not, keep waiting
+                if (waitForSenseManager()) {
+                    return false;
+                }
+                mInitState = -1;
+                checkDevicePicked();
+        }
+        mSenseManager.registerEventCallbackHandler(mSensorDataEventHandler);
+
+        if (mSenseManager.isConnectedAndAvailable()) {
+            mSenseManager.enableNotifications(true);
+        }
+        updateConnectionStateWidgets();
+        //updateTemperatureScaleType();
+        //updateGyroState();
+        //updateAccelerometerState();
+        //updateCompassState();
+        Settings.addChangeListener(this);
+        return true;
+    }
+
+    /**
+     * Acquire reference to the SenseManager serivce....This is asynchronous
+     *
+     * @return
+     */
+    private boolean waitForSenseManager() {
+        // Check if the SenseManager is available. If not, keep retrying
+        mSenseManager = SenseManager.getInstance();
+        if (mSenseManager == null) {
+            mUiHandler.sendEmptyMessageDelayed(COMPLETE_INIT, Settings.SERVICE_INIT_TIMEOUT_MS);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Exit the application and cleanup resources
+     */
+    protected void exitApp() {
+        if (DBG_LIFECYCLE) {
+            Log.d(TAG, "exitApp");
+        }
+        SenseManager.destroy();
+        finish();
+    }
+
+    /**
+     * Update the battery level UI widgets
+     *
+     * @param batteryLevel
+     */
+    private void updateBatteryLevelWidget(int batteryLevel) {
+        mLastBatteryStatus = batteryLevel;
+        invalidateOptionsMenu();
+    }
+
+
+    //region License Stuff
+
+    /**
+     * Initialize the license agreement dialog
+     */
+    private void initLicenseUtils() {
+        mLicense = new LicenseUtils(this, this);
+    }
+
+    /**
+     * Initialize the exit confirmation dialog
+     */
+    private void initExitConfirm() {
+        mExitConfirm = new ExitConfirmUtils(this);
+    }
+
+    //endregion
+
+
+    //region Device Selection/Connection
+
+    /**
+     * Update all UI components related to the connection state
+     */
+    private void updateConnectionStateWidgets() {
+        mConnectDisconnectPending = false;
+        if (mButtonConnectDisconnect != null) {
+            if (mSenseManager.getDevice() == null) {
+                mButtonConnectDisconnect.setEnabled(false);
+                mButtonConnectDisconnect.setText(R.string.no_device);
+                return;
+            }
+            if (!mButtonConnectDisconnect.isEnabled()) {
+                mButtonConnectDisconnect.setEnabled(true);
+            }
+            if (mSenseManager.isConnectedAndAvailable()) {
+                mButtonConnectDisconnect.setText(R.string.disconnect);
+            } else {
+                mButtonConnectDisconnect.setText(R.string.connect);
+            }
+            mButtonConnectDisconnect.setEnabled(true);
+        }
+        invalidateOptionsMenu();
+    }
+
+    /*
+     * Initialize the device picker
+     *
+     * @return
+     */
+    private void initDevicePicker() {
+        mDevicePickerTitle = getString(R.string.title_devicepicker);
+        mDevicePicker = new DevicePicker(this, Settings.PACKAGE_NAME,
+                DevicePickerActivity.class.getName(), this,
+                Uri.parse("content://com.brodcom.app.wicedsense/device/pick"));
+        mDevicePicker.init();
+    }
+
+    /**
+     * Launch the device picker
+     */
+    private void launchDevicePicker() {
+        mDevicePicker.launch(mDevicePickerTitle, null, null);
+    }
+
+    /**
+     * Cleanup the device picker
+     */
+    private void cleanupDevicePicker() {
+        if (mDevicePicker != null) {
+            mDevicePicker.cleanup();
+            mDevicePicker = null;
+        }
+    }
+
+    /**
+     * Check if a device has been picked, and launch the device picker if not...
+     *
+     * @return
+     */
+    private boolean checkDevicePicked() {
+        if (mSenseManager != null && mSenseManager.getDevice() != null) {
+            return true;
+        }
+        // Launch device picker
+        launchDevicePicker();
+        return false;
+    }
+
+    /**
+     * Start the connect or disconnect, based on the current state of the device
+     */
+    private void doConnectDisconnect() {
+        if (!mSenseManager.isConnectedAndAvailable()) {
+            if (!mSenseManager.connect()) {
+                updateConnectionStateWidgets();
+            }
+        } else {
+            if (!mSenseManager.disconnect()) {
+                updateConnectionStateWidgets();
+            }
+        }
+    }
+
+    //endregion
+
+
+    /**
+     * Parses the sensor data bytes and updates the corresponding sensor(s) UI
+     * component
+     *
+     * @param sensorData
+     */
+    private void processSensorData(byte[] sensorData) {
+        if (mAnimation != null && mAnimation.useAnimation()) {
+            mAnimation.init();
+        }
+
+        if (mAnimationSlower != null && mAnimationSlower.useAnimation()) {
+            mAnimationSlower.init();
+        }
+
+        int maskField = sensorData[0];
+        int offset = 0;
+        int[] values = new int[3];
+        boolean updateView = false;
+        long currentTimeMs = System.currentTimeMillis();
+        switch (sensorData.length) {
+            case 19:
+                if (currentTimeMs - mLastRefreshTimeMs < Settings.REFRESH_INTERVAL_MS) {
+                    return;
+                } else {
+                    mLastRefreshTimeMs = currentTimeMs;
+                }
+
+                // packet type specifying accelerometer, gyro, magno
+                offset = 1;
+                if (SensorDataParser.accelerometerHasChanged(maskField)) {
+                    if (Settings.accelerometerEnabled() && mAccelerometerFrag.isVisible()) {
+                        SensorDataParser.getAccelorometerData(sensorData, offset, values);
+                        //mAccelerometerFrag.setValue(mAnimation, values[0], values[1], values[2]);
+                        updateView = true;
+                    }
+                    offset += SensorDataParser.SENSOR_ACCEL_DATA_SIZE;
+                }
+
+                if (SensorDataParser.gyroHasChanged(maskField)) {
+                    if (Settings.gyroEnabled() && mGyroFrag.isVisible()) {
+                        SensorDataParser.getGyroData(sensorData, offset, values);
+                        mGyroFrag.setValue(mAnimation, values[0], values[1], values[2]);
+                        updateView = true;
+                    }
+                    offset += SensorDataParser.SENSOR_GYRO_DATA_SIZE;
+                }
+
+                if (SensorDataParser.magnetometerHasChanged(maskField)) {
+                    if (Settings.compassEnabled() && mCompassFrag.isVisible()) {
+                        SensorDataParser.getMagnometerData(sensorData, offset, values);
+                        float angle = SensorDataParser.getCompassAngleDegrees(values);
+                        mCompassFrag.setValue(mAnimation, angle, values[0], values[1], values[2]);
+                        updateView = true;
+                    }
+                    offset += SensorDataParser.SENSOR_MAGNO_DATA_SIZE;
+                }
+
+                if (updateView && mAnimation != null) {
+                    mAnimation.animate();
+                }
+                break;
+            case 7:
+
+                if (currentTimeMs - mLastRefreshSlowerTimeMs < Settings.REFRESH_INTERVAL_SLOWER_MS) {
+                    return;
+                } else {
+                    mLastRefreshSlowerTimeMs = currentTimeMs;
+                }
+
+                // packet type specifying temp, humid, press
+                offset = 1;
+                float value = 0;
+                if (mHumidityFrag.isVisible() && SensorDataParser.humidityHasChanged(maskField)) {
+                    value = SensorDataParser.getHumidityPercent(sensorData, offset);
+                    mHumidityValue = Float.toString(value);
+                    Log.d(JEFF_TAG,"Humidity = " + mHumidityValue);
+                    offset += SensorDataParser.SENSOR_HUMD_DATA_SIZE;
+                    //mHumidityFrag.setValue(mAnimationSlower, value);
+                    updateView = true;
+                }
+                if (mPressureFrag.isVisible() && SensorDataParser.pressureHasChanged(maskField)) {
+                    value = SensorDataParser.getPressureMBar(sensorData, offset);
+                    mPressureValue = Float.toString(value);
+                    Log.d(JEFF_TAG, "Pressure = " + mPressureValue);
+                    offset += SensorDataParser.SENSOR_PRES_DATA_SIZE;
+                    //mPressureFrag.setValue(mAnimationSlower, value);
+                    updateView = true;
+                }
+
+                if (mTemperatureFrag.isVisible() && SensorDataParser.temperatureHasChanged(maskField)) {
+                    if (mIsTempScaleF) {
+                        value = SensorDataParser.getTemperatureF(sensorData, offset);
+                    } else {
+                        value = SensorDataParser.getTemperatureC(sensorData, offset);
+                    }
+                    mTemperatureValue = Float.toString(value);
+                    Log.d(JEFF_TAG, "Temperature = "+mTemperatureValue);
+                    offset += SensorDataParser.SENSOR_TEMP_DATA_SIZE;
+                    //mTemperatureFrag.setValue(mAnimationSlower, value);
+                    updateView = true;
+                }
+                if (updateView && mAnimationSlower != null) {
+                    mAnimationSlower.animate();
+                    addThermoData();
+                    //***********************************************************************************************************************
+                }
+                break;
+        }
+
+        // If animation is enabled, call animate...
+    }
+
+
+    //region Firmware section. Is this for the fab thing you connect to?
+
+    /**
+     * Start a request to read application id, major version,minor version of a
+     * connected WICED Sense tag...
+     */
+    private void getFirmwareInfo() {
+        if (mSenseManager != null) {
+            mShowAppInfoDialog = true;
+            mSenseManager.getAppInfo();
+        }
+    }
+
+    /**
+     * Check for firmware update, if the user allows it or if there is a
+     * mandatory update. The connection is assumed to be up
+     */
+    private void checkForFirmwareUpdate() {
+        if (mSenseManager == null) {
+            return;
+        }
+        // Check if we are connected
+        if (!mSenseManager.isConnectedAndAvailable()) {
+            mCanAskForFirmwareUpdate = true;
+            boolean success = mSenseManager.connect();
+            if (!success) {
+                mCanAskForFirmwareUpdate = false;
+            }
+        } else {
+            mCanAskForFirmwareUpdate = true;
+            checkForFirmwareUpdateIfAllowed();
+        }
+    }
+
+    /**
+     * Check for firmware update, if the user allows it. The connection is
+     * assumed to be up
+     *
+     * @return
+     */
+    private boolean checkForFirmwareUpdateIfAllowed() {
+        if (!mCanAskForFirmwareUpdate && !Settings.hasMandatoryUpdate()) {
+            if (DBG) {
+                Log.d(TAG, "firmwareUpdateCheck(): user opted out...skipping..");
+            }
+            return false;
+        }
+        mFirmwareUpdateCheckPending = true;
+        if (!mSenseManager.getAppInfo()) {
+            mFirmwareUpdateCheckPending = false;
+            if (DBG) {
+                Log.d(TAG, "checkForFirmwareUpdates(): unable to get app info");
+            }
+            return false;
+        }
+        if (DBG) {
+            Log.d(TAG, "firmwareUpdateCheck(): getting app info");
+        }
+        return true;
+    }
+
+    private void onConnected() {
+        if (checkForFirmwareUpdateIfAllowed()) {
+            // Wait for firmware check...
+            if (DBG) {
+                Log.d(TAG, "onConnected:Checking for firmware updates..");
+            }
+        } else {
+            if (DBG) {
+                Log.d(TAG, "onConnected: enabling notifications");
+            }
+            if (mSenseManager != null) {
+                mSenseManager.enableNotifications(true);
+            }
+        }
+    }
+
+    private boolean canUpdateToFirmware(OtaAppInfo appInfo, OtaResource otaResource) {
+        if (otaResource == null || appInfo == null) {
+            return false;
+        }
+        if (otaResource.getMajor() <= 0) {
+            return true;
+        }
+        if (appInfo.mMajorVersion < otaResource.getMajor()) {
+            return true;
+        } else if (appInfo.mMajorVersion == otaResource.getMajor()
+                && appInfo.mMinorVersion < otaResource.getMinor()) {
+            return true;
+        }
+        return false;
+    }
+
+    private void checkForFirmwareUpdate(OtaAppInfo appInfo) {
+        mCanAskForFirmwareUpdate = false;
+        mMandatoryUpdateRequired = false;
+
+        ArrayList<OtaResource> otaResources = new ArrayList<OtaResource>();
+        OtaResource defaultResource = Settings.getDefaultOtaResource();
+        if (defaultResource != null && canUpdateToFirmware(appInfo, defaultResource)) {
+            mMandatoryUpdateRequired = defaultResource.isMandatory();
+            otaResources.add(defaultResource);
+        }
+        if (!mMandatoryUpdateRequired) {
+            OtaUiHelper.createOtaResources(Settings.getOtaDirectory(), Settings.getOtaFileFilter(),
+                    otaResources);
+            Iterator<OtaResource> i = otaResources.iterator();
+            while (i.hasNext()) {
+                OtaResource otaResource = i.next();
+                if (!canUpdateToFirmware(appInfo, otaResource)) {
+                    if (DBG) {
+                        Log.d(TAG, "Skipping OTA firmware " + otaResource.getName());
+                    }
+                    i.remove();
+                }
+            }
+        }
+        if (otaResources.size() > 0) {
+            mSenseManager.setOtaUpdateMode(true);
+            mOtaUiHelper.startUpdate(getApplicationContext(), mSenseManager.getDevice(),
+                    mSenseManager.getGattManager(), getFragmentManager(), otaResources, this, true);
+        } else {
+            mSenseManager.setOtaUpdateMode(false);
+            mSenseManager.enableNotifications(true);
+        }
+    }
+
+    //endregion
+
+
+    //region Code which we probably don't need. Commented out and kept here in case we desire to reference
+    /*
+
+
+
+    //region Update data display states? Not needed?
+
+    private void updateGyroState() {
+        if (mGyroFrag != null) {
+            mGyroFrag.setEnabled(Settings.gyroEnabled());
+        }
+    }
+
+    private void updateAccelerometerState() {
+        if (mAccelerometerFrag != null) {
+            mAccelerometerFrag.setEnabled(Settings.accelerometerEnabled());
+        }
+
+    }
+
+    private void updateCompassState() {
+        if (mCompassFrag != null) {
+            mCompassFrag.setEnabled(Settings.compassEnabled());
+        }
+    }
+
+    //endregion
+
+
+
+
+    /**
+     * Update the temperature gauge by dynamically replacing the gauge with the
+     * correct temperature type scale
+     *
+    private void updateTemperatureScaleType() {
+        // Get the old temperatureType
+        String tempScaleType = Settings.getTemperatureeScaleType();
+        mIsTempScaleF = Settings.TEMPERATURE_SCALE_TYPE_F.equals(tempScaleType);
+
+        // Check if this is a new temperature fragment
+        if (mTemperatureFrag == null) {
+            TemperatureFragment f = new TemperatureFragment();
+            f.setScaleType(mIsTempScaleF ? TemperatureFragment.SCALE_F
+                    : TemperatureFragment.SCALE_C);
+            FragmentTransaction ft = getFragmentManager().beginTransaction();
+            ft.replace(R.id.fragment_temp, f, FRAGMENT_TEMPERATURE);
+            ft.commit();
+            mTemperatureFrag = f;
+            mAnimationSlower.addAnimated(f);
+            return;
+        }
+
+        // This is a refresh. Check if the temp scale has changed
+        boolean isLastScaleF = TemperatureFragment.SCALE_F == mTemperatureFrag.getScaleType();
+        if (mIsTempScaleF == isLastScaleF) {
+            // No change. exit
+            return;
+        }
+
+        float lastTempValue = mTemperatureFrag.getLastValue();
+        TemperatureFragment f = new TemperatureFragment();
+        f.setScaleType(mIsTempScaleF ? TemperatureFragment.SCALE_F : TemperatureFragment.SCALE_C);
+        FragmentTransaction ft = getFragmentManager().beginTransaction();
+        ft.replace(R.id.fragment_temp, f, FRAGMENT_TEMPERATURE);
+        if (mIsTempScaleF) {
+            // Convert last temp C to F
+            f.setInitialValue(SensorDataParser.tempCtoF(lastTempValue));
+        } else {
+            // Convert last temp F to C
+            f.setInitialValue(SensorDataParser.tempFtoC(lastTempValue));
+        }
+        ft.commit();
+        mAnimationSlower.removeAnimated(mTemperatureFrag);
+        mAnimationSlower.addAnimated(f);
+
+        mTemperatureFrag = f;
+    }
+    */
+
+    //endregion
+
+
+    //endregion
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/MultipleFragmentActivity.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/MultipleFragmentActivity.java
index 6c87f91cb64fd6f9508dc1863c723f3aa4765195..4748c0cd23e99633fcaaf454b46b82583c2bc6a2 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/MultipleFragmentActivity.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/MultipleFragmentActivity.java
@@ -1,38 +1,38 @@
-package com.broadcom.app.wicedsense;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-
-/**
- * Abstract class for creating a fragment.
- * May need to change to multiple fragment activity at a later date? Not sure what the difference
- * would be as far as code.
- */
-public abstract class MultipleFragmentActivity extends FragmentActivity {
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        // Get id of xml-associated file.
-        setContentView(R.layout.activity_fragment);
-
-        // Create a new Fragment Manager.
-        FragmentManager fm = getSupportFragmentManager();
-
-        // Find fragment inside the FM, if currently exists.
-        Fragment fragment = fm.findFragmentById(R.id.fragment_container);
-
-        // If fragment is null, create new one.
-        if (fragment == null) {
-            fragment = createFragment();
-            fm.beginTransaction()
-                    .add(R.id.fragment_container, fragment)
-                    .commit();
-        }
-    }
-
-    // Abstract method to return a fragment for use.
-    protected abstract Fragment createFragment();
-}
+package com.broadcom.app.wicedsense;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+
+/**
+ * Abstract class for creating a fragment.
+ * May need to change to multiple fragment activity at a later date? Not sure what the difference
+ * would be as far as code.
+ */
+public abstract class MultipleFragmentActivity extends FragmentActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // Get id of xml-associated file.
+        setContentView(R.layout.activity_fragment);
+
+        // Create a new Fragment Manager.
+        FragmentManager fm = getSupportFragmentManager();
+
+        // Find fragment inside the FM, if currently exists.
+        Fragment fragment = fm.findFragmentById(R.id.fragment_container);
+
+        // If fragment is null, create new one.
+        if (fragment == null) {
+            fragment = createFragment();
+            fm.beginTransaction()
+                    .add(R.id.fragment_container, fragment)
+                    .commit();
+        }
+    }
+
+    // Abstract method to return a fragment for use.
+    protected abstract Fragment createFragment();
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/PressureFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/PressureFragment.java
index a3e6874ba86b441ef202890eca4583767dc4023a..8bc651221a018d2b47ce538c53cb2098fb5d39ea 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/PressureFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/PressureFragment.java
@@ -1,118 +1,118 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-/**
- * Our Implimentation of PressureFragment.
- * Will attempt to closely resemble practices done in class/assignments.
- */
-public class PressureFragment extends Fragment {
-
-//region Variables
-
-    private TextView mCurrent;
-    private TextView mMin;
-    private TextView mMax;
-    private TextView mAvg;
-
-    //endregion
-
-
-
-    //region Static information to summon Fragment.
-    private static final String ARG_PRESSURE_ID= "pressure_id";
-
-    private static PressureFragment newInstance() {
-        // Provided in case bundle is required in the future.
-        Bundle args = new Bundle();
-
-        // Make and return new fragment.
-        PressureFragment fragment = new PressureFragment();
-        fragment.setArguments(args);
-        return fragment;
-    }
-
-    //endregion
-
-
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Nullable
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        // Use inflater to get view from layout.
-        View view = inflater.inflate(R.layout.speed_fragment, container, false);
-
-        // Set class level vars to appropriate xml attributes.
-        mCurrent = (TextView) view.findViewById(R.id.pressure_current);
-        mMin = (TextView) view.findViewById(R.id.pressure_min);
-        mMax = (TextView) view.findViewById(R.id.pressure_max);
-        mAvg = (TextView) view.findViewById(R.id.pressure_avg);
-
-        // Read in from database and set values here?
-
-        return view;
-    }
-}
-
-
-/**
- * WICEDSENCE default stuff.
- * Commenting out instead of removing in case we need to reference it to get the program running.
- *
- *
- *
- *
- */ /*
-public class PressureFragment extends BaseThermoFragment {
-
-    @Override
-    public void initRangeValues() {
-        mMaxValue = SensorDataParser.SENSOR_PRESSURE_MAX;
-        mMinValue = SensorDataParser.SENSOR_PRESSURE_MIN;
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        View v = inflater.inflate(R.layout.pressure_fragment, null);
-        return v;
-    }
-
-    @Override
-    protected void setGaugeText(float value) {
-        //GaugeValue.setText(getString(R.string.pressure_value, String.valueOf((int) value)));
-    }
-
-    @Override
-    protected String getPropertyName() {
-        return "pres";
-    }
-
-} */
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Our Implimentation of PressureFragment.
+ * Will attempt to closely resemble practices done in class/assignments.
+ */
+public class PressureFragment extends Fragment {
+
+//region Variables
+
+    private TextView mCurrent;
+    private TextView mMin;
+    private TextView mMax;
+    private TextView mAvg;
+
+    //endregion
+
+
+
+    //region Static information to summon Fragment.
+    private static final String ARG_PRESSURE_ID= "pressure_id";
+
+    private static PressureFragment newInstance() {
+        // Provided in case bundle is required in the future.
+        Bundle args = new Bundle();
+
+        // Make and return new fragment.
+        PressureFragment fragment = new PressureFragment();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    //endregion
+
+
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        // Use inflater to get view from layout.
+        View view = inflater.inflate(R.layout.speed_fragment, container, false);
+
+        // Set class level vars to appropriate xml attributes.
+        mCurrent = (TextView) view.findViewById(R.id.pressure_current);
+        mMin = (TextView) view.findViewById(R.id.pressure_min);
+        mMax = (TextView) view.findViewById(R.id.pressure_max);
+        mAvg = (TextView) view.findViewById(R.id.pressure_avg);
+
+        // Read in from database and set values here?
+
+        return view;
+    }
+}
+
+
+/**
+ * WICEDSENCE default stuff.
+ * Commenting out instead of removing in case we need to reference it to get the program running.
+ *
+ *
+ *
+ *
+ */ /*
+public class PressureFragment extends BaseThermoFragment {
+
+    @Override
+    public void initRangeValues() {
+        mMaxValue = SensorDataParser.SENSOR_PRESSURE_MAX;
+        mMinValue = SensorDataParser.SENSOR_PRESSURE_MIN;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.pressure_fragment, null);
+        return v;
+    }
+
+    @Override
+    protected void setGaugeText(float value) {
+        //GaugeValue.setText(getString(R.string.pressure_value, String.valueOf((int) value)));
+    }
+
+    @Override
+    protected String getPropertyName() {
+        return "pres";
+    }
+
+} */
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SenseDeviceState.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SenseDeviceState.java
index 736e6110c4f984058cd65b833895f075716ae359..24ef19f114a8d26fd5f4037a99494790fedae874 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SenseDeviceState.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SenseDeviceState.java
@@ -1,449 +1,449 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import java.util.List;
-import java.util.UUID;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallback;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattDescriptor;
-import android.bluetooth.BluetoothGattService;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.broadcom.app.wicedsmart.ota.OtaAppInfo;
-import com.broadcom.app.wicedsmart.ota.OtaAppInfoReader;
-import com.broadcom.app.wicedsmart.ota.OtaAppInfoReader.Callback;
-import com.broadcom.util.GattRequestManager;
-import com.broadcom.util.GattRequestManager.LePairingCallback;
-
-/**
- * Manages the connection and service/characteristics to a WICED Sense Device
- *
- *
- */
-public class SenseDeviceState extends BluetoothGattCallback implements Handler.Callback, Callback,
-        LePairingCallback {
-    private static final String TAG = Settings.TAG_PREFIX + "DeviceState";
-    private static final boolean DBG = Settings.DBG;
-
-    /**
-     * Event callback interface invoked to report events to interested listeners
-     *
-     */
-    public interface EventCallback {
-        public void onConnected(SenseDeviceState deviceState);
-
-        public void onDisconnected(SenseDeviceState deviceState);
-
-        public void onUnsupportedDevice(SenseDeviceState deviceState);
-
-        public void onBatteryStatus(SenseDeviceState deviceState, int batteryLevel);
-
-        public void onSensorData(SenseDeviceState deviceState, byte[] sensorData);
-
-        public void onAppInfoRead(SenseDeviceState deviceState, boolean success, OtaAppInfo info);
-    }
-
-    private static final int DISCONNECT_DELAY_MS = 500;
-    private static final int CONNECT_COMPLETE_TIMER = 5000;
-
-    /** Descriptor used to enable/disable notifications/indications */
-    private static final UUID CLIENT_CONFIG_UUID = UUID
-            .fromString("00002902-0000-1000-8000-00805f9b34fb");
-
-    private static final UUID SENSOR_SERVICE_UUID = UUID
-            .fromString("739298B6-87B6-4984-A5DC-BDC18B068985");
-    private static final UUID SENSOR_NOTIFICATION_UUID = UUID
-            .fromString("33EF9113-3B55-413E-B553-FEA1EAADA459");
-
-    private static final UUID BATTERY_SERVICE_UUID = UUID
-            .fromString("0000180F-0000-1000-8000-00805f9b34fb");
-    private static final UUID BATTERY_LEVEL_UUID = UUID
-            .fromString("00002a19-0000-1000-8000-00805f9b34fb");
-
-    private static final int GET_BATTERY_STATUS = 100;
-    private static final int DISCONNECT = 102;
-
-    private static String getMessageName(int what) {
-        switch (what) {
-        case GET_BATTERY_STATUS:
-            return "GET_BATTERY_STATUS";
-        case DISCONNECT:
-            return "DISCONNECT";
-        }
-        return "UNKNOWN:" + what;
-    }
-
-    private final EventCallback mEventCallback;
-
-    private final Handler mHandler;
-    private final BluetoothDevice mDevice;
-    private final GattRequestManager mGattManager;
-    private boolean mIsConnectedAndAvailable;
-    private BluetoothGattCharacteristic mSensorNotification;
-    private BluetoothGattDescriptor mSensorNotificationClientConfig;
-    private BluetoothGattService mSensorService;
-    private BluetoothGattService mBatteryService;
-    private BluetoothGattCharacteristic mBatteryLevel;
-    private boolean mEnableSensorNotifications;
-    private boolean mSensorNotificationsEnabled;
-    private boolean mMonitorBattery;
-    private boolean mConnectAfterBonding;
-    private final OtaAppInfoReader mOtaAppReader;
-
-    public SenseDeviceState(Context ctx, BluetoothDevice device, Looper l, EventCallback cb) {
-        mEventCallback = cb;
-        mHandler = new Handler(l, this);
-        mDevice = device;
-        mGattManager = new GattRequestManager(ctx, device);
-        mGattManager.setAutoConnect(false);
-        mGattManager.setDiscoverServices(true);
-        mGattManager.setRetryFailedConnection(false, -1);
-        if (Settings.PAIRNG_REQUIRED) {
-            mGattManager.setPairingTimeout(Settings.PAIRING_TIMEOUT_MS);
-        }
-        mGattManager.addCallback(this);
-        mGattManager.addPairingCallback(this);
-
-        mOtaAppReader = new OtaAppInfoReader(this, l);
-    }
-
-    public BluetoothDevice getDevice() {
-        return mDevice;
-    }
-
-    public GattRequestManager getGattManager() {
-        return mGattManager;
-    }
-
-    public OtaAppInfoReader getAppInfoReader() {
-        return mOtaAppReader;
-    }
-
-    public boolean isConnectedAndAvailable() {
-        return mIsConnectedAndAvailable;
-    }
-
-    private void cancelBatteryStatus() {
-        mHandler.removeMessages(GET_BATTERY_STATUS);
-        mGattManager.removeRequest(GattRequestManager.REQUEST_READ_CHAR, mBatteryLevel);
-    }
-
-    private boolean loadServicesAndCharacteristics(BluetoothGatt gatt) {
-        // Get sensor service
-        mSensorService = gatt.getService(SENSOR_SERVICE_UUID);
-        if (mSensorService == null) {
-            Log.w(TAG,
-                    "onServicesDiscovered: Sensor Service not found. This device is not supported");
-            return false;
-        }
-
-        // Get notification characteristic
-        mSensorNotification = mSensorService.getCharacteristic(SENSOR_NOTIFICATION_UUID);
-        if (mSensorNotification == null) {
-            Log.w(TAG,
-                    "onServicesDiscovered: Sensor Characteristic not found. This device is not supported");
-            return false;
-        }
-        // Get client config for notification
-        mSensorNotificationClientConfig = mSensorNotification.getDescriptor(CLIENT_CONFIG_UUID);
-        if (mSensorNotificationClientConfig == null) {
-            Log.w(TAG,
-                    "onServicesDiscovered: Sensor Descriptor not found. This device is not supported");
-            return false;
-        }
-
-        // Get battery service and characteristic
-        mBatteryService = gatt.getService(BATTERY_SERVICE_UUID);
-        if (mBatteryService != null) {
-            mBatteryLevel = mBatteryService.getCharacteristic(BATTERY_LEVEL_UUID);
-        }
-        if (mBatteryLevel == null) {
-            Log.w(TAG, "onServiceDiscovered: Battery Level Characteristic not found.");
-        }
-
-        // Get OTA Service and characteristic
-        if (!mOtaAppReader.initServicesAndCharacteristics(mGattManager)) {
-            Log.w(TAG, "onServiceDiscovered: AppInfo Characteristics not found.");
-        }
-        return true;
-
-    }
-
-    @Override
-    public boolean handleMessage(Message msg) {
-        if (DBG) {
-            Log.d(TAG, "handleMessage:" + getMessageName(msg.what));
-        }
-        switch (msg.what) {
-        case DISCONNECT:
-            boolean closeResources = msg.arg1 == 1;
-            if (mGattManager != null) {
-                mGattManager.disconnect(closeResources);
-            }
-            break;
-        case GET_BATTERY_STATUS:
-            mGattManager.read(mBatteryLevel);
-            break;
-        }
-        return true;
-    }
-
-    @Override
-    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
-        super.onConnectionStateChange(gatt, status, newState);
-        if (DBG) {
-            Log.d(TAG, "onConnectionStateChange: " + mDevice + " status " + status + ": state="
-                    + newState);
-        }
-
-        if (BluetoothGatt.STATE_DISCONNECTED == newState) {
-            mIsConnectedAndAvailable = false;
-            mSensorNotificationsEnabled = false;
-            cancelBatteryStatus();
-            mOtaAppReader.finish();
-
-            // Send disconnected event
-            if (mEventCallback != null) {
-                mEventCallback.onDisconnected(this);
-            }
-            return;
-        }
-    }
-
-    @Override
-    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
-        if (mIsConnectedAndAvailable) {
-            if (DBG) {
-                Log.d(TAG,
-                        "onServicesDiscovered: Device already connected and services already discovered...");
-            }
-            return;
-        }
-
-        if (DBG) {
-            Log.d(TAG, "onServicesDiscovered: status=" + status);
-            List<BluetoothGattService> services = gatt.getServices();
-            if (services != null && services.size() > 0) {
-                for (int i = 0; i < services.size(); i++) {
-                    BluetoothGattService s = services.get(i);
-                    Log.d(TAG, "Service #" + i + ": " + s.getUuid().toString());
-                }
-            }
-        }
-
-        // Load the services and characteristics
-        if (!loadServicesAndCharacteristics(gatt)) {
-            if (mEventCallback != null) {
-                mEventCallback.onUnsupportedDevice(this);
-            }
-            disconnectDelayed();
-            return;
-        }
-        mIsConnectedAndAvailable = true;
-        mGattManager.startConnectCompleteTimer(CONNECT_COMPLETE_TIMER);
-        if (mEventCallback != null) {
-            mEventCallback.onConnected(this);
-        }
-    }
-
-    @Override
-    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
-        if (DBG) {
-            Log.d(TAG, "onDescriptorWrite  " + descriptor.getUuid());
-        }
-
-        if (mSensorNotification == null) {
-            Log.w(TAG, "onDescriptorWrite: mSensorNotification not found...");
-            return;
-        }
-        boolean success = mGattManager.setCharacteristicNotification(mSensorNotification,
-                mEnableSensorNotifications);
-        if (success) {
-            mSensorNotificationsEnabled = mEnableSensorNotifications;
-        }
-        Log.d(TAG,"onDescriptorWrite(): set char notification status success= " + success );
-        Log.d(TAG,"onDescriptorWrite(): mSensorNotificationsEnabled = " + mSensorNotificationsEnabled);
-    }
-
-    @Override
-    public void onCharacteristicRead(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic, int status) {
-        if (DBG) {
-            Log.d(TAG, "onCharacteristicRead  " + characteristic.getUuid());
-        }
-
-        if (BATTERY_LEVEL_UUID.equals(characteristic.getUuid())) {
-            if (status == BluetoothGatt.GATT_SUCCESS) {
-                try {
-                    int batteryLevel = characteristic.getIntValue(
-                            BluetoothGattCharacteristic.FORMAT_UINT8, 0);
-                    if (mEventCallback != null) {
-                        mEventCallback.onBatteryStatus(this, batteryLevel);
-                    }
-                } catch (Throwable t) {
-                    Log.e(TAG, "Unable to read battery level", t);
-                    return;
-                }
-            } else {
-                // Read right away for error case
-                mGattManager.read(mBatteryLevel);
-                return;
-            }
-
-            if (mMonitorBattery) {
-                getBatteryStatus(true);
-            }
-        }
-    }
-
-    @Override
-    public void onCharacteristicChanged(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic) {
-        if (SENSOR_NOTIFICATION_UUID.equals(characteristic.getUuid())) {
-            byte[] value = characteristic.getValue();
-            if (mEventCallback != null) {
-                mEventCallback.onSensorData(this, value);
-            }
-        }
-    }
-
-    public boolean pairIfNeeded() {
-        if (Settings.PAIRNG_REQUIRED && mDevice != null
-                && mDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
-            try {
-                mConnectAfterBonding = true;
-                return mGattManager.pair();
-            } catch (Throwable t) {
-                mConnectAfterBonding = false;
-                Log.e(TAG, "error", t);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void onPaired(boolean paired) {
-        if (DBG) {
-            Log.d(TAG, "onPaired: paired=" + paired);
-        }
-        if (mConnectAfterBonding) {
-            mConnectAfterBonding = false;
-            if (paired) {
-                mGattManager.connect();
-            } else {
-                if (mEventCallback != null) {
-                    mEventCallback.onDisconnected(this);
-                }
-            }
-        }
-
-    }
-
-    public void enableNotifications(boolean enable) {
-        enableSensorNotifications(enable);
-        enableBatteryMonitoring(enable);
-    }
-
-    private void disconnectDelayed() {
-        mHandler.sendEmptyMessageDelayed(DISCONNECT, DISCONNECT_DELAY_MS);
-    }
-
-    private boolean enableSensorNotifications(boolean enable) {
-        if (DBG) {
-            Log.d(TAG, "enableSensorNotifications: enable=" + enable);
-        }
-
-        if (mGattManager == null || mSensorNotification == null
-                || mSensorNotificationClientConfig == null) {
-            Log.w(TAG, "enableSensorNotifications: resources not available");
-            return false;
-        }
-        if (enable == mSensorNotificationsEnabled) {
-            Log.w(TAG, "enableSensorNotifications: notifications state already is enabled="
-                    + mSensorNotificationsEnabled);
-        }
-
-        mEnableSensorNotifications = enable; // Set flag used in callback
-        try {
-            mGattManager.write(mSensorNotificationClientConfig,
-                    mEnableSensorNotifications ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
-                            : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
-        } catch (Throwable t) {
-            Log.e(TAG, "enableSensorNotifications: error", t);
-            return false;
-        }
-        return true;
-    }
-
-    private void enableBatteryMonitoring(boolean enable) {
-        if (DBG) {
-            Log.d(TAG, "enableBatteryMonitoring: enable=" + enable + ", mMonitorBattery="
-                    + mMonitorBattery);
-        }
-
-        if (mMonitorBattery == enable) {
-            Log.w(TAG, "enableBatteryMonitoring: already in state enabled=" + mMonitorBattery);
-            return;
-        }
-        mMonitorBattery = enable;
-
-        if (enable) {
-            getBatteryStatus(false);
-        } else {
-            cancelBatteryStatus();
-        }
-    }
-
-    public void getBatteryStatus(boolean delayed) {
-        if (!mIsConnectedAndAvailable) {
-            return;
-        }
-        cancelBatteryStatus();
-        mGattManager.removeRequest(GattRequestManager.REQUEST_READ_CHAR, mBatteryLevel);
-        if (delayed) {
-            mHandler.sendEmptyMessageDelayed(GET_BATTERY_STATUS,
-                    Settings.BATTERY_STATUS_INTERVAL_MS);
-        } else {
-            mGattManager.read(mBatteryLevel, true);
-        }
-    }
-
-    @Override
-    public void onAppInfoRead(boolean success, OtaAppInfo info) {
-        if (DBG) {
-            Log.d(TAG, "onAppInfoRead");
-        }
-
-        OtaAppInfoReader reader = mOtaAppReader;
-        GattRequestManager gattManager = mGattManager;
-        if (gattManager != null && reader != null) {
-            gattManager.removeCallback(reader);
-        }
-        if (mEventCallback != null) {
-            mEventCallback.onAppInfoRead(this, success, info);
-        }
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import java.util.List;
+import java.util.UUID;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import com.broadcom.app.wicedsmart.ota.OtaAppInfo;
+import com.broadcom.app.wicedsmart.ota.OtaAppInfoReader;
+import com.broadcom.app.wicedsmart.ota.OtaAppInfoReader.Callback;
+import com.broadcom.util.GattRequestManager;
+import com.broadcom.util.GattRequestManager.LePairingCallback;
+
+/**
+ * Manages the connection and service/characteristics to a WICED Sense Device
+ *
+ *
+ */
+public class SenseDeviceState extends BluetoothGattCallback implements Handler.Callback, Callback,
+        LePairingCallback {
+    private static final String TAG = Settings.TAG_PREFIX + "DeviceState";
+    private static final boolean DBG = Settings.DBG;
+
+    /**
+     * Event callback interface invoked to report events to interested listeners
+     *
+     */
+    public interface EventCallback {
+        public void onConnected(SenseDeviceState deviceState);
+
+        public void onDisconnected(SenseDeviceState deviceState);
+
+        public void onUnsupportedDevice(SenseDeviceState deviceState);
+
+        public void onBatteryStatus(SenseDeviceState deviceState, int batteryLevel);
+
+        public void onSensorData(SenseDeviceState deviceState, byte[] sensorData);
+
+        public void onAppInfoRead(SenseDeviceState deviceState, boolean success, OtaAppInfo info);
+    }
+
+    private static final int DISCONNECT_DELAY_MS = 500;
+    private static final int CONNECT_COMPLETE_TIMER = 5000;
+
+    /** Descriptor used to enable/disable notifications/indications */
+    private static final UUID CLIENT_CONFIG_UUID = UUID
+            .fromString("00002902-0000-1000-8000-00805f9b34fb");
+
+    private static final UUID SENSOR_SERVICE_UUID = UUID
+            .fromString("739298B6-87B6-4984-A5DC-BDC18B068985");
+    private static final UUID SENSOR_NOTIFICATION_UUID = UUID
+            .fromString("33EF9113-3B55-413E-B553-FEA1EAADA459");
+
+    private static final UUID BATTERY_SERVICE_UUID = UUID
+            .fromString("0000180F-0000-1000-8000-00805f9b34fb");
+    private static final UUID BATTERY_LEVEL_UUID = UUID
+            .fromString("00002a19-0000-1000-8000-00805f9b34fb");
+
+    private static final int GET_BATTERY_STATUS = 100;
+    private static final int DISCONNECT = 102;
+
+    private static String getMessageName(int what) {
+        switch (what) {
+        case GET_BATTERY_STATUS:
+            return "GET_BATTERY_STATUS";
+        case DISCONNECT:
+            return "DISCONNECT";
+        }
+        return "UNKNOWN:" + what;
+    }
+
+    private final EventCallback mEventCallback;
+
+    private final Handler mHandler;
+    private final BluetoothDevice mDevice;
+    private final GattRequestManager mGattManager;
+    private boolean mIsConnectedAndAvailable;
+    private BluetoothGattCharacteristic mSensorNotification;
+    private BluetoothGattDescriptor mSensorNotificationClientConfig;
+    private BluetoothGattService mSensorService;
+    private BluetoothGattService mBatteryService;
+    private BluetoothGattCharacteristic mBatteryLevel;
+    private boolean mEnableSensorNotifications;
+    private boolean mSensorNotificationsEnabled;
+    private boolean mMonitorBattery;
+    private boolean mConnectAfterBonding;
+    private final OtaAppInfoReader mOtaAppReader;
+
+    public SenseDeviceState(Context ctx, BluetoothDevice device, Looper l, EventCallback cb) {
+        mEventCallback = cb;
+        mHandler = new Handler(l, this);
+        mDevice = device;
+        mGattManager = new GattRequestManager(ctx, device);
+        mGattManager.setAutoConnect(false);
+        mGattManager.setDiscoverServices(true);
+        mGattManager.setRetryFailedConnection(false, -1);
+        if (Settings.PAIRNG_REQUIRED) {
+            mGattManager.setPairingTimeout(Settings.PAIRING_TIMEOUT_MS);
+        }
+        mGattManager.addCallback(this);
+        mGattManager.addPairingCallback(this);
+
+        mOtaAppReader = new OtaAppInfoReader(this, l);
+    }
+
+    public BluetoothDevice getDevice() {
+        return mDevice;
+    }
+
+    public GattRequestManager getGattManager() {
+        return mGattManager;
+    }
+
+    public OtaAppInfoReader getAppInfoReader() {
+        return mOtaAppReader;
+    }
+
+    public boolean isConnectedAndAvailable() {
+        return mIsConnectedAndAvailable;
+    }
+
+    private void cancelBatteryStatus() {
+        mHandler.removeMessages(GET_BATTERY_STATUS);
+        mGattManager.removeRequest(GattRequestManager.REQUEST_READ_CHAR, mBatteryLevel);
+    }
+
+    private boolean loadServicesAndCharacteristics(BluetoothGatt gatt) {
+        // Get sensor service
+        mSensorService = gatt.getService(SENSOR_SERVICE_UUID);
+        if (mSensorService == null) {
+            Log.w(TAG,
+                    "onServicesDiscovered: Sensor Service not found. This device is not supported");
+            return false;
+        }
+
+        // Get notification characteristic
+        mSensorNotification = mSensorService.getCharacteristic(SENSOR_NOTIFICATION_UUID);
+        if (mSensorNotification == null) {
+            Log.w(TAG,
+                    "onServicesDiscovered: Sensor Characteristic not found. This device is not supported");
+            return false;
+        }
+        // Get client config for notification
+        mSensorNotificationClientConfig = mSensorNotification.getDescriptor(CLIENT_CONFIG_UUID);
+        if (mSensorNotificationClientConfig == null) {
+            Log.w(TAG,
+                    "onServicesDiscovered: Sensor Descriptor not found. This device is not supported");
+            return false;
+        }
+
+        // Get battery service and characteristic
+        mBatteryService = gatt.getService(BATTERY_SERVICE_UUID);
+        if (mBatteryService != null) {
+            mBatteryLevel = mBatteryService.getCharacteristic(BATTERY_LEVEL_UUID);
+        }
+        if (mBatteryLevel == null) {
+            Log.w(TAG, "onServiceDiscovered: Battery Level Characteristic not found.");
+        }
+
+        // Get OTA Service and characteristic
+        if (!mOtaAppReader.initServicesAndCharacteristics(mGattManager)) {
+            Log.w(TAG, "onServiceDiscovered: AppInfo Characteristics not found.");
+        }
+        return true;
+
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        if (DBG) {
+            Log.d(TAG, "handleMessage:" + getMessageName(msg.what));
+        }
+        switch (msg.what) {
+        case DISCONNECT:
+            boolean closeResources = msg.arg1 == 1;
+            if (mGattManager != null) {
+                mGattManager.disconnect(closeResources);
+            }
+            break;
+        case GET_BATTERY_STATUS:
+            mGattManager.read(mBatteryLevel);
+            break;
+        }
+        return true;
+    }
+
+    @Override
+    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+        super.onConnectionStateChange(gatt, status, newState);
+        if (DBG) {
+            Log.d(TAG, "onConnectionStateChange: " + mDevice + " status " + status + ": state="
+                    + newState);
+        }
+
+        if (BluetoothGatt.STATE_DISCONNECTED == newState) {
+            mIsConnectedAndAvailable = false;
+            mSensorNotificationsEnabled = false;
+            cancelBatteryStatus();
+            mOtaAppReader.finish();
+
+            // Send disconnected event
+            if (mEventCallback != null) {
+                mEventCallback.onDisconnected(this);
+            }
+            return;
+        }
+    }
+
+    @Override
+    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+        if (mIsConnectedAndAvailable) {
+            if (DBG) {
+                Log.d(TAG,
+                        "onServicesDiscovered: Device already connected and services already discovered...");
+            }
+            return;
+        }
+
+        if (DBG) {
+            Log.d(TAG, "onServicesDiscovered: status=" + status);
+            List<BluetoothGattService> services = gatt.getServices();
+            if (services != null && services.size() > 0) {
+                for (int i = 0; i < services.size(); i++) {
+                    BluetoothGattService s = services.get(i);
+                    Log.d(TAG, "Service #" + i + ": " + s.getUuid().toString());
+                }
+            }
+        }
+
+        // Load the services and characteristics
+        if (!loadServicesAndCharacteristics(gatt)) {
+            if (mEventCallback != null) {
+                mEventCallback.onUnsupportedDevice(this);
+            }
+            disconnectDelayed();
+            return;
+        }
+        mIsConnectedAndAvailable = true;
+        mGattManager.startConnectCompleteTimer(CONNECT_COMPLETE_TIMER);
+        if (mEventCallback != null) {
+            mEventCallback.onConnected(this);
+        }
+    }
+
+    @Override
+    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
+        if (DBG) {
+            Log.d(TAG, "onDescriptorWrite  " + descriptor.getUuid());
+        }
+
+        if (mSensorNotification == null) {
+            Log.w(TAG, "onDescriptorWrite: mSensorNotification not found...");
+            return;
+        }
+        boolean success = mGattManager.setCharacteristicNotification(mSensorNotification,
+                mEnableSensorNotifications);
+        if (success) {
+            mSensorNotificationsEnabled = mEnableSensorNotifications;
+        }
+        Log.d(TAG,"onDescriptorWrite(): set char notification status success= " + success );
+        Log.d(TAG,"onDescriptorWrite(): mSensorNotificationsEnabled = " + mSensorNotificationsEnabled);
+    }
+
+    @Override
+    public void onCharacteristicRead(BluetoothGatt gatt,
+            BluetoothGattCharacteristic characteristic, int status) {
+        if (DBG) {
+            Log.d(TAG, "onCharacteristicRead  " + characteristic.getUuid());
+        }
+
+        if (BATTERY_LEVEL_UUID.equals(characteristic.getUuid())) {
+            if (status == BluetoothGatt.GATT_SUCCESS) {
+                try {
+                    int batteryLevel = characteristic.getIntValue(
+                            BluetoothGattCharacteristic.FORMAT_UINT8, 0);
+                    if (mEventCallback != null) {
+                        mEventCallback.onBatteryStatus(this, batteryLevel);
+                    }
+                } catch (Throwable t) {
+                    Log.e(TAG, "Unable to read battery level", t);
+                    return;
+                }
+            } else {
+                // Read right away for error case
+                mGattManager.read(mBatteryLevel);
+                return;
+            }
+
+            if (mMonitorBattery) {
+                getBatteryStatus(true);
+            }
+        }
+    }
+
+    @Override
+    public void onCharacteristicChanged(BluetoothGatt gatt,
+            BluetoothGattCharacteristic characteristic) {
+        if (SENSOR_NOTIFICATION_UUID.equals(characteristic.getUuid())) {
+            byte[] value = characteristic.getValue();
+            if (mEventCallback != null) {
+                mEventCallback.onSensorData(this, value);
+            }
+        }
+    }
+
+    public boolean pairIfNeeded() {
+        if (Settings.PAIRNG_REQUIRED && mDevice != null
+                && mDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
+            try {
+                mConnectAfterBonding = true;
+                return mGattManager.pair();
+            } catch (Throwable t) {
+                mConnectAfterBonding = false;
+                Log.e(TAG, "error", t);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void onPaired(boolean paired) {
+        if (DBG) {
+            Log.d(TAG, "onPaired: paired=" + paired);
+        }
+        if (mConnectAfterBonding) {
+            mConnectAfterBonding = false;
+            if (paired) {
+                mGattManager.connect();
+            } else {
+                if (mEventCallback != null) {
+                    mEventCallback.onDisconnected(this);
+                }
+            }
+        }
+
+    }
+
+    public void enableNotifications(boolean enable) {
+        enableSensorNotifications(enable);
+        enableBatteryMonitoring(enable);
+    }
+
+    private void disconnectDelayed() {
+        mHandler.sendEmptyMessageDelayed(DISCONNECT, DISCONNECT_DELAY_MS);
+    }
+
+    private boolean enableSensorNotifications(boolean enable) {
+        if (DBG) {
+            Log.d(TAG, "enableSensorNotifications: enable=" + enable);
+        }
+
+        if (mGattManager == null || mSensorNotification == null
+                || mSensorNotificationClientConfig == null) {
+            Log.w(TAG, "enableSensorNotifications: resources not available");
+            return false;
+        }
+        if (enable == mSensorNotificationsEnabled) {
+            Log.w(TAG, "enableSensorNotifications: notifications state already is enabled="
+                    + mSensorNotificationsEnabled);
+        }
+
+        mEnableSensorNotifications = enable; // Set flag used in callback
+        try {
+            mGattManager.write(mSensorNotificationClientConfig,
+                    mEnableSensorNotifications ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
+                            : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
+        } catch (Throwable t) {
+            Log.e(TAG, "enableSensorNotifications: error", t);
+            return false;
+        }
+        return true;
+    }
+
+    private void enableBatteryMonitoring(boolean enable) {
+        if (DBG) {
+            Log.d(TAG, "enableBatteryMonitoring: enable=" + enable + ", mMonitorBattery="
+                    + mMonitorBattery);
+        }
+
+        if (mMonitorBattery == enable) {
+            Log.w(TAG, "enableBatteryMonitoring: already in state enabled=" + mMonitorBattery);
+            return;
+        }
+        mMonitorBattery = enable;
+
+        if (enable) {
+            getBatteryStatus(false);
+        } else {
+            cancelBatteryStatus();
+        }
+    }
+
+    public void getBatteryStatus(boolean delayed) {
+        if (!mIsConnectedAndAvailable) {
+            return;
+        }
+        cancelBatteryStatus();
+        mGattManager.removeRequest(GattRequestManager.REQUEST_READ_CHAR, mBatteryLevel);
+        if (delayed) {
+            mHandler.sendEmptyMessageDelayed(GET_BATTERY_STATUS,
+                    Settings.BATTERY_STATUS_INTERVAL_MS);
+        } else {
+            mGattManager.read(mBatteryLevel, true);
+        }
+    }
+
+    @Override
+    public void onAppInfoRead(boolean success, OtaAppInfo info) {
+        if (DBG) {
+            Log.d(TAG, "onAppInfoRead");
+        }
+
+        OtaAppInfoReader reader = mOtaAppReader;
+        GattRequestManager gattManager = mGattManager;
+        if (gattManager != null && reader != null) {
+            gattManager.removeCallback(reader);
+        }
+        if (mEventCallback != null) {
+            mEventCallback.onAppInfoRead(this, success, info);
+        }
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SenseManager.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SenseManager.java
index af01581d8d70a4c5d7a890fb8a3e06cffc8d1e2d..66afbc771b46e2d4edf262445ae9265b8b3e552c 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SenseManager.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SenseManager.java
@@ -1,364 +1,364 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import java.util.ArrayList;
-import com.broadcom.app.wicedsmart.ota.OtaAppInfo;
-import com.broadcom.app.wicedsmart.ota.OtaAppInfoReader;
-import com.broadcom.util.GattRequestManager;
-import android.app.Service;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Message;
-import android.util.Log;
-
-/**
- * Manages WICED Sense devices. Currently, this application only manages one
- * WICED Sense device at a time. But this can be expanded to support more than
- * one device connection
- *
- * @author fredc
- *
- */
-public class SenseManager extends Service implements SenseDeviceState.EventCallback {
-    private static final String TAG = Settings.TAG_PREFIX + "SenseManager";
-    private static final boolean DBG = Settings.DBG;
-
-    public static final int EVENT_CONNECTED = 10;
-    public static final int EVENT_DISCONNECTED = 11;
-    public static final int EVENT_DEVICE_UNSUPPORTED = 12;
-    public static final int EVENT_SENSOR_DATA = 50;
-    public static final int EVENT_BATTERY_STATUS = 60;
-    public static final int EVENT_APP_INFO = 70;
-
-    private static SenseManager sService;
-
-    public static synchronized SenseManager getInstance() {
-        return sService;
-    }
-
-    public static synchronized void init(Context ctx) {
-        Context appCtx = ctx.getApplicationContext();
-        Settings.init(appCtx);
-        Intent i = new Intent(appCtx, SenseManager.class);
-        appCtx.startService(i);
-    }
-
-    public static synchronized void destroy() {
-        SenseManager s = SenseManager.getInstance();
-        if (s != null && s.mIsStarted) {
-            s.stop();
-        }
-        Settings.finish();
-    }
-
-    private boolean mIsStarted;
-    private BluetoothAdapter mBluetoothAdapter;
-    private BluetoothManager mBluetoothManager;
-    private SenseDeviceState mDeviceState;
-    private final ArrayList<Handler> mEventCallbackHandlers = new ArrayList<Handler>();
-    private boolean mIsOtaUpdateMode;
-    private HandlerThread mHandlerThread;
-
-    @Override
-    public void onCreate() {
-        if (DBG) {
-            Log.d(TAG, "onCreate()");
-        }
-        super.onCreate();
-        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
-        if (mBluetoothAdapter == null || mBluetoothManager == null) {
-            Log.w(TAG, "Bluetooth not available!!!!");
-        }
-        synchronized (SenseManager.class) {
-            sService = this;
-        }
-        mHandlerThread = new HandlerThread("SenseManagerHandlerThread");
-        mHandlerThread.start();
-    }
-
-    @Override
-    public synchronized void onDestroy() {
-        if (DBG) {
-            Log.d(TAG, "onDestroy()");
-        }
-        if (mHandlerThread != null) {
-            mHandlerThread.quit();
-        }
-        super.onDestroy();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public synchronized int onStartCommand(Intent intent, int flags, int startId) {
-        mIsStarted = true;
-        return super.onStartCommand(intent, flags, startId);
-    }
-
-    public void onApplicationMinimized(boolean minimized) {
-
-    }
-
-    public synchronized boolean isStarted() {
-        return mIsStarted;
-    }
-
-    public synchronized void stop() {
-        if (DBG) {
-            Log.d(TAG, "stop()");
-        }
-        mIsStarted = false;
-        GattRequestManager gattManager = mDeviceState == null ? null : mDeviceState
-                .getGattManager();
-        if (gattManager != null) {
-            gattManager.disconnect(true);
-        }
-        mEventCallbackHandlers.clear();
-        super.stopSelf();
-        synchronized (SenseManager.class) {
-            sService = null;
-        }
-    }
-
-    public void registerEventCallbackHandler(Handler callback) {
-        if (mEventCallbackHandlers.contains(callback)) {
-            Log.w(TAG, "registerEventCallbackHandler: callback already registered");
-            return;
-        }
-        mEventCallbackHandlers.add(callback);
-    }
-
-    public void unregisterEventCallbackHandler(Handler callback) {
-        mEventCallbackHandlers.remove(callback);
-    }
-
-    public synchronized void setDevice(BluetoothDevice device) {
-        GattRequestManager gattManager = mDeviceState == null ? null : mDeviceState
-                .getGattManager();
-        if (gattManager != null) {
-            gattManager.disconnect(true);
-        }
-        mDeviceState = new SenseDeviceState(this, device, mHandlerThread.getLooper(), this);
-        if (Settings.CONNECT_AFTER_DEVICE_PICK) {
-            connect();
-        }
-    }
-
-    public synchronized SenseDeviceState getDeviceState() {
-        return mDeviceState;
-    }
-
-    public BluetoothDevice getDevice() {
-        return mDeviceState == null ? null : mDeviceState.getDevice();
-    }
-
-    public GattRequestManager getGattManager() {
-        return mDeviceState == null ? null : mDeviceState.getGattManager();
-    }
-
-    public boolean connect() {
-        if (DBG) {
-            Log.d(TAG, "connect(): mGattState=" + mDeviceState);
-        }
-        if (mDeviceState == null) {
-            return false;
-        }
-        if (!mDeviceState.pairIfNeeded()) {
-            mDeviceState.getGattManager().connect();
-        }
-        return true;
-    }
-
-    public boolean disconnect() {
-        GattRequestManager gattManager = mDeviceState == null ? null : mDeviceState
-                .getGattManager();
-        if (gattManager != null) {
-            return gattManager.disconnect(true);
-        } else {
-            return false;
-        }
-    }
-
-    public boolean isConnectedAndAvailable() {
-        return mDeviceState != null && mDeviceState.isConnectedAndAvailable();
-    }
-
-    public boolean getAppInfo() {
-        if (mDeviceState == null) {
-            return false;
-        }
-        GattRequestManager gattManager = null;
-        OtaAppInfoReader reader = null;
-        if (mDeviceState != null) {
-            gattManager = mDeviceState.getGattManager();
-            reader = mDeviceState.getAppInfoReader();
-        }
-        if (gattManager == null || reader == null) {
-            return false;
-        }
-        gattManager.addCallback(reader);
-        boolean success = reader.read();
-        if (!success) {
-            gattManager.removeCallback(reader);
-        }
-        return success;
-    }
-
-    public void getBatteryStatus() {
-        if (isConnectedAndAvailable()) {
-            mDeviceState.getBatteryStatus(false);
-        }
-    }
-
-    public void enableNotifications(boolean enable) {
-        if (DBG) {
-            Log.d(TAG, "enableNotifications: enable= " + enable + ", mGattState= " + mDeviceState
-                    + ", mIsOtaUpdateMode=" + mIsOtaUpdateMode);
-        }
-        if (!isConnectedAndAvailable()) {
-            Log.w(TAG, "enableNotifications: not connected or available...");
-            return;
-        }
-
-        if (enable && mIsOtaUpdateMode) {
-            Log.w(TAG,
-                    "enableNotifications: is currently in OtaUpdateMode Ignoring enable request...");
-            return;
-        }
-
-        mDeviceState.enableNotifications(enable);
-    }
-
-    /**
-     * Unregister for events and unregister for callbacks
-     *
-     * @param isOtaUpdateMode
-     */
-    public void setOtaUpdateMode(boolean isOtaUpdateMode) {
-        mIsOtaUpdateMode = isOtaUpdateMode;
-        if (isOtaUpdateMode) {
-            enableNotifications(false);
-        } else {
-            GattRequestManager gattManager = mDeviceState == null ? null : mDeviceState
-                    .getGattManager();
-            if (gattManager != null) {
-                gattManager.addCallback(mDeviceState);
-            }
-            enableNotifications(true);
-        }
-    }
-
-    private void sendEvent(int eventType, SenseDeviceState state) {
-        @SuppressWarnings("unchecked")
-        ArrayList<Handler> eventCallbacks = (ArrayList<Handler>) mEventCallbackHandlers.clone();
-        int sz = eventCallbacks == null ? 0 : eventCallbacks.size();
-        for (int i = 0; i < sz; i++) {
-            Handler cb = eventCallbacks.get(i);
-            if (cb != null) {
-                try {
-                    Message event = cb.obtainMessage(eventType, state);
-                    cb.sendMessage(event);
-                } catch (Throwable t) {
-                    Log.w(TAG, "sendEvent error, callback #" + i, t);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onConnected(SenseDeviceState deviceState) {
-        sendEvent(EVENT_CONNECTED, deviceState);
-    }
-
-    @Override
-    public void onDisconnected(SenseDeviceState deviceState) {
-        sendEvent(EVENT_DISCONNECTED, deviceState);
-    }
-
-    @Override
-    public void onUnsupportedDevice(SenseDeviceState deviceState) {
-        sendEvent(EVENT_DEVICE_UNSUPPORTED, deviceState);
-    }
-
-    @Override
-    public void onBatteryStatus(SenseDeviceState deviceState, int batteryLevel) {
-        @SuppressWarnings("unchecked")
-        ArrayList<Handler> eventCallbacks = (ArrayList<Handler>) mEventCallbackHandlers.clone();
-        int sz = eventCallbacks == null ? 0 : eventCallbacks.size();
-        for (int i = 0; i < sz; i++) {
-            Handler cb = eventCallbacks.get(i);
-            if (cb != null) {
-                try {
-                    Message event = cb.obtainMessage(EVENT_BATTERY_STATUS, batteryLevel,
-                            batteryLevel, deviceState);
-                    cb.sendMessage(event);
-                } catch (Throwable t) {
-                    Log.w(TAG, "onBatteryStatus error, callback #" + i, t);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onSensorData(SenseDeviceState deviceState, byte[] sensorData) {
-        @SuppressWarnings("unchecked")
-        ArrayList<Handler> eventCallbacks = (ArrayList<Handler>) mEventCallbackHandlers.clone();
-        int sz = eventCallbacks == null ? 0 : eventCallbacks.size();
-        for (int i = 0; i < sz; i++) {
-            Handler cb = eventCallbacks.get(i);
-            if (cb != null) {
-                try {
-                    Message event = cb.obtainMessage(EVENT_SENSOR_DATA, sensorData);
-                    cb.sendMessage(event);
-                } catch (Throwable t) {
-                    Log.w(TAG, "onSensorData error, callback #" + i, t);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void onAppInfoRead(SenseDeviceState deviceState, boolean success, OtaAppInfo info) {
-        @SuppressWarnings("unchecked")
-        ArrayList<Handler> eventCallbacks = (ArrayList<Handler>) mEventCallbackHandlers.clone();
-        int sz = eventCallbacks == null ? 0 : eventCallbacks.size();
-        for (int i = 0; i < sz; i++) {
-            Handler cb = eventCallbacks.get(i);
-            if (cb != null) {
-                try {
-                    Message event = cb.obtainMessage(EVENT_APP_INFO, success ? 1 : 0, 0, info);
-                    cb.sendMessage(event);
-                } catch (Throwable t) {
-                    Log.w(TAG, "onAppInfoRead error, callback #" + i, t);
-                }
-            }
-        }
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import java.util.ArrayList;
+import com.broadcom.app.wicedsmart.ota.OtaAppInfo;
+import com.broadcom.app.wicedsmart.ota.OtaAppInfoReader;
+import com.broadcom.util.GattRequestManager;
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * Manages WICED Sense devices. Currently, this application only manages one
+ * WICED Sense device at a time. But this can be expanded to support more than
+ * one device connection
+ *
+ * @author fredc
+ *
+ */
+public class SenseManager extends Service implements SenseDeviceState.EventCallback {
+    private static final String TAG = Settings.TAG_PREFIX + "SenseManager";
+    private static final boolean DBG = Settings.DBG;
+
+    public static final int EVENT_CONNECTED = 10;
+    public static final int EVENT_DISCONNECTED = 11;
+    public static final int EVENT_DEVICE_UNSUPPORTED = 12;
+    public static final int EVENT_SENSOR_DATA = 50;
+    public static final int EVENT_BATTERY_STATUS = 60;
+    public static final int EVENT_APP_INFO = 70;
+
+    private static SenseManager sService;
+
+    public static synchronized SenseManager getInstance() {
+        return sService;
+    }
+
+    public static synchronized void init(Context ctx) {
+        Context appCtx = ctx.getApplicationContext();
+        Settings.init(appCtx);
+        Intent i = new Intent(appCtx, SenseManager.class);
+        appCtx.startService(i);
+    }
+
+    public static synchronized void destroy() {
+        SenseManager s = SenseManager.getInstance();
+        if (s != null && s.mIsStarted) {
+            s.stop();
+        }
+        Settings.finish();
+    }
+
+    private boolean mIsStarted;
+    private BluetoothAdapter mBluetoothAdapter;
+    private BluetoothManager mBluetoothManager;
+    private SenseDeviceState mDeviceState;
+    private final ArrayList<Handler> mEventCallbackHandlers = new ArrayList<Handler>();
+    private boolean mIsOtaUpdateMode;
+    private HandlerThread mHandlerThread;
+
+    @Override
+    public void onCreate() {
+        if (DBG) {
+            Log.d(TAG, "onCreate()");
+        }
+        super.onCreate();
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+        if (mBluetoothAdapter == null || mBluetoothManager == null) {
+            Log.w(TAG, "Bluetooth not available!!!!");
+        }
+        synchronized (SenseManager.class) {
+            sService = this;
+        }
+        mHandlerThread = new HandlerThread("SenseManagerHandlerThread");
+        mHandlerThread.start();
+    }
+
+    @Override
+    public synchronized void onDestroy() {
+        if (DBG) {
+            Log.d(TAG, "onDestroy()");
+        }
+        if (mHandlerThread != null) {
+            mHandlerThread.quit();
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public synchronized int onStartCommand(Intent intent, int flags, int startId) {
+        mIsStarted = true;
+        return super.onStartCommand(intent, flags, startId);
+    }
+
+    public void onApplicationMinimized(boolean minimized) {
+
+    }
+
+    public synchronized boolean isStarted() {
+        return mIsStarted;
+    }
+
+    public synchronized void stop() {
+        if (DBG) {
+            Log.d(TAG, "stop()");
+        }
+        mIsStarted = false;
+        GattRequestManager gattManager = mDeviceState == null ? null : mDeviceState
+                .getGattManager();
+        if (gattManager != null) {
+            gattManager.disconnect(true);
+        }
+        mEventCallbackHandlers.clear();
+        super.stopSelf();
+        synchronized (SenseManager.class) {
+            sService = null;
+        }
+    }
+
+    public void registerEventCallbackHandler(Handler callback) {
+        if (mEventCallbackHandlers.contains(callback)) {
+            Log.w(TAG, "registerEventCallbackHandler: callback already registered");
+            return;
+        }
+        mEventCallbackHandlers.add(callback);
+    }
+
+    public void unregisterEventCallbackHandler(Handler callback) {
+        mEventCallbackHandlers.remove(callback);
+    }
+
+    public synchronized void setDevice(BluetoothDevice device) {
+        GattRequestManager gattManager = mDeviceState == null ? null : mDeviceState
+                .getGattManager();
+        if (gattManager != null) {
+            gattManager.disconnect(true);
+        }
+        mDeviceState = new SenseDeviceState(this, device, mHandlerThread.getLooper(), this);
+        if (Settings.CONNECT_AFTER_DEVICE_PICK) {
+            connect();
+        }
+    }
+
+    public synchronized SenseDeviceState getDeviceState() {
+        return mDeviceState;
+    }
+
+    public BluetoothDevice getDevice() {
+        return mDeviceState == null ? null : mDeviceState.getDevice();
+    }
+
+    public GattRequestManager getGattManager() {
+        return mDeviceState == null ? null : mDeviceState.getGattManager();
+    }
+
+    public boolean connect() {
+        if (DBG) {
+            Log.d(TAG, "connect(): mGattState=" + mDeviceState);
+        }
+        if (mDeviceState == null) {
+            return false;
+        }
+        if (!mDeviceState.pairIfNeeded()) {
+            mDeviceState.getGattManager().connect();
+        }
+        return true;
+    }
+
+    public boolean disconnect() {
+        GattRequestManager gattManager = mDeviceState == null ? null : mDeviceState
+                .getGattManager();
+        if (gattManager != null) {
+            return gattManager.disconnect(true);
+        } else {
+            return false;
+        }
+    }
+
+    public boolean isConnectedAndAvailable() {
+        return mDeviceState != null && mDeviceState.isConnectedAndAvailable();
+    }
+
+    public boolean getAppInfo() {
+        if (mDeviceState == null) {
+            return false;
+        }
+        GattRequestManager gattManager = null;
+        OtaAppInfoReader reader = null;
+        if (mDeviceState != null) {
+            gattManager = mDeviceState.getGattManager();
+            reader = mDeviceState.getAppInfoReader();
+        }
+        if (gattManager == null || reader == null) {
+            return false;
+        }
+        gattManager.addCallback(reader);
+        boolean success = reader.read();
+        if (!success) {
+            gattManager.removeCallback(reader);
+        }
+        return success;
+    }
+
+    public void getBatteryStatus() {
+        if (isConnectedAndAvailable()) {
+            mDeviceState.getBatteryStatus(false);
+        }
+    }
+
+    public void enableNotifications(boolean enable) {
+        if (DBG) {
+            Log.d(TAG, "enableNotifications: enable= " + enable + ", mGattState= " + mDeviceState
+                    + ", mIsOtaUpdateMode=" + mIsOtaUpdateMode);
+        }
+        if (!isConnectedAndAvailable()) {
+            Log.w(TAG, "enableNotifications: not connected or available...");
+            return;
+        }
+
+        if (enable && mIsOtaUpdateMode) {
+            Log.w(TAG,
+                    "enableNotifications: is currently in OtaUpdateMode Ignoring enable request...");
+            return;
+        }
+
+        mDeviceState.enableNotifications(enable);
+    }
+
+    /**
+     * Unregister for events and unregister for callbacks
+     *
+     * @param isOtaUpdateMode
+     */
+    public void setOtaUpdateMode(boolean isOtaUpdateMode) {
+        mIsOtaUpdateMode = isOtaUpdateMode;
+        if (isOtaUpdateMode) {
+            enableNotifications(false);
+        } else {
+            GattRequestManager gattManager = mDeviceState == null ? null : mDeviceState
+                    .getGattManager();
+            if (gattManager != null) {
+                gattManager.addCallback(mDeviceState);
+            }
+            enableNotifications(true);
+        }
+    }
+
+    private void sendEvent(int eventType, SenseDeviceState state) {
+        @SuppressWarnings("unchecked")
+        ArrayList<Handler> eventCallbacks = (ArrayList<Handler>) mEventCallbackHandlers.clone();
+        int sz = eventCallbacks == null ? 0 : eventCallbacks.size();
+        for (int i = 0; i < sz; i++) {
+            Handler cb = eventCallbacks.get(i);
+            if (cb != null) {
+                try {
+                    Message event = cb.obtainMessage(eventType, state);
+                    cb.sendMessage(event);
+                } catch (Throwable t) {
+                    Log.w(TAG, "sendEvent error, callback #" + i, t);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onConnected(SenseDeviceState deviceState) {
+        sendEvent(EVENT_CONNECTED, deviceState);
+    }
+
+    @Override
+    public void onDisconnected(SenseDeviceState deviceState) {
+        sendEvent(EVENT_DISCONNECTED, deviceState);
+    }
+
+    @Override
+    public void onUnsupportedDevice(SenseDeviceState deviceState) {
+        sendEvent(EVENT_DEVICE_UNSUPPORTED, deviceState);
+    }
+
+    @Override
+    public void onBatteryStatus(SenseDeviceState deviceState, int batteryLevel) {
+        @SuppressWarnings("unchecked")
+        ArrayList<Handler> eventCallbacks = (ArrayList<Handler>) mEventCallbackHandlers.clone();
+        int sz = eventCallbacks == null ? 0 : eventCallbacks.size();
+        for (int i = 0; i < sz; i++) {
+            Handler cb = eventCallbacks.get(i);
+            if (cb != null) {
+                try {
+                    Message event = cb.obtainMessage(EVENT_BATTERY_STATUS, batteryLevel,
+                            batteryLevel, deviceState);
+                    cb.sendMessage(event);
+                } catch (Throwable t) {
+                    Log.w(TAG, "onBatteryStatus error, callback #" + i, t);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onSensorData(SenseDeviceState deviceState, byte[] sensorData) {
+        @SuppressWarnings("unchecked")
+        ArrayList<Handler> eventCallbacks = (ArrayList<Handler>) mEventCallbackHandlers.clone();
+        int sz = eventCallbacks == null ? 0 : eventCallbacks.size();
+        for (int i = 0; i < sz; i++) {
+            Handler cb = eventCallbacks.get(i);
+            if (cb != null) {
+                try {
+                    Message event = cb.obtainMessage(EVENT_SENSOR_DATA, sensorData);
+                    cb.sendMessage(event);
+                } catch (Throwable t) {
+                    Log.w(TAG, "onSensorData error, callback #" + i, t);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onAppInfoRead(SenseDeviceState deviceState, boolean success, OtaAppInfo info) {
+        @SuppressWarnings("unchecked")
+        ArrayList<Handler> eventCallbacks = (ArrayList<Handler>) mEventCallbackHandlers.clone();
+        int sz = eventCallbacks == null ? 0 : eventCallbacks.size();
+        for (int i = 0; i < sz; i++) {
+            Handler cb = eventCallbacks.get(i);
+            if (cb != null) {
+                try {
+                    Message event = cb.obtainMessage(EVENT_APP_INFO, success ? 1 : 0, 0, info);
+                    cb.sendMessage(event);
+                } catch (Throwable t) {
+                    Log.w(TAG, "onAppInfoRead error, callback #" + i, t);
+                }
+            }
+        }
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SensorDataParser.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SensorDataParser.java
index 2de173868d2d75116b84e67270890b02c349318c..c546f1f6281a1cfac39e19616d4a610009349835 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SensorDataParser.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SensorDataParser.java
@@ -1,150 +1,150 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import com.broadcom.util.MathUtils;
-
-/**
- * Helper class to parse the sensor data packets
- *
- * @author fredc
- *
- */
-public class SensorDataParser {
-    public static final String TAG = Settings.TAG_PREFIX + "SensorDataParser";
-
-    public static final int SENSOR_FLAG_ACCEL = (0x1 << 0);
-    public static final int SENSOR_FLAG_GYRO = (0x1 << 1);
-    public static final int SENSOR_FLAG_HUMIDITY = (0x1 << 2);
-    public static final int SENSOR_FLAG_MAGNO = (0x1 << 3);
-    public static final int SENSOR_FLAG_PRESSURE = (0x1 << 4);
-    public static final int SENSOR_FLAG_TEMP = (0x1 << 5);
-
-    // not currently in use - but should be set so that the match what the
-    // sensor produces - currently wrong
-    public static final int SENSOR_ACCEL_MIN = -90;
-    public static final int SENSOR_ACCEL_MAX = 90;
-
-    // not currently in use - but should be set so that the match what the
-    // sensor produces - currently wrong
-    public static final int SENSOR_GYRO_MIN = -327;
-    public static final int SENSOR_GYRO_MAX = 327;
-
-    public static final int SENSOR_HUMIDITY_MIN = 0;
-    public static final int SENSOR_HUMIDITY_MAX = 100;
-
-    // not currently in use - but should be set so that the match what the
-    // sensor produces - currently wrong
-    public static final int SENSOR_MAGNO_MIN = -180;
-    public static final int SENSOR_MAGNO_MAX = 180;
-
-    public static final int SENSOR_PRESSURE_MIN = 800;
-    public static final int SENSOR_PRESSURE_MAX = 1200;
-
-    public static final float SENSOR_TEMP_MIN_F = -40;
-    public static final float SENSOR_TEMP_MAX_F = 120;
-
-    public static final float SENSOR_TEMP_MIN_C = -40;
-    public static final float SENSOR_TEMP_MAX_C = 60;
-
-    public static final int SENSOR_TEMP_DATA_SIZE = 2;
-    public static final int SENSOR_PRES_DATA_SIZE = 2;
-    public static final int SENSOR_HUMD_DATA_SIZE = 2;
-
-    public static final int SENSOR_ACCEL_DATA_SIZE = 6;
-    public static final int SENSOR_MAGNO_DATA_SIZE = 6;
-    public static final int SENSOR_GYRO_DATA_SIZE = 6;
-
-    private static int getTwoByteValue(byte[] bytes, int offset) {
-        return (bytes[offset + 1] << 8) + (bytes[offset] & 0xFF);
-    }
-
-    public static boolean accelerometerHasChanged(int mask) {
-        return (SENSOR_FLAG_ACCEL & mask) > 0;
-    }
-
-    public static boolean gyroHasChanged(int mask) {
-        return (SENSOR_FLAG_GYRO & mask) > 0;
-    }
-
-    public static boolean magnetometerHasChanged(int mask) {
-        return (SENSOR_FLAG_MAGNO & mask) > 0;
-    }
-
-    public static boolean humidityHasChanged(int mask) {
-        return (SENSOR_FLAG_HUMIDITY & mask) > 0;
-    }
-
-    public static boolean temperatureHasChanged(int mask) {
-        return (SENSOR_FLAG_TEMP & mask) > 0;
-    }
-
-    public static boolean pressureHasChanged(int mask) {
-        return (SENSOR_FLAG_PRESSURE & mask) > 0;
-    }
-
-    public static float getHumidityPercent(byte[] sensorData, int offset) {
-        return ((float) getTwoByteValue(sensorData, offset)) / 10;
-    }
-
-    public static float getPressureMBar(byte[] sensorData, int offset) {
-        return ((float) getTwoByteValue(sensorData, offset)) / 10;
-    }
-
-    public static float getTemperatureC(byte[] sensorData, int offset) {
-        return ((float) getTwoByteValue(sensorData, offset)) / 10;
-    }
-
-    public static float getTemperatureF(byte[] sensorData, int offset) {
-        return getTemperatureC(sensorData, offset) * 9 / 5 + 32;
-    }
-
-    public static void getAccelorometerData(byte[] sensorData, int offset, int[] values) {
-        values[0] = getTwoByteValue(sensorData, offset);
-        values[1] = getTwoByteValue(sensorData, offset + 2);
-        values[2] = getTwoByteValue(sensorData, offset + 4);
-    }
-
-    public static void getMagnometerData(byte[] sensorData, int offset, int[] values) {
-        values[0] = getTwoByteValue(sensorData, offset);
-        values[1] = getTwoByteValue(sensorData, offset + 2);
-        values[2] = getTwoByteValue(sensorData, offset + 4);
-
-    }
-
-    public static float getCompassAngleDegrees(int[] magnometerValues) {
-        double x = magnometerValues[0];
-        double y = magnometerValues[1];
-        return (float) MathUtils.getDegrees(y, x);
-    }
-
-    public static void getGyroData(byte[] sensorData, int offset, int[] values) {
-        values[0] = getTwoByteValue(sensorData, offset) / 100;
-        values[1] = getTwoByteValue(sensorData, offset + 2) / 100;
-        values[2] = getTwoByteValue(sensorData, offset + 4) / 100;
-    }
-
-    public static float tempCtoF(float c) {
-        return c * 9 / 5 + 32;
-    }
-
-    public static float tempFtoC(float f) {
-        return (f - 32) * 5 / 9;
-    }
-
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import com.broadcom.util.MathUtils;
+
+/**
+ * Helper class to parse the sensor data packets
+ *
+ * @author fredc
+ *
+ */
+public class SensorDataParser {
+    public static final String TAG = Settings.TAG_PREFIX + "SensorDataParser";
+
+    public static final int SENSOR_FLAG_ACCEL = (0x1 << 0);
+    public static final int SENSOR_FLAG_GYRO = (0x1 << 1);
+    public static final int SENSOR_FLAG_HUMIDITY = (0x1 << 2);
+    public static final int SENSOR_FLAG_MAGNO = (0x1 << 3);
+    public static final int SENSOR_FLAG_PRESSURE = (0x1 << 4);
+    public static final int SENSOR_FLAG_TEMP = (0x1 << 5);
+
+    // not currently in use - but should be set so that the match what the
+    // sensor produces - currently wrong
+    public static final int SENSOR_ACCEL_MIN = -90;
+    public static final int SENSOR_ACCEL_MAX = 90;
+
+    // not currently in use - but should be set so that the match what the
+    // sensor produces - currently wrong
+    public static final int SENSOR_GYRO_MIN = -327;
+    public static final int SENSOR_GYRO_MAX = 327;
+
+    public static final int SENSOR_HUMIDITY_MIN = 0;
+    public static final int SENSOR_HUMIDITY_MAX = 100;
+
+    // not currently in use - but should be set so that the match what the
+    // sensor produces - currently wrong
+    public static final int SENSOR_MAGNO_MIN = -180;
+    public static final int SENSOR_MAGNO_MAX = 180;
+
+    public static final int SENSOR_PRESSURE_MIN = 800;
+    public static final int SENSOR_PRESSURE_MAX = 1200;
+
+    public static final float SENSOR_TEMP_MIN_F = -40;
+    public static final float SENSOR_TEMP_MAX_F = 120;
+
+    public static final float SENSOR_TEMP_MIN_C = -40;
+    public static final float SENSOR_TEMP_MAX_C = 60;
+
+    public static final int SENSOR_TEMP_DATA_SIZE = 2;
+    public static final int SENSOR_PRES_DATA_SIZE = 2;
+    public static final int SENSOR_HUMD_DATA_SIZE = 2;
+
+    public static final int SENSOR_ACCEL_DATA_SIZE = 6;
+    public static final int SENSOR_MAGNO_DATA_SIZE = 6;
+    public static final int SENSOR_GYRO_DATA_SIZE = 6;
+
+    private static int getTwoByteValue(byte[] bytes, int offset) {
+        return (bytes[offset + 1] << 8) + (bytes[offset] & 0xFF);
+    }
+
+    public static boolean accelerometerHasChanged(int mask) {
+        return (SENSOR_FLAG_ACCEL & mask) > 0;
+    }
+
+    public static boolean gyroHasChanged(int mask) {
+        return (SENSOR_FLAG_GYRO & mask) > 0;
+    }
+
+    public static boolean magnetometerHasChanged(int mask) {
+        return (SENSOR_FLAG_MAGNO & mask) > 0;
+    }
+
+    public static boolean humidityHasChanged(int mask) {
+        return (SENSOR_FLAG_HUMIDITY & mask) > 0;
+    }
+
+    public static boolean temperatureHasChanged(int mask) {
+        return (SENSOR_FLAG_TEMP & mask) > 0;
+    }
+
+    public static boolean pressureHasChanged(int mask) {
+        return (SENSOR_FLAG_PRESSURE & mask) > 0;
+    }
+
+    public static float getHumidityPercent(byte[] sensorData, int offset) {
+        return ((float) getTwoByteValue(sensorData, offset)) / 10;
+    }
+
+    public static float getPressureMBar(byte[] sensorData, int offset) {
+        return ((float) getTwoByteValue(sensorData, offset)) / 10;
+    }
+
+    public static float getTemperatureC(byte[] sensorData, int offset) {
+        return ((float) getTwoByteValue(sensorData, offset)) / 10;
+    }
+
+    public static float getTemperatureF(byte[] sensorData, int offset) {
+        return getTemperatureC(sensorData, offset) * 9 / 5 + 32;
+    }
+
+    public static void getAccelorometerData(byte[] sensorData, int offset, int[] values) {
+        values[0] = getTwoByteValue(sensorData, offset);
+        values[1] = getTwoByteValue(sensorData, offset + 2);
+        values[2] = getTwoByteValue(sensorData, offset + 4);
+    }
+
+    public static void getMagnometerData(byte[] sensorData, int offset, int[] values) {
+        values[0] = getTwoByteValue(sensorData, offset);
+        values[1] = getTwoByteValue(sensorData, offset + 2);
+        values[2] = getTwoByteValue(sensorData, offset + 4);
+
+    }
+
+    public static float getCompassAngleDegrees(int[] magnometerValues) {
+        double x = magnometerValues[0];
+        double y = magnometerValues[1];
+        return (float) MathUtils.getDegrees(y, x);
+    }
+
+    public static void getGyroData(byte[] sensorData, int offset, int[] values) {
+        values[0] = getTwoByteValue(sensorData, offset) / 100;
+        values[1] = getTwoByteValue(sensorData, offset + 2) / 100;
+        values[2] = getTwoByteValue(sensorData, offset + 4) / 100;
+    }
+
+    public static float tempCtoF(float c) {
+        return c * 9 / 5 + 32;
+    }
+
+    public static float tempFtoC(float f) {
+        return (f - 32) * 5 / 9;
+    }
+
 }
\ No newline at end of file
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/Settings.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/Settings.java
index b81fa79d0cd87207a6ad70e7b7178c694af67f32..404215f4f3ce306c50e04cebd2cb4dc84c7b6206 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/Settings.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/Settings.java
@@ -1,300 +1,300 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-
-import com.broadcom.app.wicedsmart.ota.ui.OtaResource;
-import com.broadcom.app.wicedsmart.ota.ui.OtaUiHelper;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.content.pm.PackageInfo;
-import android.os.Environment;
-import android.util.Log;
-
-/**
- * Configurable settings for the WICED Sense Application
- *
- */
-public class Settings {
-    public static final String TEMPERATURE_SCALE_TYPE_F = "F";
-    public static final String TEMPERATURE_SCALE_TYPE_C = "C";
-
-    /**
-     * Specifies if pairing/encryption is required to WICED Sense tag
-     */
-    public static final boolean PAIRNG_REQUIRED = true;
-    public static final int PAIRING_TIMEOUT_MS = 20000;
-
-    /**
-     * If true, WICED Sense app automatically connects to the WICED Sense tag
-     * after it is picked from the device picker
-     */
-    public static final boolean CONNECT_AFTER_DEVICE_PICK = false;
-
-    /**
-     * Frequency the battery status of the WICED Sense tag should be polled (in
-     * msec)
-     */
-    public static final int BATTERY_STATUS_INTERVAL_MS = 120000; // Every 2mins
-
-    /**
-     * Timeout to wait for a connection to the SenseManager service
-     */
-    public static final int SERVICE_INIT_TIMEOUT_MS = 250;
-
-    /**
-     * Number of retry attempts if BLE service discovery of the WICED Sense tag
-     * fails
-     */
-    public static final int SERVICE_DISCOVERY_RETRY = 2;
-
-    /**
-     * If true, a firmware update check will be performed after the WICED Sense
-     * tag is connected
-     */
-    public static final boolean CHECK_FOR_UPDATES_ON_CONNECT = true;
-
-    /**
-     * Enable debug tracing to adb logcat logs
-     */
-    public static final boolean DBG = true;
-
-    /**
-     * String contant that all adb logcat messages will be prefixed with (to
-     * simplify filtering)
-     */
-    public static final String TAG_PREFIX = "WicedSense.";
-
-    // --------------------Do not modify below-------------------------------
-    public interface SettingChangeListener {
-        public void onSettingsChanged(String settingName);
-    }
-
-    private static final String TAG = TAG_PREFIX + "Settings";
-
-    public static final String PACKAGE_NAME = "com.broadcom.app.wicedsense";
-
-    private static final String SETTINGS_PREF_NAME = "com.broadcom.app.wicedsense_preferences";
-    static final String SETTINGS_KEY_PREFIX = "settings_";
-    static final String SETTINGS_KEY_ANIMATION = SETTINGS_KEY_PREFIX + "animation";
-
-    static final String SETTINGS_KEY_GYRO = SETTINGS_KEY_PREFIX + "gyro";
-    static final String SETTINGS_KEY_ECOMPASS = SETTINGS_KEY_PREFIX + "ecompass";
-    static final String SETTINGS_KEY_ACCELEROMETER = SETTINGS_KEY_PREFIX + "accelerometer";
-
-    static final String SETTINGS_KEY_TEMPERATURE_SCALE_TYPE = SETTINGS_KEY_PREFIX
-            + "temperature_scale_type";
-    static final String SETTINGS_KEY_VERSION = SETTINGS_KEY_PREFIX + "version";
-
-    /**
-     * Period of time gauge values are animated
-     */
-    public static int ANIMATE_TIME_INTERVAL_MS = 150;
-    public static final int ANIMATION_FRAME_DELAY_MS = 50;
-    public static final int REFRESH_INTERVAL_MS = 50;
-    public static final int REFRESH_INTERVAL_SLOWER_MS = 3000;
-
-    private static String sVersionName;
-    private static SharedPreferences sPrefs;
-    private static OtaResource sDefaultOtaResource;
-    private static boolean sAnimate;
-    private static String sTemperatureScaleType;
-    private static File sOtaDirectory;
-    private static FilenameFilter sOtaFileFilter;
-    private static final ArrayList<SettingChangeListener> mChangeListeners = new ArrayList<Settings.SettingChangeListener>();
-    private static boolean sGyro;
-    private static boolean sEcompass;
-    private static boolean sAccelerometer;
-
-
-    private static OnSharedPreferenceChangeListener mPrefListener = new OnSharedPreferenceChangeListener() {
-        @Override
-        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-            if (!key.startsWith(SETTINGS_KEY_PREFIX)) {
-                return;
-            }
-            if (SETTINGS_KEY_ANIMATION.equals(key)) {
-                sAnimate = sharedPreferences.getBoolean(SETTINGS_KEY_ANIMATION, false);
-                Log.d(TAG, "sAnimate = " + sAnimate);
-            } else if (SETTINGS_KEY_TEMPERATURE_SCALE_TYPE.equals(key)) {
-                sTemperatureScaleType = sharedPreferences.getString(
-                        SETTINGS_KEY_TEMPERATURE_SCALE_TYPE, TEMPERATURE_SCALE_TYPE_F);
-            }else if (SETTINGS_KEY_GYRO.equals(key)){
-              	 sGyro = sharedPreferences.getBoolean(SETTINGS_KEY_GYRO, false);
-                 Log.d(TAG, "sGyro = " + sGyro);
-            }else if (SETTINGS_KEY_ECOMPASS.equals(key)){
-                 sEcompass = sharedPreferences.getBoolean(SETTINGS_KEY_ECOMPASS, false);
-                 Log.d(TAG, "sEcompass = " + sEcompass);
-            }else if (SETTINGS_KEY_ACCELEROMETER.equals(key)){
-            	 sAccelerometer = sharedPreferences.getBoolean(SETTINGS_KEY_ACCELEROMETER, false);
-            	 Log.d(TAG, "sAccelerometer = " + sAccelerometer);
-           }
-            else {
-                return;
-            }
-
-            SettingChangeListener[] listeners = new SettingChangeListener[mChangeListeners.size()];
-            mChangeListeners.toArray(listeners);
-            for (int i = 0; i < mChangeListeners.size(); i++) {
-                try {
-                    mChangeListeners.get(i).onSettingsChanged(key);
-                } catch (Throwable t) {
-                    Log.e(TAG, "onSharedPreferenceChanged error. Listener#" + i, t);
-                }
-            }
-        }
-
-
-    };
-
-    private static void checkAndInitializeSettings(SharedPreferences pref) {
-        boolean initialized = pref.getBoolean(SETTINGS_KEY_PREFIX + "initialized", false);
-        if (initialized) {
-            return;
-        }
-
-        Editor editor = pref.edit();
-        editor.putBoolean(SETTINGS_KEY_ANIMATION, false);
-        editor.putString(SETTINGS_KEY_TEMPERATURE_SCALE_TYPE, TEMPERATURE_SCALE_TYPE_F);
-        editor.putBoolean(SETTINGS_KEY_PREFIX + "initialized", true);
-        editor.putBoolean(SETTINGS_KEY_GYRO, true);
-        editor.putBoolean(SETTINGS_KEY_ECOMPASS, true);
-        editor.putBoolean(SETTINGS_KEY_ACCELEROMETER, true);
-        editor.commit();
-    }
-
-    private static void initOtaResources(Context ctx) {
-        int major = 0;
-        int minor = 0;
-        int appId = 0;
-        boolean mandatory=false;
-        try {
-            major = Integer.parseInt(ctx.getString(R.string.default_ota_fw_version_major));
-        } catch (Throwable t) {
-        }
-        try {
-            minor = Integer.parseInt(ctx.getString(R.string.default_ota_fw_version_minor));
-        } catch (Throwable t) {
-        }
-        try {
-            appId = Integer.parseInt(ctx.getString(R.string.default_ota_fw_version_minor));
-        } catch (Throwable t) {
-        }
-
-        try {
-            mandatory = Boolean.parseBoolean(ctx.getString(R.string.default_ota_fw_mandatory));
-        } catch (Throwable t) {
-        }
-
-        sDefaultOtaResource = OtaUiHelper.createRawOtaResource(
-                ctx.getString(R.string.default_ota_fw_version_name), appId, major, minor,
-                ctx.getResources(), R.raw.wiced_sense_1_3_update,mandatory);
-        sOtaDirectory = new File(Environment.getExternalStorageDirectory(), "broadcom/wicedsense");
-        sOtaFileFilter = new FilenameFilter() {
-            @Override
-            public boolean accept(File dir, String filename) {
-                return filename.startsWith("wiced_sense") && filename.endsWith(".ota.bin.signed");
-            }
-        };
-    }
-
-    public static void addChangeListener(SettingChangeListener l) {
-        if (!mChangeListeners.contains(l)) {
-            mChangeListeners.add(l);
-        }
-    }
-
-    public static void removeChangeListener(SettingChangeListener l) {
-        mChangeListeners.remove(l);
-    }
-
-    public static void init(Context ctx) {
-        try {
-            PackageInfo pInfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0);
-            sVersionName = pInfo.versionName;
-        } catch (Throwable t) {
-
-        }
-        sPrefs = ctx.getSharedPreferences(SETTINGS_PREF_NAME, Context.MODE_PRIVATE);
-        sPrefs.registerOnSharedPreferenceChangeListener(mPrefListener);
-
-        // Check if preferences initialized. If not, initialize with default
-        // values.
-        checkAndInitializeSettings(sPrefs);
-        sAnimate = sPrefs.getBoolean(SETTINGS_KEY_ANIMATION, false);
-        sGyro = sPrefs.getBoolean(SETTINGS_KEY_GYRO, false);
-        sEcompass = sPrefs.getBoolean(SETTINGS_KEY_ECOMPASS, false);
-        sAccelerometer = sPrefs.getBoolean(SETTINGS_KEY_ACCELEROMETER, false);
-        sTemperatureScaleType = sPrefs.getString(SETTINGS_KEY_TEMPERATURE_SCALE_TYPE,
-                TEMPERATURE_SCALE_TYPE_F);
-        initOtaResources(ctx);
-
-    }
-
-    public static void finish() {
-        sPrefs.unregisterOnSharedPreferenceChangeListener(mPrefListener);
-    }
-
-    static String getVersionName() {
-        return sVersionName;
-    }
-
-    static boolean animate() {
-        return sAnimate;
-    }
-
-    static String getTemperatureeScaleType() {
-        return sTemperatureScaleType;
-    }
-
-    static OtaResource getDefaultOtaResource() {
-        return sDefaultOtaResource;
-    }
-
-    static boolean hasMandatoryUpdate() {
-        return sDefaultOtaResource != null && sDefaultOtaResource.isMandatory();
-    }
-
-    static File getOtaDirectory() {
-        return sOtaDirectory;
-
-    }
-
-    static FilenameFilter getOtaFileFilter() {
-        return sOtaFileFilter;
-    }
-
-    static boolean gyroEnabled(){
-    	return sGyro;
-    }
-    static boolean compassEnabled(){
-    	return sEcompass;
-    }
-
-    static boolean accelerometerEnabled(){
-    	return sAccelerometer;
-    }
-
-
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+
+import com.broadcom.app.wicedsmart.ota.ui.OtaResource;
+import com.broadcom.app.wicedsmart.ota.ui.OtaUiHelper;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.pm.PackageInfo;
+import android.os.Environment;
+import android.util.Log;
+
+/**
+ * Configurable settings for the WICED Sense Application
+ *
+ */
+public class Settings {
+    public static final String TEMPERATURE_SCALE_TYPE_F = "F";
+    public static final String TEMPERATURE_SCALE_TYPE_C = "C";
+
+    /**
+     * Specifies if pairing/encryption is required to WICED Sense tag
+     */
+    public static final boolean PAIRNG_REQUIRED = true;
+    public static final int PAIRING_TIMEOUT_MS = 20000;
+
+    /**
+     * If true, WICED Sense app automatically connects to the WICED Sense tag
+     * after it is picked from the device picker
+     */
+    public static final boolean CONNECT_AFTER_DEVICE_PICK = false;
+
+    /**
+     * Frequency the battery status of the WICED Sense tag should be polled (in
+     * msec)
+     */
+    public static final int BATTERY_STATUS_INTERVAL_MS = 120000; // Every 2mins
+
+    /**
+     * Timeout to wait for a connection to the SenseManager service
+     */
+    public static final int SERVICE_INIT_TIMEOUT_MS = 250;
+
+    /**
+     * Number of retry attempts if BLE service discovery of the WICED Sense tag
+     * fails
+     */
+    public static final int SERVICE_DISCOVERY_RETRY = 2;
+
+    /**
+     * If true, a firmware update check will be performed after the WICED Sense
+     * tag is connected
+     */
+    public static final boolean CHECK_FOR_UPDATES_ON_CONNECT = true;
+
+    /**
+     * Enable debug tracing to adb logcat logs
+     */
+    public static final boolean DBG = true;
+
+    /**
+     * String contant that all adb logcat messages will be prefixed with (to
+     * simplify filtering)
+     */
+    public static final String TAG_PREFIX = "WicedSense.";
+
+    // --------------------Do not modify below-------------------------------
+    public interface SettingChangeListener {
+        public void onSettingsChanged(String settingName);
+    }
+
+    private static final String TAG = TAG_PREFIX + "Settings";
+
+    public static final String PACKAGE_NAME = "com.broadcom.app.wicedsense";
+
+    private static final String SETTINGS_PREF_NAME = "com.broadcom.app.wicedsense_preferences";
+    static final String SETTINGS_KEY_PREFIX = "settings_";
+    static final String SETTINGS_KEY_ANIMATION = SETTINGS_KEY_PREFIX + "animation";
+
+    static final String SETTINGS_KEY_GYRO = SETTINGS_KEY_PREFIX + "gyro";
+    static final String SETTINGS_KEY_ECOMPASS = SETTINGS_KEY_PREFIX + "ecompass";
+    static final String SETTINGS_KEY_ACCELEROMETER = SETTINGS_KEY_PREFIX + "accelerometer";
+
+    static final String SETTINGS_KEY_TEMPERATURE_SCALE_TYPE = SETTINGS_KEY_PREFIX
+            + "temperature_scale_type";
+    static final String SETTINGS_KEY_VERSION = SETTINGS_KEY_PREFIX + "version";
+
+    /**
+     * Period of time gauge values are animated
+     */
+    public static int ANIMATE_TIME_INTERVAL_MS = 150;
+    public static final int ANIMATION_FRAME_DELAY_MS = 50;
+    public static final int REFRESH_INTERVAL_MS = 50;
+    public static final int REFRESH_INTERVAL_SLOWER_MS = 3000;
+
+    private static String sVersionName;
+    private static SharedPreferences sPrefs;
+    private static OtaResource sDefaultOtaResource;
+    private static boolean sAnimate;
+    private static String sTemperatureScaleType;
+    private static File sOtaDirectory;
+    private static FilenameFilter sOtaFileFilter;
+    private static final ArrayList<SettingChangeListener> mChangeListeners = new ArrayList<Settings.SettingChangeListener>();
+    private static boolean sGyro;
+    private static boolean sEcompass;
+    private static boolean sAccelerometer;
+
+
+    private static OnSharedPreferenceChangeListener mPrefListener = new OnSharedPreferenceChangeListener() {
+        @Override
+        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+            if (!key.startsWith(SETTINGS_KEY_PREFIX)) {
+                return;
+            }
+            if (SETTINGS_KEY_ANIMATION.equals(key)) {
+                sAnimate = sharedPreferences.getBoolean(SETTINGS_KEY_ANIMATION, false);
+                Log.d(TAG, "sAnimate = " + sAnimate);
+            } else if (SETTINGS_KEY_TEMPERATURE_SCALE_TYPE.equals(key)) {
+                sTemperatureScaleType = sharedPreferences.getString(
+                        SETTINGS_KEY_TEMPERATURE_SCALE_TYPE, TEMPERATURE_SCALE_TYPE_F);
+            }else if (SETTINGS_KEY_GYRO.equals(key)){
+              	 sGyro = sharedPreferences.getBoolean(SETTINGS_KEY_GYRO, false);
+                 Log.d(TAG, "sGyro = " + sGyro);
+            }else if (SETTINGS_KEY_ECOMPASS.equals(key)){
+                 sEcompass = sharedPreferences.getBoolean(SETTINGS_KEY_ECOMPASS, false);
+                 Log.d(TAG, "sEcompass = " + sEcompass);
+            }else if (SETTINGS_KEY_ACCELEROMETER.equals(key)){
+            	 sAccelerometer = sharedPreferences.getBoolean(SETTINGS_KEY_ACCELEROMETER, false);
+            	 Log.d(TAG, "sAccelerometer = " + sAccelerometer);
+           }
+            else {
+                return;
+            }
+
+            SettingChangeListener[] listeners = new SettingChangeListener[mChangeListeners.size()];
+            mChangeListeners.toArray(listeners);
+            for (int i = 0; i < mChangeListeners.size(); i++) {
+                try {
+                    mChangeListeners.get(i).onSettingsChanged(key);
+                } catch (Throwable t) {
+                    Log.e(TAG, "onSharedPreferenceChanged error. Listener#" + i, t);
+                }
+            }
+        }
+
+
+    };
+
+    private static void checkAndInitializeSettings(SharedPreferences pref) {
+        boolean initialized = pref.getBoolean(SETTINGS_KEY_PREFIX + "initialized", false);
+        if (initialized) {
+            return;
+        }
+
+        Editor editor = pref.edit();
+        editor.putBoolean(SETTINGS_KEY_ANIMATION, false);
+        editor.putString(SETTINGS_KEY_TEMPERATURE_SCALE_TYPE, TEMPERATURE_SCALE_TYPE_F);
+        editor.putBoolean(SETTINGS_KEY_PREFIX + "initialized", true);
+        editor.putBoolean(SETTINGS_KEY_GYRO, true);
+        editor.putBoolean(SETTINGS_KEY_ECOMPASS, true);
+        editor.putBoolean(SETTINGS_KEY_ACCELEROMETER, true);
+        editor.commit();
+    }
+
+    private static void initOtaResources(Context ctx) {
+        int major = 0;
+        int minor = 0;
+        int appId = 0;
+        boolean mandatory=false;
+        try {
+            major = Integer.parseInt(ctx.getString(R.string.default_ota_fw_version_major));
+        } catch (Throwable t) {
+        }
+        try {
+            minor = Integer.parseInt(ctx.getString(R.string.default_ota_fw_version_minor));
+        } catch (Throwable t) {
+        }
+        try {
+            appId = Integer.parseInt(ctx.getString(R.string.default_ota_fw_version_minor));
+        } catch (Throwable t) {
+        }
+
+        try {
+            mandatory = Boolean.parseBoolean(ctx.getString(R.string.default_ota_fw_mandatory));
+        } catch (Throwable t) {
+        }
+
+        sDefaultOtaResource = OtaUiHelper.createRawOtaResource(
+                ctx.getString(R.string.default_ota_fw_version_name), appId, major, minor,
+                ctx.getResources(), R.raw.wiced_sense_1_3_update,mandatory);
+        sOtaDirectory = new File(Environment.getExternalStorageDirectory(), "broadcom/wicedsense");
+        sOtaFileFilter = new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String filename) {
+                return filename.startsWith("wiced_sense") && filename.endsWith(".ota.bin.signed");
+            }
+        };
+    }
+
+    public static void addChangeListener(SettingChangeListener l) {
+        if (!mChangeListeners.contains(l)) {
+            mChangeListeners.add(l);
+        }
+    }
+
+    public static void removeChangeListener(SettingChangeListener l) {
+        mChangeListeners.remove(l);
+    }
+
+    public static void init(Context ctx) {
+        try {
+            PackageInfo pInfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0);
+            sVersionName = pInfo.versionName;
+        } catch (Throwable t) {
+
+        }
+        sPrefs = ctx.getSharedPreferences(SETTINGS_PREF_NAME, Context.MODE_PRIVATE);
+        sPrefs.registerOnSharedPreferenceChangeListener(mPrefListener);
+
+        // Check if preferences initialized. If not, initialize with default
+        // values.
+        checkAndInitializeSettings(sPrefs);
+        sAnimate = sPrefs.getBoolean(SETTINGS_KEY_ANIMATION, false);
+        sGyro = sPrefs.getBoolean(SETTINGS_KEY_GYRO, false);
+        sEcompass = sPrefs.getBoolean(SETTINGS_KEY_ECOMPASS, false);
+        sAccelerometer = sPrefs.getBoolean(SETTINGS_KEY_ACCELEROMETER, false);
+        sTemperatureScaleType = sPrefs.getString(SETTINGS_KEY_TEMPERATURE_SCALE_TYPE,
+                TEMPERATURE_SCALE_TYPE_F);
+        initOtaResources(ctx);
+
+    }
+
+    public static void finish() {
+        sPrefs.unregisterOnSharedPreferenceChangeListener(mPrefListener);
+    }
+
+    static String getVersionName() {
+        return sVersionName;
+    }
+
+    static boolean animate() {
+        return sAnimate;
+    }
+
+    static String getTemperatureeScaleType() {
+        return sTemperatureScaleType;
+    }
+
+    static OtaResource getDefaultOtaResource() {
+        return sDefaultOtaResource;
+    }
+
+    static boolean hasMandatoryUpdate() {
+        return sDefaultOtaResource != null && sDefaultOtaResource.isMandatory();
+    }
+
+    static File getOtaDirectory() {
+        return sOtaDirectory;
+
+    }
+
+    static FilenameFilter getOtaFileFilter() {
+        return sOtaFileFilter;
+    }
+
+    static boolean gyroEnabled(){
+    	return sGyro;
+    }
+    static boolean compassEnabled(){
+    	return sEcompass;
+    }
+
+    static boolean accelerometerEnabled(){
+    	return sAccelerometer;
+    }
+
+
 }
\ No newline at end of file
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SettingsActivity.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SettingsActivity.java
index 084cc1dda9d5cb0a6887dec9fc268f503f1eae7e..3ed3fdf34aebb4b6739575054b8e9de7dac00b25 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SettingsActivity.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SettingsActivity.java
@@ -1,35 +1,35 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class SettingsActivity extends Activity {
-
-    SettingsFragment mSettingsFragment;
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mSettingsFragment = new SettingsFragment();
-        getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment())
-                .commit();
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class SettingsActivity extends Activity {
+
+    SettingsFragment mSettingsFragment;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mSettingsFragment = new SettingsFragment();
+        getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment())
+                .commit();
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SettingsFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SettingsFragment.java
index d5f160e868528fd63898910a51438d5ef4206864..ec64b23710570c30f02b161fa64f5b70d2892e6b 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SettingsFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/SettingsFragment.java
@@ -1,63 +1,63 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import com.broadcom.util.PreferenceUtils;
-
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceFragment;
-import android.preference.PreferenceGroup;
-import android.preference.PreferenceScreen;
-
-public class SettingsFragment extends PreferenceFragment implements
-        OnSharedPreferenceChangeListener {
-
-    private String mPreferenceKeyPrefix;
-    private PreferenceScreen mRootPref;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mPreferenceKeyPrefix = Settings.SETTINGS_KEY_PREFIX;
-        addPreferencesFromResource(R.xml.settings);
-        mRootPref = getPreferenceScreen();
-
-        getPreferenceManager().getSharedPreferences()
-                .registerOnSharedPreferenceChangeListener(this);
-        PreferenceUtils.setSummaryToValue((PreferenceGroup) mRootPref);
-        Preference p = findPreference(Settings.SETTINGS_KEY_VERSION);
-        String versionName = Settings.getVersionName();
-        if (versionName == null) {
-            versionName = "??";
-        }
-        p.setSummary(versionName);
-
-    }
-
-    @Override
-    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-        if (mPreferenceKeyPrefix == null || !key.startsWith(mPreferenceKeyPrefix)) {
-            return;
-        }
-        PreferenceUtils.setSummaryToValue(mRootPref, key);
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import com.broadcom.util.PreferenceUtils;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+
+public class SettingsFragment extends PreferenceFragment implements
+        OnSharedPreferenceChangeListener {
+
+    private String mPreferenceKeyPrefix;
+    private PreferenceScreen mRootPref;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mPreferenceKeyPrefix = Settings.SETTINGS_KEY_PREFIX;
+        addPreferencesFromResource(R.xml.settings);
+        mRootPref = getPreferenceScreen();
+
+        getPreferenceManager().getSharedPreferences()
+                .registerOnSharedPreferenceChangeListener(this);
+        PreferenceUtils.setSummaryToValue((PreferenceGroup) mRootPref);
+        Preference p = findPreference(Settings.SETTINGS_KEY_VERSION);
+        String versionName = Settings.getVersionName();
+        if (versionName == null) {
+            versionName = "??";
+        }
+        p.setSummary(versionName);
+
+    }
+
+    @Override
+    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+        if (mPreferenceKeyPrefix == null || !key.startsWith(mPreferenceKeyPrefix)) {
+            return;
+        }
+        PreferenceUtils.setSummaryToValue(mRootPref, key);
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/TemperatureFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/TemperatureFragment.java
index 007472d2c7c42b82b96a8741f8d97fde37b91ba6..c5c81c3c0f1280bd4e9f51c7ce32e51e3c7a6522 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/TemperatureFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/TemperatureFragment.java
@@ -1,153 +1,153 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsense;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-/**
- * Our Implimentation of TemperatureFragment.
- * Will attempt to closely resemble practices done in class/assignments.
- */
-public class TemperatureFragment extends Fragment {
-
-    //region Variables
-
-    private TextView mCurrent;
-    private TextView mMin;
-    private TextView mMax;
-    private TextView mAvg;
-
-    //endregion
-
-
-
-    //region Static information to summon Fragment.
-    private static final String ARG_TEMPERATURE_ID= "temperature_id";
-
-    private static TemperatureFragment newInstance() {
-        // Provided in case bundle is required in the future.
-        Bundle args = new Bundle();
-
-        // Make and return new fragment.
-        TemperatureFragment fragment = new TemperatureFragment();
-        fragment.setArguments(args);
-        return fragment;
-    }
-
-    //endregion
-
-
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Nullable
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        // Use inflater to get view from layout.
-        View view = inflater.inflate(R.layout.temperature_fragment, container, false);
-
-        // Set class level vars to appropriate xml attributes.
-        mCurrent = (TextView) view.findViewById(R.id.temp_current);
-        mMin = (TextView) view.findViewById(R.id.temp_min);
-        mMax = (TextView) view.findViewById(R.id.temp_max);
-        mAvg = (TextView) view.findViewById(R.id.temp_avg);
-
-        // Read in from database and set values here?
-
-        return view;
-    }
-}
-
-/**
- * WICEDSENCE default stuff.
- * Commenting out instead of removing in case we need to reference it to get the program running.
- *
- *
- *
- *
- * Fragment for the temperature widget. Supports both F and C scales
- * <p/>
- * NOTE: caller of setValue() is expected to pass in the temperature with the
- * correct scaled value. *
- */
-/*
-public class TemperatureFragment extends BaseThermoFragment {
-    public static final int SCALE_F = 0;
-    public static final int SCALE_C = 1;
-
-    private int mScaleType = SCALE_F;
-
-    @Override
-    protected void initRangeValues() {
-        if (mScaleType == SCALE_F) {
-            mMaxValue = SensorDataParser.SENSOR_TEMP_MAX_F;
-            mMinValue = SensorDataParser.SENSOR_TEMP_MIN_F;
-        } else {
-            mMaxValue = SensorDataParser.SENSOR_TEMP_MAX_C;
-            mMinValue = SensorDataParser.SENSOR_TEMP_MIN_C;
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        if (mScaleType == SCALE_F) {
-            return inflater.inflate(R.layout.temperature_fragment, null);
-        } else {
-            return inflater.inflate(R.layout.temperature_fragment_c, null);
-        }
-    }
-
-    @Override
-    protected void setGaugeText(float value) {
-        if (mScaleType == SCALE_F) {
-           // mGaugeValue.setText(getString(R.string.temperature_value_f,
-                    //String.format("%.1f", value)));
-        } else {
-            //mGaugeValue.setText(getString(R.string.temperature_value_c,
-                    //String.format("%.1f", value)));
-        }
-    }
-
-    @Override
-    protected String getPropertyName() {
-        return "temp";
-    }
-
-    public void setScaleType(int scaleType) {
-        mScaleType = scaleType;
-        initRange();
-    }
-
-    public int getScaleType() {
-        return mScaleType;
-    }
-
-    public float getLastValue() {
-        return mValue;
-
-    }
-} */
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsense;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Our Implimentation of TemperatureFragment.
+ * Will attempt to closely resemble practices done in class/assignments.
+ */
+public class TemperatureFragment extends Fragment {
+
+    //region Variables
+
+    private TextView mCurrent;
+    private TextView mMin;
+    private TextView mMax;
+    private TextView mAvg;
+
+    //endregion
+
+
+
+    //region Static information to summon Fragment.
+    private static final String ARG_TEMPERATURE_ID= "temperature_id";
+
+    private static TemperatureFragment newInstance() {
+        // Provided in case bundle is required in the future.
+        Bundle args = new Bundle();
+
+        // Make and return new fragment.
+        TemperatureFragment fragment = new TemperatureFragment();
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    //endregion
+
+
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        // Use inflater to get view from layout.
+        View view = inflater.inflate(R.layout.temperature_fragment, container, false);
+
+        // Set class level vars to appropriate xml attributes.
+        mCurrent = (TextView) view.findViewById(R.id.temp_current);
+        mMin = (TextView) view.findViewById(R.id.temp_min);
+        mMax = (TextView) view.findViewById(R.id.temp_max);
+        mAvg = (TextView) view.findViewById(R.id.temp_avg);
+
+        // Read in from database and set values here?
+
+        return view;
+    }
+}
+
+/**
+ * WICEDSENCE default stuff.
+ * Commenting out instead of removing in case we need to reference it to get the program running.
+ *
+ *
+ *
+ *
+ * Fragment for the temperature widget. Supports both F and C scales
+ * <p/>
+ * NOTE: caller of setValue() is expected to pass in the temperature with the
+ * correct scaled value. *
+ */
+/*
+public class TemperatureFragment extends BaseThermoFragment {
+    public static final int SCALE_F = 0;
+    public static final int SCALE_C = 1;
+
+    private int mScaleType = SCALE_F;
+
+    @Override
+    protected void initRangeValues() {
+        if (mScaleType == SCALE_F) {
+            mMaxValue = SensorDataParser.SENSOR_TEMP_MAX_F;
+            mMinValue = SensorDataParser.SENSOR_TEMP_MIN_F;
+        } else {
+            mMaxValue = SensorDataParser.SENSOR_TEMP_MAX_C;
+            mMinValue = SensorDataParser.SENSOR_TEMP_MIN_C;
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        if (mScaleType == SCALE_F) {
+            return inflater.inflate(R.layout.temperature_fragment, null);
+        } else {
+            return inflater.inflate(R.layout.temperature_fragment_c, null);
+        }
+    }
+
+    @Override
+    protected void setGaugeText(float value) {
+        if (mScaleType == SCALE_F) {
+           // mGaugeValue.setText(getString(R.string.temperature_value_f,
+                    //String.format("%.1f", value)));
+        } else {
+            //mGaugeValue.setText(getString(R.string.temperature_value_c,
+                    //String.format("%.1f", value)));
+        }
+    }
+
+    @Override
+    protected String getPropertyName() {
+        return "temp";
+    }
+
+    public void setScaleType(int scaleType) {
+        mScaleType = scaleType;
+        initRange();
+    }
+
+    public int getScaleType() {
+        return mScaleType;
+    }
+
+    public float getLastValue() {
+        return mValue;
+
+    }
+} */
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/ThermoBaseHelper.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/ThermoBaseHelper.java
index 4cc663338334c17cde91c1c5409223b9097770a3..cc3edf265d54a1d6378a4341236117ceb4add519 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/ThermoBaseHelper.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/ThermoBaseHelper.java
@@ -1,38 +1,38 @@
-package com.broadcom.app.wicedsense;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-
-
-/**
- * Created by jmartin5229 on 11/9/2015.
- */
-public class ThermoBaseHelper  extends SQLiteOpenHelper {// The SQLiteOpenHelper does the following
-    // 1. Check to see if the database already exists.
-    // 2. If it does not, create it and create the tables and initial data it needs.
-    // 3. If it does, open it up and see what version of your ThermoDbSchema it has.
-    // 4. If it is an old version, run code to upgrade it to a newer version.
-    private static final int VERSION = 1;
-    private static final String DATABASE_NAME = "/mnt/sdcard/thermoBase.db";
-
-    public ThermoBaseHelper(Context context) {
-        super(context, DATABASE_NAME, null, VERSION);
-    }
-
-    @Override
-    public void onCreate(SQLiteDatabase db){  //  Creates the ThermoTable and defines its fields.
-        db.execSQL("create table " + WicedDBSchema.ThermoTable.NAME + "(" +
-                        " _id integer primary key autoincrement, " +
-                        WicedDBSchema.ThermoTable.Cols.TIME + ", "+
-                        WicedDBSchema.ThermoTable.Cols.HUMIDITY + ", " +
-                        WicedDBSchema.ThermoTable.Cols.PRESSURE + ", " +
-                        WicedDBSchema.ThermoTable.Cols.TEMPERATURE + ")"
-        );
-    }
-
-    @Override
-    public void onUpgrade(SQLiteDatabase db, int OldVersion, int newVersion){
-
-    }
-}
+package com.broadcom.app.wicedsense;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+
+/**
+ * Created by jmartin5229 on 11/9/2015.
+ */
+public class ThermoBaseHelper  extends SQLiteOpenHelper {// The SQLiteOpenHelper does the following
+    // 1. Check to see if the database already exists.
+    // 2. If it does not, create it and create the tables and initial data it needs.
+    // 3. If it does, open it up and see what version of your ThermoDbSchema it has.
+    // 4. If it is an old version, run code to upgrade it to a newer version.
+    private static final int VERSION = 1;
+    private static final String DATABASE_NAME = "/mnt/sdcard/thermoBase.db";
+
+    public ThermoBaseHelper(Context context) {
+        super(context, DATABASE_NAME, null, VERSION);
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db){  //  Creates the ThermoTable and defines its fields.
+        db.execSQL("create table " + WicedDBSchema.ThermoTable.NAME + "(" +
+                        " _id integer primary key autoincrement, " +
+                        WicedDBSchema.ThermoTable.Cols.TIME + ", "+
+                        WicedDBSchema.ThermoTable.Cols.HUMIDITY + ", " +
+                        WicedDBSchema.ThermoTable.Cols.PRESSURE + ", " +
+                        WicedDBSchema.ThermoTable.Cols.TEMPERATURE + ")"
+        );
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int OldVersion, int newVersion){
+
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/WicedDBSchema.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/WicedDBSchema.java
index af9b11aeddb1dc65f197c93d990813a8dc76149e..d3f0237569b9c74c02caca9127c0c20714556b77 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/WicedDBSchema.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsense/WicedDBSchema.java
@@ -1,18 +1,18 @@
-package com.broadcom.app.wicedsense;
-
-/**
- * Created by jmartin5229 on 11/9/2015.
- */
-public class WicedDBSchema {
-    public static final class ThermoTable { //  Name of the Table
-        public static final String NAME = "thermo";
-
-        public static final class Cols { //  Name of the Columns (Fields)
-            public static final String TIME = "time";
-            public static final String HUMIDITY = "humidity";
-            public static final String PRESSURE = "pressure";
-            public static final String TEMPERATURE = "temerature";
-
-        }
-    }
-}
+package com.broadcom.app.wicedsense;
+
+/**
+ * Created by jmartin5229 on 11/9/2015.
+ */
+public class WicedDBSchema {
+    public static final class ThermoTable { //  Name of the Table
+        public static final String NAME = "thermo";
+
+        public static final class Cols { //  Name of the Columns (Fields)
+            public static final String TIME = "time";
+            public static final String HUMIDITY = "humidity";
+            public static final String PRESSURE = "pressure";
+            public static final String TEMPERATURE = "temerature";
+
+        }
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaAppInfo.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaAppInfo.java
index 9dbde6c794d438b3ac1846b296f7e33616adf23f..0bf2ae495c38501891a96f281134e85e1a6874b3 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaAppInfo.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaAppInfo.java
@@ -1,30 +1,30 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota;
-
-public class OtaAppInfo {
-    public int mAppId;
-    public int mMajorVersion;
-    public int mMinorVersion;
-
-    public OtaAppInfo(int appId, int majorVersion, int minorVersion) {
-        mAppId = appId;
-        mMajorVersion = majorVersion;
-        mMinorVersion = minorVersion;
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota;
+
+public class OtaAppInfo {
+    public int mAppId;
+    public int mMajorVersion;
+    public int mMinorVersion;
+
+    public OtaAppInfo(int appId, int majorVersion, int minorVersion) {
+        mAppId = appId;
+        mMajorVersion = majorVersion;
+        mMinorVersion = minorVersion;
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaAppInfoReader.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaAppInfoReader.java
index 827b0f90690c6cb912aa151b270a428a3b95f972..215528107d8a9f28f8264f91802524d62dd93e27 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaAppInfoReader.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaAppInfoReader.java
@@ -1,150 +1,150 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota;
-
-import java.util.UUID;
-
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallback;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import com.broadcom.util.ByteUtils;
-import com.broadcom.util.GattRequestManager;
-import com.broadcom.util.GattRequestManager.GattRequest;
-import com.broadcom.util.GattRequestManager.GattTimeoutCallback;
-
-public class OtaAppInfoReader extends BluetoothGattCallback implements android.os.Handler.Callback,
-        GattTimeoutCallback {
-    private static final String TAG = OtaSettings.TAG_PREFIX + "OtaAppInfoReader";
-
-    public interface Callback {
-        public void onAppInfoRead(boolean success, OtaAppInfo info);
-    }
-
-    private static final UUID UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO = UUID
-            .fromString("6AA5711B-0376-44F1-BCA1-8647B48BDB55");
-    private static final int EVENT_APP_INFO = 100;
-
-    private GattRequestManager mGattManager;
-    private final Callback mCallback;
-    private BluetoothGattCharacteristic mAppInfoChar;
-    private Handler mEventHandler;
-
-    public OtaAppInfoReader(Callback cb) {
-        this(cb, null);
-    }
-
-    public OtaAppInfoReader(Callback cb, Looper l) {
-        mCallback = cb;
-        if (l != null) {
-            mEventHandler = new Handler(l, this);
-        } else {
-            mEventHandler = new Handler(this);
-        }
-    }
-
-    private void sendAppInfoEvent(boolean success, byte[] appInfo) {
-        mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_APP_INFO, success ? 1 : 0, 0,
-                appInfo));
-    }
-
-    @Override
-    public void onCharacteristicRead(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic, int status) {
-        if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO.equals(characteristic.getUuid())) {
-            byte[] appInfoBytes = characteristic.getValue();
-            sendAppInfoEvent(true, appInfoBytes);
-        }
-    }
-
-    @Override
-    public boolean handleMessage(Message msg) {
-        switch (msg.what) {
-        case EVENT_APP_INFO:
-            boolean success = msg.arg1 == 1;
-            byte[] appInfoBytes = (byte[]) msg.obj;
-            processAppInfoRead(success, appInfoBytes);
-
-        }
-        return false;
-    }
-
-    @Override
-    public void onTimeout(GattRequest request) {
-        if (request == null) {
-            return;
-        }
-        BluetoothGattCharacteristic c = request.mCharacteristic;
-        if (c == null) {
-            return;
-        }
-
-        if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO.equals(c.getUuid())) {
-            Log.w(TAG, "read(): error timeout reading characeristic...");
-            sendAppInfoEvent(false, null);
-        }
-    }
-
-    private void processAppInfoRead(boolean success, byte[] appInfoBytes) {
-        OtaAppInfo info = null;
-        if (success && appInfoBytes != null && appInfoBytes.length >= 4) {
-
-            info = new OtaAppInfo(ByteUtils.bytesToUInt16LI(appInfoBytes, 0, 0), appInfoBytes[2],
-                    appInfoBytes[3]);
-        }
-        if (mCallback != null) {
-            mCallback.onAppInfoRead(success, info);
-        }
-    }
-
-    public boolean initServicesAndCharacteristics(GattRequestManager mgr) {
-        mGattManager = mgr;
-
-        // Find the app info characteristic
-        mAppInfoChar = mGattManager.findCharacteristic(OtaManager.UUID_WS_SECURE_UPGRADE_SERVICE,
-                UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO);
-        if (mAppInfoChar == null) {
-            return false;
-        }
-
-        mGattManager.addCallback(this);
-        mGattManager.addTimeoutCallback(this);
-        return true;
-    }
-
-    public void finish() {
-        if (mGattManager != null) {
-            mGattManager.removeCallback(this);
-            mGattManager.removeTimeoutCallback(this);
-        }
-    }
-
-    public boolean read() {
-        if (mAppInfoChar == null) {
-            return false;
-        }
-
-        mGattManager.read(mAppInfoChar);
-        return true;
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota;
+
+import java.util.UUID;
+
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import com.broadcom.util.ByteUtils;
+import com.broadcom.util.GattRequestManager;
+import com.broadcom.util.GattRequestManager.GattRequest;
+import com.broadcom.util.GattRequestManager.GattTimeoutCallback;
+
+public class OtaAppInfoReader extends BluetoothGattCallback implements android.os.Handler.Callback,
+        GattTimeoutCallback {
+    private static final String TAG = OtaSettings.TAG_PREFIX + "OtaAppInfoReader";
+
+    public interface Callback {
+        public void onAppInfoRead(boolean success, OtaAppInfo info);
+    }
+
+    private static final UUID UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO = UUID
+            .fromString("6AA5711B-0376-44F1-BCA1-8647B48BDB55");
+    private static final int EVENT_APP_INFO = 100;
+
+    private GattRequestManager mGattManager;
+    private final Callback mCallback;
+    private BluetoothGattCharacteristic mAppInfoChar;
+    private Handler mEventHandler;
+
+    public OtaAppInfoReader(Callback cb) {
+        this(cb, null);
+    }
+
+    public OtaAppInfoReader(Callback cb, Looper l) {
+        mCallback = cb;
+        if (l != null) {
+            mEventHandler = new Handler(l, this);
+        } else {
+            mEventHandler = new Handler(this);
+        }
+    }
+
+    private void sendAppInfoEvent(boolean success, byte[] appInfo) {
+        mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_APP_INFO, success ? 1 : 0, 0,
+                appInfo));
+    }
+
+    @Override
+    public void onCharacteristicRead(BluetoothGatt gatt,
+            BluetoothGattCharacteristic characteristic, int status) {
+        if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO.equals(characteristic.getUuid())) {
+            byte[] appInfoBytes = characteristic.getValue();
+            sendAppInfoEvent(true, appInfoBytes);
+        }
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        switch (msg.what) {
+        case EVENT_APP_INFO:
+            boolean success = msg.arg1 == 1;
+            byte[] appInfoBytes = (byte[]) msg.obj;
+            processAppInfoRead(success, appInfoBytes);
+
+        }
+        return false;
+    }
+
+    @Override
+    public void onTimeout(GattRequest request) {
+        if (request == null) {
+            return;
+        }
+        BluetoothGattCharacteristic c = request.mCharacteristic;
+        if (c == null) {
+            return;
+        }
+
+        if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO.equals(c.getUuid())) {
+            Log.w(TAG, "read(): error timeout reading characeristic...");
+            sendAppInfoEvent(false, null);
+        }
+    }
+
+    private void processAppInfoRead(boolean success, byte[] appInfoBytes) {
+        OtaAppInfo info = null;
+        if (success && appInfoBytes != null && appInfoBytes.length >= 4) {
+
+            info = new OtaAppInfo(ByteUtils.bytesToUInt16LI(appInfoBytes, 0, 0), appInfoBytes[2],
+                    appInfoBytes[3]);
+        }
+        if (mCallback != null) {
+            mCallback.onAppInfoRead(success, info);
+        }
+    }
+
+    public boolean initServicesAndCharacteristics(GattRequestManager mgr) {
+        mGattManager = mgr;
+
+        // Find the app info characteristic
+        mAppInfoChar = mGattManager.findCharacteristic(OtaManager.UUID_WS_SECURE_UPGRADE_SERVICE,
+                UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_APP_INFO);
+        if (mAppInfoChar == null) {
+            return false;
+        }
+
+        mGattManager.addCallback(this);
+        mGattManager.addTimeoutCallback(this);
+        return true;
+    }
+
+    public void finish() {
+        if (mGattManager != null) {
+            mGattManager.removeCallback(this);
+            mGattManager.removeTimeoutCallback(this);
+        }
+    }
+
+    public boolean read() {
+        if (mAppInfoChar == null) {
+            return false;
+        }
+
+        mGattManager.read(mAppInfoChar);
+        return true;
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaCallback.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaCallback.java
index d60bc4438ee38593d1bffd26ff1c1f0ba8c91857..26aea4912868994d4921110493354a32eb5c2215 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaCallback.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaCallback.java
@@ -1,29 +1,29 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota;
-
-public interface OtaCallback {
-    public void onOtaStateChanged(int state);
-
-    public void onOtaError(int state, int errorCode);
-
-    public void onOtaUploadProgress(int loopCount, int bytesCurrent, int bytesTotal);
-
-    public void onOtaAborted();
-
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota;
+
+public interface OtaCallback {
+    public void onOtaStateChanged(int state);
+
+    public void onOtaError(int state, int errorCode);
+
+    public void onOtaUploadProgress(int loopCount, int bytesCurrent, int bytesTotal);
+
+    public void onOtaAborted();
+
 }
\ No newline at end of file
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaManager.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaManager.java
index 564e7c91ed66108a381280a542a50e6d8a3fcc24..ae4731b2564cc62c7fe352448c945d99a8cf3b12 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaManager.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaManager.java
@@ -1,767 +1,767 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota;
-
-import android.os.Handler;
-import android.os.Handler.Callback;
-import android.os.Message;
-import android.util.Log;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallback;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattDescriptor;
-import android.bluetooth.BluetoothGattService;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-
-import java.io.BufferedInputStream;
-import java.util.UUID;
-import com.broadcom.util.ByteUtils;
-import com.broadcom.util.GattRequestManager;
-import com.broadcom.util.GattRequestManager.GattRequest;
-import com.broadcom.util.GattRequestManager.GattTimeoutCallback;
-
-public class OtaManager extends BluetoothGattCallback implements Callback, GattTimeoutCallback {
-    public static final int STATE_NONE = 0;
-    public static final int STATE_CONNECT = 1;
-    public static final int STATE_DISCOVER = 2;
-    public static final int STATE_ENABLE_NOTIFY = 3;
-    public static final int STATE_PREPARE_DOWNLOAD = 4;
-    public static final int STATE_START_DOWNLOAD = 5;
-    public static final int STATE_SEND_FW_INFO = 6;
-    public static final int STATE_SEND_FW = 7;
-    public static final int STATE_SEND_FW_COMPLETED = 8;
-    public static final int STATE_VERIFY_FW = 9;
-    public static final int STATE_UPGRADE_COMPLETED = 10;
-    public static final int STATE_ABORTED = -10;
-
-    public static final int WS_UPGRADE_STATUS_OK = 0;
-    public static final int WS_UPGRADE_STATUS_UNSUPPORTED_COMMAND = 1;
-    public static final int WS_UPGRADE_STATUS_ILLEGAL_STATE = 2;
-    public static final int WS_UPGRADE_STATUS_VERIFICATION_FAILED = 3;
-    public static final int WS_UPGRADE_STATUS_INVALID_IMAGE = 4;
-    public static final int WS_UPGRADE_STATUS_INVALID_IMAGE_SIZE = 5;
-    public static final int WS_UPGRADE_STATUS_MORE_DATA = 6;
-    public static final int WS_UPGRADE_STATUS_INVALID_APPID = 7;
-    public static final int WS_UPGRADE_STATUS_INVALID_VERSION = 8;
-    public static final int WS_UPGRADE_WRITE_STATUS_SUCCESS = 0x00;
-    public static final int WS_UPGRADE_WRITE_STATUS_BAD_ID = 0x81;
-    public static final int WS_UPGRADE_WRITE_STATUS_BAD_MAJOR = 0x82;
-    public static final int WS_UPGRADE_WRITE_STATUS_TOO_MUCH_DATA = 0x83;
-    public static final int WS_UPGRADE_WRITE_STATUS_TOO_SHORT = 0x84;
-    public static final int WS_UPGRADE_WRITE_STATUS_ABORTED = 0x85;
-    public static final int ERROR_CONNECT = -100;
-    public static final int ERROR_DISCOVER = -101;
-    public static final int ERROR_SERVICE = -102;
-    public static final int ERROR_DESCRIPTOR_WRITE = -110;
-    public static final int ERROR_DESCRIPTOR_NOT_FOUND = -111;
-    public static final int ERROR_CHARACTERISTIC_WRITE = -112;
-    public static final int ERROR_FIRMWARE_INFO_READ = -120;
-    public static final int ERROR_FIRMWARE_INFO_WRITE = -121;
-    public static final int ERROR_FIRMWARE_READ = -122;
-    public static final int ERROR_FIRMWARE_WRITE = -123;
-    public static final int ERROR_TIMEOUT = -200;
-
-    public static final String getStateString(int state) {
-        switch (state) {
-        case STATE_NONE:
-            return "STATE_NONE";
-        case STATE_CONNECT:
-            return "STATE_CONNECT";
-        case STATE_DISCOVER:
-            return "STATE_DISCOVER";
-        case STATE_ENABLE_NOTIFY:
-            return "STATE_ENABLE_NOTIFY";
-        case STATE_PREPARE_DOWNLOAD:
-            return "STATE_PREPARE_DOWNLOAD";
-        case STATE_START_DOWNLOAD:
-            return "STATE_START_DOWNLOAD";
-        case STATE_SEND_FW_INFO:
-            return "STATE_SEND_FW_INFO";
-        case STATE_SEND_FW:
-            return "STATE_SEND_FW";
-        case STATE_SEND_FW_COMPLETED:
-            return "STATE_SEND_FW_COMPLETED";
-        case STATE_VERIFY_FW:
-            return "STATE_VERIFY_FW";
-        case STATE_UPGRADE_COMPLETED:
-            return "STATE_UPGRADE_COMPLETED";
-        case STATE_ABORTED:
-            return "STATE_ABORTED";
-        default:
-            return "STATE_UNKNOWN";
-        }
-    }
-
-    public static final String getStatusString(int status) {
-        switch (status) {
-        case WS_UPGRADE_STATUS_OK:
-            return "WS_UPGRADE_STATUS_OK";
-        case WS_UPGRADE_STATUS_UNSUPPORTED_COMMAND:
-            return "WS_UPGRADE_STATUS_UNSUPPORTED_COMMAND";
-        case WS_UPGRADE_STATUS_ILLEGAL_STATE:
-            return "WS_UPGRADE_STATUS_ILLEGAL_STATE";
-        case WS_UPGRADE_STATUS_VERIFICATION_FAILED:
-            return "WS_UPGRADE_STATUS_VERIFICATION_FAILED";
-        case WS_UPGRADE_STATUS_INVALID_IMAGE:
-            return "WS_UPGRADE_STATUS_INVALID_IMAGE";
-        case WS_UPGRADE_STATUS_INVALID_IMAGE_SIZE:
-            return "WS_UPGRADE_STATUS_INVALID_IMAGE_SIZE";
-        case WS_UPGRADE_STATUS_MORE_DATA:
-            return "WS_UPGRADE_STATUS_MORE_DATA";
-        case WS_UPGRADE_STATUS_INVALID_APPID:
-            return "WS_UPGRADE_STATUS_INVALID_APPID";
-        case WS_UPGRADE_STATUS_INVALID_VERSION:
-            return "WS_UPGRADE_STATUS_INVALID_VERSION";
-        case WS_UPGRADE_WRITE_STATUS_BAD_ID:
-            return "WS_UPGRADE_WRITE_STATUS_BAD_ID";
-        case WS_UPGRADE_WRITE_STATUS_BAD_MAJOR:
-            return "WS_UPGRADE_WRITE_STATUS_BAD_MAJOR";
-        case WS_UPGRADE_WRITE_STATUS_TOO_MUCH_DATA:
-            return "WS_UPGRADE_WRITE_STATUS_TOO_MUCH_DATA";
-        case WS_UPGRADE_WRITE_STATUS_TOO_SHORT:
-            return "WS_UPGRADE_WRITE_STATUS_TOO_SHORT";
-        case WS_UPGRADE_WRITE_STATUS_ABORTED:
-            return "WS_UPGRADE_WRITE_STATUS_ABORTED";
-        case ERROR_CONNECT:
-            return "ERROR_CONNECT";
-        case ERROR_DISCOVER:
-            return "ERROR_DISCOVER";
-        case ERROR_SERVICE:
-            return "ERROR_SERVICE";
-        case ERROR_DESCRIPTOR_WRITE:
-            return "ERROR_DESCRIPTOR_WRITE";
-        case ERROR_DESCRIPTOR_NOT_FOUND:
-            return "ERROR_DESCRIPTOR_NOT_FOUND";
-        case ERROR_CHARACTERISTIC_WRITE:
-            return "ERROR_CHARACTERISTIC_WRITE";
-        case ERROR_FIRMWARE_INFO_READ:
-            return "ERROR_FIRMWARE_INFO_READ";
-        case ERROR_FIRMWARE_INFO_WRITE:
-            return "ERROR_FIRMWARE_INFO_WRITE";
-        case ERROR_FIRMWARE_READ:
-            return "ERROR_FIRMWARE_READ";
-        case ERROR_FIRMWARE_WRITE:
-            return "ERROR_FIRMWARE_WRITE";
-        case ERROR_TIMEOUT:
-            return "ERROR_TIMEOUT";
-        default:
-            return "UNKNOWN_STATUS";
-        }
-    }
-
-    private static final String TAG = OtaSettings.TAG_PREFIX + "OtaManager";
-    private static final boolean DBG = OtaSettings.DBG;
-    static final UUID UUID_WS_SECURE_UPGRADE_SERVICE = UUID
-            .fromString("A86ABC2D-D44C-442E-99F7-80059A873E36");
-    private static final UUID UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT = UUID
-            .fromString("1BD19C14-B78A-4E0F-AEB5-8E0352BAC382");
-    private static final UUID UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA = UUID
-            .fromString("279F9DAB-79BE-4663-AF1D-24407347AF13");
-    private static final UUID GATT_DESCRIPTOR_UUID = UUID
-            .fromString("00002902-0000-1000-8000-00805F9B34FB");
-    private static final int OTA_FW_INFO_PACKET_LENGTH = 4;
-    private static final int OTA_MAX_TX_WRITE_PACKET_LENGTH = 20;
-    private static final int EVENT_TIMEOUT_PAIRING = -1000;
-    private static final int EVENT_ERROR = 1;
-    private static final int EVENT_ABORTED = 2;
-    private static final int EVENT_STATE_CHANGED = 3;
-    private static final int EVENT_SEND_PROGRESS = 4;
-
-    private class BluetoothBondingReceiver extends BroadcastReceiver {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-            BluetoothDevice d = mGatt.getDevice();
-            if (device != null
-                    && d != null
-                    && device.equals(d)
-                    && (device.getBondState() == BluetoothDevice.BOND_BONDED || device
-                            .getBondState() == BluetoothDevice.BOND_BONDING)) {
-                onPaired();
-            }
-        }
-    }
-
-    private Context mContext;
-    private GattRequestManager mGatt;
-    private BluetoothGattService mOtaFwService;
-    private BluetoothGattCharacteristic mOtaCharControlPoint;
-    private BluetoothGattCharacteristic mOtaCharData;
-
-    private BluetoothGattDescriptor mCccDescriptor;
-    private int mFirmwareLength;
-    private BufferedInputStream mFirmwareInputStream;
-    private int mState = STATE_NONE;
-    private int mFirmwareSendLoopCount;
-    private int mFirmwareBytesSent;
-    private OtaCallback mCallback;
-    private final Handler mEventHandler = new Handler(this);
-    private boolean mHasError;
-    private boolean mConnectAfterBonding = true;
-    private boolean mDisconnectOnFinished = false;
-    private BluetoothBondingReceiver mBondReceiver;
-
-    public void setDisconnectOnFinished(boolean disconnect) {
-        mDisconnectOnFinished = disconnect;
-    }
-
-    @Override
-    public boolean handleMessage(Message msg) {
-        OtaCallback cb = mCallback;
-        if (cb == null) {
-            return true;
-        }
-        try {
-            switch (msg.what) {
-            case EVENT_TIMEOUT_PAIRING:
-                cb.onOtaError(STATE_CONNECT, msg.arg2);
-                break;
-            case EVENT_STATE_CHANGED:
-                if (msg.arg1 == STATE_UPGRADE_COMPLETED) {
-                    unregisterGatt();
-                }
-                cb.onOtaStateChanged(msg.arg1);
-                break;
-            case EVENT_SEND_PROGRESS:
-                cb.onOtaUploadProgress(msg.getData().getInt("l", -1), msg.arg1, msg.arg2);
-                break;
-            case EVENT_ABORTED:
-                unregisterGatt();
-                cb.onOtaAborted();
-                break;
-            case EVENT_ERROR:
-                unregisterGatt();
-                mHasError = true;
-                cb.onOtaError(msg.arg1, msg.arg2);
-                break;
-            }
-        } catch (Throwable t) {
-            Log.e(TAG, "handleMessage: error", t);
-        }
-        return true;
-    }
-
-    private void setState(int state) {
-        mState = state;
-        mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_STATE_CHANGED, state, 0));
-    }
-
-    private boolean loadGattServicesAndCharacteristics() {
-        BluetoothGatt gatt = mGatt.getGatt();
-        if (gatt == null) {
-            return false;
-        }
-
-        mOtaFwService = gatt.getService(UUID_WS_SECURE_UPGRADE_SERVICE);
-        if (mOtaFwService == null) {
-            return false;
-        }
-
-        mOtaCharData = mOtaFwService.getCharacteristic(UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA);
-        if (mOtaCharData == null) {
-            return false;
-        }
-
-        mOtaCharControlPoint = mOtaFwService
-                .getCharacteristic(UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT);
-        if (mOtaCharControlPoint == null) {
-            return false;
-        }
-
-        mCccDescriptor = mOtaCharControlPoint.getDescriptor(GATT_DESCRIPTOR_UUID);
-        if (mCccDescriptor == null) {
-            return false;
-        }
-        return true;
-    }
-
-    private void enableOtaNotify(boolean enable) {
-        if (DBG) {
-            Log.d(TAG, "enableOtaNotify");
-        }
-        setState(STATE_ENABLE_NOTIFY);
-        if (mCccDescriptor == null) {
-            Log.e(TAG, "mCccDescriptor is null");
-            onOtaNotifyCompleted(false, ERROR_DESCRIPTOR_NOT_FOUND);
-        }
-        mGatt.write(mCccDescriptor, new byte[] { 0x00, 0x02 });
-        mGatt.setCharacteristicNotification(mOtaCharControlPoint, enable);
-    }
-
-    private void onOtaNotifyCompleted(boolean success, int errorCode) {
-        if (DBG) {
-            Log.d(TAG, "onOtaNotifyCompleted: success=" + success + ", errorCode=" + errorCode
-                    + "=" + getStateString(errorCode));
-        }
-        if (!success) {
-            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
-            return;
-        }
-        prepareDownload();
-    }
-
-    private void prepareDownload() {
-        if (DBG) {
-            Log.d(TAG, "prepareDownload");
-        }
-        setState(STATE_PREPARE_DOWNLOAD);
-        mGatt.write(mOtaCharControlPoint, new byte[] { 0x01 });
-    }
-
-    private void onDownloadPrepared(boolean success, int errorCode) {
-        if (DBG) {
-            Log.d(TAG, "onDownloadPrepared: success=" + success + ", errorCode=" + errorCode + "="
-                    + getStateString(errorCode));
-        }
-        if (!success) {
-            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
-            return;
-        }
-        startDownload(mFirmwareLength);
-
-    }
-
-    private void startDownload(int firmwareLength) {
-        if (DBG) {
-            Log.d(TAG, "startDownload: firmwareLength=" + firmwareLength);
-        }
-        mState = STATE_START_DOWNLOAD;
-        byte[] packet = new byte[] { 0x02, 0x00, 0x00 };
-        ByteUtils.uInt16ToBytesLI(firmwareLength, packet, 1);
-        mGatt.write(mOtaCharControlPoint, packet);
-    }
-
-    private void onDownloadStarted(boolean success, int errorCode) {
-        if (DBG) {
-            Log.d(TAG, "onDownloadStarted: success=" + success + ", errorCode=" + errorCode + "="
-                    + getStateString(errorCode));
-        }
-        if (!success) {
-            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
-            return;
-        }
-        sendFirmwareInfo();
-    }
-
-    private byte[] getFirmwareInfoBytes() {
-        if (mFirmwareInputStream == null) {
-            return null;
-        }
-        byte[] firmwareInfo = new byte[OTA_FW_INFO_PACKET_LENGTH];
-
-        try {
-            int bytesRead = mFirmwareInputStream.read(firmwareInfo, 0, OTA_FW_INFO_PACKET_LENGTH);
-            if (bytesRead != OTA_FW_INFO_PACKET_LENGTH) {
-                Log.w(TAG, "Could not read firmware info... Incorrect length.");
-                return null;
-            }
-        } catch (Throwable t) {
-            Log.w(TAG, "Could not read firmware info.", t);
-            return null;
-        }
-
-        return firmwareInfo;
-    }
-
-    private void sendFirmwareInfo() {
-        if (DBG) {
-            Log.d(TAG, "sendFirmwareInfo");
-        }
-        setState(STATE_SEND_FW_INFO);
-
-        byte[] firmwareInfo = getFirmwareInfoBytes();
-        if (firmwareInfo == null) {
-            onFirmwareInfoSent(false, ERROR_FIRMWARE_INFO_READ);
-        }
-        mGatt.write(mOtaCharData, firmwareInfo);
-    }
-
-    private void onFirmwareInfoSent(boolean success, int errorCode) {
-        Log.d(TAG, "onFirmwareInfoSent: success=" + success + ", errorCode=" + errorCode + "="
-                + getStateString(errorCode));
-
-        if (!success) {
-            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
-            return;
-        }
-        mFirmwareSendLoopCount = 0;
-        mFirmwareBytesSent = 0;
-        sendFirmware();
-    }
-
-    private byte[] getFirmwareBytes() {
-        if (mFirmwareInputStream == null) {
-            return null;
-        }
-        byte[] firmware = new byte[OTA_MAX_TX_WRITE_PACKET_LENGTH];
-        try {
-            int bytesRead = mFirmwareInputStream.read(firmware, 0, OTA_MAX_TX_WRITE_PACKET_LENGTH);
-            if (bytesRead <= 0) {
-                return new byte[0];
-            }
-
-            if (bytesRead == OTA_FW_INFO_PACKET_LENGTH) {
-                return firmware;
-            }
-            // Truncate byte array
-            byte[] truncatedBytes = new byte[bytesRead];
-            if (bytesRead > 0) {
-                System.arraycopy(firmware, 0, truncatedBytes, 0, bytesRead);
-            }
-            return truncatedBytes;
-
-        } catch (Throwable t) {
-            Log.w(TAG, "Could not read firmware info.", t);
-            return null;
-        }
-    }
-
-    private void sendFirmware() {
-        if (DBG) {
-            Log.d(TAG, "sendFirmware");
-        }
-        if (mState != STATE_SEND_FW) {
-            setState(STATE_SEND_FW);
-        }
-
-        byte[] firmware = getFirmwareBytes();
-        if (firmware == null) {
-            onFirmwareSent(false, ERROR_FIRMWARE_READ);
-        }
-        if (firmware.length == 0) {
-            onFirmwareSendCompleted();
-        } else {
-            mFirmwareSendLoopCount++;
-            mFirmwareBytesSent += firmware.length;
-            Message m = mEventHandler.obtainMessage(EVENT_SEND_PROGRESS, mFirmwareBytesSent,
-                    mFirmwareLength);
-            m.getData().putInt("l", mFirmwareSendLoopCount);
-            mEventHandler.sendMessage(m);
-            if (DBG) {
-                Log.d(TAG, "sendFirmware: " + mFirmwareSendLoopCount + ", value= " + firmware);
-                if (firmware != null) {
-                    Log.d(TAG, "sendFirmware: length =" + firmware.length);
-                }
-            }
-            mGatt.write(mFirmwareSendLoopCount, mOtaCharData, firmware);
-        }
-    }
-
-    private void onFirmwareSent(boolean success, int errorCode) {
-        if (DBG) {
-            Log.d(TAG, "onFirmwareSent: success=" + success + ", errorCode=" + errorCode + "="
-                    + getStateString(errorCode));
-        }
-        if (!success) {
-            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
-            return;
-        }
-        // Otherwise keep sending remaining firmware
-        sendFirmware();
-    }
-
-    private void onFirmwareSendCompleted() {
-        Log.d(TAG, "onFirmwareSendCompleted");
-        setState(STATE_SEND_FW_COMPLETED);
-        verifyFirmware();
-    }
-
-    private void verifyFirmware() {
-        if (DBG) {
-            Log.d(TAG, "verifyFirmware");
-        }
-        setState(STATE_VERIFY_FW);
-        mGatt.write(mOtaCharControlPoint, new byte[] { 0x3 });
-    }
-
-    private void onFirmwareVerified(boolean success, int errorCode) {
-        if (DBG) {
-            Log.d(TAG, "onFirmwareVerified: success=" + success + ", errorCode=" + errorCode + "="
-                    + getStateString(errorCode));
-        }
-        if (!success) {
-            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
-            return;
-        }
-        setState(STATE_UPGRADE_COMPLETED);
-    }
-
-    private void processControlPointStatus(boolean success, int errorCode) {
-        int state = mState;
-        switch (state) {
-        case STATE_ENABLE_NOTIFY:
-            onOtaNotifyCompleted(success, errorCode);
-            break;
-        case STATE_PREPARE_DOWNLOAD:
-            onDownloadPrepared(success, errorCode);
-            break;
-        case STATE_START_DOWNLOAD:
-            onDownloadStarted(success, errorCode);
-            break;
-        case STATE_SEND_FW_INFO:
-            onFirmwareInfoSent(success, errorCode);
-            break;
-        case STATE_SEND_FW:
-            onFirmwareSent(success, errorCode);
-            break;
-        case STATE_VERIFY_FW:
-            onFirmwareVerified(success, errorCode);
-            break;
-        }
-    }
-
-    private void processDataWriteError() {
-        int state = mState;
-        if (state == STATE_SEND_FW_INFO) {
-            onFirmwareSent(false, ERROR_FIRMWARE_INFO_WRITE);
-        } else if (state == STATE_SEND_FW) {
-            onFirmwareSent(false, ERROR_FIRMWARE_WRITE);
-        }
-    }
-
-    /**
-     * GATT client callbacks
-     */
-
-    @Override
-    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
-        if (newState == BluetoothGatt.STATE_DISCONNECTED
-                || newState == BluetoothGatt.STATE_DISCONNECTING) {
-            if (mState != STATE_NONE && mState != STATE_UPGRADE_COMPLETED && !mHasError) {
-                mEventHandler.sendEmptyMessage(EVENT_ABORTED);
-            }
-        }
-    }
-
-    @Override
-    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
-        Log.d(TAG, "onServicesDiscovered -- status " + status);
-        if (!loadGattServicesAndCharacteristics()) {
-            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState,
-                    ERROR_SERVICE));
-        } else {
-            enableOtaNotify(true);
-        }
-    }
-
-    @Override
-    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
-        if (descriptor.getCharacteristic().getUuid()
-                .equals(UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT)) {
-            boolean success = status == BluetoothGatt.GATT_SUCCESS;
-            onOtaNotifyCompleted(success, success ? 0 : ERROR_DESCRIPTOR_WRITE);
-        }
-    }
-
-    @Override
-    public void onCharacteristicChanged(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic) {
-        UUID uuid = characteristic.getUuid();
-        if (!UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT.equals(uuid)) {
-            Log.e(TAG, "onCharacteristicChanged: UUID" + uuid + " not control point");
-            return;
-        }
-        int status = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
-        if (DBG) {
-            Log.d(TAG, "onCharacteristicChanged(): + " + uuid + ": status=" + status);
-        }
-        switch (status) {
-
-        case WS_UPGRADE_STATUS_OK:
-            // case WS_UPGRADE_WRITE_STATUS_SUCCESS:
-        case WS_UPGRADE_STATUS_MORE_DATA:
-            processControlPointStatus(true, WS_UPGRADE_STATUS_OK);
-            break;
-        case WS_UPGRADE_WRITE_STATUS_ABORTED:
-            // mEventHandler.sendEmptyMessage(EVENT_ABORTED);
-            break;
-        default:
-            processControlPointStatus(false, status);
-            break;
-        }
-    }
-
-    @Override
-    public void onCharacteristicWrite(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic, int status) {
-        UUID uuid = characteristic.getUuid();
-        if (DBG) {
-            Log.d(TAG, "onCharacteristicWrite: " + uuid + ", status= " + status);
-            Log.d(TAG, "write type = " + characteristic.getWriteType());
-        }
-        if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT.equals(uuid)) {
-            if (status != BluetoothGatt.GATT_SUCCESS) {
-                processControlPointStatus(false, ERROR_CHARACTERISTIC_WRITE);
-            }
-        }
-
-        else if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA.equals(uuid)) {
-            if (status == BluetoothGatt.GATT_SUCCESS) {
-                processControlPointStatus(true, WS_UPGRADE_STATUS_OK);
-            } else {
-                processDataWriteError();
-            }
-        }
-
-    }
-
-    @Override
-    public void onTimeout(GattRequest request) {
-        if (DBG) {
-            Log.d(TAG, "onTimeout()");
-        }
-        if (request.mRequestType == GattRequestManager.REQUEST_WRITE_CHAR) {
-            UUID uuid = request.mCharacteristic == null ? null : request.mCharacteristic.getUuid();
-            if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT.equals(uuid)
-                    || UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA.equals(uuid)) {
-                Log.d(TAG, "onTimeout(): CP");
-                processControlPointStatus(false, ERROR_TIMEOUT);
-            }
-        } else if (request.mRequestType == GattRequestManager.REQUEST_WRITE_DESCRIPTOR) {
-            UUID uuid = null;
-            UUID cUuid = null;
-            if (request.mDescriptor != null) {
-                uuid = request.mDescriptor.getUuid();
-                cUuid = request.mDescriptor.getCharacteristic().getUuid();
-            }
-            if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT.equals(cUuid)
-                    && GATT_DESCRIPTOR_UUID.equals(uuid)) {
-                processControlPointStatus(false, ERROR_TIMEOUT);
-            }
-        }
-    }
-
-    private void connect() {
-        if (!mGatt.connect()) {
-            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState,
-                    ERROR_CONNECT));
-        } else {
-            mDisconnectOnFinished = true;
-        }
-    }
-
-    private boolean pairIfNeeded() {
-        BluetoothDevice device = mGatt.getDevice();
-
-        if (OtaSettings.PAIRING_REQUIRED && device.getBondState() != BluetoothDevice.BOND_BONDED) {
-            if (DBG) {
-                Log.d(TAG, "Pairing device...");
-            }
-            try {
-                mConnectAfterBonding = true;
-                mEventHandler.sendEmptyMessageDelayed(EVENT_TIMEOUT_PAIRING,
-                        OtaSettings.TIMEOUT_PAIRING_MS);
-                mGatt.pair();
-                return true;
-            } catch (Throwable t) {
-                mConnectAfterBonding = false;
-                Log.e(TAG, "error", t);
-            }
-        }
-        return false;
-    }
-
-    private void onPaired() {
-        if (DBG) {
-            Log.d(TAG, "onPaired");
-        }
-        if (mConnectAfterBonding) {
-            mEventHandler.removeMessages(EVENT_TIMEOUT_PAIRING);
-            mConnectAfterBonding = false;
-            connect();
-        }
-
-    }
-
-    private void unregisterGatt() {
-        if (mGatt != null) {
-            mGatt.removeCallback(this);
-            mGatt.removeTimeoutCallback(this);
-        }
-    }
-
-    // ---------------Public API-----------------------------------------------
-
-    public void addCallback(OtaCallback cb) {
-        mCallback = cb;
-    }
-
-    public void removeCallback(OtaCallback cb) {
-        if (mCallback == cb) {
-            mCallback = null;
-        }
-    }
-
-    public void startUpdate(Context ctx, GattRequestManager gattManager, int firmwareLength,
-            BufferedInputStream in) {
-        mContext = ctx;
-        mBondReceiver = new BluetoothBondingReceiver();
-        mContext.registerReceiver(mBondReceiver, new IntentFilter(
-                BluetoothDevice.ACTION_BOND_STATE_CHANGED));
-        mGatt = gattManager;
-        mGatt.addCallback(this);
-        mGatt.addTimeoutCallback(this);
-
-        mFirmwareLength = firmwareLength;
-        mFirmwareInputStream = in;
-        mState = STATE_NONE;
-        mHasError = false;
-        mFirmwareSendLoopCount = 0;
-        mFirmwareBytesSent = 0;
-        if (mGatt.isConnected()) {
-            if (DBG) {
-                Log.d(TAG, "startUpgrade: GattManager already connected");
-            }
-            if (!loadGattServicesAndCharacteristics()) {
-                if (!mGatt.discoverServices()) {
-                    onServicesDiscovered(mGatt.getGatt(), -600);
-                }
-            } else {
-                enableOtaNotify(true);
-            }
-        } else {
-            if (!pairIfNeeded()) {
-                if (DBG) {
-                    Log.d(TAG, "startUpgrade: connecting...");
-                }
-                connect();
-            }
-        }
-    }
-
-    public void abortUpdate() {
-        mGatt.write(mOtaCharControlPoint, new byte[] { 0x7 });
-        setState(STATE_ABORTED);
-        mEventHandler.sendEmptyMessage(EVENT_ABORTED);
-    }
-
-    public void finish() {
-        mContext.unregisterReceiver(mBondReceiver);
-        unregisterGatt();
-        if (mDisconnectOnFinished) {
-            mGatt.disconnect(true);
-        }
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota;
+
+import android.os.Handler;
+import android.os.Handler.Callback;
+import android.os.Message;
+import android.util.Log;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import java.io.BufferedInputStream;
+import java.util.UUID;
+import com.broadcom.util.ByteUtils;
+import com.broadcom.util.GattRequestManager;
+import com.broadcom.util.GattRequestManager.GattRequest;
+import com.broadcom.util.GattRequestManager.GattTimeoutCallback;
+
+public class OtaManager extends BluetoothGattCallback implements Callback, GattTimeoutCallback {
+    public static final int STATE_NONE = 0;
+    public static final int STATE_CONNECT = 1;
+    public static final int STATE_DISCOVER = 2;
+    public static final int STATE_ENABLE_NOTIFY = 3;
+    public static final int STATE_PREPARE_DOWNLOAD = 4;
+    public static final int STATE_START_DOWNLOAD = 5;
+    public static final int STATE_SEND_FW_INFO = 6;
+    public static final int STATE_SEND_FW = 7;
+    public static final int STATE_SEND_FW_COMPLETED = 8;
+    public static final int STATE_VERIFY_FW = 9;
+    public static final int STATE_UPGRADE_COMPLETED = 10;
+    public static final int STATE_ABORTED = -10;
+
+    public static final int WS_UPGRADE_STATUS_OK = 0;
+    public static final int WS_UPGRADE_STATUS_UNSUPPORTED_COMMAND = 1;
+    public static final int WS_UPGRADE_STATUS_ILLEGAL_STATE = 2;
+    public static final int WS_UPGRADE_STATUS_VERIFICATION_FAILED = 3;
+    public static final int WS_UPGRADE_STATUS_INVALID_IMAGE = 4;
+    public static final int WS_UPGRADE_STATUS_INVALID_IMAGE_SIZE = 5;
+    public static final int WS_UPGRADE_STATUS_MORE_DATA = 6;
+    public static final int WS_UPGRADE_STATUS_INVALID_APPID = 7;
+    public static final int WS_UPGRADE_STATUS_INVALID_VERSION = 8;
+    public static final int WS_UPGRADE_WRITE_STATUS_SUCCESS = 0x00;
+    public static final int WS_UPGRADE_WRITE_STATUS_BAD_ID = 0x81;
+    public static final int WS_UPGRADE_WRITE_STATUS_BAD_MAJOR = 0x82;
+    public static final int WS_UPGRADE_WRITE_STATUS_TOO_MUCH_DATA = 0x83;
+    public static final int WS_UPGRADE_WRITE_STATUS_TOO_SHORT = 0x84;
+    public static final int WS_UPGRADE_WRITE_STATUS_ABORTED = 0x85;
+    public static final int ERROR_CONNECT = -100;
+    public static final int ERROR_DISCOVER = -101;
+    public static final int ERROR_SERVICE = -102;
+    public static final int ERROR_DESCRIPTOR_WRITE = -110;
+    public static final int ERROR_DESCRIPTOR_NOT_FOUND = -111;
+    public static final int ERROR_CHARACTERISTIC_WRITE = -112;
+    public static final int ERROR_FIRMWARE_INFO_READ = -120;
+    public static final int ERROR_FIRMWARE_INFO_WRITE = -121;
+    public static final int ERROR_FIRMWARE_READ = -122;
+    public static final int ERROR_FIRMWARE_WRITE = -123;
+    public static final int ERROR_TIMEOUT = -200;
+
+    public static final String getStateString(int state) {
+        switch (state) {
+        case STATE_NONE:
+            return "STATE_NONE";
+        case STATE_CONNECT:
+            return "STATE_CONNECT";
+        case STATE_DISCOVER:
+            return "STATE_DISCOVER";
+        case STATE_ENABLE_NOTIFY:
+            return "STATE_ENABLE_NOTIFY";
+        case STATE_PREPARE_DOWNLOAD:
+            return "STATE_PREPARE_DOWNLOAD";
+        case STATE_START_DOWNLOAD:
+            return "STATE_START_DOWNLOAD";
+        case STATE_SEND_FW_INFO:
+            return "STATE_SEND_FW_INFO";
+        case STATE_SEND_FW:
+            return "STATE_SEND_FW";
+        case STATE_SEND_FW_COMPLETED:
+            return "STATE_SEND_FW_COMPLETED";
+        case STATE_VERIFY_FW:
+            return "STATE_VERIFY_FW";
+        case STATE_UPGRADE_COMPLETED:
+            return "STATE_UPGRADE_COMPLETED";
+        case STATE_ABORTED:
+            return "STATE_ABORTED";
+        default:
+            return "STATE_UNKNOWN";
+        }
+    }
+
+    public static final String getStatusString(int status) {
+        switch (status) {
+        case WS_UPGRADE_STATUS_OK:
+            return "WS_UPGRADE_STATUS_OK";
+        case WS_UPGRADE_STATUS_UNSUPPORTED_COMMAND:
+            return "WS_UPGRADE_STATUS_UNSUPPORTED_COMMAND";
+        case WS_UPGRADE_STATUS_ILLEGAL_STATE:
+            return "WS_UPGRADE_STATUS_ILLEGAL_STATE";
+        case WS_UPGRADE_STATUS_VERIFICATION_FAILED:
+            return "WS_UPGRADE_STATUS_VERIFICATION_FAILED";
+        case WS_UPGRADE_STATUS_INVALID_IMAGE:
+            return "WS_UPGRADE_STATUS_INVALID_IMAGE";
+        case WS_UPGRADE_STATUS_INVALID_IMAGE_SIZE:
+            return "WS_UPGRADE_STATUS_INVALID_IMAGE_SIZE";
+        case WS_UPGRADE_STATUS_MORE_DATA:
+            return "WS_UPGRADE_STATUS_MORE_DATA";
+        case WS_UPGRADE_STATUS_INVALID_APPID:
+            return "WS_UPGRADE_STATUS_INVALID_APPID";
+        case WS_UPGRADE_STATUS_INVALID_VERSION:
+            return "WS_UPGRADE_STATUS_INVALID_VERSION";
+        case WS_UPGRADE_WRITE_STATUS_BAD_ID:
+            return "WS_UPGRADE_WRITE_STATUS_BAD_ID";
+        case WS_UPGRADE_WRITE_STATUS_BAD_MAJOR:
+            return "WS_UPGRADE_WRITE_STATUS_BAD_MAJOR";
+        case WS_UPGRADE_WRITE_STATUS_TOO_MUCH_DATA:
+            return "WS_UPGRADE_WRITE_STATUS_TOO_MUCH_DATA";
+        case WS_UPGRADE_WRITE_STATUS_TOO_SHORT:
+            return "WS_UPGRADE_WRITE_STATUS_TOO_SHORT";
+        case WS_UPGRADE_WRITE_STATUS_ABORTED:
+            return "WS_UPGRADE_WRITE_STATUS_ABORTED";
+        case ERROR_CONNECT:
+            return "ERROR_CONNECT";
+        case ERROR_DISCOVER:
+            return "ERROR_DISCOVER";
+        case ERROR_SERVICE:
+            return "ERROR_SERVICE";
+        case ERROR_DESCRIPTOR_WRITE:
+            return "ERROR_DESCRIPTOR_WRITE";
+        case ERROR_DESCRIPTOR_NOT_FOUND:
+            return "ERROR_DESCRIPTOR_NOT_FOUND";
+        case ERROR_CHARACTERISTIC_WRITE:
+            return "ERROR_CHARACTERISTIC_WRITE";
+        case ERROR_FIRMWARE_INFO_READ:
+            return "ERROR_FIRMWARE_INFO_READ";
+        case ERROR_FIRMWARE_INFO_WRITE:
+            return "ERROR_FIRMWARE_INFO_WRITE";
+        case ERROR_FIRMWARE_READ:
+            return "ERROR_FIRMWARE_READ";
+        case ERROR_FIRMWARE_WRITE:
+            return "ERROR_FIRMWARE_WRITE";
+        case ERROR_TIMEOUT:
+            return "ERROR_TIMEOUT";
+        default:
+            return "UNKNOWN_STATUS";
+        }
+    }
+
+    private static final String TAG = OtaSettings.TAG_PREFIX + "OtaManager";
+    private static final boolean DBG = OtaSettings.DBG;
+    static final UUID UUID_WS_SECURE_UPGRADE_SERVICE = UUID
+            .fromString("A86ABC2D-D44C-442E-99F7-80059A873E36");
+    private static final UUID UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT = UUID
+            .fromString("1BD19C14-B78A-4E0F-AEB5-8E0352BAC382");
+    private static final UUID UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA = UUID
+            .fromString("279F9DAB-79BE-4663-AF1D-24407347AF13");
+    private static final UUID GATT_DESCRIPTOR_UUID = UUID
+            .fromString("00002902-0000-1000-8000-00805F9B34FB");
+    private static final int OTA_FW_INFO_PACKET_LENGTH = 4;
+    private static final int OTA_MAX_TX_WRITE_PACKET_LENGTH = 20;
+    private static final int EVENT_TIMEOUT_PAIRING = -1000;
+    private static final int EVENT_ERROR = 1;
+    private static final int EVENT_ABORTED = 2;
+    private static final int EVENT_STATE_CHANGED = 3;
+    private static final int EVENT_SEND_PROGRESS = 4;
+
+    private class BluetoothBondingReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            BluetoothDevice d = mGatt.getDevice();
+            if (device != null
+                    && d != null
+                    && device.equals(d)
+                    && (device.getBondState() == BluetoothDevice.BOND_BONDED || device
+                            .getBondState() == BluetoothDevice.BOND_BONDING)) {
+                onPaired();
+            }
+        }
+    }
+
+    private Context mContext;
+    private GattRequestManager mGatt;
+    private BluetoothGattService mOtaFwService;
+    private BluetoothGattCharacteristic mOtaCharControlPoint;
+    private BluetoothGattCharacteristic mOtaCharData;
+
+    private BluetoothGattDescriptor mCccDescriptor;
+    private int mFirmwareLength;
+    private BufferedInputStream mFirmwareInputStream;
+    private int mState = STATE_NONE;
+    private int mFirmwareSendLoopCount;
+    private int mFirmwareBytesSent;
+    private OtaCallback mCallback;
+    private final Handler mEventHandler = new Handler(this);
+    private boolean mHasError;
+    private boolean mConnectAfterBonding = true;
+    private boolean mDisconnectOnFinished = false;
+    private BluetoothBondingReceiver mBondReceiver;
+
+    public void setDisconnectOnFinished(boolean disconnect) {
+        mDisconnectOnFinished = disconnect;
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        OtaCallback cb = mCallback;
+        if (cb == null) {
+            return true;
+        }
+        try {
+            switch (msg.what) {
+            case EVENT_TIMEOUT_PAIRING:
+                cb.onOtaError(STATE_CONNECT, msg.arg2);
+                break;
+            case EVENT_STATE_CHANGED:
+                if (msg.arg1 == STATE_UPGRADE_COMPLETED) {
+                    unregisterGatt();
+                }
+                cb.onOtaStateChanged(msg.arg1);
+                break;
+            case EVENT_SEND_PROGRESS:
+                cb.onOtaUploadProgress(msg.getData().getInt("l", -1), msg.arg1, msg.arg2);
+                break;
+            case EVENT_ABORTED:
+                unregisterGatt();
+                cb.onOtaAborted();
+                break;
+            case EVENT_ERROR:
+                unregisterGatt();
+                mHasError = true;
+                cb.onOtaError(msg.arg1, msg.arg2);
+                break;
+            }
+        } catch (Throwable t) {
+            Log.e(TAG, "handleMessage: error", t);
+        }
+        return true;
+    }
+
+    private void setState(int state) {
+        mState = state;
+        mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_STATE_CHANGED, state, 0));
+    }
+
+    private boolean loadGattServicesAndCharacteristics() {
+        BluetoothGatt gatt = mGatt.getGatt();
+        if (gatt == null) {
+            return false;
+        }
+
+        mOtaFwService = gatt.getService(UUID_WS_SECURE_UPGRADE_SERVICE);
+        if (mOtaFwService == null) {
+            return false;
+        }
+
+        mOtaCharData = mOtaFwService.getCharacteristic(UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA);
+        if (mOtaCharData == null) {
+            return false;
+        }
+
+        mOtaCharControlPoint = mOtaFwService
+                .getCharacteristic(UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT);
+        if (mOtaCharControlPoint == null) {
+            return false;
+        }
+
+        mCccDescriptor = mOtaCharControlPoint.getDescriptor(GATT_DESCRIPTOR_UUID);
+        if (mCccDescriptor == null) {
+            return false;
+        }
+        return true;
+    }
+
+    private void enableOtaNotify(boolean enable) {
+        if (DBG) {
+            Log.d(TAG, "enableOtaNotify");
+        }
+        setState(STATE_ENABLE_NOTIFY);
+        if (mCccDescriptor == null) {
+            Log.e(TAG, "mCccDescriptor is null");
+            onOtaNotifyCompleted(false, ERROR_DESCRIPTOR_NOT_FOUND);
+        }
+        mGatt.write(mCccDescriptor, new byte[] { 0x00, 0x02 });
+        mGatt.setCharacteristicNotification(mOtaCharControlPoint, enable);
+    }
+
+    private void onOtaNotifyCompleted(boolean success, int errorCode) {
+        if (DBG) {
+            Log.d(TAG, "onOtaNotifyCompleted: success=" + success + ", errorCode=" + errorCode
+                    + "=" + getStateString(errorCode));
+        }
+        if (!success) {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
+            return;
+        }
+        prepareDownload();
+    }
+
+    private void prepareDownload() {
+        if (DBG) {
+            Log.d(TAG, "prepareDownload");
+        }
+        setState(STATE_PREPARE_DOWNLOAD);
+        mGatt.write(mOtaCharControlPoint, new byte[] { 0x01 });
+    }
+
+    private void onDownloadPrepared(boolean success, int errorCode) {
+        if (DBG) {
+            Log.d(TAG, "onDownloadPrepared: success=" + success + ", errorCode=" + errorCode + "="
+                    + getStateString(errorCode));
+        }
+        if (!success) {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
+            return;
+        }
+        startDownload(mFirmwareLength);
+
+    }
+
+    private void startDownload(int firmwareLength) {
+        if (DBG) {
+            Log.d(TAG, "startDownload: firmwareLength=" + firmwareLength);
+        }
+        mState = STATE_START_DOWNLOAD;
+        byte[] packet = new byte[] { 0x02, 0x00, 0x00 };
+        ByteUtils.uInt16ToBytesLI(firmwareLength, packet, 1);
+        mGatt.write(mOtaCharControlPoint, packet);
+    }
+
+    private void onDownloadStarted(boolean success, int errorCode) {
+        if (DBG) {
+            Log.d(TAG, "onDownloadStarted: success=" + success + ", errorCode=" + errorCode + "="
+                    + getStateString(errorCode));
+        }
+        if (!success) {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
+            return;
+        }
+        sendFirmwareInfo();
+    }
+
+    private byte[] getFirmwareInfoBytes() {
+        if (mFirmwareInputStream == null) {
+            return null;
+        }
+        byte[] firmwareInfo = new byte[OTA_FW_INFO_PACKET_LENGTH];
+
+        try {
+            int bytesRead = mFirmwareInputStream.read(firmwareInfo, 0, OTA_FW_INFO_PACKET_LENGTH);
+            if (bytesRead != OTA_FW_INFO_PACKET_LENGTH) {
+                Log.w(TAG, "Could not read firmware info... Incorrect length.");
+                return null;
+            }
+        } catch (Throwable t) {
+            Log.w(TAG, "Could not read firmware info.", t);
+            return null;
+        }
+
+        return firmwareInfo;
+    }
+
+    private void sendFirmwareInfo() {
+        if (DBG) {
+            Log.d(TAG, "sendFirmwareInfo");
+        }
+        setState(STATE_SEND_FW_INFO);
+
+        byte[] firmwareInfo = getFirmwareInfoBytes();
+        if (firmwareInfo == null) {
+            onFirmwareInfoSent(false, ERROR_FIRMWARE_INFO_READ);
+        }
+        mGatt.write(mOtaCharData, firmwareInfo);
+    }
+
+    private void onFirmwareInfoSent(boolean success, int errorCode) {
+        Log.d(TAG, "onFirmwareInfoSent: success=" + success + ", errorCode=" + errorCode + "="
+                + getStateString(errorCode));
+
+        if (!success) {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
+            return;
+        }
+        mFirmwareSendLoopCount = 0;
+        mFirmwareBytesSent = 0;
+        sendFirmware();
+    }
+
+    private byte[] getFirmwareBytes() {
+        if (mFirmwareInputStream == null) {
+            return null;
+        }
+        byte[] firmware = new byte[OTA_MAX_TX_WRITE_PACKET_LENGTH];
+        try {
+            int bytesRead = mFirmwareInputStream.read(firmware, 0, OTA_MAX_TX_WRITE_PACKET_LENGTH);
+            if (bytesRead <= 0) {
+                return new byte[0];
+            }
+
+            if (bytesRead == OTA_FW_INFO_PACKET_LENGTH) {
+                return firmware;
+            }
+            // Truncate byte array
+            byte[] truncatedBytes = new byte[bytesRead];
+            if (bytesRead > 0) {
+                System.arraycopy(firmware, 0, truncatedBytes, 0, bytesRead);
+            }
+            return truncatedBytes;
+
+        } catch (Throwable t) {
+            Log.w(TAG, "Could not read firmware info.", t);
+            return null;
+        }
+    }
+
+    private void sendFirmware() {
+        if (DBG) {
+            Log.d(TAG, "sendFirmware");
+        }
+        if (mState != STATE_SEND_FW) {
+            setState(STATE_SEND_FW);
+        }
+
+        byte[] firmware = getFirmwareBytes();
+        if (firmware == null) {
+            onFirmwareSent(false, ERROR_FIRMWARE_READ);
+        }
+        if (firmware.length == 0) {
+            onFirmwareSendCompleted();
+        } else {
+            mFirmwareSendLoopCount++;
+            mFirmwareBytesSent += firmware.length;
+            Message m = mEventHandler.obtainMessage(EVENT_SEND_PROGRESS, mFirmwareBytesSent,
+                    mFirmwareLength);
+            m.getData().putInt("l", mFirmwareSendLoopCount);
+            mEventHandler.sendMessage(m);
+            if (DBG) {
+                Log.d(TAG, "sendFirmware: " + mFirmwareSendLoopCount + ", value= " + firmware);
+                if (firmware != null) {
+                    Log.d(TAG, "sendFirmware: length =" + firmware.length);
+                }
+            }
+            mGatt.write(mFirmwareSendLoopCount, mOtaCharData, firmware);
+        }
+    }
+
+    private void onFirmwareSent(boolean success, int errorCode) {
+        if (DBG) {
+            Log.d(TAG, "onFirmwareSent: success=" + success + ", errorCode=" + errorCode + "="
+                    + getStateString(errorCode));
+        }
+        if (!success) {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
+            return;
+        }
+        // Otherwise keep sending remaining firmware
+        sendFirmware();
+    }
+
+    private void onFirmwareSendCompleted() {
+        Log.d(TAG, "onFirmwareSendCompleted");
+        setState(STATE_SEND_FW_COMPLETED);
+        verifyFirmware();
+    }
+
+    private void verifyFirmware() {
+        if (DBG) {
+            Log.d(TAG, "verifyFirmware");
+        }
+        setState(STATE_VERIFY_FW);
+        mGatt.write(mOtaCharControlPoint, new byte[] { 0x3 });
+    }
+
+    private void onFirmwareVerified(boolean success, int errorCode) {
+        if (DBG) {
+            Log.d(TAG, "onFirmwareVerified: success=" + success + ", errorCode=" + errorCode + "="
+                    + getStateString(errorCode));
+        }
+        if (!success) {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState, errorCode));
+            return;
+        }
+        setState(STATE_UPGRADE_COMPLETED);
+    }
+
+    private void processControlPointStatus(boolean success, int errorCode) {
+        int state = mState;
+        switch (state) {
+        case STATE_ENABLE_NOTIFY:
+            onOtaNotifyCompleted(success, errorCode);
+            break;
+        case STATE_PREPARE_DOWNLOAD:
+            onDownloadPrepared(success, errorCode);
+            break;
+        case STATE_START_DOWNLOAD:
+            onDownloadStarted(success, errorCode);
+            break;
+        case STATE_SEND_FW_INFO:
+            onFirmwareInfoSent(success, errorCode);
+            break;
+        case STATE_SEND_FW:
+            onFirmwareSent(success, errorCode);
+            break;
+        case STATE_VERIFY_FW:
+            onFirmwareVerified(success, errorCode);
+            break;
+        }
+    }
+
+    private void processDataWriteError() {
+        int state = mState;
+        if (state == STATE_SEND_FW_INFO) {
+            onFirmwareSent(false, ERROR_FIRMWARE_INFO_WRITE);
+        } else if (state == STATE_SEND_FW) {
+            onFirmwareSent(false, ERROR_FIRMWARE_WRITE);
+        }
+    }
+
+    /**
+     * GATT client callbacks
+     */
+
+    @Override
+    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+        if (newState == BluetoothGatt.STATE_DISCONNECTED
+                || newState == BluetoothGatt.STATE_DISCONNECTING) {
+            if (mState != STATE_NONE && mState != STATE_UPGRADE_COMPLETED && !mHasError) {
+                mEventHandler.sendEmptyMessage(EVENT_ABORTED);
+            }
+        }
+    }
+
+    @Override
+    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+        Log.d(TAG, "onServicesDiscovered -- status " + status);
+        if (!loadGattServicesAndCharacteristics()) {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState,
+                    ERROR_SERVICE));
+        } else {
+            enableOtaNotify(true);
+        }
+    }
+
+    @Override
+    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
+        if (descriptor.getCharacteristic().getUuid()
+                .equals(UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT)) {
+            boolean success = status == BluetoothGatt.GATT_SUCCESS;
+            onOtaNotifyCompleted(success, success ? 0 : ERROR_DESCRIPTOR_WRITE);
+        }
+    }
+
+    @Override
+    public void onCharacteristicChanged(BluetoothGatt gatt,
+            BluetoothGattCharacteristic characteristic) {
+        UUID uuid = characteristic.getUuid();
+        if (!UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT.equals(uuid)) {
+            Log.e(TAG, "onCharacteristicChanged: UUID" + uuid + " not control point");
+            return;
+        }
+        int status = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
+        if (DBG) {
+            Log.d(TAG, "onCharacteristicChanged(): + " + uuid + ": status=" + status);
+        }
+        switch (status) {
+
+        case WS_UPGRADE_STATUS_OK:
+            // case WS_UPGRADE_WRITE_STATUS_SUCCESS:
+        case WS_UPGRADE_STATUS_MORE_DATA:
+            processControlPointStatus(true, WS_UPGRADE_STATUS_OK);
+            break;
+        case WS_UPGRADE_WRITE_STATUS_ABORTED:
+            // mEventHandler.sendEmptyMessage(EVENT_ABORTED);
+            break;
+        default:
+            processControlPointStatus(false, status);
+            break;
+        }
+    }
+
+    @Override
+    public void onCharacteristicWrite(BluetoothGatt gatt,
+            BluetoothGattCharacteristic characteristic, int status) {
+        UUID uuid = characteristic.getUuid();
+        if (DBG) {
+            Log.d(TAG, "onCharacteristicWrite: " + uuid + ", status= " + status);
+            Log.d(TAG, "write type = " + characteristic.getWriteType());
+        }
+        if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT.equals(uuid)) {
+            if (status != BluetoothGatt.GATT_SUCCESS) {
+                processControlPointStatus(false, ERROR_CHARACTERISTIC_WRITE);
+            }
+        }
+
+        else if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA.equals(uuid)) {
+            if (status == BluetoothGatt.GATT_SUCCESS) {
+                processControlPointStatus(true, WS_UPGRADE_STATUS_OK);
+            } else {
+                processDataWriteError();
+            }
+        }
+
+    }
+
+    @Override
+    public void onTimeout(GattRequest request) {
+        if (DBG) {
+            Log.d(TAG, "onTimeout()");
+        }
+        if (request.mRequestType == GattRequestManager.REQUEST_WRITE_CHAR) {
+            UUID uuid = request.mCharacteristic == null ? null : request.mCharacteristic.getUuid();
+            if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT.equals(uuid)
+                    || UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_DATA.equals(uuid)) {
+                Log.d(TAG, "onTimeout(): CP");
+                processControlPointStatus(false, ERROR_TIMEOUT);
+            }
+        } else if (request.mRequestType == GattRequestManager.REQUEST_WRITE_DESCRIPTOR) {
+            UUID uuid = null;
+            UUID cUuid = null;
+            if (request.mDescriptor != null) {
+                uuid = request.mDescriptor.getUuid();
+                cUuid = request.mDescriptor.getCharacteristic().getUuid();
+            }
+            if (UUID_WS_SECURE_UPGRADE_CHARACTERISTIC_CONTROL_POINT.equals(cUuid)
+                    && GATT_DESCRIPTOR_UUID.equals(uuid)) {
+                processControlPointStatus(false, ERROR_TIMEOUT);
+            }
+        }
+    }
+
+    private void connect() {
+        if (!mGatt.connect()) {
+            mEventHandler.sendMessage(mEventHandler.obtainMessage(EVENT_ERROR, mState,
+                    ERROR_CONNECT));
+        } else {
+            mDisconnectOnFinished = true;
+        }
+    }
+
+    private boolean pairIfNeeded() {
+        BluetoothDevice device = mGatt.getDevice();
+
+        if (OtaSettings.PAIRING_REQUIRED && device.getBondState() != BluetoothDevice.BOND_BONDED) {
+            if (DBG) {
+                Log.d(TAG, "Pairing device...");
+            }
+            try {
+                mConnectAfterBonding = true;
+                mEventHandler.sendEmptyMessageDelayed(EVENT_TIMEOUT_PAIRING,
+                        OtaSettings.TIMEOUT_PAIRING_MS);
+                mGatt.pair();
+                return true;
+            } catch (Throwable t) {
+                mConnectAfterBonding = false;
+                Log.e(TAG, "error", t);
+            }
+        }
+        return false;
+    }
+
+    private void onPaired() {
+        if (DBG) {
+            Log.d(TAG, "onPaired");
+        }
+        if (mConnectAfterBonding) {
+            mEventHandler.removeMessages(EVENT_TIMEOUT_PAIRING);
+            mConnectAfterBonding = false;
+            connect();
+        }
+
+    }
+
+    private void unregisterGatt() {
+        if (mGatt != null) {
+            mGatt.removeCallback(this);
+            mGatt.removeTimeoutCallback(this);
+        }
+    }
+
+    // ---------------Public API-----------------------------------------------
+
+    public void addCallback(OtaCallback cb) {
+        mCallback = cb;
+    }
+
+    public void removeCallback(OtaCallback cb) {
+        if (mCallback == cb) {
+            mCallback = null;
+        }
+    }
+
+    public void startUpdate(Context ctx, GattRequestManager gattManager, int firmwareLength,
+            BufferedInputStream in) {
+        mContext = ctx;
+        mBondReceiver = new BluetoothBondingReceiver();
+        mContext.registerReceiver(mBondReceiver, new IntentFilter(
+                BluetoothDevice.ACTION_BOND_STATE_CHANGED));
+        mGatt = gattManager;
+        mGatt.addCallback(this);
+        mGatt.addTimeoutCallback(this);
+
+        mFirmwareLength = firmwareLength;
+        mFirmwareInputStream = in;
+        mState = STATE_NONE;
+        mHasError = false;
+        mFirmwareSendLoopCount = 0;
+        mFirmwareBytesSent = 0;
+        if (mGatt.isConnected()) {
+            if (DBG) {
+                Log.d(TAG, "startUpgrade: GattManager already connected");
+            }
+            if (!loadGattServicesAndCharacteristics()) {
+                if (!mGatt.discoverServices()) {
+                    onServicesDiscovered(mGatt.getGatt(), -600);
+                }
+            } else {
+                enableOtaNotify(true);
+            }
+        } else {
+            if (!pairIfNeeded()) {
+                if (DBG) {
+                    Log.d(TAG, "startUpgrade: connecting...");
+                }
+                connect();
+            }
+        }
+    }
+
+    public void abortUpdate() {
+        mGatt.write(mOtaCharControlPoint, new byte[] { 0x7 });
+        setState(STATE_ABORTED);
+        mEventHandler.sendEmptyMessage(EVENT_ABORTED);
+    }
+
+    public void finish() {
+        mContext.unregisterReceiver(mBondReceiver);
+        unregisterGatt();
+        if (mDisconnectOnFinished) {
+            mGatt.disconnect(true);
+        }
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaSettings.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaSettings.java
index 6c8da76ce874497b75dcf2942e8b590a03ef7d2d..872dc749d5c6a2643fa22bb7a32d54d653271eb8 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaSettings.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/OtaSettings.java
@@ -1,25 +1,25 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota;
-
-public class OtaSettings {
-    public static final boolean DBG = true;
-    public static final String TAG_PREFIX = "WicedSmartOta";
-    public static final boolean PAIRING_REQUIRED = true;
-    public static final int TIMEOUT_PAIRING_MS = 3000;
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota;
+
+public class OtaSettings {
+    public static final boolean DBG = true;
+    public static final String TAG_PREFIX = "WicedSmartOta";
+    public static final boolean PAIRING_REQUIRED = true;
+    public static final int TIMEOUT_PAIRING_MS = 3000;
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaAppInfoFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaAppInfoFragment.java
index ef22bd0373059ba90a5aa4a83ba0fef32a1fc745..2098abb0521d0272a09265d10c1835282f9e0784 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaAppInfoFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaAppInfoFragment.java
@@ -1,115 +1,115 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
- * Also, make sure you include the following in your application
- *
- * values/strings_ota.xml in
- * layout/ota_app_info.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import java.io.File;
-import com.broadcom.app.wicedsmart.ota.OtaAppInfo;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.bluetooth.BluetoothDevice;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnShowListener;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.TextView;
-
-public class OtaAppInfoFragment extends DialogFragment implements OnShowListener {
-
-    public interface Callback {
-        public void onOtaSoftwareSelected(File f);
-
-        public void onOtaCancelled();
-    }
-
-    public static OtaAppInfoFragment createDialog(BluetoothDevice device, OtaAppInfo appInfo) {
-        OtaAppInfoFragment f = new OtaAppInfoFragment();
-        f.mAppInfo = appInfo;
-        f.mDevice = device;
-        return f;
-    }
-
-    public static void setAppInfoWidgets(View rootView, BluetoothDevice device, OtaAppInfo appInfo,
-            String noDeviceValue, String noDeviceNameValue, String unknownValue) {
-        TextView deviceName = (TextView) rootView.findViewById(R.id.ota_device_name);
-        TextView deviceAddress = (TextView) rootView.findViewById(R.id.ota_device_address);
-        TextView appId = (TextView) rootView.findViewById(R.id.ota_app_id);
-        TextView majorVersion = (TextView) rootView.findViewById(R.id.ota_major_version);
-        TextView minorVersion = (TextView) rootView.findViewById(R.id.ota_minor_version);
-        if (device == null) {
-            deviceName.setText(noDeviceValue);
-            deviceAddress.setText("");
-        } else {
-            String name = device.getName();
-            String addr = device.getAddress();
-            if (name == null || name.length() <= 0) {
-                deviceName.setText(noDeviceNameValue);
-            } else {
-                deviceName.setText(name);
-            }
-            deviceAddress.setText(addr);
-        }
-
-        if (appInfo == null) {
-            appId.setText(unknownValue);
-            majorVersion.setText(unknownValue);
-            minorVersion.setText(unknownValue);
-        } else {
-            appId.setText(String.format("0x%x", appInfo.mAppId));
-            majorVersion.setText(String.valueOf(appInfo.mMajorVersion));
-            minorVersion.setText(String.valueOf(appInfo.mMinorVersion));
-        }
-    }
-
-    private OtaAppInfo mAppInfo;
-    private Dialog mDialog;
-    private BluetoothDevice mDevice;
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-
-        AlertDialog.Builder b = new AlertDialog.Builder(getActivity()).setTitle(
-                getString(R.string.ota_app_info_title))
-                .setPositiveButton(R.string.ota_lbl_ok, null);
-        View v = getActivity().getLayoutInflater().inflate(R.layout.ota_app_info, null);
-        b.setView(v);
-        mDialog = b.create();
-        mDialog.setOnShowListener(this);
-
-        return mDialog;
-    }
-
-    @Override
-    public void onShow(DialogInterface d) {
-        TextView deviceName = (TextView) mDialog.findViewById(R.id.ota_device_name);
-
-        setAppInfoWidgets(deviceName.getRootView(), mDevice, mAppInfo,
-                getString(R.string.ota_unknown_value), getString(R.string.ota_unknown_device_name),
-                getString(R.string.ota_unknown_value));
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
+ * Also, make sure you include the following in your application
+ *
+ * values/strings_ota.xml in
+ * layout/ota_app_info.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import java.io.File;
+import com.broadcom.app.wicedsmart.ota.OtaAppInfo;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.bluetooth.BluetoothDevice;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnShowListener;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+
+public class OtaAppInfoFragment extends DialogFragment implements OnShowListener {
+
+    public interface Callback {
+        public void onOtaSoftwareSelected(File f);
+
+        public void onOtaCancelled();
+    }
+
+    public static OtaAppInfoFragment createDialog(BluetoothDevice device, OtaAppInfo appInfo) {
+        OtaAppInfoFragment f = new OtaAppInfoFragment();
+        f.mAppInfo = appInfo;
+        f.mDevice = device;
+        return f;
+    }
+
+    public static void setAppInfoWidgets(View rootView, BluetoothDevice device, OtaAppInfo appInfo,
+            String noDeviceValue, String noDeviceNameValue, String unknownValue) {
+        TextView deviceName = (TextView) rootView.findViewById(R.id.ota_device_name);
+        TextView deviceAddress = (TextView) rootView.findViewById(R.id.ota_device_address);
+        TextView appId = (TextView) rootView.findViewById(R.id.ota_app_id);
+        TextView majorVersion = (TextView) rootView.findViewById(R.id.ota_major_version);
+        TextView minorVersion = (TextView) rootView.findViewById(R.id.ota_minor_version);
+        if (device == null) {
+            deviceName.setText(noDeviceValue);
+            deviceAddress.setText("");
+        } else {
+            String name = device.getName();
+            String addr = device.getAddress();
+            if (name == null || name.length() <= 0) {
+                deviceName.setText(noDeviceNameValue);
+            } else {
+                deviceName.setText(name);
+            }
+            deviceAddress.setText(addr);
+        }
+
+        if (appInfo == null) {
+            appId.setText(unknownValue);
+            majorVersion.setText(unknownValue);
+            minorVersion.setText(unknownValue);
+        } else {
+            appId.setText(String.format("0x%x", appInfo.mAppId));
+            majorVersion.setText(String.valueOf(appInfo.mMajorVersion));
+            minorVersion.setText(String.valueOf(appInfo.mMinorVersion));
+        }
+    }
+
+    private OtaAppInfo mAppInfo;
+    private Dialog mDialog;
+    private BluetoothDevice mDevice;
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+
+        AlertDialog.Builder b = new AlertDialog.Builder(getActivity()).setTitle(
+                getString(R.string.ota_app_info_title))
+                .setPositiveButton(R.string.ota_lbl_ok, null);
+        View v = getActivity().getLayoutInflater().inflate(R.layout.ota_app_info, null);
+        b.setView(v);
+        mDialog = b.create();
+        mDialog.setOnShowListener(this);
+
+        return mDialog;
+    }
+
+    @Override
+    public void onShow(DialogInterface d) {
+        TextView deviceName = (TextView) mDialog.findViewById(R.id.ota_device_name);
+
+        setAppInfoWidgets(deviceName.getRootView(), mDevice, mAppInfo,
+                getString(R.string.ota_unknown_value), getString(R.string.ota_unknown_device_name),
+                getString(R.string.ota_unknown_value));
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaChooserFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaChooserFragment.java
index ed37e7ec17df362b0130b34885d07260059467c1..c99924cb5451d9acb3647dfe4bac8ceff12afc89 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaChooserFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaChooserFragment.java
@@ -1,84 +1,84 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
- * Also, make sure you include the following in your application
- *
- * values/strings_ota.xml in
- * layout/ota_app_info.xml
- */
-import com.broadcom.app.wicedsense.R;
-import java.util.List;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.DialogInterface;
-import android.os.Bundle;
-
-public class OtaChooserFragment extends DialogFragment implements
-        android.content.DialogInterface.OnClickListener {
-
-    public interface Callback {
-        public void onOtaSoftwareSelected(OtaResource f);
-
-        public void onOtaCancelled();
-    }
-
-    public static OtaChooserFragment createDialog(List<OtaResource> otaResources, Callback cb) {
-        OtaChooserFragment f = new OtaChooserFragment();
-        f.mOtaResources = otaResources;
-        f.mCallback = cb;
-        return f;
-    }
-
-    private List<OtaResource> mOtaResources;
-    private OtaResource mSelected;
-    private Callback mCallback;
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-
-        String[] otaResourceNames = new String[mOtaResources == null ? 0 : mOtaResources.size()];
-        for (int i = 0; i < otaResourceNames.length; i++) {
-            otaResourceNames[i] = mOtaResources.get(i).getName();
-        }
-        return new AlertDialog.Builder(getActivity())
-                .setTitle(getString(R.string.ota_chooser_title)).setItems(otaResourceNames, this)
-                .setNegativeButton(R.string.ota_lbl_cancel, null).create();
-    }
-
-    @Override
-    public void onDismiss(DialogInterface dialog) {
-        super.onDismiss(dialog);
-        if (mSelected == null) {
-            if (mCallback != null) {
-                mCallback.onOtaCancelled();
-            }
-        }
-    }
-
-    @Override
-    public void onClick(DialogInterface dialog, int which) {
-        mSelected = mOtaResources.get(which);
-        if (mCallback != null) {
-            mCallback.onOtaSoftwareSelected(mSelected);
-        }
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
+ * Also, make sure you include the following in your application
+ *
+ * values/strings_ota.xml in
+ * layout/ota_app_info.xml
+ */
+import com.broadcom.app.wicedsense.R;
+import java.util.List;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+public class OtaChooserFragment extends DialogFragment implements
+        android.content.DialogInterface.OnClickListener {
+
+    public interface Callback {
+        public void onOtaSoftwareSelected(OtaResource f);
+
+        public void onOtaCancelled();
+    }
+
+    public static OtaChooserFragment createDialog(List<OtaResource> otaResources, Callback cb) {
+        OtaChooserFragment f = new OtaChooserFragment();
+        f.mOtaResources = otaResources;
+        f.mCallback = cb;
+        return f;
+    }
+
+    private List<OtaResource> mOtaResources;
+    private OtaResource mSelected;
+    private Callback mCallback;
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+
+        String[] otaResourceNames = new String[mOtaResources == null ? 0 : mOtaResources.size()];
+        for (int i = 0; i < otaResourceNames.length; i++) {
+            otaResourceNames[i] = mOtaResources.get(i).getName();
+        }
+        return new AlertDialog.Builder(getActivity())
+                .setTitle(getString(R.string.ota_chooser_title)).setItems(otaResourceNames, this)
+                .setNegativeButton(R.string.ota_lbl_cancel, null).create();
+    }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        super.onDismiss(dialog);
+        if (mSelected == null) {
+            if (mCallback != null) {
+                mCallback.onOtaCancelled();
+            }
+        }
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        mSelected = mOtaResources.get(which);
+        if (mCallback != null) {
+            mCallback.onOtaSoftwareSelected(mSelected);
+        }
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaConfirmFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaConfirmFragment.java
index dbd62342176b3aec2ec8386c403a762021891634..d3f3ce72c30e9140861792c3b195420ca1973306 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaConfirmFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaConfirmFragment.java
@@ -1,94 +1,94 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
- * Also, make sure you include the following in your application
- *
- * values/strings_ota.xml in
- * layout/ota_app_info.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import com.broadcom.app.wicedsmart.ota.OtaSettings;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.util.Log;
-
-public class OtaConfirmFragment extends DialogFragment implements
-        android.content.DialogInterface.OnClickListener {
-    public interface Callback {
-        public void onOtaConfirmed();
-
-        public void onOtaCancelled();
-    }
-
-    private static final String TAG = OtaSettings.TAG_PREFIX + "OtaConnectConfirmFragment";
-
-    public static OtaConfirmFragment createDialog(Callback cb, OtaResource resource) {
-        OtaConfirmFragment f = new OtaConfirmFragment();
-        f.mCallback = cb;
-        f.mOtaResource = resource;
-        return f;
-    }
-
-    private Callback mCallback;
-    private boolean mIsOk;
-    private OtaResource mOtaResource;
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        Log.d(TAG, "onCreateDialog()");
-        AlertDialog.Builder b = new AlertDialog.Builder(getActivity())
-                .setMessage(getString(R.string.ota_confirm_msg, mOtaResource.getName()))
-                .setPositiveButton(R.string.ota_lbl_ok, this)
-                .setNegativeButton(R.string.ota_lbl_cancel, this);
-        if (mOtaResource.isMandatory()) {
-            b.setTitle(getString(R.string.ota_dialog_title_mandatory));
-        } else {
-            b.setTitle(getString(R.string.ota_dialog_title_available));
-        }
-        return b.create();
-    }
-
-    @Override
-    public void onClick(DialogInterface dialog, int which) {
-        if (mCallback == null) {
-            return;
-        }
-        if (which == AlertDialog.BUTTON_POSITIVE) {
-            mIsOk = true;
-            mCallback.onOtaConfirmed();
-        }
-    }
-
-    @Override
-    public void onDismiss(DialogInterface dialog) {
-        super.onDismiss(dialog);
-        if (!mIsOk) {
-            if (mCallback != null) {
-                mCallback.onOtaCancelled();
-            }
-        }
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
+ * Also, make sure you include the following in your application
+ *
+ * values/strings_ota.xml in
+ * layout/ota_app_info.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import com.broadcom.app.wicedsmart.ota.OtaSettings;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+
+public class OtaConfirmFragment extends DialogFragment implements
+        android.content.DialogInterface.OnClickListener {
+    public interface Callback {
+        public void onOtaConfirmed();
+
+        public void onOtaCancelled();
+    }
+
+    private static final String TAG = OtaSettings.TAG_PREFIX + "OtaConnectConfirmFragment";
+
+    public static OtaConfirmFragment createDialog(Callback cb, OtaResource resource) {
+        OtaConfirmFragment f = new OtaConfirmFragment();
+        f.mCallback = cb;
+        f.mOtaResource = resource;
+        return f;
+    }
+
+    private Callback mCallback;
+    private boolean mIsOk;
+    private OtaResource mOtaResource;
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Log.d(TAG, "onCreateDialog()");
+        AlertDialog.Builder b = new AlertDialog.Builder(getActivity())
+                .setMessage(getString(R.string.ota_confirm_msg, mOtaResource.getName()))
+                .setPositiveButton(R.string.ota_lbl_ok, this)
+                .setNegativeButton(R.string.ota_lbl_cancel, this);
+        if (mOtaResource.isMandatory()) {
+            b.setTitle(getString(R.string.ota_dialog_title_mandatory));
+        } else {
+            b.setTitle(getString(R.string.ota_dialog_title_available));
+        }
+        return b.create();
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (mCallback == null) {
+            return;
+        }
+        if (which == AlertDialog.BUTTON_POSITIVE) {
+            mIsOk = true;
+            mCallback.onOtaConfirmed();
+        }
+    }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        super.onDismiss(dialog);
+        if (!mIsOk) {
+            if (mCallback != null) {
+                mCallback.onOtaCancelled();
+            }
+        }
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaFinishedFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaFinishedFragment.java
index c0a9d66821360e89b020a80d13722ebe168b3ce4..e3c6978abd8afa8dd5647a8d52250433ca95d10d 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaFinishedFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaFinishedFragment.java
@@ -1,70 +1,70 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
- * Also, make sure you include the following in your application
- *
- * values/strings_ota.xml in
- * layout/ota_app_info.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.DialogInterface;
-import android.os.Bundle;
-
-public class OtaFinishedFragment extends DialogFragment {
-    public interface Callback {
-        public void onOtaFinished(boolean updateComplete);
-    }
-
-    public static OtaFinishedFragment createDialog(Callback cb, String msg, boolean isError,
-            boolean isAbort) {
-        OtaFinishedFragment f = new OtaFinishedFragment();
-        f.mCallback = cb;
-        f.mMessage = msg;
-        f.mIsError = isError;
-        f.mIsAbort = isAbort;
-        return f;
-    }
-
-    private Callback mCallback;
-    private String mMessage;
-    private boolean mIsError;
-    private boolean mIsAbort;
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        return new AlertDialog.Builder(getActivity())
-                .setTitle(getString(R.string.ota_dialog_title)).setMessage(mMessage)
-                .setPositiveButton(R.string.ota_lbl_ok, null).create();
-    }
-
-    @Override
-    public void onDismiss(DialogInterface dialog) {
-        super.onDismiss(dialog);
-        if (mCallback != null) {
-            mCallback.onOtaFinished(!mIsError && !mIsAbort);
-        }
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
+ * Also, make sure you include the following in your application
+ *
+ * values/strings_ota.xml in
+ * layout/ota_app_info.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+public class OtaFinishedFragment extends DialogFragment {
+    public interface Callback {
+        public void onOtaFinished(boolean updateComplete);
+    }
+
+    public static OtaFinishedFragment createDialog(Callback cb, String msg, boolean isError,
+            boolean isAbort) {
+        OtaFinishedFragment f = new OtaFinishedFragment();
+        f.mCallback = cb;
+        f.mMessage = msg;
+        f.mIsError = isError;
+        f.mIsAbort = isAbort;
+        return f;
+    }
+
+    private Callback mCallback;
+    private String mMessage;
+    private boolean mIsError;
+    private boolean mIsAbort;
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        return new AlertDialog.Builder(getActivity())
+                .setTitle(getString(R.string.ota_dialog_title)).setMessage(mMessage)
+                .setPositiveButton(R.string.ota_lbl_ok, null).create();
+    }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        super.onDismiss(dialog);
+        if (mCallback != null) {
+            mCallback.onOtaFinished(!mIsError && !mIsAbort);
+        }
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaNoFirmwareFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaNoFirmwareFragment.java
index b30c5de6f27946d951376324224fc657d486fb05..e045571586b10362cd7b47ab33fc67fa7c766b30 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaNoFirmwareFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaNoFirmwareFragment.java
@@ -1,48 +1,48 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
- * Also, make sure you include the following in your application
- *
- * values/strings_ota.xml in
- * layout/ota_app_info.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.os.Bundle;
-
-public class OtaNoFirmwareFragment extends DialogFragment {
-    public static OtaNoFirmwareFragment createDialog() {
-        OtaNoFirmwareFragment f = new OtaNoFirmwareFragment();
-        return f;
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        return new AlertDialog.Builder(getActivity())
-                .setTitle(getString(R.string.ota_dialog_title))
-                .setMessage(getString(R.string.ota_nofirmware_msg))
-                .setPositiveButton(R.string.ota_lbl_ok, null).create();
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
+ * Also, make sure you include the following in your application
+ *
+ * values/strings_ota.xml in
+ * layout/ota_app_info.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.os.Bundle;
+
+public class OtaNoFirmwareFragment extends DialogFragment {
+    public static OtaNoFirmwareFragment createDialog() {
+        OtaNoFirmwareFragment f = new OtaNoFirmwareFragment();
+        return f;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        return new AlertDialog.Builder(getActivity())
+                .setTitle(getString(R.string.ota_dialog_title))
+                .setMessage(getString(R.string.ota_nofirmware_msg))
+                .setPositiveButton(R.string.ota_lbl_ok, null).create();
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaProgressFragment.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaProgressFragment.java
index a266f5a75bae69e301d63d4f6880a4fad1ac037d..76df52afee0b2667813ab7a762106b2db2c4e281 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaProgressFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaProgressFragment.java
@@ -1,106 +1,106 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
- * Also, make sure you include the following in your application
- *
- * values/strings_ota.xml in
- * layout/ota_app_info.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.ProgressDialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnShowListener;
-import android.os.Bundle;
-
-public class OtaProgressFragment extends DialogFragment implements
-        android.content.DialogInterface.OnClickListener, OnShowListener {
-
-    public interface Callback {
-        public void onOtaProgressDialogShow();
-        public void onOtaCancelled();
-    }
-
-    public static OtaProgressFragment createDialog(Callback cb, String initialMsg) {
-        OtaProgressFragment f = new OtaProgressFragment();
-        f.mCallback = cb;
-        f.mInitialMsg = initialMsg;
-        return f;
-    }
-
-    public ProgressDialog mProgressDialog;
-    private Callback mCallback;
-    private String mInitialMsg;
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        ProgressDialog d = new ProgressDialog(getActivity());
-        d.setTitle(R.string.ota_dialog_progress_title);
-        d.setButton(Dialog.BUTTON_POSITIVE, getString(R.string.ota_lbl_cancel), this);
-        d.setCancelable(false);
-        d.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
-        d.setMax(100);
-        d.setProgress(0);
-        d.setMessage(mInitialMsg == null ? "" : mInitialMsg);
-        mProgressDialog = d;
-        mProgressDialog.setOnShowListener(this);
-        return d;
-    }
-
-    public void setProgressMax(int max) {
-        ProgressDialog d = mProgressDialog;
-        if (d == null)
-            return;
-        d.setMax(max);
-    }
-
-    public void setProgress(int p) {
-        ProgressDialog d = mProgressDialog;
-        if (d == null)
-            return;
-        d.setProgress(p);
-    }
-
-    public void setMessage(String m) {
-        ProgressDialog d = mProgressDialog;
-        if (d == null)
-            return;
-        d.setMessage(m);
-    }
-
-    @Override
-    public void onClick(DialogInterface dialog, int which) {
-        if (which == Dialog.BUTTON_POSITIVE) {
-            if (mCallback != null) {
-                mCallback.onOtaCancelled();
-            }
-        }
-    }
-
-    @Override
-    public void onShow(DialogInterface dialog) {
-        if (mCallback != null) {
-            mCallback.onOtaProgressDialogShow();
-        }
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
+ * Also, make sure you include the following in your application
+ *
+ * values/strings_ota.xml in
+ * layout/ota_app_info.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnShowListener;
+import android.os.Bundle;
+
+public class OtaProgressFragment extends DialogFragment implements
+        android.content.DialogInterface.OnClickListener, OnShowListener {
+
+    public interface Callback {
+        public void onOtaProgressDialogShow();
+        public void onOtaCancelled();
+    }
+
+    public static OtaProgressFragment createDialog(Callback cb, String initialMsg) {
+        OtaProgressFragment f = new OtaProgressFragment();
+        f.mCallback = cb;
+        f.mInitialMsg = initialMsg;
+        return f;
+    }
+
+    public ProgressDialog mProgressDialog;
+    private Callback mCallback;
+    private String mInitialMsg;
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        ProgressDialog d = new ProgressDialog(getActivity());
+        d.setTitle(R.string.ota_dialog_progress_title);
+        d.setButton(Dialog.BUTTON_POSITIVE, getString(R.string.ota_lbl_cancel), this);
+        d.setCancelable(false);
+        d.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+        d.setMax(100);
+        d.setProgress(0);
+        d.setMessage(mInitialMsg == null ? "" : mInitialMsg);
+        mProgressDialog = d;
+        mProgressDialog.setOnShowListener(this);
+        return d;
+    }
+
+    public void setProgressMax(int max) {
+        ProgressDialog d = mProgressDialog;
+        if (d == null)
+            return;
+        d.setMax(max);
+    }
+
+    public void setProgress(int p) {
+        ProgressDialog d = mProgressDialog;
+        if (d == null)
+            return;
+        d.setProgress(p);
+    }
+
+    public void setMessage(String m) {
+        ProgressDialog d = mProgressDialog;
+        if (d == null)
+            return;
+        d.setMessage(m);
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (which == Dialog.BUTTON_POSITIVE) {
+            if (mCallback != null) {
+                mCallback.onOtaCancelled();
+            }
+        }
+    }
+
+    @Override
+    public void onShow(DialogInterface dialog) {
+        if (mCallback != null) {
+            mCallback.onOtaProgressDialogShow();
+        }
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaResource.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaResource.java
index fdac9d2fb8706f99a33f949e47c1198e9586d2c4..4628e45732dafdcd67267198b20f86136159b65d 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaResource.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaResource.java
@@ -1,21 +1,21 @@
-package com.broadcom.app.wicedsmart.ota.ui;
-
-import java.io.InputStream;
-
-public interface OtaResource {
-    public String getName();
-
-    public int getAppId();
-
-    public int getMajor();
-
-    public int getMinor();
-
-    public long getLength();
-
-    public InputStream getStream();
-
-    public void closeStream();
-
-    public boolean isMandatory();
+package com.broadcom.app.wicedsmart.ota.ui;
+
+import java.io.InputStream;
+
+public interface OtaResource {
+    public String getName();
+
+    public int getAppId();
+
+    public int getMajor();
+
+    public int getMinor();
+
+    public long getLength();
+
+    public InputStream getStream();
+
+    public void closeStream();
+
+    public boolean isMandatory();
 }
\ No newline at end of file
diff --git a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaUiHelper.java b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaUiHelper.java
index 617c0f17a5c6036c35a78d90c7cc302e500cdf1b..7830e237a7f97cafa20d3b0b5c6a86f6e7e33ab8 100644
--- a/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaUiHelper.java
+++ b/WicedSense/app/src/main/java/com/broadcom/app/wicedsmart/ota/ui/OtaUiHelper.java
@@ -1,594 +1,594 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.app.wicedsmart.ota.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
- * Also, make sure you include the following in your application
- *
- * values/strings_ota.xml in
- * layout/ota_app_info.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FilenameFilter;
-import java.io.InputStream;
-import java.util.LinkedList;
-import java.util.List;
-
-import android.app.FragmentManager;
-import android.bluetooth.BluetoothDevice;
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import com.broadcom.app.wicedsmart.ota.OtaSettings;
-import com.broadcom.app.wicedsmart.ota.OtaManager;
-import com.broadcom.app.wicedsmart.ota.OtaCallback;
-import com.broadcom.util.GattRequestManager;
-
-public class OtaUiHelper implements com.broadcom.app.wicedsmart.ota.ui.OtaChooserFragment.Callback,
-        OtaConfirmFragment.Callback, OtaCallback,
-        com.broadcom.app.wicedsmart.ota.ui.OtaFinishedFragment.Callback,
-        com.broadcom.app.wicedsmart.ota.ui.OtaProgressFragment.Callback {
-    private static final String TAG = OtaSettings.TAG_PREFIX + "OtaUiHelper";
-
-    private static final String FRAG_OTA_PICK = "ota_pick";
-    private static final String FRAG_OTA_CONFIRM = "ota_confirm";
-    private static final String FRAG_OTA_PROGRESS = "ota_progress";
-    private static final String FRAG_OTA_FINISHED = "ota_finished";
-
-    private static class RawOtaResource implements OtaResource {
-        private final String mName;
-        private final Resources mResources;
-        private final int mResourceId;
-        private long mLength;
-        private InputStream mInputStream;
-        private final int mAppId;
-        private final int mMajor;
-        private final int mMinor;
-        private final boolean mMandatory;
-
-        public RawOtaResource(String name, int appId, int major, int minor, Resources resources,
-                int resourceId, boolean mandatory) {
-            mAppId = appId;
-            mName = name;
-            mResources = resources;
-            mResourceId = resourceId;
-            mMandatory = mandatory;
-            InputStream i = getStream();
-            try {
-                // Calculate the length
-                int length = 0;
-                if (i != null) {
-                    while (i.read() >= 0) {
-                        length++;
-                    }
-                }
-                mLength = length;
-            } catch (Throwable t) {
-                Log.d(TAG, "RawOtaResource(): error opening resource " + mResourceId, t);
-                throw new RuntimeException();
-            }
-            Log.d(TAG, "length = " + mLength);
-            closeStream();
-            mMajor = major;
-            mMinor = minor;
-        }
-
-        @Override
-        public String getName() {
-            return mName;
-        }
-
-        @Override
-        public int getAppId() {
-            return mAppId;
-        }
-
-        @Override
-        public int getMajor() {
-            return mMajor;
-        }
-
-        @Override
-        public int getMinor() {
-            return mMinor;
-        }
-
-        @Override
-        public long getLength() {
-            return mLength;
-        }
-
-        @Override
-        public boolean isMandatory() {
-            return mMandatory;
-        }
-
-        @Override
-        public InputStream getStream() {
-            try {
-                return mInputStream = mResources.openRawResource(mResourceId);
-            } catch (Throwable t) {
-
-            }
-            return null;
-        }
-
-        @Override
-        public void closeStream() {
-            if (mInputStream != null) {
-                try {
-                    mInputStream.close();
-                    mInputStream = null;
-                } catch (Throwable t) {
-                }
-            }
-        }
-    }
-
-    private static class FileOtaResource implements OtaResource {
-        File mOtaFile;
-        FileInputStream mFileStream;
-
-        private FileOtaResource(File otaFile) {
-            mOtaFile = otaFile;
-        }
-
-        @Override
-        public String getName() {
-            return mOtaFile.getName();
-        }
-
-        @Override
-        public long getLength() {
-            return mOtaFile.length();
-        }
-
-        @Override
-        public InputStream getStream() {
-            try {
-                mFileStream = new FileInputStream(mOtaFile);
-                return mFileStream;
-            } catch (Throwable t) {
-            }
-            return null;
-        }
-
-        @Override
-        public void closeStream() {
-            if (mFileStream != null) {
-                try {
-                    mFileStream.close();
-                    mFileStream = null;
-                } catch (Throwable t) {
-                }
-            }
-        }
-
-        @Override
-        public int getAppId() {
-            return 0;
-        }
-
-        @Override
-        public int getMajor() {
-            return 0;
-        }
-
-        @Override
-        public int getMinor() {
-            return 0;
-        }
-
-        @Override
-        public boolean isMandatory() {
-            return false;
-        }
-    }
-
-    public static interface OtaUiCallback {
-        public void onOtaFinished(boolean completed);
-    }
-
-    public static OtaResource createRawOtaResource(String name, int appId, int major, int minor,
-            Resources resources, int resourceId, boolean mandatory) {
-        return new RawOtaResource(name, appId, major, minor, resources, resourceId, mandatory);
-    }
-
-    public static void createOtaResources(File fwDirectory, FilenameFilter filter,
-            List<OtaResource> resources) {
-        File[] fwFiles = null;
-
-        if (fwDirectory != null && fwDirectory.isDirectory()) {
-            if (filter == null) {
-                fwFiles = fwDirectory.listFiles();
-            } else {
-                fwFiles = fwDirectory.listFiles(filter);
-            }
-        }
-        if (fwFiles != null && fwFiles.length > 0) {
-            for (int i = 0; i < fwFiles.length; i++) {
-                FileOtaResource r = new FileOtaResource(fwFiles[i]);
-                if (resources != null) {
-                    resources.add(r);
-                }
-            }
-        }
-    }
-
-    private Context mContext;
-    private GattRequestManager mGatt;
-    private FragmentManager mFragMgr;
-    private final LinkedList<OtaResource> mOtaResources = new LinkedList<OtaResource>();
-
-    private BluetoothDevice mDevice;
-    private OtaUiCallback mCallback;
-    private OtaConfirmFragment mConnectConfirmFragment;
-    private OtaProgressFragment mProgressFragment;
-    private boolean mShowProgressDialog = true;
-    private boolean mShowFinishedDialog = true;
-    private int mLastOtaState;
-    private boolean mDownloadProgressStarted;
-    private OtaManager mOtaManager;
-    private OtaResource mSelectedResource;
-    private boolean mDisconnectOnFinished;
-
-    private void reset() {
-        mOtaResources.clear();
-        mDevice = null;
-        mCallback = null;
-        mProgressFragment = null;
-        mShowProgressDialog = true;
-        mShowFinishedDialog = true;
-        mLastOtaState = 0;
-        mDownloadProgressStarted = false;
-        mOtaManager = null;
-        mSelectedResource = null;
-    }
-
-    private void showFinishedDialog(String msg, boolean error, boolean abort) {
-        if (mProgressFragment != null) {
-            mProgressFragment.dismiss();
-            mProgressFragment = null;
-        }
-        if (mShowFinishedDialog) {
-            OtaFinishedFragment mFinishedFragment = OtaFinishedFragment.createDialog(this, msg,
-                    error, abort);
-            mFinishedFragment.show(mFragMgr, FRAG_OTA_FINISHED);
-        } else {
-            onOtaFinished(!error & !abort);
-        }
-    }
-
-    private void getSelectedFirmware() {
-        if (mOtaResources != null && mOtaResources.size() > 0) {
-            if (mOtaResources.size() == 1) {
-                onOtaSoftwareSelected(mOtaResources.get(0));
-            } else {
-                // Show chooser
-                OtaChooserFragment.createDialog(mOtaResources, this).show(mFragMgr, FRAG_OTA_PICK);
-            }
-            return;
-        }
-        // Show no firmware dialog
-        showFinishedDialog(mContext.getString(R.string.ota_nofirmware_msg), true, false);
-    }
-
-    @Override
-    public void onOtaSoftwareSelected(OtaResource r) {
-        mSelectedResource = r;
-        showConfirm();
-    }
-
-    @Override
-    public void onOtaProgressDialogShow() {
-        startUpdate();
-    }
-
-    private boolean mIsConfirmDone;
-
-    private void showConfirm() {
-        mConnectConfirmFragment = OtaConfirmFragment.createDialog(this, mSelectedResource);
-        mConnectConfirmFragment.show(mFragMgr, FRAG_OTA_CONFIRM);
-    }
-
-    @Override
-    public void onOtaConfirmed() {
-        mIsConfirmDone = true;
-        initUpdate();
-    }
-
-    private void initUpdate() {
-        if (mShowProgressDialog) {
-            mProgressFragment = OtaProgressFragment.createDialog(this,
-                    mContext.getString(R.string.ota_dialog_progress_msg_starting));
-            mProgressFragment.show(mFragMgr, FRAG_OTA_PROGRESS);
-        } else {
-            startUpdate();
-        }
-    }
-
-    private void startUpdate() {
-        Log.d(TAG, "startUpdate: selected resource = " + mSelectedResource);
-        if (mSelectedResource == null) {
-            showFinishedDialog(mContext.getString(R.string.ota_error_fw_open_error), true, false);
-            return;
-        }
-        // Create a Gatt Instance
-        if (mGatt == null) {
-            mGatt = new GattRequestManager(mContext, mDevice);
-        }
-        BufferedInputStream in = null;
-        long fwSizeBytes = 0;
-        try {
-            in = new BufferedInputStream(mSelectedResource.getStream());
-            fwSizeBytes = mSelectedResource.getLength();
-            // Create OtaManager instance
-            mOtaManager = new OtaManager();
-            mOtaManager.setDisconnectOnFinished(mDisconnectOnFinished);
-            mOtaManager.addCallback(this);
-            Log.d(TAG, "Starting update: size=" + fwSizeBytes);
-            // Start upgrade
-            mOtaManager.startUpdate(mContext, mGatt, (int) fwSizeBytes, in);
-        } catch (Throwable t) {
-            Log.e(TAG, "startUpdate(): error", t);
-            showFinishedDialog(mContext.getString(R.string.ota_error_fw_open_error), true, false);
-        }
-
-    }
-
-    @Override
-    public void onOtaStateChanged(int state) {
-        Log.d(TAG, "onOtaStateChanged: state= " + state + "(" + OtaManager.getStateString(state)
-                + ")");
-
-        if (mProgressFragment == null || mLastOtaState == state) {
-            Log.d(TAG, "onOtaStateChanged: same state...ignoring...");
-            return;
-        }
-        mLastOtaState = state;
-        switch (state) {
-        case OtaManager.STATE_CONNECT:
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_connecting));
-            break;
-        case OtaManager.STATE_DISCOVER:
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_discovering));
-            break;
-        case OtaManager.STATE_ENABLE_NOTIFY:
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_enablenotify));
-            break;
-
-        case OtaManager.STATE_PREPARE_DOWNLOAD:
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_preparing));
-            break;
-        case OtaManager.STATE_START_DOWNLOAD:
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_enablenotify));
-            break;
-        case OtaManager.STATE_SEND_FW_INFO:
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_send_fw_info));
-            break;
-        case OtaManager.STATE_SEND_FW:
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_send_fw));
-            break;
-        case OtaManager.STATE_VERIFY_FW:
-            mProgressFragment.setProgress(mProgressFragment.mProgressDialog.getMax());
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_verify_fw));
-            break;
-        case OtaManager.STATE_UPGRADE_COMPLETED:
-            showFinishedDialog(mContext.getString(R.string.ota_dialog_completed), false, false);
-            break;
-        default:
-        }
-    }
-
-    @Override
-    public void onOtaError(int currentState, int statusCode) {
-        Log.d(TAG,
-                "onOtaError: currentState= " + currentState + "("
-                        + OtaManager.getStateString(currentState) + "), status="
-                        + OtaManager.getStatusString(statusCode));
-
-        String message = null;
-        String status = OtaManager.getStatusString(statusCode);
-        switch (statusCode) {
-        case OtaManager.WS_UPGRADE_STATUS_UNSUPPORTED_COMMAND:
-        case OtaManager.WS_UPGRADE_STATUS_ILLEGAL_STATE:
-        case OtaManager.ERROR_SERVICE:
-        case OtaManager.ERROR_DESCRIPTOR_WRITE:
-        case OtaManager.ERROR_DESCRIPTOR_NOT_FOUND:
-            message = mContext.getString(R.string.ota_error_internal, status);
-            break;
-        case OtaManager.ERROR_CONNECT:
-            message = mContext.getString(R.string.ota_error_connect);
-            break;
-        case OtaManager.ERROR_DISCOVER:
-            message = mContext.getString(R.string.ota_error_discover);
-            break;
-        case OtaManager.ERROR_TIMEOUT:
-            message = mContext.getString(R.string.ota_error_timeout,
-                    OtaManager.getStatusString(statusCode));
-            break;
-        case OtaManager.ERROR_CHARACTERISTIC_WRITE:
-            message = mContext.getString(R.string.ota_error_write_char);
-            break;
-
-        case OtaManager.ERROR_FIRMWARE_INFO_WRITE:
-            message = mContext.getString(R.string.ota_error_write_fw_info);
-
-            break;
-        case OtaManager.ERROR_FIRMWARE_WRITE:
-            message = mContext.getString(R.string.ota_error_write_fw);
-
-            break;
-
-        case OtaManager.ERROR_FIRMWARE_INFO_READ:
-        case OtaManager.WS_UPGRADE_STATUS_INVALID_APPID:
-        case OtaManager.WS_UPGRADE_STATUS_INVALID_VERSION:
-        case OtaManager.WS_UPGRADE_WRITE_STATUS_BAD_ID:
-        case OtaManager.WS_UPGRADE_WRITE_STATUS_BAD_MAJOR:
-            message = mContext.getString(R.string.ota_error_bad_fw_info, status);
-            break;
-        case OtaManager.ERROR_FIRMWARE_READ:
-        case OtaManager.WS_UPGRADE_STATUS_INVALID_IMAGE:
-        case OtaManager.WS_UPGRADE_STATUS_INVALID_IMAGE_SIZE:
-        case OtaManager.WS_UPGRADE_WRITE_STATUS_TOO_MUCH_DATA:
-        case OtaManager.WS_UPGRADE_WRITE_STATUS_TOO_SHORT:
-            message = mContext.getString(R.string.ota_error_bad_fw, status);
-            break;
-        case OtaManager.WS_UPGRADE_STATUS_VERIFICATION_FAILED:
-            message = mContext.getString(R.string.ota_error_fw_validate_error, status);
-            break;
-        }
-        showFinishedDialog(message, true, false);
-
-    }
-
-    @Override
-    public void onOtaUploadProgress(int loopCount, int bytesCurrent, int bytesTotal) {
-        Log.d(TAG, "onOtaDownload: loopCount= " + loopCount + ", bytesCurrent=" + bytesCurrent
-                + ", bytesTotal=" + bytesTotal);
-        if (mProgressFragment != null) {
-            if (!mDownloadProgressStarted) {
-                mProgressFragment.setProgressMax(bytesTotal);
-                mDownloadProgressStarted = true;
-                mProgressFragment.setProgress(1);
-            }
-            mProgressFragment.setMessage(mContext
-                    .getString(R.string.ota_dialog_progress_msg_send_fw));
-            mProgressFragment.setProgress(bytesCurrent);
-        }
-    }
-
-    @Override
-    public void onOtaCancelled() {
-        if (!mIsConfirmDone) {
-            onOtaFinished(false);
-        } else {
-            abortUpdate();
-        }
-    }
-
-    @Override
-    public void onOtaAborted() {
-        showFinishedDialog(mContext.getString(R.string.ota_aborted), true, true);
-    }
-
-    @Override
-    public void onOtaFinished(boolean isComplete) {
-        if (mSelectedResource != null) {
-            mSelectedResource.closeStream();
-        }
-        // Make call back into app that launched this helper
-        if (mCallback != null) {
-            mCallback.onOtaFinished(isComplete);
-        }
-    }
-
-    // ----------------Public APIs---------------------------------------------
-
-    public void setOptionShowFinishedDialog(boolean showFinished) {
-        mShowFinishedDialog = showFinished;
-    }
-
-    public void setOptionShowProgressDialog(boolean showProgress) {
-        mShowProgressDialog = showProgress;
-    }
-
-    /**
-     * Start OTA update for specified name and strem
-     *
-     * @param ctx
-     * @param device
-     * @param gattMgr
-     * @param fragManager
-     * @param otaName
-     * @param inputStream
-     * @param fwSize
-     * @param cb
-     */
-    public void startUpdate(Context ctx, BluetoothDevice device, GattRequestManager gattMgr,
-            FragmentManager fragManager, OtaResource otaResource, OtaUiCallback cb,
-            boolean disconnectOnFinish) {
-        LinkedList<OtaResource> resources = null;
-        if (otaResource != null) {
-            resources = new LinkedList<OtaResource>();
-            resources.add(otaResource);
-        }
-        startUpdate(ctx, device, gattMgr, fragManager, resources, cb, disconnectOnFinish);
-    }
-
-    /**
-     * Ask user which OTA file they want to upgrade to
-     *
-     * @param ctx
-     * @param device
-     * @param gattMgr
-     * @param fragManager
-     * @param fwDirectory
-     * @param fwFileFilter
-     * @param cb
-     */
-    public void startUpdate(Context ctx, BluetoothDevice device, GattRequestManager gattMgr,
-            FragmentManager fragManager, List<OtaResource> otaResources, OtaUiCallback cb,
-            boolean disconnectOnFinish) {
-        reset();
-        mDisconnectOnFinished = disconnectOnFinish;
-        mGatt = gattMgr;
-        mDevice = device;
-        if (mGatt == null && mDevice == null) {
-            return;
-        }
-        mContext = ctx;
-        mCallback = cb;
-        mFragMgr = fragManager;
-        mOtaResources.clear();
-        if (otaResources != null) {
-            mOtaResources.addAll(otaResources);
-        }
-        getSelectedFirmware();
-
-    }
-
-    public void abortUpdate() {
-        if (mOtaManager != null) {
-            mOtaManager.abortUpdate();
-        } else {
-            onOtaAborted();
-        }
-    }
-
-    public void finish() {
-        mFragMgr = null;
-        if (mOtaManager != null) {
-            mOtaManager.finish();
-        }
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.app.wicedsmart.ota.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application if you embed OTA in your app
+ * Also, make sure you include the following in your application
+ *
+ * values/strings_ota.xml in
+ * layout/ota_app_info.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.InputStream;
+import java.util.LinkedList;
+import java.util.List;
+
+import android.app.FragmentManager;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+import com.broadcom.app.wicedsmart.ota.OtaSettings;
+import com.broadcom.app.wicedsmart.ota.OtaManager;
+import com.broadcom.app.wicedsmart.ota.OtaCallback;
+import com.broadcom.util.GattRequestManager;
+
+public class OtaUiHelper implements com.broadcom.app.wicedsmart.ota.ui.OtaChooserFragment.Callback,
+        OtaConfirmFragment.Callback, OtaCallback,
+        com.broadcom.app.wicedsmart.ota.ui.OtaFinishedFragment.Callback,
+        com.broadcom.app.wicedsmart.ota.ui.OtaProgressFragment.Callback {
+    private static final String TAG = OtaSettings.TAG_PREFIX + "OtaUiHelper";
+
+    private static final String FRAG_OTA_PICK = "ota_pick";
+    private static final String FRAG_OTA_CONFIRM = "ota_confirm";
+    private static final String FRAG_OTA_PROGRESS = "ota_progress";
+    private static final String FRAG_OTA_FINISHED = "ota_finished";
+
+    private static class RawOtaResource implements OtaResource {
+        private final String mName;
+        private final Resources mResources;
+        private final int mResourceId;
+        private long mLength;
+        private InputStream mInputStream;
+        private final int mAppId;
+        private final int mMajor;
+        private final int mMinor;
+        private final boolean mMandatory;
+
+        public RawOtaResource(String name, int appId, int major, int minor, Resources resources,
+                int resourceId, boolean mandatory) {
+            mAppId = appId;
+            mName = name;
+            mResources = resources;
+            mResourceId = resourceId;
+            mMandatory = mandatory;
+            InputStream i = getStream();
+            try {
+                // Calculate the length
+                int length = 0;
+                if (i != null) {
+                    while (i.read() >= 0) {
+                        length++;
+                    }
+                }
+                mLength = length;
+            } catch (Throwable t) {
+                Log.d(TAG, "RawOtaResource(): error opening resource " + mResourceId, t);
+                throw new RuntimeException();
+            }
+            Log.d(TAG, "length = " + mLength);
+            closeStream();
+            mMajor = major;
+            mMinor = minor;
+        }
+
+        @Override
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public int getAppId() {
+            return mAppId;
+        }
+
+        @Override
+        public int getMajor() {
+            return mMajor;
+        }
+
+        @Override
+        public int getMinor() {
+            return mMinor;
+        }
+
+        @Override
+        public long getLength() {
+            return mLength;
+        }
+
+        @Override
+        public boolean isMandatory() {
+            return mMandatory;
+        }
+
+        @Override
+        public InputStream getStream() {
+            try {
+                return mInputStream = mResources.openRawResource(mResourceId);
+            } catch (Throwable t) {
+
+            }
+            return null;
+        }
+
+        @Override
+        public void closeStream() {
+            if (mInputStream != null) {
+                try {
+                    mInputStream.close();
+                    mInputStream = null;
+                } catch (Throwable t) {
+                }
+            }
+        }
+    }
+
+    private static class FileOtaResource implements OtaResource {
+        File mOtaFile;
+        FileInputStream mFileStream;
+
+        private FileOtaResource(File otaFile) {
+            mOtaFile = otaFile;
+        }
+
+        @Override
+        public String getName() {
+            return mOtaFile.getName();
+        }
+
+        @Override
+        public long getLength() {
+            return mOtaFile.length();
+        }
+
+        @Override
+        public InputStream getStream() {
+            try {
+                mFileStream = new FileInputStream(mOtaFile);
+                return mFileStream;
+            } catch (Throwable t) {
+            }
+            return null;
+        }
+
+        @Override
+        public void closeStream() {
+            if (mFileStream != null) {
+                try {
+                    mFileStream.close();
+                    mFileStream = null;
+                } catch (Throwable t) {
+                }
+            }
+        }
+
+        @Override
+        public int getAppId() {
+            return 0;
+        }
+
+        @Override
+        public int getMajor() {
+            return 0;
+        }
+
+        @Override
+        public int getMinor() {
+            return 0;
+        }
+
+        @Override
+        public boolean isMandatory() {
+            return false;
+        }
+    }
+
+    public static interface OtaUiCallback {
+        public void onOtaFinished(boolean completed);
+    }
+
+    public static OtaResource createRawOtaResource(String name, int appId, int major, int minor,
+            Resources resources, int resourceId, boolean mandatory) {
+        return new RawOtaResource(name, appId, major, minor, resources, resourceId, mandatory);
+    }
+
+    public static void createOtaResources(File fwDirectory, FilenameFilter filter,
+            List<OtaResource> resources) {
+        File[] fwFiles = null;
+
+        if (fwDirectory != null && fwDirectory.isDirectory()) {
+            if (filter == null) {
+                fwFiles = fwDirectory.listFiles();
+            } else {
+                fwFiles = fwDirectory.listFiles(filter);
+            }
+        }
+        if (fwFiles != null && fwFiles.length > 0) {
+            for (int i = 0; i < fwFiles.length; i++) {
+                FileOtaResource r = new FileOtaResource(fwFiles[i]);
+                if (resources != null) {
+                    resources.add(r);
+                }
+            }
+        }
+    }
+
+    private Context mContext;
+    private GattRequestManager mGatt;
+    private FragmentManager mFragMgr;
+    private final LinkedList<OtaResource> mOtaResources = new LinkedList<OtaResource>();
+
+    private BluetoothDevice mDevice;
+    private OtaUiCallback mCallback;
+    private OtaConfirmFragment mConnectConfirmFragment;
+    private OtaProgressFragment mProgressFragment;
+    private boolean mShowProgressDialog = true;
+    private boolean mShowFinishedDialog = true;
+    private int mLastOtaState;
+    private boolean mDownloadProgressStarted;
+    private OtaManager mOtaManager;
+    private OtaResource mSelectedResource;
+    private boolean mDisconnectOnFinished;
+
+    private void reset() {
+        mOtaResources.clear();
+        mDevice = null;
+        mCallback = null;
+        mProgressFragment = null;
+        mShowProgressDialog = true;
+        mShowFinishedDialog = true;
+        mLastOtaState = 0;
+        mDownloadProgressStarted = false;
+        mOtaManager = null;
+        mSelectedResource = null;
+    }
+
+    private void showFinishedDialog(String msg, boolean error, boolean abort) {
+        if (mProgressFragment != null) {
+            mProgressFragment.dismiss();
+            mProgressFragment = null;
+        }
+        if (mShowFinishedDialog) {
+            OtaFinishedFragment mFinishedFragment = OtaFinishedFragment.createDialog(this, msg,
+                    error, abort);
+            mFinishedFragment.show(mFragMgr, FRAG_OTA_FINISHED);
+        } else {
+            onOtaFinished(!error & !abort);
+        }
+    }
+
+    private void getSelectedFirmware() {
+        if (mOtaResources != null && mOtaResources.size() > 0) {
+            if (mOtaResources.size() == 1) {
+                onOtaSoftwareSelected(mOtaResources.get(0));
+            } else {
+                // Show chooser
+                OtaChooserFragment.createDialog(mOtaResources, this).show(mFragMgr, FRAG_OTA_PICK);
+            }
+            return;
+        }
+        // Show no firmware dialog
+        showFinishedDialog(mContext.getString(R.string.ota_nofirmware_msg), true, false);
+    }
+
+    @Override
+    public void onOtaSoftwareSelected(OtaResource r) {
+        mSelectedResource = r;
+        showConfirm();
+    }
+
+    @Override
+    public void onOtaProgressDialogShow() {
+        startUpdate();
+    }
+
+    private boolean mIsConfirmDone;
+
+    private void showConfirm() {
+        mConnectConfirmFragment = OtaConfirmFragment.createDialog(this, mSelectedResource);
+        mConnectConfirmFragment.show(mFragMgr, FRAG_OTA_CONFIRM);
+    }
+
+    @Override
+    public void onOtaConfirmed() {
+        mIsConfirmDone = true;
+        initUpdate();
+    }
+
+    private void initUpdate() {
+        if (mShowProgressDialog) {
+            mProgressFragment = OtaProgressFragment.createDialog(this,
+                    mContext.getString(R.string.ota_dialog_progress_msg_starting));
+            mProgressFragment.show(mFragMgr, FRAG_OTA_PROGRESS);
+        } else {
+            startUpdate();
+        }
+    }
+
+    private void startUpdate() {
+        Log.d(TAG, "startUpdate: selected resource = " + mSelectedResource);
+        if (mSelectedResource == null) {
+            showFinishedDialog(mContext.getString(R.string.ota_error_fw_open_error), true, false);
+            return;
+        }
+        // Create a Gatt Instance
+        if (mGatt == null) {
+            mGatt = new GattRequestManager(mContext, mDevice);
+        }
+        BufferedInputStream in = null;
+        long fwSizeBytes = 0;
+        try {
+            in = new BufferedInputStream(mSelectedResource.getStream());
+            fwSizeBytes = mSelectedResource.getLength();
+            // Create OtaManager instance
+            mOtaManager = new OtaManager();
+            mOtaManager.setDisconnectOnFinished(mDisconnectOnFinished);
+            mOtaManager.addCallback(this);
+            Log.d(TAG, "Starting update: size=" + fwSizeBytes);
+            // Start upgrade
+            mOtaManager.startUpdate(mContext, mGatt, (int) fwSizeBytes, in);
+        } catch (Throwable t) {
+            Log.e(TAG, "startUpdate(): error", t);
+            showFinishedDialog(mContext.getString(R.string.ota_error_fw_open_error), true, false);
+        }
+
+    }
+
+    @Override
+    public void onOtaStateChanged(int state) {
+        Log.d(TAG, "onOtaStateChanged: state= " + state + "(" + OtaManager.getStateString(state)
+                + ")");
+
+        if (mProgressFragment == null || mLastOtaState == state) {
+            Log.d(TAG, "onOtaStateChanged: same state...ignoring...");
+            return;
+        }
+        mLastOtaState = state;
+        switch (state) {
+        case OtaManager.STATE_CONNECT:
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_connecting));
+            break;
+        case OtaManager.STATE_DISCOVER:
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_discovering));
+            break;
+        case OtaManager.STATE_ENABLE_NOTIFY:
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_enablenotify));
+            break;
+
+        case OtaManager.STATE_PREPARE_DOWNLOAD:
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_preparing));
+            break;
+        case OtaManager.STATE_START_DOWNLOAD:
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_enablenotify));
+            break;
+        case OtaManager.STATE_SEND_FW_INFO:
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_send_fw_info));
+            break;
+        case OtaManager.STATE_SEND_FW:
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_send_fw));
+            break;
+        case OtaManager.STATE_VERIFY_FW:
+            mProgressFragment.setProgress(mProgressFragment.mProgressDialog.getMax());
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_verify_fw));
+            break;
+        case OtaManager.STATE_UPGRADE_COMPLETED:
+            showFinishedDialog(mContext.getString(R.string.ota_dialog_completed), false, false);
+            break;
+        default:
+        }
+    }
+
+    @Override
+    public void onOtaError(int currentState, int statusCode) {
+        Log.d(TAG,
+                "onOtaError: currentState= " + currentState + "("
+                        + OtaManager.getStateString(currentState) + "), status="
+                        + OtaManager.getStatusString(statusCode));
+
+        String message = null;
+        String status = OtaManager.getStatusString(statusCode);
+        switch (statusCode) {
+        case OtaManager.WS_UPGRADE_STATUS_UNSUPPORTED_COMMAND:
+        case OtaManager.WS_UPGRADE_STATUS_ILLEGAL_STATE:
+        case OtaManager.ERROR_SERVICE:
+        case OtaManager.ERROR_DESCRIPTOR_WRITE:
+        case OtaManager.ERROR_DESCRIPTOR_NOT_FOUND:
+            message = mContext.getString(R.string.ota_error_internal, status);
+            break;
+        case OtaManager.ERROR_CONNECT:
+            message = mContext.getString(R.string.ota_error_connect);
+            break;
+        case OtaManager.ERROR_DISCOVER:
+            message = mContext.getString(R.string.ota_error_discover);
+            break;
+        case OtaManager.ERROR_TIMEOUT:
+            message = mContext.getString(R.string.ota_error_timeout,
+                    OtaManager.getStatusString(statusCode));
+            break;
+        case OtaManager.ERROR_CHARACTERISTIC_WRITE:
+            message = mContext.getString(R.string.ota_error_write_char);
+            break;
+
+        case OtaManager.ERROR_FIRMWARE_INFO_WRITE:
+            message = mContext.getString(R.string.ota_error_write_fw_info);
+
+            break;
+        case OtaManager.ERROR_FIRMWARE_WRITE:
+            message = mContext.getString(R.string.ota_error_write_fw);
+
+            break;
+
+        case OtaManager.ERROR_FIRMWARE_INFO_READ:
+        case OtaManager.WS_UPGRADE_STATUS_INVALID_APPID:
+        case OtaManager.WS_UPGRADE_STATUS_INVALID_VERSION:
+        case OtaManager.WS_UPGRADE_WRITE_STATUS_BAD_ID:
+        case OtaManager.WS_UPGRADE_WRITE_STATUS_BAD_MAJOR:
+            message = mContext.getString(R.string.ota_error_bad_fw_info, status);
+            break;
+        case OtaManager.ERROR_FIRMWARE_READ:
+        case OtaManager.WS_UPGRADE_STATUS_INVALID_IMAGE:
+        case OtaManager.WS_UPGRADE_STATUS_INVALID_IMAGE_SIZE:
+        case OtaManager.WS_UPGRADE_WRITE_STATUS_TOO_MUCH_DATA:
+        case OtaManager.WS_UPGRADE_WRITE_STATUS_TOO_SHORT:
+            message = mContext.getString(R.string.ota_error_bad_fw, status);
+            break;
+        case OtaManager.WS_UPGRADE_STATUS_VERIFICATION_FAILED:
+            message = mContext.getString(R.string.ota_error_fw_validate_error, status);
+            break;
+        }
+        showFinishedDialog(message, true, false);
+
+    }
+
+    @Override
+    public void onOtaUploadProgress(int loopCount, int bytesCurrent, int bytesTotal) {
+        Log.d(TAG, "onOtaDownload: loopCount= " + loopCount + ", bytesCurrent=" + bytesCurrent
+                + ", bytesTotal=" + bytesTotal);
+        if (mProgressFragment != null) {
+            if (!mDownloadProgressStarted) {
+                mProgressFragment.setProgressMax(bytesTotal);
+                mDownloadProgressStarted = true;
+                mProgressFragment.setProgress(1);
+            }
+            mProgressFragment.setMessage(mContext
+                    .getString(R.string.ota_dialog_progress_msg_send_fw));
+            mProgressFragment.setProgress(bytesCurrent);
+        }
+    }
+
+    @Override
+    public void onOtaCancelled() {
+        if (!mIsConfirmDone) {
+            onOtaFinished(false);
+        } else {
+            abortUpdate();
+        }
+    }
+
+    @Override
+    public void onOtaAborted() {
+        showFinishedDialog(mContext.getString(R.string.ota_aborted), true, true);
+    }
+
+    @Override
+    public void onOtaFinished(boolean isComplete) {
+        if (mSelectedResource != null) {
+            mSelectedResource.closeStream();
+        }
+        // Make call back into app that launched this helper
+        if (mCallback != null) {
+            mCallback.onOtaFinished(isComplete);
+        }
+    }
+
+    // ----------------Public APIs---------------------------------------------
+
+    public void setOptionShowFinishedDialog(boolean showFinished) {
+        mShowFinishedDialog = showFinished;
+    }
+
+    public void setOptionShowProgressDialog(boolean showProgress) {
+        mShowProgressDialog = showProgress;
+    }
+
+    /**
+     * Start OTA update for specified name and strem
+     *
+     * @param ctx
+     * @param device
+     * @param gattMgr
+     * @param fragManager
+     * @param otaName
+     * @param inputStream
+     * @param fwSize
+     * @param cb
+     */
+    public void startUpdate(Context ctx, BluetoothDevice device, GattRequestManager gattMgr,
+            FragmentManager fragManager, OtaResource otaResource, OtaUiCallback cb,
+            boolean disconnectOnFinish) {
+        LinkedList<OtaResource> resources = null;
+        if (otaResource != null) {
+            resources = new LinkedList<OtaResource>();
+            resources.add(otaResource);
+        }
+        startUpdate(ctx, device, gattMgr, fragManager, resources, cb, disconnectOnFinish);
+    }
+
+    /**
+     * Ask user which OTA file they want to upgrade to
+     *
+     * @param ctx
+     * @param device
+     * @param gattMgr
+     * @param fragManager
+     * @param fwDirectory
+     * @param fwFileFilter
+     * @param cb
+     */
+    public void startUpdate(Context ctx, BluetoothDevice device, GattRequestManager gattMgr,
+            FragmentManager fragManager, List<OtaResource> otaResources, OtaUiCallback cb,
+            boolean disconnectOnFinish) {
+        reset();
+        mDisconnectOnFinished = disconnectOnFinish;
+        mGatt = gattMgr;
+        mDevice = device;
+        if (mGatt == null && mDevice == null) {
+            return;
+        }
+        mContext = ctx;
+        mCallback = cb;
+        mFragMgr = fragManager;
+        mOtaResources.clear();
+        if (otaResources != null) {
+            mOtaResources.addAll(otaResources);
+        }
+        getSelectedFirmware();
+
+    }
+
+    public void abortUpdate() {
+        if (mOtaManager != null) {
+            mOtaManager.abortUpdate();
+        } else {
+            onOtaAborted();
+        }
+    }
+
+    public void finish() {
+        mFragMgr = null;
+        if (mOtaManager != null) {
+            mOtaManager.finish();
+        }
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/ui/BluetoothEnabler.java b/WicedSense/app/src/main/java/com/broadcom/ui/BluetoothEnabler.java
index 72fe877e13b60b49a55ad0cd6abbbfb841f2557f..f8878ba98a834164587b8faba058a02e518641b3 100644
--- a/WicedSense/app/src/main/java/com/broadcom/ui/BluetoothEnabler.java
+++ b/WicedSense/app/src/main/java/com/broadcom/ui/BluetoothEnabler.java
@@ -1,60 +1,60 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application
- * Also, make sure you include the following resources
- * assets/license.html
- */
-import com.broadcom.app.wicedsense.R;
-import android.app.Activity;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothManager;
-import android.content.Context;
-import android.content.Intent;
-import android.widget.Toast;
-
-/**
- * Helper class to display a dialog requesting the user to turn on Bluetooth, if
- * it is not already turned on
- *
- *
- */
-public class BluetoothEnabler {
-    public static final int REQUEST_ENABLE_BT = 100;
-
-    public static boolean checkBluetoothOn(Activity a) {
-
-        BluetoothManager bluetoothManager = (BluetoothManager) a
-                .getSystemService(Context.BLUETOOTH_SERVICE);
-        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
-        if (bluetoothManager == null || bluetoothAdapter == null) {
-            Toast.makeText(a, R.string.notifier_bluetooth_unsupported, Toast.LENGTH_SHORT).show();
-            return false;
-        }
-
-        if (!bluetoothAdapter.isEnabled()) {
-            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
-            a.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
-            return false;
-        }
-        return true;
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application
+ * Also, make sure you include the following resources
+ * assets/license.html
+ */
+import com.broadcom.app.wicedsense.R;
+import android.app.Activity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+import android.content.Intent;
+import android.widget.Toast;
+
+/**
+ * Helper class to display a dialog requesting the user to turn on Bluetooth, if
+ * it is not already turned on
+ *
+ *
+ */
+public class BluetoothEnabler {
+    public static final int REQUEST_ENABLE_BT = 100;
+
+    public static boolean checkBluetoothOn(Activity a) {
+
+        BluetoothManager bluetoothManager = (BluetoothManager) a
+                .getSystemService(Context.BLUETOOTH_SERVICE);
+        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
+        if (bluetoothManager == null || bluetoothAdapter == null) {
+            Toast.makeText(a, R.string.notifier_bluetooth_unsupported, Toast.LENGTH_SHORT).show();
+            return false;
+        }
+
+        if (!bluetoothAdapter.isEnabled()) {
+            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+            a.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
+            return false;
+        }
+        return true;
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/ui/ExitConfirmFragment.java b/WicedSense/app/src/main/java/com/broadcom/ui/ExitConfirmFragment.java
index 9dcf58586de21094550f783b2e70349771b2eff0..c9a4a85f4c63b131335f3d6a469e1de8317204e0 100644
--- a/WicedSense/app/src/main/java/com/broadcom/ui/ExitConfirmFragment.java
+++ b/WicedSense/app/src/main/java/com/broadcom/ui/ExitConfirmFragment.java
@@ -1,90 +1,90 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.ui;
-
-/**
- * NOTE: replace "R.class" with your R.class declared in your application
- * Also, make sure you include the following resources
- * assets/license.html
- * values/strings_exitconfirm.xml
- */
-import com.broadcom.app.wicedsense.R;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.util.Log;
-
-/**
- * Displays a dialog prompting the user to quit the application
- *
- */
-public class ExitConfirmFragment extends DialogFragment implements
-        android.content.DialogInterface.OnClickListener {
-    private static final String JEFF_TAG = "Jeff_Tag";
-    public static interface ExitConfirmCallback {
-        public void onExit();
-
-        public void onExitCancelled();
-    }
-
-    public static ExitConfirmFragment createDialog(ExitConfirmCallback cb) {
-        ExitConfirmFragment f = new ExitConfirmFragment();
-        f.mCallback = cb;
-        return f;
-    }
-
-    private ExitConfirmCallback mCallback;
-
-    public void setCallback(ExitConfirmCallback cb) {
-        mCallback = cb;
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        return new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.exit_title))
-                .setPositiveButton(R.string.exit_ok, this)
-                .setNegativeButton(R.string.exit_cancel, this).create();
-    }
-
-    @Override
-    public void onCancel(DialogInterface dialog) {
-        if (mCallback != null) {
-            mCallback.onExitCancelled();
-        }
-    }
-
-    @Override
-    public void onClick(DialogInterface dialog, int which) {
-        if (mCallback != null) {
-            try {
-                if (which == AlertDialog.BUTTON_POSITIVE) {
-                    mCallback.onExit();
-                } else if (which == AlertDialog.BUTTON_NEGATIVE) {
-                    mCallback.onExitCancelled();
-                }
-
-            } catch (Throwable t) {
-            }
-        }
-    }
-
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.ui;
+
+/**
+ * NOTE: replace "R.class" with your R.class declared in your application
+ * Also, make sure you include the following resources
+ * assets/license.html
+ * values/strings_exitconfirm.xml
+ */
+import com.broadcom.app.wicedsense.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Displays a dialog prompting the user to quit the application
+ *
+ */
+public class ExitConfirmFragment extends DialogFragment implements
+        android.content.DialogInterface.OnClickListener {
+    private static final String JEFF_TAG = "Jeff_Tag";
+    public static interface ExitConfirmCallback {
+        public void onExit();
+
+        public void onExitCancelled();
+    }
+
+    public static ExitConfirmFragment createDialog(ExitConfirmCallback cb) {
+        ExitConfirmFragment f = new ExitConfirmFragment();
+        f.mCallback = cb;
+        return f;
+    }
+
+    private ExitConfirmCallback mCallback;
+
+    public void setCallback(ExitConfirmCallback cb) {
+        mCallback = cb;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        return new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.exit_title))
+                .setPositiveButton(R.string.exit_ok, this)
+                .setNegativeButton(R.string.exit_cancel, this).create();
+    }
+
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        if (mCallback != null) {
+            mCallback.onExitCancelled();
+        }
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (mCallback != null) {
+            try {
+                if (which == AlertDialog.BUTTON_POSITIVE) {
+                    mCallback.onExit();
+                } else if (which == AlertDialog.BUTTON_NEGATIVE) {
+                    mCallback.onExitCancelled();
+                }
+
+            } catch (Throwable t) {
+            }
+        }
+    }
+
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/ui/ExitConfirmUtils.java b/WicedSense/app/src/main/java/com/broadcom/ui/ExitConfirmUtils.java
index 16ad53d47f4812210b1bd2c23d2302cdccee6565..4efcbdbd14107e7d0165a936b140a4f0b51411cc 100644
--- a/WicedSense/app/src/main/java/com/broadcom/ui/ExitConfirmUtils.java
+++ b/WicedSense/app/src/main/java/com/broadcom/ui/ExitConfirmUtils.java
@@ -1,78 +1,78 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.ui;
-
-import com.broadcom.ui.ExitConfirmFragment.ExitConfirmCallback;
-
-import android.app.FragmentManager;
-
-/**
- * Helper class to show/hide the ExitConfirm dialog, and to receive callbacks
- * for the user's interaction
- *
- * @author fredc
- *
- */
-public class ExitConfirmUtils implements ExitConfirmCallback {
-
-    private final ExitConfirmFragment.ExitConfirmCallback mListener;
-    private ExitConfirmFragment mDialog;
-
-    @Override
-    public void onExit() {
-        mDialog = null;
-        if (mListener != null) {
-            try {
-                mListener.onExit();
-            } catch (Throwable t) {
-            }
-        }
-    }
-
-    @Override
-    public void onExitCancelled() {
-        mDialog = null;
-        if (mListener != null) {
-            try {
-                mListener.onExitCancelled();
-            } catch (Throwable t) {
-            }
-        }
-    }
-
-    public ExitConfirmUtils(ExitConfirmFragment.ExitConfirmCallback listener) {
-        mListener = listener;
-    }
-
-    public void show(FragmentManager mgr) {
-
-        if (mDialog == null) {
-            mDialog = ExitConfirmFragment.createDialog(this);
-            mDialog.show(mgr, null);
-        }
-    }
-
-    public void dismiss() {
-        if (mDialog != null) {
-            mDialog.setCallback(null);
-            mDialog.dismiss();
-            mDialog = null;
-        }
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.ui;
+
+import com.broadcom.ui.ExitConfirmFragment.ExitConfirmCallback;
+
+import android.app.FragmentManager;
+
+/**
+ * Helper class to show/hide the ExitConfirm dialog, and to receive callbacks
+ * for the user's interaction
+ *
+ * @author fredc
+ *
+ */
+public class ExitConfirmUtils implements ExitConfirmCallback {
+
+    private final ExitConfirmFragment.ExitConfirmCallback mListener;
+    private ExitConfirmFragment mDialog;
+
+    @Override
+    public void onExit() {
+        mDialog = null;
+        if (mListener != null) {
+            try {
+                mListener.onExit();
+            } catch (Throwable t) {
+            }
+        }
+    }
+
+    @Override
+    public void onExitCancelled() {
+        mDialog = null;
+        if (mListener != null) {
+            try {
+                mListener.onExitCancelled();
+            } catch (Throwable t) {
+            }
+        }
+    }
+
+    public ExitConfirmUtils(ExitConfirmFragment.ExitConfirmCallback listener) {
+        mListener = listener;
+    }
+
+    public void show(FragmentManager mgr) {
+
+        if (mDialog == null) {
+            mDialog = ExitConfirmFragment.createDialog(this);
+            mDialog.show(mgr, null);
+        }
+    }
+
+    public void dismiss() {
+        if (mDialog != null) {
+            mDialog.setCallback(null);
+            mDialog.dismiss();
+            mDialog = null;
+        }
+    }
+
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/util/ByteUtils.java b/WicedSense/app/src/main/java/com/broadcom/util/ByteUtils.java
index 8eb36fac4f14560bdbc5e207e2c658e287056bad..752311b7555901f089c284e3e1cf38c1bba50d2b 100644
--- a/WicedSense/app/src/main/java/com/broadcom/util/ByteUtils.java
+++ b/WicedSense/app/src/main/java/com/broadcom/util/ByteUtils.java
@@ -1,135 +1,135 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.util;
-
-import android.bluetooth.BluetoothDevice;
-
-/**
- * Helper class to convert bytes to ints and ints to bytes
- *
- */
-public class ByteUtils {
-    static final int BD_ADDR_LEN = 6; // bytes
-
-    public static void printBytes(byte[] bytes, StringBuilder builder, int bytesPerLine) {
-        for (int i = 0; i < bytes.length; i++) {
-            if (i != 0 && i % bytesPerLine == 0) {
-                builder.append("\n");
-            }
-            builder.append(String.format("%02x  ", bytes[i]));
-        }
-    }
-
-    public static int bytesToUInt16LI(byte[] bytes, int startIndex, int defaultValue) {
-        if (bytes == null || startIndex + 1 >= bytes.length) {
-            return defaultValue;
-        }
-        int value = bytes[startIndex] + (((int) bytes[startIndex + 1]) << 8);
-        return value;
-    }
-
-    public static String printBytes(byte[] bytes, int bytesPerLine) {
-        StringBuilder builder = new StringBuilder();
-        printBytes(bytes, builder, bytesPerLine);
-        return builder.toString();
-    }
-
-    public static void uInt32ToBytesLI(long value, byte[] buffer, int startIndex) {
-        buffer[startIndex++] = (byte) (value >>> 0);
-        buffer[startIndex++] = (byte) (value >>> 8);
-        buffer[startIndex++] = (byte) (value >>> 16);
-        buffer[startIndex++] = (byte) (value >>> 24);
-    }
-
-    public static byte[] uInt32ToBytesLI(long value) {
-        byte b[] = new byte[4];
-        uInt32ToBytesLI(value, b, 0);
-        return b;
-    }
-
-    public static void uInt32ToBytesBI(long value, byte[] buffer, int startIndex) {
-        buffer[startIndex++] = (byte) (value >>> 24);
-        buffer[startIndex++] = (byte) (value >>> 16);
-        buffer[startIndex++] = (byte) (value >>> 8);
-        buffer[startIndex++] = (byte) (value >>> 0);
-    }
-
-    public static byte[] uInt32ToBytesBI(long value) {
-        byte b[] = new byte[4];
-        uInt32ToBytesBI(value, b, 0);
-        return b;
-    }
-
-    public static void uInt16ToBytesLI(int value, byte[] buffer, int startIndex) {
-        buffer[startIndex++] = (byte) (value >>> 0);
-        buffer[startIndex++] = (byte) (value >>> 8);
-    }
-
-    public static void uInt16ToBytesBI(int value, byte[] buffer, int startIndex) {
-        buffer[startIndex++] = (byte) (value >>> 8);
-        buffer[startIndex++] = (byte) (value >>> 0);
-    }
-
-    public static byte[] uInt16ToBytesLI(int value) {
-        byte b[] = new byte[2];
-        uInt16ToBytesLI(value, b, 0);
-        return b;
-    }
-
-    public static byte[] uInt16ToBytesBI(int value) {
-        byte b[] = new byte[2];
-        uInt16ToBytesBI(value, b, 0);
-        return b;
-    }
-
-    public static byte[] getByteAddress(BluetoothDevice device) {
-        return getBytesFromAddress(device.getAddress());
-    }
-
-    public static byte[] getBytesFromAddress(String address) {
-        int i, j = 0;
-        byte[] output = new byte[BD_ADDR_LEN];
-        if (address != null) {
-            for (i = 0; i < address.length(); i++) {
-                if (address.charAt(i) != ':') {
-                    output[j] = (byte) Integer.parseInt(address.substring(i, i + 2), 16);
-                    j++;
-                    i++;
-                }
-            }
-        }
-        return output;
-    }
-
-    public static String getAddressStringFromByte(byte[] address, boolean includeSeparator) {
-        if (address == null || address.length != 6) {
-            return null;
-        }
-        if (includeSeparator) {
-            return String.format("%02X:%02X:%02X:%02X:%02X:%02X", address[0], address[1],
-                    address[2], address[3], address[4], address[5]);
-        } else {
-            return String.format("%02X%02X%02X%02X%02X%02X", address[0], address[1], address[2],
-                    address[3], address[4], address[5]);
-        }
-    }
-
-    public static String getAddressStringFromByte(byte[] address) {
-        return getAddressStringFromByte(address, true);
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.util;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * Helper class to convert bytes to ints and ints to bytes
+ *
+ */
+public class ByteUtils {
+    static final int BD_ADDR_LEN = 6; // bytes
+
+    public static void printBytes(byte[] bytes, StringBuilder builder, int bytesPerLine) {
+        for (int i = 0; i < bytes.length; i++) {
+            if (i != 0 && i % bytesPerLine == 0) {
+                builder.append("\n");
+            }
+            builder.append(String.format("%02x  ", bytes[i]));
+        }
+    }
+
+    public static int bytesToUInt16LI(byte[] bytes, int startIndex, int defaultValue) {
+        if (bytes == null || startIndex + 1 >= bytes.length) {
+            return defaultValue;
+        }
+        int value = bytes[startIndex] + (((int) bytes[startIndex + 1]) << 8);
+        return value;
+    }
+
+    public static String printBytes(byte[] bytes, int bytesPerLine) {
+        StringBuilder builder = new StringBuilder();
+        printBytes(bytes, builder, bytesPerLine);
+        return builder.toString();
+    }
+
+    public static void uInt32ToBytesLI(long value, byte[] buffer, int startIndex) {
+        buffer[startIndex++] = (byte) (value >>> 0);
+        buffer[startIndex++] = (byte) (value >>> 8);
+        buffer[startIndex++] = (byte) (value >>> 16);
+        buffer[startIndex++] = (byte) (value >>> 24);
+    }
+
+    public static byte[] uInt32ToBytesLI(long value) {
+        byte b[] = new byte[4];
+        uInt32ToBytesLI(value, b, 0);
+        return b;
+    }
+
+    public static void uInt32ToBytesBI(long value, byte[] buffer, int startIndex) {
+        buffer[startIndex++] = (byte) (value >>> 24);
+        buffer[startIndex++] = (byte) (value >>> 16);
+        buffer[startIndex++] = (byte) (value >>> 8);
+        buffer[startIndex++] = (byte) (value >>> 0);
+    }
+
+    public static byte[] uInt32ToBytesBI(long value) {
+        byte b[] = new byte[4];
+        uInt32ToBytesBI(value, b, 0);
+        return b;
+    }
+
+    public static void uInt16ToBytesLI(int value, byte[] buffer, int startIndex) {
+        buffer[startIndex++] = (byte) (value >>> 0);
+        buffer[startIndex++] = (byte) (value >>> 8);
+    }
+
+    public static void uInt16ToBytesBI(int value, byte[] buffer, int startIndex) {
+        buffer[startIndex++] = (byte) (value >>> 8);
+        buffer[startIndex++] = (byte) (value >>> 0);
+    }
+
+    public static byte[] uInt16ToBytesLI(int value) {
+        byte b[] = new byte[2];
+        uInt16ToBytesLI(value, b, 0);
+        return b;
+    }
+
+    public static byte[] uInt16ToBytesBI(int value) {
+        byte b[] = new byte[2];
+        uInt16ToBytesBI(value, b, 0);
+        return b;
+    }
+
+    public static byte[] getByteAddress(BluetoothDevice device) {
+        return getBytesFromAddress(device.getAddress());
+    }
+
+    public static byte[] getBytesFromAddress(String address) {
+        int i, j = 0;
+        byte[] output = new byte[BD_ADDR_LEN];
+        if (address != null) {
+            for (i = 0; i < address.length(); i++) {
+                if (address.charAt(i) != ':') {
+                    output[j] = (byte) Integer.parseInt(address.substring(i, i + 2), 16);
+                    j++;
+                    i++;
+                }
+            }
+        }
+        return output;
+    }
+
+    public static String getAddressStringFromByte(byte[] address, boolean includeSeparator) {
+        if (address == null || address.length != 6) {
+            return null;
+        }
+        if (includeSeparator) {
+            return String.format("%02X:%02X:%02X:%02X:%02X:%02X", address[0], address[1],
+                    address[2], address[3], address[4], address[5]);
+        } else {
+            return String.format("%02X%02X%02X%02X%02X%02X", address[0], address[1], address[2],
+                    address[3], address[4], address[5]);
+        }
+    }
+
+    public static String getAddressStringFromByte(byte[] address) {
+        return getAddressStringFromByte(address, true);
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/util/GattRequestManager.java b/WicedSense/app/src/main/java/com/broadcom/util/GattRequestManager.java
index f63e244363a7b330c0876da40123c1ca1b910fbd..c9e557b7e9104a3baa9bad3ebfb1266ec88a4c2b 100644
--- a/WicedSense/app/src/main/java/com/broadcom/util/GattRequestManager.java
+++ b/WicedSense/app/src/main/java/com/broadcom/util/GattRequestManager.java
@@ -1,1083 +1,1083 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.util;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.UUID;
-
-import com.broadcom.app.wicedsense.Settings;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCallback;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattDescriptor;
-import android.bluetooth.BluetoothGattService;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-/**
- * Helper class to manage GATT requests to a remote device, ensuring that GATT
- * read and are executed serially. In addition, this manages a timeout timer for
- * each GATT read/write request, connect/disconnect requests, and a retry
- * mechanism for service discovery
- *
- */
-public class GattRequestManager extends BluetoothGattCallback implements Handler.Callback {
-    private static final String TAG = Settings.TAG_PREFIX + "GattRequestManager";
-    private static final boolean DBG = true;
-
-    private static final int REQUEST_NONE = 0;
-    public static final int REQUEST_READ_CHAR = 1;
-    public static final int REQUEST_WRITE_CHAR = 2;
-    public static final int REQUEST_READ_DESCRIPTOR = 3;
-    public static final int REQUEST_WRITE_DESCRIPTOR = 4;
-    private static final int REQUEST_CONNECT = 10;
-    private static final int REQUEST_DISCONNECT = 20;
-    private static final int CONNECT_COMPLETE = 30;
-    private static final int EVENT_PAIRED = 40;
-    private static final int EVENT_UNPAIRED = 50;
-    private static final int CONNECT_DELAY_MS = 2000;
-
-    private static final int REQUEST_DISCOVER_SERVICES = 12;
-    private static final int DISCOVER_SERVICES_DELAY_MS = 3000;
-    private static final int TIMEOUT_TYPE_CONNECT = -1000;
-    private static final int TIMEOUT_TYPE_DISCONNECT = -1001;
-    private static final int TIMEOUT_TYPE_SERVICE_DISCOVERY = -1002;
-    private static final int TIMEOUT_TYPE_GATT_REQUEST = -1010;
-    private static final int TIMEOUT_TYPE_PAIRING = -1020;
-
-    private static final int TIMEOUT_CONNECT_MS = 10000;
-    private static final int TIMEOUT_DISCONNECT_MS = 3000;
-    private static final int TIMEOUT_SERVICE_DISCOVERY_MS = 10000;
-    private static final int TIMEOUT_GATT_REQUEST_MS = 5000;
-    private static final int TIMEOUT_PAIRING_MS = 5000;
-
-    private static String getMessageString(int msg) {
-        switch (msg) {
-        case REQUEST_NONE:
-            return "REQUEST_NONE";
-        case REQUEST_CONNECT:
-            return "REQUEST_CONNECT";
-        case REQUEST_DISCONNECT:
-            return "REQUEST_DISCONNECT";
-        case CONNECT_COMPLETE:
-            return "CONNECT_COMPLETE";
-        case EVENT_PAIRED:
-            return "EVENT_PAIRED";
-        case EVENT_UNPAIRED:
-            return "EVENT_UNPAIRED";
-        case REQUEST_READ_CHAR:
-            return "REQUEST_READ_CHAR";
-        case REQUEST_WRITE_CHAR:
-            return "REQUEST_WRITE_CHAR";
-        case REQUEST_READ_DESCRIPTOR:
-            return "REQUEST_READ_DESCRIPTOR";
-        case REQUEST_WRITE_DESCRIPTOR:
-            return "REQUEST_WRITE_DESCRIPTOR";
-        case REQUEST_DISCOVER_SERVICES:
-            return "REQUEST_DISCOVER_SERVICES";
-        case DISCOVER_SERVICES_DELAY_MS:
-            return "DISCOVER_SERVICES_DELAY_MS";
-        case TIMEOUT_TYPE_CONNECT:
-            return "TIMEOUT_TYPE_CONNECT";
-        case TIMEOUT_TYPE_DISCONNECT:
-            return "TIMEOUT_TYPE_DISCONNECT";
-        case TIMEOUT_TYPE_SERVICE_DISCOVERY:
-            return "TIMEOUT_TYPE_SERVICE_DISCOVERY";
-        case TIMEOUT_TYPE_GATT_REQUEST:
-            return "TIMEOUT_TYPE_GATT_REQUEST";
-        default:
-            return "UNKNOWN_TYPE " + msg;
-        }
-    }
-
-    private static String getConnectionStateString(int gattState) {
-        switch (gattState) {
-        case BluetoothGatt.STATE_CONNECTED:
-            return "STATE_CONNECTED";
-        case BluetoothGatt.STATE_DISCONNECTED:
-            return "STATE_DISCONNECTED";
-        case BluetoothGatt.STATE_CONNECTING:
-            return "STATE_CONNECTED";
-        case BluetoothGatt.STATE_DISCONNECTING:
-            return "STATE_DISCONNECTING";
-        default:
-            return "STATE_UNKNOWN " + gattState;
-        }
-    }
-
-    private static Method sSetPrCr;
-    private static Method sCrBd;
-    private static Method sRmBd;
-
-    static {
-        try {
-            sSetPrCr = BluetoothDevice.class.getMethod("setPairingConfirmation", boolean.class);
-            sCrBd = BluetoothDevice.class.getMethod("createBond", (Class[]) null);
-            sRmBd = BluetoothDevice.class.getMethod("removeBond", (Class[]) null);
-        } catch (Throwable t) {
-            Log.e(TAG, "error: getting bonding services", t);
-            sSetPrCr = null;
-            sCrBd = null;
-        }
-    }
-
-    private static boolean unpair(BluetoothDevice device) {
-        if (sRmBd != null) {
-            try {
-                sRmBd.invoke(device, (Object[]) null);
-                return true;
-            } catch (Throwable t) {
-                Log.e(TAG, "unpair: error", t);
-            }
-        }
-        return false;
-    }
-
-    private static boolean pair(BluetoothDevice device) {
-        if (sSetPrCr != null && sCrBd != null) {
-            try {
-                // sSetPrCr.invoke(device, true);
-                sCrBd.invoke(device, (Object[]) null);
-                return true;
-            } catch (Throwable t) {
-                Log.e(TAG, "pair: error", t);
-            }
-        }
-        return false;
-    }
-
-    public interface LePairingCallback {
-        public void onPaired(boolean isPaired);
-    }
-
-    public interface GattTimeoutCallback {
-        public void onTimeout(GattRequest request);
-    }
-
-    public static class GattRequest {
-        public final int mId;
-        public final BluetoothGattCharacteristic mCharacteristic;
-        public final BluetoothGattDescriptor mDescriptor;
-        public final int mRequestType;
-        public final byte[] mByteValues;
-
-        private GattRequest(int requestType, BluetoothGattCharacteristic c,
-                BluetoothGattDescriptor d, byte[] byteValues) {
-            this(0, requestType, c, d, byteValues);
-        }
-
-        private GattRequest(int requestType, BluetoothGattCharacteristic c,
-                BluetoothGattDescriptor d) {
-            this(requestType, c, d, null);
-        }
-
-        private GattRequest(int id, int requestType, BluetoothGattCharacteristic c,
-                BluetoothGattDescriptor d, byte[] byteValues) {
-            mId = id;
-            mRequestType = requestType;
-            mCharacteristic = c;
-            mDescriptor = d;
-            mByteValues = byteValues;
-        }
-    }
-
-    private class BluetoothPairingReceiver extends BroadcastReceiver {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-            BluetoothDevice managedDevice = getDevice();
-            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 0);
-            if (DBG) {
-                Log.d(TAG, "BluetoothBondingReceiver.onReceive(): device = " + device
-                        + ", bondState= " + bondState + ", managedDevice= " + mDevice);
-            }
-            if (device != null && device.equals(managedDevice)) {
-                if (bondState == BluetoothDevice.BOND_BONDED) {
-                    mHandler.sendEmptyMessage(EVENT_PAIRED);
-                } else if (bondState == BluetoothDevice.BOND_NONE) {
-                    mHandler.sendEmptyMessage(EVENT_UNPAIRED);
-                }
-            }
-        }
-    }
-
-    private final Object mConnectionLock = new Object(); // Lock variable
-    private final Context mContext;
-
-    private final ArrayList<BluetoothGattCallback> mGattCallbacks = new ArrayList<BluetoothGattCallback>();
-    private final ArrayList<GattTimeoutCallback> mGattTimeoutCallbacks = new ArrayList<GattTimeoutCallback>();
-    private final ArrayList<LePairingCallback> mPairingCallbacks = new ArrayList<GattRequestManager.LePairingCallback>();
-
-    private final Handler mHandler = new Handler(this);
-    private final LinkedList<GattRequest> mQueuedRequests = new LinkedList<GattRequest>();
-    private GattRequest mPendingRequest;
-
-    private int mPairingTimeoutMs = TIMEOUT_PAIRING_MS;
-    private boolean mAutoConnect = false;
-    private boolean mRetryFailedConnection = true;
-    private boolean mDiscoverServices = true;
-    private int mMaxConnectionRetries = 2;
-
-    private BluetoothPairingReceiver mPairingReceiver;
-    private boolean mPairingReceiverRegistered;
-    private final BluetoothDevice mDevice;
-    private BluetoothGatt mGatt;
-    private int mConnectState;
-    private boolean mServicesDiscovered;
-    private int mPendingConnectDisconnectRequest;
-    private boolean mIsUserDisconnectRequested;
-    private boolean mPendingClose;
-    private boolean mIsClosedAndCleanedUp;
-    private int mReconnectCount;
-
-    private void startRequestTimeout(GattRequest r) {
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(TIMEOUT_TYPE_GATT_REQUEST, r),
-                TIMEOUT_GATT_REQUEST_MS);
-    }
-
-    private void cancelRequestTimeout() {
-        mHandler.removeMessages(TIMEOUT_TYPE_GATT_REQUEST);
-    }
-
-    private void queueRequest(GattRequest r, boolean atFront) {
-        synchronized (mQueuedRequests) {
-            if (atFront) {
-                mQueuedRequests.addFirst(r);
-            } else {
-                mQueuedRequests.add(r);
-            }
-            if (mPendingRequest == null) {
-                processQueuedRequests();
-            }
-        }
-    }
-
-    private void processQueuedRequests() {
-        GattRequest r = null;
-        synchronized (mQueuedRequests) {
-            mPendingRequest = mQueuedRequests.poll();
-            if (mPendingRequest == null) {
-                return;
-            }
-            r = mPendingRequest;
-        }
-
-        switch (r.mRequestType) {
-        case REQUEST_READ_CHAR:
-            if (mGatt == null) {
-                onCharacteristicRead(null, r.mCharacteristic, BluetoothGatt.GATT_FAILURE);
-                return;
-            }
-            startRequestTimeout(r);
-            mGatt.readCharacteristic(r.mCharacteristic);
-            break;
-        case REQUEST_WRITE_DESCRIPTOR:
-            if (mGatt == null) {
-                onDescriptorWrite(null, r.mDescriptor, BluetoothGatt.GATT_FAILURE);
-                return;
-            }
-            startRequestTimeout(r);
-            if (r.mByteValues != null) {
-                r.mDescriptor.setValue(r.mByteValues);
-            }
-            mGatt.writeDescriptor(r.mDescriptor);
-            break;
-        case REQUEST_WRITE_CHAR:
-            if (mGatt == null) {
-                onCharacteristicWrite(null, r.mCharacteristic, BluetoothGatt.GATT_FAILURE);
-                return;
-            }
-            startRequestTimeout(r);
-            if (DBG) {
-                Log.d(TAG, "writeChar: id=" + r.mId + ",value=" + r.mByteValues);
-            }
-            if (r.mByteValues != null) {
-                if (DBG) {
-                    Log.d(TAG, " valueLength=" + r.mByteValues.length);
-                }
-            }
-            if (r.mByteValues != null) {
-                r.mCharacteristic.setValue(r.mByteValues);
-            }
-            mGatt.writeCharacteristic(r.mCharacteristic);
-            break;
-        case REQUEST_READ_DESCRIPTOR:
-            if (mGatt == null) {
-                onDescriptorRead(null, r.mDescriptor, BluetoothGatt.GATT_FAILURE);
-                return;
-            }
-            startRequestTimeout(r);
-            mGatt.readDescriptor(r.mDescriptor);
-            break;
-        }
-    }
-
-    private void sendTimeoutEvent(GattRequest r) {
-        GattTimeoutCallback[] l = getTimeoutCallbacks();
-        int i = 0;
-        for (; i < l.length; i++) {
-            try {
-                l[i].onTimeout(r);
-            } catch (Throwable t) {
-                Log.e(TAG, "sendTimeoutEvent error : index =" + i, t);
-            }
-        }
-    }
-
-    private BluetoothGattCallback[] getGattCallbacks() {
-        BluetoothGattCallback[] cb = null;
-        synchronized (mGattCallbacks) {
-            cb = new BluetoothGattCallback[mGattCallbacks.size()];
-            mGattCallbacks.toArray(cb);
-        }
-        return cb;
-    }
-
-    private LePairingCallback[] getPairingCallbacks() {
-        LePairingCallback[] cb = null;
-        synchronized (mPairingCallbacks) {
-            cb = new LePairingCallback[mPairingCallbacks.size()];
-            mPairingCallbacks.toArray(cb);
-        }
-        return cb;
-    }
-
-    private GattTimeoutCallback[] getTimeoutCallbacks() {
-        GattTimeoutCallback[] l = null;
-        synchronized (mGattTimeoutCallbacks) {
-            l = new GattTimeoutCallback[mGattTimeoutCallbacks.size()];
-            mGattTimeoutCallbacks.toArray(l);
-        }
-        return l;
-    }
-
-    @Override
-    public boolean handleMessage(Message msg) {
-        if (DBG) {
-            Log.d(TAG, "handleMessage:" + getMessageString(msg.what));
-        }
-        switch (msg.what) {
-        case EVENT_PAIRED:
-            onPaired(false);
-            break;
-        case EVENT_UNPAIRED:
-            onPaired(true);
-            break;
-        case REQUEST_CONNECT:
-            connect(true);
-            break;
-        case CONNECT_COMPLETE:
-            mReconnectCount = mMaxConnectionRetries;
-            break;
-        case REQUEST_DISCOVER_SERVICES:
-            if (mGatt.discoverServices()) {
-                mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_SERVICE_DISCOVERY,
-                        TIMEOUT_SERVICE_DISCOVERY_MS);
-            } else {
-                Log.w(TAG, "Error calling discover services.");
-                onServicesDiscovered(mGatt, BluetoothGatt.GATT_FAILURE);
-            }
-            break;
-        case TIMEOUT_TYPE_PAIRING:
-            onPaired(false);
-        case TIMEOUT_TYPE_CONNECT:
-            Log.w(TAG, "timeout: connect");
-            synchronized (mConnectionLock) {
-                mPendingClose = true; // Force gatt connection to close
-                onConnectionStateChange(mGatt, BluetoothGatt.GATT_FAILURE,
-                        BluetoothGatt.STATE_DISCONNECTED);
-            }
-            break;
-        case TIMEOUT_TYPE_DISCONNECT:
-            Log.w(TAG, "timeout: disconnect");
-            onConnectionStateChange(mGatt, BluetoothGatt.GATT_FAILURE,
-                    BluetoothGatt.STATE_DISCONNECTED);
-            break;
-        case TIMEOUT_TYPE_SERVICE_DISCOVERY:
-            Log.w(TAG, "timeout: service discovery");
-            onServicesDiscovered(mGatt, BluetoothGatt.GATT_FAILURE);
-            break;
-        case TIMEOUT_TYPE_GATT_REQUEST:
-            GattRequest r = (GattRequest) msg.obj;
-            Log.w(TAG, "timeout: " + r.mRequestType);
-            sendTimeoutEvent(r);
-            processQueuedRequests();
-            break;
-        }
-
-        return true;
-    }
-
-    @Override
-    public void onCharacteristicChanged(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic) {
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onCharacteristicChanged(gatt, characteristic);
-            } catch (Throwable t) {
-                Log.e(TAG, "onCharacteristicChanged[" + i + "]: error", t);
-            }
-        }
-    }
-
-    @Override
-    public void onCharacteristicRead(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic, int status) {
-        cancelRequestTimeout();
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onCharacteristicRead(gatt, characteristic, status);
-            } catch (Throwable t) {
-                Log.e(TAG, "onCharacteristicRead[" + i + "]: error", t);
-            }
-        }
-        processQueuedRequests();
-
-    }
-
-    @Override
-    public void onCharacteristicWrite(BluetoothGatt gatt,
-            BluetoothGattCharacteristic characteristic, int status) {
-        cancelRequestTimeout();
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onCharacteristicWrite(gatt, characteristic, status);
-            } catch (Throwable t) {
-                Log.e(TAG, "onCharacteristicWrite[" + i + "]: error", t);
-            }
-        }
-        processQueuedRequests();
-
-    }
-
-    private void registerPairingReceiver() {
-        if (mContext != null && !mPairingReceiverRegistered) {
-            if (mPairingReceiver == null) {
-                mPairingReceiver = new BluetoothPairingReceiver();
-            }
-            mContext.registerReceiver(mPairingReceiver, new IntentFilter(
-                    BluetoothDevice.ACTION_BOND_STATE_CHANGED));
-            mPairingReceiverRegistered = true;
-        }
-    }
-
-    private void unregisterPairingReceiver() {
-        if (mContext != null && mPairingReceiverRegistered && mPairingReceiver != null) {
-            mContext.unregisterReceiver(mPairingReceiver);
-            mPairingReceiverRegistered = false;
-        }
-    }
-
-    private void onPaired(boolean paired) {
-        mHandler.removeMessages(TIMEOUT_TYPE_PAIRING);
-        unregisterPairingReceiver();
-        LePairingCallback[] cb = getPairingCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onPaired(paired);
-            } catch (Throwable t) {
-                Log.e(TAG, "onPaired: error " + cb[i], t);
-            }
-        }
-    }
-
-    /**
-     * Cleanup after a connection is closed
-     */
-    private void closeAndCleanupGattConnection() {
-        Log.d(TAG, "closeAndCleanupGattConnection");
-        synchronized (mConnectionLock) {
-
-            // Check if we are already closed
-            if (mIsClosedAndCleanedUp) {
-                return;
-            }
-
-            // Remove all pending requests
-            mHandler.removeCallbacksAndMessages(null);
-            mQueuedRequests.clear();
-            mPendingRequest = null;
-
-            // Close gatt connection
-            if (mGatt != null) {
-                try {
-                    mGatt.close();
-                    mGatt = null;
-                } catch (Throwable t) {
-                    Log.w(TAG, "closeAndCleanupGattConnection: error", t);
-                }
-            }
-            mIsClosedAndCleanedUp = true;
-        }
-    }
-
-    /**
-     * Initialize state variables before connect request
-     */
-    private void initStateBeforeConnect() {
-        synchronized (mConnectionLock) {
-            mServicesDiscovered = false;
-            mPendingClose = false;
-            mIsClosedAndCleanedUp = false;
-            mIsUserDisconnectRequested = false;
-        }
-    }
-
-    private void startConnectDisconnectTimeout(boolean connect) {
-        synchronized (mConnectionLock) {
-            if (connect) {
-                mPendingConnectDisconnectRequest = REQUEST_CONNECT;
-                mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_CONNECT, TIMEOUT_CONNECT_MS);
-                if (DBG) {
-                    Log.d(TAG, "startConnectDisconnectTimeout(): starting connect timeout");
-                }
-            } else {
-                mPendingConnectDisconnectRequest = REQUEST_DISCONNECT;
-                mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_DISCONNECT, TIMEOUT_DISCONNECT_MS);
-                if (DBG) {
-                    Log.d(TAG, "startConnectDisconnectTimeout(): starting disconnect timeout");
-                }
-            }
-        }
-    }
-
-    private void stopConnectDisconnectTimeout() {
-        synchronized (mConnectionLock) {
-            if (mPendingConnectDisconnectRequest != REQUEST_NONE) {
-                if (DBG) {
-                    Log.d(TAG, "stopConnectDisconnectTimeout(): cancelling timeout "
-                            + getMessageString(mPendingConnectDisconnectRequest));
-                }
-                if (mPendingConnectDisconnectRequest == REQUEST_CONNECT) {
-                    mHandler.removeMessages(TIMEOUT_TYPE_CONNECT);
-                } else if (mPendingConnectDisconnectRequest == REQUEST_DISCONNECT) {
-                    mHandler.removeMessages(TIMEOUT_TYPE_DISCONNECT);
-                }
-                mPendingConnectDisconnectRequest = REQUEST_NONE;
-            }
-        }
-    }
-
-    private boolean hasPendingConnectDisconnect() {
-        return mPendingConnectDisconnectRequest != REQUEST_NONE;
-    }
-
-    public void startConnectCompleteTimer(int time) {
-        if (DBG) {
-            Log.d(TAG, "startConnectCompleteTimer(): timer=" + time);
-        }
-        if (time > 0) {
-            mHandler.sendEmptyMessageDelayed(CONNECT_COMPLETE, time);
-        }
-    }
-
-    public void stopConnectCompleteTimer() {
-        if (DBG) {
-            Log.d(TAG, "stopConnectCompleteTimer(): timer=");
-        }
-        mHandler.removeMessages(CONNECT_COMPLETE);
-    }
-
-    @Override
-    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
-        if (DBG) {
-            Log.d(TAG, "onConnectionStateChange: state=" + getConnectionStateString(newState)
-                    + ", status=" + status);
-        }
-        stopConnectDisconnectTimeout();
-        mConnectState = newState;
-        // Handle disconnect
-        if (newState == BluetoothGatt.STATE_DISCONNECTED
-                || newState == BluetoothGatt.STATE_DISCONNECTING) {
-            // If we got a disconnect, check if if this was user initiated.
-            // If not, try to reconnect
-            if (DBG) {
-                Log.d(TAG, "onConnectionStateChange: mIsUserDisconnectRequested="
-                        + mIsUserDisconnectRequested + ",mPendingClose=" + mPendingClose
-                        + ", mRetryFailedConnection=" + mRetryFailedConnection);
-            }
-            if (mPendingClose) {
-                closeAndCleanupGattConnection();
-            } else {
-                stopConnectCompleteTimer();
-                mHandler.removeCallbacksAndMessages(null);
-                mQueuedRequests.clear();
-            }
-
-            if (!mIsUserDisconnectRequested && mRetryFailedConnection
-                    && ++mReconnectCount < mMaxConnectionRetries) {
-                if (DBG) {
-                    Log.d(TAG, "onConnectionStateChange: Auto-reconnecting...");
-                }
-                connectDelayed();
-                return;
-            }
-        } else if (newState == BluetoothGatt.STATE_CONNECTED) {
-            if (mDiscoverServices) {
-                // Android 4.3: some devices can't handle an immediate service
-                // discovery request
-                discoverServicesDelayed();
-            }
-        }
-        // Send events to interested listeners
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onConnectionStateChange(gatt, status, newState);
-            } catch (Throwable t) {
-                Log.e(TAG, "onConnectionStateChange[" + i + "]: error", t);
-            }
-        }
-    }
-
-    @Override
-    public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
-        cancelRequestTimeout();
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onDescriptorRead(gatt, descriptor, status);
-            } catch (Throwable t) {
-                Log.e(TAG, "onDescriptorRead[" + i + "]: error", t);
-            }
-        }
-        processQueuedRequests();
-
-    }
-
-    @Override
-    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
-        cancelRequestTimeout();
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onDescriptorWrite(gatt, descriptor, status);
-            } catch (Throwable t) {
-                Log.e(TAG, "onDescriptorWrite[" + i + "]: error", t);
-            }
-        }
-        processQueuedRequests();
-    }
-
-    @Override
-    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onReadRemoteRssi(gatt, rssi, status);
-            } catch (Throwable t) {
-                Log.e(TAG, "onReadRemoteRssi[" + i + "]: error", t);
-            }
-        }
-    }
-
-    @Override
-    public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onReliableWriteCompleted(gatt, status);
-            } catch (Throwable t) {
-                Log.e(TAG, "onReliableWriteCompleted[" + i + "]: error", t);
-            }
-        }
-    }
-
-    @Override
-    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
-        mHandler.removeMessages(TIMEOUT_TYPE_SERVICE_DISCOVERY);
-
-        // Check if we need to retry
-        if (status == BluetoothGatt.GATT_SUCCESS) {
-            mServicesDiscovered = true;
-        }
-        if (mDiscoverServices && !mServicesDiscovered) {
-            // Disconnect and reconnect if mRetryFailedConnection=true
-            disconnect(false, false);
-            return;
-        }
-        BluetoothGattCallback[] cb = getGattCallbacks();
-        for (int i = 0; i < cb.length; i++) {
-            try {
-                cb[i].onServicesDiscovered(gatt, status);
-            } catch (Throwable t) {
-                Log.e(TAG, "onServicesDiscovered[" + i + "]: error", t);
-            }
-        }
-    }
-
-    private boolean connect(boolean isReconnect) {
-        synchronized (mConnectionLock) {
-
-            // Check if we have a pending connect/disconnect request
-            if (hasPendingConnectDisconnect()) {
-                Log.w(TAG, "connect: cannot connect, because there is a pending request "
-                        + getMessageString(mPendingConnectDisconnectRequest));
-                return false;
-            }
-            if (!isReconnect) {
-                mReconnectCount = 0;
-            }
-            // Remove any queued connect requests
-            mHandler.removeMessages(REQUEST_CONNECT);
-            initStateBeforeConnect();
-            boolean success = false;
-            startConnectDisconnectTimeout(true);
-            if (mGatt != null) {
-                success = mGatt.connect();
-            } else {
-                mGatt = mDevice.connectGatt(mContext, mAutoConnect, this);
-                success = (null != mGatt);
-            }
-            return success;
-        }
-    }
-
-    private boolean disconnect(boolean isUserRequested, boolean closeResources) {
-        synchronized (mConnectionLock) {
-            // Check if we have a pending connect/disconnect request
-            if (hasPendingConnectDisconnect()) {
-                Log.w(TAG, "disconnect: cannot disconnect, because there is a pending request "
-                        + getMessageString(mPendingConnectDisconnectRequest));
-                return false;
-            }
-            stopConnectCompleteTimer();
-            mIsUserDisconnectRequested = isUserRequested;
-            mServicesDiscovered = false;
-            if (mGatt != null) {
-                mPendingClose = closeResources;
-                startConnectDisconnectTimeout(false);
-                mGatt.disconnect();
-            } else {
-                Log.w(TAG, "disconnect: cannot disconnect, because gatt is null");
-                return false;
-            }
-            return true;
-        }
-    }
-
-    private boolean discoverServicesDelayed() {
-        if (mGatt == null) {
-            return false;
-        }
-        mHandler.sendEmptyMessageDelayed(REQUEST_DISCOVER_SERVICES, DISCOVER_SERVICES_DELAY_MS);
-        return true;
-    }
-
-    // ---------------------Public API--------------------------------------
-    public GattRequestManager(Context ctx, BluetoothDevice device) {
-        mDevice = device;
-        mContext = ctx;
-    }
-
-    public void addTimeoutCallback(GattTimeoutCallback l) {
-        synchronized (mGattTimeoutCallbacks) {
-            if (!mGattTimeoutCallbacks.contains(l)) {
-                mGattTimeoutCallbacks.add(l);
-            }
-        }
-    }
-
-    public void removeTimeoutCallback(GattTimeoutCallback l) {
-        synchronized (mGattTimeoutCallbacks) {
-            mGattTimeoutCallbacks.remove(l);
-        }
-    }
-
-    public void addCallback(BluetoothGattCallback cb) {
-        synchronized (mGattCallbacks) {
-            if (!mGattCallbacks.contains(cb)) {
-                mGattCallbacks.add(cb);
-            }
-        }
-    }
-
-    public void removeCallback(BluetoothGattCallback cb) {
-        synchronized (mGattCallbacks) {
-            mGattCallbacks.remove(cb);
-        }
-    }
-
-    public void addPairingCallback(LePairingCallback cb) {
-        synchronized (mGattCallbacks) {
-            if (!mPairingCallbacks.contains(cb)) {
-                mPairingCallbacks.add(cb);
-            }
-        }
-    }
-
-    public void removePairingCallback(LePairingCallback cb) {
-        synchronized (mGattCallbacks) {
-            mPairingCallbacks.remove(cb);
-        }
-    }
-
-    public void removeAllCallbacks() {
-        mGattCallbacks.clear();
-        mGattTimeoutCallbacks.clear();
-        mPairingCallbacks.clear();
-    }
-
-    public void setAutoConnect(boolean autoConnect) {
-        mAutoConnect = autoConnect;
-    }
-
-    public void setRetryFailedConnection(boolean retry, int maxRetries) {
-        synchronized (mConnectionLock) {
-            mRetryFailedConnection = retry;
-            mMaxConnectionRetries = maxRetries;
-        }
-    }
-
-    public void setPairingTimeout(int timeoutMs) {
-        if (timeoutMs > 0) {
-            mPairingTimeoutMs = timeoutMs;
-        }
-    }
-
-    public void setDiscoverServices(boolean discoverServices) {
-        mDiscoverServices = discoverServices;
-    }
-
-    public boolean unpair() {
-        registerPairingReceiver();
-        boolean success = mDevice != null && unpair(mDevice);
-        if (success) {
-            mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_PAIRING, mPairingTimeoutMs);
-        } else {
-            unregisterPairingReceiver();
-        }
-        return success;
-    }
-
-    public boolean pair() {
-        registerPairingReceiver();
-        boolean success = mDevice != null && pair(mDevice);
-        if (success) {
-            mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_PAIRING, mPairingTimeoutMs);
-        } else {
-            unregisterPairingReceiver();
-        }
-        return success;
-    }
-
-    /**
-     * Connect to remote device
-     *
-     * @return
-     */
-    public boolean connect() {
-        return connect(false);
-    }
-
-    public boolean connectDelayed() {
-        // Check if we have a pending connect/disconnect request
-        if (hasPendingConnectDisconnect()) {
-            Log.w(TAG, "connect: cannot connect, because there is a pending request "
-                    + getMessageString(mPendingConnectDisconnectRequest));
-            return false;
-        }
-        mHandler.sendEmptyMessageDelayed(REQUEST_CONNECT, CONNECT_DELAY_MS);
-        return true;
-    }
-
-    /**
-     * Disconnect from the remote device (if connected), and finish the gatt
-     * connection if requested
-     */
-    public boolean disconnect(boolean closeResources) {
-        return disconnect(true, closeResources);
-    }
-
-    /**
-     * Returns true if a LE connection is established to the remote device. This
-     * does NOT guarantee that services/ characteristics have been discovered
-     *
-     * @return
-     */
-    public boolean isConnected() {
-        return mConnectState == BluetoothGatt.STATE_CONNECTED;
-    }
-
-    public boolean servicesDiscovered() {
-        return mServicesDiscovered;
-    }
-
-    public boolean discoverServices() {
-        if (mGatt == null) {
-            return false;
-        }
-
-        mHandler.sendEmptyMessage(REQUEST_DISCOVER_SERVICES);
-        return true;
-    }
-
-    public void read(BluetoothGattDescriptor d) {
-        queueRequest(new GattRequest(REQUEST_READ_DESCRIPTOR, null, d), false);
-    }
-
-    public void read(BluetoothGattCharacteristic c, boolean immediate) {
-        queueRequest(new GattRequest(REQUEST_READ_CHAR, c, null), immediate);
-    }
-
-    public void read(BluetoothGattCharacteristic c) {
-        read(c, false);
-    }
-
-    public void write(BluetoothGattDescriptor d, byte[] value) {
-        queueRequest(new GattRequest(REQUEST_WRITE_DESCRIPTOR, null, d, value), false);
-    }
-
-    public void write(BluetoothGattCharacteristic c, byte[] value, boolean immediate) {
-        queueRequest(new GattRequest(REQUEST_WRITE_CHAR, c, null, value), immediate);
-    }
-
-    public void write(BluetoothGattCharacteristic c, byte[] value) {
-        write(c, value, false);
-    }
-
-    public void write(int id, BluetoothGattCharacteristic c, byte[] value) {
-        queueRequest(new GattRequest(id, REQUEST_WRITE_CHAR, c, null, value), false);
-
-    }
-
-    public boolean setCharacteristicNotification(BluetoothGattCharacteristic c, boolean enable) {
-        return mGatt != null && mGatt.setCharacteristicNotification(c, enable);
-    }
-
-    public void removeRequest(int requestType, BluetoothGattCharacteristic c) {
-        synchronized (mQueuedRequests) {
-            Iterator<GattRequest> i = mQueuedRequests.iterator();
-            while (i.hasNext()) {
-                GattRequest r = i.next();
-                if (r.mRequestType == requestType && r.mCharacteristic == c) {
-                    i.remove();
-                }
-            }
-        }
-    }
-
-    public void removeRequest(int requestType, BluetoothGattDescriptor d) {
-        synchronized (mQueuedRequests) {
-            Iterator<GattRequest> i = mQueuedRequests.iterator();
-            while (i.hasNext()) {
-                GattRequest r = i.next();
-                if (r.mRequestType == requestType && r.mDescriptor == d) {
-                    i.remove();
-                }
-            }
-        }
-    }
-
-    public BluetoothGatt getGatt() {
-        return mGatt;
-    }
-
-    public BluetoothDevice getDevice() {
-        return mDevice;
-    }
-
-    public BluetoothGattService findService(UUID uuid) {
-        if (uuid == null) {
-            return null;
-        }
-
-        List<BluetoothGattService> services = mGatt.getServices();
-        if (services == null) {
-            return null;
-        }
-        Iterator<BluetoothGattService> i = services.iterator();
-        while (i.hasNext()) {
-            BluetoothGattService s = i.next();
-            if (uuid.equals(s.getUuid())) {
-                return s;
-            }
-        }
-        return null;
-    }
-
-    public BluetoothGattCharacteristic findCharacteristic(BluetoothGattService s, UUID charUuid) {
-        if (s == null || charUuid == null) {
-            return null;
-        }
-        List<BluetoothGattCharacteristic> chars = s.getCharacteristics();
-        if (chars == null) {
-            return null;
-        }
-        Iterator<BluetoothGattCharacteristic> i = chars.iterator();
-        while (i.hasNext()) {
-            BluetoothGattCharacteristic c = i.next();
-            if (charUuid.equals(c.getUuid())) {
-                return c;
-            }
-        }
-        return null;
-    }
-
-    public BluetoothGattCharacteristic findCharacteristic(UUID serviceUuid, UUID charUuid) {
-        return findCharacteristic(findService(serviceUuid), charUuid);
-    }
-
-    public void finish() {
-        synchronized (mConnectionLock) {
-            if (mGatt != null) {
-                mGatt.close();
-                mGatt = null;
-            }
-        }
-    }
-
-    public void debugDumpInfo() {
-        Log.d(TAG, "DEBUG mAutoConnect=" + mAutoConnect);
-        Log.d(TAG, "DEBUG mRetryFailedConnection=" + mRetryFailedConnection);
-        Log.d(TAG, "DEBUG mMaxConnectionRetries=" + mMaxConnectionRetries);
-        Log.d(TAG, "DEBUG mDiscoverServices=" + mDiscoverServices);
-        Log.d(TAG, "");
-        Log.d(TAG, "DEBUG GattRequestManager = " + this);
-        Log.d(TAG, "DEBUG mGattCallbacks size= " + mGattCallbacks.size());
-        Log.d(TAG, "DEBUG mGattRequestListeners size= " + mGattTimeoutCallbacks.size());
-        Log.d(TAG, "");
-        Log.d(TAG, "DEBUG mQueuedRequests size=" + mQueuedRequests.size());
-        Log.d(TAG, "DEBUG mPendingRequest=" + mPendingRequest + ", id= "
-                + (mPendingRequest != null ? mPendingRequest.mId : "") + ", type="
-                + (mPendingRequest != null ? mPendingRequest.mRequestType : ""));
-        Log.d(TAG, "DEBUG mDevice=" + mDevice);
-        Log.d(TAG, "DEBUG mGatt=" + mGatt);
-        Log.d(TAG, "DEBUG mConnectState=" + getConnectionStateString(mConnectState));
-        Log.d(TAG, "DEBUG mServicesDiscovered=" + mServicesDiscovered);
-        Log.d(TAG, "DEBUG mPendingConnectDisconnectRequest=" + mPendingConnectDisconnectRequest);
-        Log.d(TAG, "DEBUG mIsUserDisconnectRequested=" + mIsUserDisconnectRequested);
-        Log.d(TAG, "DEBUG mPendingClose=" + mPendingClose);
-        Log.d(TAG, "DEBUG mIsClosedAndCleanedUp=" + mIsClosedAndCleanedUp);
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.util;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+import com.broadcom.app.wicedsense.Settings;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * Helper class to manage GATT requests to a remote device, ensuring that GATT
+ * read and are executed serially. In addition, this manages a timeout timer for
+ * each GATT read/write request, connect/disconnect requests, and a retry
+ * mechanism for service discovery
+ *
+ */
+public class GattRequestManager extends BluetoothGattCallback implements Handler.Callback {
+    private static final String TAG = Settings.TAG_PREFIX + "GattRequestManager";
+    private static final boolean DBG = true;
+
+    private static final int REQUEST_NONE = 0;
+    public static final int REQUEST_READ_CHAR = 1;
+    public static final int REQUEST_WRITE_CHAR = 2;
+    public static final int REQUEST_READ_DESCRIPTOR = 3;
+    public static final int REQUEST_WRITE_DESCRIPTOR = 4;
+    private static final int REQUEST_CONNECT = 10;
+    private static final int REQUEST_DISCONNECT = 20;
+    private static final int CONNECT_COMPLETE = 30;
+    private static final int EVENT_PAIRED = 40;
+    private static final int EVENT_UNPAIRED = 50;
+    private static final int CONNECT_DELAY_MS = 2000;
+
+    private static final int REQUEST_DISCOVER_SERVICES = 12;
+    private static final int DISCOVER_SERVICES_DELAY_MS = 3000;
+    private static final int TIMEOUT_TYPE_CONNECT = -1000;
+    private static final int TIMEOUT_TYPE_DISCONNECT = -1001;
+    private static final int TIMEOUT_TYPE_SERVICE_DISCOVERY = -1002;
+    private static final int TIMEOUT_TYPE_GATT_REQUEST = -1010;
+    private static final int TIMEOUT_TYPE_PAIRING = -1020;
+
+    private static final int TIMEOUT_CONNECT_MS = 10000;
+    private static final int TIMEOUT_DISCONNECT_MS = 3000;
+    private static final int TIMEOUT_SERVICE_DISCOVERY_MS = 10000;
+    private static final int TIMEOUT_GATT_REQUEST_MS = 5000;
+    private static final int TIMEOUT_PAIRING_MS = 5000;
+
+    private static String getMessageString(int msg) {
+        switch (msg) {
+        case REQUEST_NONE:
+            return "REQUEST_NONE";
+        case REQUEST_CONNECT:
+            return "REQUEST_CONNECT";
+        case REQUEST_DISCONNECT:
+            return "REQUEST_DISCONNECT";
+        case CONNECT_COMPLETE:
+            return "CONNECT_COMPLETE";
+        case EVENT_PAIRED:
+            return "EVENT_PAIRED";
+        case EVENT_UNPAIRED:
+            return "EVENT_UNPAIRED";
+        case REQUEST_READ_CHAR:
+            return "REQUEST_READ_CHAR";
+        case REQUEST_WRITE_CHAR:
+            return "REQUEST_WRITE_CHAR";
+        case REQUEST_READ_DESCRIPTOR:
+            return "REQUEST_READ_DESCRIPTOR";
+        case REQUEST_WRITE_DESCRIPTOR:
+            return "REQUEST_WRITE_DESCRIPTOR";
+        case REQUEST_DISCOVER_SERVICES:
+            return "REQUEST_DISCOVER_SERVICES";
+        case DISCOVER_SERVICES_DELAY_MS:
+            return "DISCOVER_SERVICES_DELAY_MS";
+        case TIMEOUT_TYPE_CONNECT:
+            return "TIMEOUT_TYPE_CONNECT";
+        case TIMEOUT_TYPE_DISCONNECT:
+            return "TIMEOUT_TYPE_DISCONNECT";
+        case TIMEOUT_TYPE_SERVICE_DISCOVERY:
+            return "TIMEOUT_TYPE_SERVICE_DISCOVERY";
+        case TIMEOUT_TYPE_GATT_REQUEST:
+            return "TIMEOUT_TYPE_GATT_REQUEST";
+        default:
+            return "UNKNOWN_TYPE " + msg;
+        }
+    }
+
+    private static String getConnectionStateString(int gattState) {
+        switch (gattState) {
+        case BluetoothGatt.STATE_CONNECTED:
+            return "STATE_CONNECTED";
+        case BluetoothGatt.STATE_DISCONNECTED:
+            return "STATE_DISCONNECTED";
+        case BluetoothGatt.STATE_CONNECTING:
+            return "STATE_CONNECTED";
+        case BluetoothGatt.STATE_DISCONNECTING:
+            return "STATE_DISCONNECTING";
+        default:
+            return "STATE_UNKNOWN " + gattState;
+        }
+    }
+
+    private static Method sSetPrCr;
+    private static Method sCrBd;
+    private static Method sRmBd;
+
+    static {
+        try {
+            sSetPrCr = BluetoothDevice.class.getMethod("setPairingConfirmation", boolean.class);
+            sCrBd = BluetoothDevice.class.getMethod("createBond", (Class[]) null);
+            sRmBd = BluetoothDevice.class.getMethod("removeBond", (Class[]) null);
+        } catch (Throwable t) {
+            Log.e(TAG, "error: getting bonding services", t);
+            sSetPrCr = null;
+            sCrBd = null;
+        }
+    }
+
+    private static boolean unpair(BluetoothDevice device) {
+        if (sRmBd != null) {
+            try {
+                sRmBd.invoke(device, (Object[]) null);
+                return true;
+            } catch (Throwable t) {
+                Log.e(TAG, "unpair: error", t);
+            }
+        }
+        return false;
+    }
+
+    private static boolean pair(BluetoothDevice device) {
+        if (sSetPrCr != null && sCrBd != null) {
+            try {
+                // sSetPrCr.invoke(device, true);
+                sCrBd.invoke(device, (Object[]) null);
+                return true;
+            } catch (Throwable t) {
+                Log.e(TAG, "pair: error", t);
+            }
+        }
+        return false;
+    }
+
+    public interface LePairingCallback {
+        public void onPaired(boolean isPaired);
+    }
+
+    public interface GattTimeoutCallback {
+        public void onTimeout(GattRequest request);
+    }
+
+    public static class GattRequest {
+        public final int mId;
+        public final BluetoothGattCharacteristic mCharacteristic;
+        public final BluetoothGattDescriptor mDescriptor;
+        public final int mRequestType;
+        public final byte[] mByteValues;
+
+        private GattRequest(int requestType, BluetoothGattCharacteristic c,
+                BluetoothGattDescriptor d, byte[] byteValues) {
+            this(0, requestType, c, d, byteValues);
+        }
+
+        private GattRequest(int requestType, BluetoothGattCharacteristic c,
+                BluetoothGattDescriptor d) {
+            this(requestType, c, d, null);
+        }
+
+        private GattRequest(int id, int requestType, BluetoothGattCharacteristic c,
+                BluetoothGattDescriptor d, byte[] byteValues) {
+            mId = id;
+            mRequestType = requestType;
+            mCharacteristic = c;
+            mDescriptor = d;
+            mByteValues = byteValues;
+        }
+    }
+
+    private class BluetoothPairingReceiver extends BroadcastReceiver {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            BluetoothDevice managedDevice = getDevice();
+            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 0);
+            if (DBG) {
+                Log.d(TAG, "BluetoothBondingReceiver.onReceive(): device = " + device
+                        + ", bondState= " + bondState + ", managedDevice= " + mDevice);
+            }
+            if (device != null && device.equals(managedDevice)) {
+                if (bondState == BluetoothDevice.BOND_BONDED) {
+                    mHandler.sendEmptyMessage(EVENT_PAIRED);
+                } else if (bondState == BluetoothDevice.BOND_NONE) {
+                    mHandler.sendEmptyMessage(EVENT_UNPAIRED);
+                }
+            }
+        }
+    }
+
+    private final Object mConnectionLock = new Object(); // Lock variable
+    private final Context mContext;
+
+    private final ArrayList<BluetoothGattCallback> mGattCallbacks = new ArrayList<BluetoothGattCallback>();
+    private final ArrayList<GattTimeoutCallback> mGattTimeoutCallbacks = new ArrayList<GattTimeoutCallback>();
+    private final ArrayList<LePairingCallback> mPairingCallbacks = new ArrayList<GattRequestManager.LePairingCallback>();
+
+    private final Handler mHandler = new Handler(this);
+    private final LinkedList<GattRequest> mQueuedRequests = new LinkedList<GattRequest>();
+    private GattRequest mPendingRequest;
+
+    private int mPairingTimeoutMs = TIMEOUT_PAIRING_MS;
+    private boolean mAutoConnect = false;
+    private boolean mRetryFailedConnection = true;
+    private boolean mDiscoverServices = true;
+    private int mMaxConnectionRetries = 2;
+
+    private BluetoothPairingReceiver mPairingReceiver;
+    private boolean mPairingReceiverRegistered;
+    private final BluetoothDevice mDevice;
+    private BluetoothGatt mGatt;
+    private int mConnectState;
+    private boolean mServicesDiscovered;
+    private int mPendingConnectDisconnectRequest;
+    private boolean mIsUserDisconnectRequested;
+    private boolean mPendingClose;
+    private boolean mIsClosedAndCleanedUp;
+    private int mReconnectCount;
+
+    private void startRequestTimeout(GattRequest r) {
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(TIMEOUT_TYPE_GATT_REQUEST, r),
+                TIMEOUT_GATT_REQUEST_MS);
+    }
+
+    private void cancelRequestTimeout() {
+        mHandler.removeMessages(TIMEOUT_TYPE_GATT_REQUEST);
+    }
+
+    private void queueRequest(GattRequest r, boolean atFront) {
+        synchronized (mQueuedRequests) {
+            if (atFront) {
+                mQueuedRequests.addFirst(r);
+            } else {
+                mQueuedRequests.add(r);
+            }
+            if (mPendingRequest == null) {
+                processQueuedRequests();
+            }
+        }
+    }
+
+    private void processQueuedRequests() {
+        GattRequest r = null;
+        synchronized (mQueuedRequests) {
+            mPendingRequest = mQueuedRequests.poll();
+            if (mPendingRequest == null) {
+                return;
+            }
+            r = mPendingRequest;
+        }
+
+        switch (r.mRequestType) {
+        case REQUEST_READ_CHAR:
+            if (mGatt == null) {
+                onCharacteristicRead(null, r.mCharacteristic, BluetoothGatt.GATT_FAILURE);
+                return;
+            }
+            startRequestTimeout(r);
+            mGatt.readCharacteristic(r.mCharacteristic);
+            break;
+        case REQUEST_WRITE_DESCRIPTOR:
+            if (mGatt == null) {
+                onDescriptorWrite(null, r.mDescriptor, BluetoothGatt.GATT_FAILURE);
+                return;
+            }
+            startRequestTimeout(r);
+            if (r.mByteValues != null) {
+                r.mDescriptor.setValue(r.mByteValues);
+            }
+            mGatt.writeDescriptor(r.mDescriptor);
+            break;
+        case REQUEST_WRITE_CHAR:
+            if (mGatt == null) {
+                onCharacteristicWrite(null, r.mCharacteristic, BluetoothGatt.GATT_FAILURE);
+                return;
+            }
+            startRequestTimeout(r);
+            if (DBG) {
+                Log.d(TAG, "writeChar: id=" + r.mId + ",value=" + r.mByteValues);
+            }
+            if (r.mByteValues != null) {
+                if (DBG) {
+                    Log.d(TAG, " valueLength=" + r.mByteValues.length);
+                }
+            }
+            if (r.mByteValues != null) {
+                r.mCharacteristic.setValue(r.mByteValues);
+            }
+            mGatt.writeCharacteristic(r.mCharacteristic);
+            break;
+        case REQUEST_READ_DESCRIPTOR:
+            if (mGatt == null) {
+                onDescriptorRead(null, r.mDescriptor, BluetoothGatt.GATT_FAILURE);
+                return;
+            }
+            startRequestTimeout(r);
+            mGatt.readDescriptor(r.mDescriptor);
+            break;
+        }
+    }
+
+    private void sendTimeoutEvent(GattRequest r) {
+        GattTimeoutCallback[] l = getTimeoutCallbacks();
+        int i = 0;
+        for (; i < l.length; i++) {
+            try {
+                l[i].onTimeout(r);
+            } catch (Throwable t) {
+                Log.e(TAG, "sendTimeoutEvent error : index =" + i, t);
+            }
+        }
+    }
+
+    private BluetoothGattCallback[] getGattCallbacks() {
+        BluetoothGattCallback[] cb = null;
+        synchronized (mGattCallbacks) {
+            cb = new BluetoothGattCallback[mGattCallbacks.size()];
+            mGattCallbacks.toArray(cb);
+        }
+        return cb;
+    }
+
+    private LePairingCallback[] getPairingCallbacks() {
+        LePairingCallback[] cb = null;
+        synchronized (mPairingCallbacks) {
+            cb = new LePairingCallback[mPairingCallbacks.size()];
+            mPairingCallbacks.toArray(cb);
+        }
+        return cb;
+    }
+
+    private GattTimeoutCallback[] getTimeoutCallbacks() {
+        GattTimeoutCallback[] l = null;
+        synchronized (mGattTimeoutCallbacks) {
+            l = new GattTimeoutCallback[mGattTimeoutCallbacks.size()];
+            mGattTimeoutCallbacks.toArray(l);
+        }
+        return l;
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        if (DBG) {
+            Log.d(TAG, "handleMessage:" + getMessageString(msg.what));
+        }
+        switch (msg.what) {
+        case EVENT_PAIRED:
+            onPaired(false);
+            break;
+        case EVENT_UNPAIRED:
+            onPaired(true);
+            break;
+        case REQUEST_CONNECT:
+            connect(true);
+            break;
+        case CONNECT_COMPLETE:
+            mReconnectCount = mMaxConnectionRetries;
+            break;
+        case REQUEST_DISCOVER_SERVICES:
+            if (mGatt.discoverServices()) {
+                mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_SERVICE_DISCOVERY,
+                        TIMEOUT_SERVICE_DISCOVERY_MS);
+            } else {
+                Log.w(TAG, "Error calling discover services.");
+                onServicesDiscovered(mGatt, BluetoothGatt.GATT_FAILURE);
+            }
+            break;
+        case TIMEOUT_TYPE_PAIRING:
+            onPaired(false);
+        case TIMEOUT_TYPE_CONNECT:
+            Log.w(TAG, "timeout: connect");
+            synchronized (mConnectionLock) {
+                mPendingClose = true; // Force gatt connection to close
+                onConnectionStateChange(mGatt, BluetoothGatt.GATT_FAILURE,
+                        BluetoothGatt.STATE_DISCONNECTED);
+            }
+            break;
+        case TIMEOUT_TYPE_DISCONNECT:
+            Log.w(TAG, "timeout: disconnect");
+            onConnectionStateChange(mGatt, BluetoothGatt.GATT_FAILURE,
+                    BluetoothGatt.STATE_DISCONNECTED);
+            break;
+        case TIMEOUT_TYPE_SERVICE_DISCOVERY:
+            Log.w(TAG, "timeout: service discovery");
+            onServicesDiscovered(mGatt, BluetoothGatt.GATT_FAILURE);
+            break;
+        case TIMEOUT_TYPE_GATT_REQUEST:
+            GattRequest r = (GattRequest) msg.obj;
+            Log.w(TAG, "timeout: " + r.mRequestType);
+            sendTimeoutEvent(r);
+            processQueuedRequests();
+            break;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onCharacteristicChanged(BluetoothGatt gatt,
+            BluetoothGattCharacteristic characteristic) {
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onCharacteristicChanged(gatt, characteristic);
+            } catch (Throwable t) {
+                Log.e(TAG, "onCharacteristicChanged[" + i + "]: error", t);
+            }
+        }
+    }
+
+    @Override
+    public void onCharacteristicRead(BluetoothGatt gatt,
+            BluetoothGattCharacteristic characteristic, int status) {
+        cancelRequestTimeout();
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onCharacteristicRead(gatt, characteristic, status);
+            } catch (Throwable t) {
+                Log.e(TAG, "onCharacteristicRead[" + i + "]: error", t);
+            }
+        }
+        processQueuedRequests();
+
+    }
+
+    @Override
+    public void onCharacteristicWrite(BluetoothGatt gatt,
+            BluetoothGattCharacteristic characteristic, int status) {
+        cancelRequestTimeout();
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onCharacteristicWrite(gatt, characteristic, status);
+            } catch (Throwable t) {
+                Log.e(TAG, "onCharacteristicWrite[" + i + "]: error", t);
+            }
+        }
+        processQueuedRequests();
+
+    }
+
+    private void registerPairingReceiver() {
+        if (mContext != null && !mPairingReceiverRegistered) {
+            if (mPairingReceiver == null) {
+                mPairingReceiver = new BluetoothPairingReceiver();
+            }
+            mContext.registerReceiver(mPairingReceiver, new IntentFilter(
+                    BluetoothDevice.ACTION_BOND_STATE_CHANGED));
+            mPairingReceiverRegistered = true;
+        }
+    }
+
+    private void unregisterPairingReceiver() {
+        if (mContext != null && mPairingReceiverRegistered && mPairingReceiver != null) {
+            mContext.unregisterReceiver(mPairingReceiver);
+            mPairingReceiverRegistered = false;
+        }
+    }
+
+    private void onPaired(boolean paired) {
+        mHandler.removeMessages(TIMEOUT_TYPE_PAIRING);
+        unregisterPairingReceiver();
+        LePairingCallback[] cb = getPairingCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onPaired(paired);
+            } catch (Throwable t) {
+                Log.e(TAG, "onPaired: error " + cb[i], t);
+            }
+        }
+    }
+
+    /**
+     * Cleanup after a connection is closed
+     */
+    private void closeAndCleanupGattConnection() {
+        Log.d(TAG, "closeAndCleanupGattConnection");
+        synchronized (mConnectionLock) {
+
+            // Check if we are already closed
+            if (mIsClosedAndCleanedUp) {
+                return;
+            }
+
+            // Remove all pending requests
+            mHandler.removeCallbacksAndMessages(null);
+            mQueuedRequests.clear();
+            mPendingRequest = null;
+
+            // Close gatt connection
+            if (mGatt != null) {
+                try {
+                    mGatt.close();
+                    mGatt = null;
+                } catch (Throwable t) {
+                    Log.w(TAG, "closeAndCleanupGattConnection: error", t);
+                }
+            }
+            mIsClosedAndCleanedUp = true;
+        }
+    }
+
+    /**
+     * Initialize state variables before connect request
+     */
+    private void initStateBeforeConnect() {
+        synchronized (mConnectionLock) {
+            mServicesDiscovered = false;
+            mPendingClose = false;
+            mIsClosedAndCleanedUp = false;
+            mIsUserDisconnectRequested = false;
+        }
+    }
+
+    private void startConnectDisconnectTimeout(boolean connect) {
+        synchronized (mConnectionLock) {
+            if (connect) {
+                mPendingConnectDisconnectRequest = REQUEST_CONNECT;
+                mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_CONNECT, TIMEOUT_CONNECT_MS);
+                if (DBG) {
+                    Log.d(TAG, "startConnectDisconnectTimeout(): starting connect timeout");
+                }
+            } else {
+                mPendingConnectDisconnectRequest = REQUEST_DISCONNECT;
+                mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_DISCONNECT, TIMEOUT_DISCONNECT_MS);
+                if (DBG) {
+                    Log.d(TAG, "startConnectDisconnectTimeout(): starting disconnect timeout");
+                }
+            }
+        }
+    }
+
+    private void stopConnectDisconnectTimeout() {
+        synchronized (mConnectionLock) {
+            if (mPendingConnectDisconnectRequest != REQUEST_NONE) {
+                if (DBG) {
+                    Log.d(TAG, "stopConnectDisconnectTimeout(): cancelling timeout "
+                            + getMessageString(mPendingConnectDisconnectRequest));
+                }
+                if (mPendingConnectDisconnectRequest == REQUEST_CONNECT) {
+                    mHandler.removeMessages(TIMEOUT_TYPE_CONNECT);
+                } else if (mPendingConnectDisconnectRequest == REQUEST_DISCONNECT) {
+                    mHandler.removeMessages(TIMEOUT_TYPE_DISCONNECT);
+                }
+                mPendingConnectDisconnectRequest = REQUEST_NONE;
+            }
+        }
+    }
+
+    private boolean hasPendingConnectDisconnect() {
+        return mPendingConnectDisconnectRequest != REQUEST_NONE;
+    }
+
+    public void startConnectCompleteTimer(int time) {
+        if (DBG) {
+            Log.d(TAG, "startConnectCompleteTimer(): timer=" + time);
+        }
+        if (time > 0) {
+            mHandler.sendEmptyMessageDelayed(CONNECT_COMPLETE, time);
+        }
+    }
+
+    public void stopConnectCompleteTimer() {
+        if (DBG) {
+            Log.d(TAG, "stopConnectCompleteTimer(): timer=");
+        }
+        mHandler.removeMessages(CONNECT_COMPLETE);
+    }
+
+    @Override
+    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+        if (DBG) {
+            Log.d(TAG, "onConnectionStateChange: state=" + getConnectionStateString(newState)
+                    + ", status=" + status);
+        }
+        stopConnectDisconnectTimeout();
+        mConnectState = newState;
+        // Handle disconnect
+        if (newState == BluetoothGatt.STATE_DISCONNECTED
+                || newState == BluetoothGatt.STATE_DISCONNECTING) {
+            // If we got a disconnect, check if if this was user initiated.
+            // If not, try to reconnect
+            if (DBG) {
+                Log.d(TAG, "onConnectionStateChange: mIsUserDisconnectRequested="
+                        + mIsUserDisconnectRequested + ",mPendingClose=" + mPendingClose
+                        + ", mRetryFailedConnection=" + mRetryFailedConnection);
+            }
+            if (mPendingClose) {
+                closeAndCleanupGattConnection();
+            } else {
+                stopConnectCompleteTimer();
+                mHandler.removeCallbacksAndMessages(null);
+                mQueuedRequests.clear();
+            }
+
+            if (!mIsUserDisconnectRequested && mRetryFailedConnection
+                    && ++mReconnectCount < mMaxConnectionRetries) {
+                if (DBG) {
+                    Log.d(TAG, "onConnectionStateChange: Auto-reconnecting...");
+                }
+                connectDelayed();
+                return;
+            }
+        } else if (newState == BluetoothGatt.STATE_CONNECTED) {
+            if (mDiscoverServices) {
+                // Android 4.3: some devices can't handle an immediate service
+                // discovery request
+                discoverServicesDelayed();
+            }
+        }
+        // Send events to interested listeners
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onConnectionStateChange(gatt, status, newState);
+            } catch (Throwable t) {
+                Log.e(TAG, "onConnectionStateChange[" + i + "]: error", t);
+            }
+        }
+    }
+
+    @Override
+    public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
+        cancelRequestTimeout();
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onDescriptorRead(gatt, descriptor, status);
+            } catch (Throwable t) {
+                Log.e(TAG, "onDescriptorRead[" + i + "]: error", t);
+            }
+        }
+        processQueuedRequests();
+
+    }
+
+    @Override
+    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
+        cancelRequestTimeout();
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onDescriptorWrite(gatt, descriptor, status);
+            } catch (Throwable t) {
+                Log.e(TAG, "onDescriptorWrite[" + i + "]: error", t);
+            }
+        }
+        processQueuedRequests();
+    }
+
+    @Override
+    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onReadRemoteRssi(gatt, rssi, status);
+            } catch (Throwable t) {
+                Log.e(TAG, "onReadRemoteRssi[" + i + "]: error", t);
+            }
+        }
+    }
+
+    @Override
+    public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onReliableWriteCompleted(gatt, status);
+            } catch (Throwable t) {
+                Log.e(TAG, "onReliableWriteCompleted[" + i + "]: error", t);
+            }
+        }
+    }
+
+    @Override
+    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+        mHandler.removeMessages(TIMEOUT_TYPE_SERVICE_DISCOVERY);
+
+        // Check if we need to retry
+        if (status == BluetoothGatt.GATT_SUCCESS) {
+            mServicesDiscovered = true;
+        }
+        if (mDiscoverServices && !mServicesDiscovered) {
+            // Disconnect and reconnect if mRetryFailedConnection=true
+            disconnect(false, false);
+            return;
+        }
+        BluetoothGattCallback[] cb = getGattCallbacks();
+        for (int i = 0; i < cb.length; i++) {
+            try {
+                cb[i].onServicesDiscovered(gatt, status);
+            } catch (Throwable t) {
+                Log.e(TAG, "onServicesDiscovered[" + i + "]: error", t);
+            }
+        }
+    }
+
+    private boolean connect(boolean isReconnect) {
+        synchronized (mConnectionLock) {
+
+            // Check if we have a pending connect/disconnect request
+            if (hasPendingConnectDisconnect()) {
+                Log.w(TAG, "connect: cannot connect, because there is a pending request "
+                        + getMessageString(mPendingConnectDisconnectRequest));
+                return false;
+            }
+            if (!isReconnect) {
+                mReconnectCount = 0;
+            }
+            // Remove any queued connect requests
+            mHandler.removeMessages(REQUEST_CONNECT);
+            initStateBeforeConnect();
+            boolean success = false;
+            startConnectDisconnectTimeout(true);
+            if (mGatt != null) {
+                success = mGatt.connect();
+            } else {
+                mGatt = mDevice.connectGatt(mContext, mAutoConnect, this);
+                success = (null != mGatt);
+            }
+            return success;
+        }
+    }
+
+    private boolean disconnect(boolean isUserRequested, boolean closeResources) {
+        synchronized (mConnectionLock) {
+            // Check if we have a pending connect/disconnect request
+            if (hasPendingConnectDisconnect()) {
+                Log.w(TAG, "disconnect: cannot disconnect, because there is a pending request "
+                        + getMessageString(mPendingConnectDisconnectRequest));
+                return false;
+            }
+            stopConnectCompleteTimer();
+            mIsUserDisconnectRequested = isUserRequested;
+            mServicesDiscovered = false;
+            if (mGatt != null) {
+                mPendingClose = closeResources;
+                startConnectDisconnectTimeout(false);
+                mGatt.disconnect();
+            } else {
+                Log.w(TAG, "disconnect: cannot disconnect, because gatt is null");
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private boolean discoverServicesDelayed() {
+        if (mGatt == null) {
+            return false;
+        }
+        mHandler.sendEmptyMessageDelayed(REQUEST_DISCOVER_SERVICES, DISCOVER_SERVICES_DELAY_MS);
+        return true;
+    }
+
+    // ---------------------Public API--------------------------------------
+    public GattRequestManager(Context ctx, BluetoothDevice device) {
+        mDevice = device;
+        mContext = ctx;
+    }
+
+    public void addTimeoutCallback(GattTimeoutCallback l) {
+        synchronized (mGattTimeoutCallbacks) {
+            if (!mGattTimeoutCallbacks.contains(l)) {
+                mGattTimeoutCallbacks.add(l);
+            }
+        }
+    }
+
+    public void removeTimeoutCallback(GattTimeoutCallback l) {
+        synchronized (mGattTimeoutCallbacks) {
+            mGattTimeoutCallbacks.remove(l);
+        }
+    }
+
+    public void addCallback(BluetoothGattCallback cb) {
+        synchronized (mGattCallbacks) {
+            if (!mGattCallbacks.contains(cb)) {
+                mGattCallbacks.add(cb);
+            }
+        }
+    }
+
+    public void removeCallback(BluetoothGattCallback cb) {
+        synchronized (mGattCallbacks) {
+            mGattCallbacks.remove(cb);
+        }
+    }
+
+    public void addPairingCallback(LePairingCallback cb) {
+        synchronized (mGattCallbacks) {
+            if (!mPairingCallbacks.contains(cb)) {
+                mPairingCallbacks.add(cb);
+            }
+        }
+    }
+
+    public void removePairingCallback(LePairingCallback cb) {
+        synchronized (mGattCallbacks) {
+            mPairingCallbacks.remove(cb);
+        }
+    }
+
+    public void removeAllCallbacks() {
+        mGattCallbacks.clear();
+        mGattTimeoutCallbacks.clear();
+        mPairingCallbacks.clear();
+    }
+
+    public void setAutoConnect(boolean autoConnect) {
+        mAutoConnect = autoConnect;
+    }
+
+    public void setRetryFailedConnection(boolean retry, int maxRetries) {
+        synchronized (mConnectionLock) {
+            mRetryFailedConnection = retry;
+            mMaxConnectionRetries = maxRetries;
+        }
+    }
+
+    public void setPairingTimeout(int timeoutMs) {
+        if (timeoutMs > 0) {
+            mPairingTimeoutMs = timeoutMs;
+        }
+    }
+
+    public void setDiscoverServices(boolean discoverServices) {
+        mDiscoverServices = discoverServices;
+    }
+
+    public boolean unpair() {
+        registerPairingReceiver();
+        boolean success = mDevice != null && unpair(mDevice);
+        if (success) {
+            mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_PAIRING, mPairingTimeoutMs);
+        } else {
+            unregisterPairingReceiver();
+        }
+        return success;
+    }
+
+    public boolean pair() {
+        registerPairingReceiver();
+        boolean success = mDevice != null && pair(mDevice);
+        if (success) {
+            mHandler.sendEmptyMessageDelayed(TIMEOUT_TYPE_PAIRING, mPairingTimeoutMs);
+        } else {
+            unregisterPairingReceiver();
+        }
+        return success;
+    }
+
+    /**
+     * Connect to remote device
+     *
+     * @return
+     */
+    public boolean connect() {
+        return connect(false);
+    }
+
+    public boolean connectDelayed() {
+        // Check if we have a pending connect/disconnect request
+        if (hasPendingConnectDisconnect()) {
+            Log.w(TAG, "connect: cannot connect, because there is a pending request "
+                    + getMessageString(mPendingConnectDisconnectRequest));
+            return false;
+        }
+        mHandler.sendEmptyMessageDelayed(REQUEST_CONNECT, CONNECT_DELAY_MS);
+        return true;
+    }
+
+    /**
+     * Disconnect from the remote device (if connected), and finish the gatt
+     * connection if requested
+     */
+    public boolean disconnect(boolean closeResources) {
+        return disconnect(true, closeResources);
+    }
+
+    /**
+     * Returns true if a LE connection is established to the remote device. This
+     * does NOT guarantee that services/ characteristics have been discovered
+     *
+     * @return
+     */
+    public boolean isConnected() {
+        return mConnectState == BluetoothGatt.STATE_CONNECTED;
+    }
+
+    public boolean servicesDiscovered() {
+        return mServicesDiscovered;
+    }
+
+    public boolean discoverServices() {
+        if (mGatt == null) {
+            return false;
+        }
+
+        mHandler.sendEmptyMessage(REQUEST_DISCOVER_SERVICES);
+        return true;
+    }
+
+    public void read(BluetoothGattDescriptor d) {
+        queueRequest(new GattRequest(REQUEST_READ_DESCRIPTOR, null, d), false);
+    }
+
+    public void read(BluetoothGattCharacteristic c, boolean immediate) {
+        queueRequest(new GattRequest(REQUEST_READ_CHAR, c, null), immediate);
+    }
+
+    public void read(BluetoothGattCharacteristic c) {
+        read(c, false);
+    }
+
+    public void write(BluetoothGattDescriptor d, byte[] value) {
+        queueRequest(new GattRequest(REQUEST_WRITE_DESCRIPTOR, null, d, value), false);
+    }
+
+    public void write(BluetoothGattCharacteristic c, byte[] value, boolean immediate) {
+        queueRequest(new GattRequest(REQUEST_WRITE_CHAR, c, null, value), immediate);
+    }
+
+    public void write(BluetoothGattCharacteristic c, byte[] value) {
+        write(c, value, false);
+    }
+
+    public void write(int id, BluetoothGattCharacteristic c, byte[] value) {
+        queueRequest(new GattRequest(id, REQUEST_WRITE_CHAR, c, null, value), false);
+
+    }
+
+    public boolean setCharacteristicNotification(BluetoothGattCharacteristic c, boolean enable) {
+        return mGatt != null && mGatt.setCharacteristicNotification(c, enable);
+    }
+
+    public void removeRequest(int requestType, BluetoothGattCharacteristic c) {
+        synchronized (mQueuedRequests) {
+            Iterator<GattRequest> i = mQueuedRequests.iterator();
+            while (i.hasNext()) {
+                GattRequest r = i.next();
+                if (r.mRequestType == requestType && r.mCharacteristic == c) {
+                    i.remove();
+                }
+            }
+        }
+    }
+
+    public void removeRequest(int requestType, BluetoothGattDescriptor d) {
+        synchronized (mQueuedRequests) {
+            Iterator<GattRequest> i = mQueuedRequests.iterator();
+            while (i.hasNext()) {
+                GattRequest r = i.next();
+                if (r.mRequestType == requestType && r.mDescriptor == d) {
+                    i.remove();
+                }
+            }
+        }
+    }
+
+    public BluetoothGatt getGatt() {
+        return mGatt;
+    }
+
+    public BluetoothDevice getDevice() {
+        return mDevice;
+    }
+
+    public BluetoothGattService findService(UUID uuid) {
+        if (uuid == null) {
+            return null;
+        }
+
+        List<BluetoothGattService> services = mGatt.getServices();
+        if (services == null) {
+            return null;
+        }
+        Iterator<BluetoothGattService> i = services.iterator();
+        while (i.hasNext()) {
+            BluetoothGattService s = i.next();
+            if (uuid.equals(s.getUuid())) {
+                return s;
+            }
+        }
+        return null;
+    }
+
+    public BluetoothGattCharacteristic findCharacteristic(BluetoothGattService s, UUID charUuid) {
+        if (s == null || charUuid == null) {
+            return null;
+        }
+        List<BluetoothGattCharacteristic> chars = s.getCharacteristics();
+        if (chars == null) {
+            return null;
+        }
+        Iterator<BluetoothGattCharacteristic> i = chars.iterator();
+        while (i.hasNext()) {
+            BluetoothGattCharacteristic c = i.next();
+            if (charUuid.equals(c.getUuid())) {
+                return c;
+            }
+        }
+        return null;
+    }
+
+    public BluetoothGattCharacteristic findCharacteristic(UUID serviceUuid, UUID charUuid) {
+        return findCharacteristic(findService(serviceUuid), charUuid);
+    }
+
+    public void finish() {
+        synchronized (mConnectionLock) {
+            if (mGatt != null) {
+                mGatt.close();
+                mGatt = null;
+            }
+        }
+    }
+
+    public void debugDumpInfo() {
+        Log.d(TAG, "DEBUG mAutoConnect=" + mAutoConnect);
+        Log.d(TAG, "DEBUG mRetryFailedConnection=" + mRetryFailedConnection);
+        Log.d(TAG, "DEBUG mMaxConnectionRetries=" + mMaxConnectionRetries);
+        Log.d(TAG, "DEBUG mDiscoverServices=" + mDiscoverServices);
+        Log.d(TAG, "");
+        Log.d(TAG, "DEBUG GattRequestManager = " + this);
+        Log.d(TAG, "DEBUG mGattCallbacks size= " + mGattCallbacks.size());
+        Log.d(TAG, "DEBUG mGattRequestListeners size= " + mGattTimeoutCallbacks.size());
+        Log.d(TAG, "");
+        Log.d(TAG, "DEBUG mQueuedRequests size=" + mQueuedRequests.size());
+        Log.d(TAG, "DEBUG mPendingRequest=" + mPendingRequest + ", id= "
+                + (mPendingRequest != null ? mPendingRequest.mId : "") + ", type="
+                + (mPendingRequest != null ? mPendingRequest.mRequestType : ""));
+        Log.d(TAG, "DEBUG mDevice=" + mDevice);
+        Log.d(TAG, "DEBUG mGatt=" + mGatt);
+        Log.d(TAG, "DEBUG mConnectState=" + getConnectionStateString(mConnectState));
+        Log.d(TAG, "DEBUG mServicesDiscovered=" + mServicesDiscovered);
+        Log.d(TAG, "DEBUG mPendingConnectDisconnectRequest=" + mPendingConnectDisconnectRequest);
+        Log.d(TAG, "DEBUG mIsUserDisconnectRequested=" + mIsUserDisconnectRequested);
+        Log.d(TAG, "DEBUG mPendingClose=" + mPendingClose);
+        Log.d(TAG, "DEBUG mIsClosedAndCleanedUp=" + mIsClosedAndCleanedUp);
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/util/MathUtils.java b/WicedSense/app/src/main/java/com/broadcom/util/MathUtils.java
index 4d692b2f520a3257e703f43171bdb8ec0b488408..d6f91ddefb0f4ee1032ffd1a7731ac3c4b9f8602 100644
--- a/WicedSense/app/src/main/java/com/broadcom/util/MathUtils.java
+++ b/WicedSense/app/src/main/java/com/broadcom/util/MathUtils.java
@@ -1,46 +1,46 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.util;
-
-/**
- * Helper math class
- *
- *
- */
-public class MathUtils {
-
-    public static double degreesToRadians(double value) {
-        return 0.0174532925 * value;
-    }
-
-    public static double radiansToDegrees(double value) {
-        return 57.295779578 * value;
-    }
-
-    public static double getMagnitude(double x, double y) {
-        return Math.sqrt(x * x + y * y);
-    }
-
-    public static double getDegrees(double y, double x) {
-
-        double mag = getMagnitude(x, y);
-        double nY = y / mag;
-        double nX = x / mag;
-        return radiansToDegrees(Math.atan2(nY, nX));
-    }
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.util;
+
+/**
+ * Helper math class
+ *
+ *
+ */
+public class MathUtils {
+
+    public static double degreesToRadians(double value) {
+        return 0.0174532925 * value;
+    }
+
+    public static double radiansToDegrees(double value) {
+        return 57.295779578 * value;
+    }
+
+    public static double getMagnitude(double x, double y) {
+        return Math.sqrt(x * x + y * y);
+    }
+
+    public static double getDegrees(double y, double x) {
+
+        double mag = getMagnitude(x, y);
+        double nY = y / mag;
+        double nX = x / mag;
+        return radiansToDegrees(Math.atan2(nY, nX));
+    }
+}
diff --git a/WicedSense/app/src/main/java/com/broadcom/util/PreferenceUtils.java b/WicedSense/app/src/main/java/com/broadcom/util/PreferenceUtils.java
index 01f45f26b2102789e96ca8962cd92db1c25d8df6..e6af42990cb7702cc977e0fe8c1101e9aa9f969a 100644
--- a/WicedSense/app/src/main/java/com/broadcom/util/PreferenceUtils.java
+++ b/WicedSense/app/src/main/java/com/broadcom/util/PreferenceUtils.java
@@ -1,112 +1,112 @@
-/******************************************************************************
- *
- *  Copyright (C) 2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-package com.broadcom.util;
-
-import android.preference.EditTextPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceGroup;
-import android.preference.PreferenceScreen;
-import android.util.Log;
-
-public class PreferenceUtils {
-    private static final String TAG = "PreferenceUtils";
-
-    public static void setSummaryToEditTextValue(PreferenceScreen root, String prefKey) {
-        EditTextPreference pref = null;
-        try {
-            pref = (EditTextPreference) root.findPreference(prefKey);
-            if (pref == null) {
-                return;
-            }
-            pref.setSummary(((EditTextPreference) pref).getText());
-        } catch (Throwable t) {
-            Log.w(TAG, "setSummaryToEditTextValue(): error", t);
-        }
-    }
-
-    public static void setSummaryToListValue(PreferenceScreen root, String prefKey) {
-        ListPreference pref = null;
-        try {
-            pref = (ListPreference) root.findPreference(prefKey);
-            if (pref == null) {
-                return;
-            }
-            pref.setSummary(((ListPreference) pref).getEntry());
-        } catch (Throwable t) {
-            Log.w(TAG, "setSummaryToListValue(): error", t);
-        }
-    }
-
-    public static void setSummaryToValue(Preference pref) {
-        if (pref.getClass() == EditTextPreference.class) {
-            pref.setSummary(((EditTextPreference) pref).getText());
-        } else if (pref.getClass() == ListPreference.class) {
-            pref.setSummary(((ListPreference) pref).getEntry());
-        } else {
-            Log.w(TAG, "setSummaryToValue(): unknown preference type " + pref);
-        }
-    }
-
-    public static void setSummaryToValue(PreferenceGroup pGroup) {
-        int prefcount = pGroup.getPreferenceCount();
-        for (int i = 0; i < prefcount; i++) {
-            setSummaryToValue(pGroup.getPreference(i));
-        }
-    }
-
-    public static void setSummaryToValue(PreferenceScreen root, String prefKey) {
-        Preference pref = null;
-        try {
-            pref = root.findPreference(prefKey);
-            if (pref == null) {
-                Log.w(TAG, "setSummaryToValue(): preference not found " + prefKey);
-                return;
-            }
-            setSummaryToValue(pref);
-        } catch (Throwable t) {
-            Log.w(TAG, "setSummaryToValue(): error", t);
-        }
-    }
-
-    public static void setValue(Preference pref, String value) {
-        if (pref.getClass() == EditTextPreference.class) {
-            ((EditTextPreference) pref).setText(value);
-        } else if (pref.getClass() == ListPreference.class) {
-            ((ListPreference) pref).setValue(value);
-        } else {
-            Log.w(TAG, "setValue(): unknown preference type " + pref.getClass());
-        }
-    }
-
-    public static void setValue(PreferenceScreen root, String prefKey, String value) {
-        Preference pref = null;
-        try {
-            pref = root.findPreference(prefKey);
-            if (pref == null) {
-                Log.d(TAG, "setValue(): preference not found " + prefKey);
-                return;
-            }
-            setValue(pref, value);
-        } catch (Throwable t) {
-            Log.d(TAG, "setValue(): error", t);
-        }
-
-    }
-
-}
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+package com.broadcom.util;
+
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+
+public class PreferenceUtils {
+    private static final String TAG = "PreferenceUtils";
+
+    public static void setSummaryToEditTextValue(PreferenceScreen root, String prefKey) {
+        EditTextPreference pref = null;
+        try {
+            pref = (EditTextPreference) root.findPreference(prefKey);
+            if (pref == null) {
+                return;
+            }
+            pref.setSummary(((EditTextPreference) pref).getText());
+        } catch (Throwable t) {
+            Log.w(TAG, "setSummaryToEditTextValue(): error", t);
+        }
+    }
+
+    public static void setSummaryToListValue(PreferenceScreen root, String prefKey) {
+        ListPreference pref = null;
+        try {
+            pref = (ListPreference) root.findPreference(prefKey);
+            if (pref == null) {
+                return;
+            }
+            pref.setSummary(((ListPreference) pref).getEntry());
+        } catch (Throwable t) {
+            Log.w(TAG, "setSummaryToListValue(): error", t);
+        }
+    }
+
+    public static void setSummaryToValue(Preference pref) {
+        if (pref.getClass() == EditTextPreference.class) {
+            pref.setSummary(((EditTextPreference) pref).getText());
+        } else if (pref.getClass() == ListPreference.class) {
+            pref.setSummary(((ListPreference) pref).getEntry());
+        } else {
+            Log.w(TAG, "setSummaryToValue(): unknown preference type " + pref);
+        }
+    }
+
+    public static void setSummaryToValue(PreferenceGroup pGroup) {
+        int prefcount = pGroup.getPreferenceCount();
+        for (int i = 0; i < prefcount; i++) {
+            setSummaryToValue(pGroup.getPreference(i));
+        }
+    }
+
+    public static void setSummaryToValue(PreferenceScreen root, String prefKey) {
+        Preference pref = null;
+        try {
+            pref = root.findPreference(prefKey);
+            if (pref == null) {
+                Log.w(TAG, "setSummaryToValue(): preference not found " + prefKey);
+                return;
+            }
+            setSummaryToValue(pref);
+        } catch (Throwable t) {
+            Log.w(TAG, "setSummaryToValue(): error", t);
+        }
+    }
+
+    public static void setValue(Preference pref, String value) {
+        if (pref.getClass() == EditTextPreference.class) {
+            ((EditTextPreference) pref).setText(value);
+        } else if (pref.getClass() == ListPreference.class) {
+            ((ListPreference) pref).setValue(value);
+        } else {
+            Log.w(TAG, "setValue(): unknown preference type " + pref.getClass());
+        }
+    }
+
+    public static void setValue(PreferenceScreen root, String prefKey, String value) {
+        Preference pref = null;
+        try {
+            pref = root.findPreference(prefKey);
+            if (pref == null) {
+                Log.d(TAG, "setValue(): preference not found " + prefKey);
+                return;
+            }
+            setValue(pref, value);
+        } catch (Throwable t) {
+            Log.d(TAG, "setValue(): error", t);
+        }
+
+    }
+
+}
diff --git a/WicedSense/app/src/main/res/drawable-ldpi/devicepicker_progress.xml b/WicedSense/app/src/main/res/drawable-ldpi/devicepicker_progress.xml
index f3011592ddfdab0d95208e2e51756b6f961f5e17..a217c18feaf9fdf4885f3c82593ce0e863ad7924 100644
--- a/WicedSense/app/src/main/res/drawable-ldpi/devicepicker_progress.xml
+++ b/WicedSense/app/src/main/res/drawable-ldpi/devicepicker_progress.xml
@@ -1,46 +1,46 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <item android:id="@android:id/background">
-        <shape>
-            <corners android:radius="2dp" />
-
-            <gradient
-                android:angle="270"
-                android:centerColor="#aaa"
-                android:centerY="0.75"
-                android:endColor="#ccc"
-                android:startColor="#eee" />
-        </shape>
-    </item>
-    <item android:id="@android:id/progress">
-        <clip>
-            <shape>
-                <corners android:radius="2dp" />
-
-                <gradient
-                    android:angle="270"
-                    android:endColor="#003760"
-                    android:startColor="#005794" />
-            </shape>
-        </clip>
-    </item>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item android:id="@android:id/background">
+        <shape>
+            <corners android:radius="2dp" />
+
+            <gradient
+                android:angle="270"
+                android:centerColor="#aaa"
+                android:centerY="0.75"
+                android:endColor="#ccc"
+                android:startColor="#eee" />
+        </shape>
+    </item>
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <corners android:radius="2dp" />
+
+                <gradient
+                    android:angle="270"
+                    android:endColor="#003760"
+                    android:startColor="#005794" />
+            </shape>
+        </clip>
+    </item>
+
 </layer-list>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/drawable-mdpi/devicepicker_progress.xml b/WicedSense/app/src/main/res/drawable-mdpi/devicepicker_progress.xml
index f3011592ddfdab0d95208e2e51756b6f961f5e17..a217c18feaf9fdf4885f3c82593ce0e863ad7924 100644
--- a/WicedSense/app/src/main/res/drawable-mdpi/devicepicker_progress.xml
+++ b/WicedSense/app/src/main/res/drawable-mdpi/devicepicker_progress.xml
@@ -1,46 +1,46 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <item android:id="@android:id/background">
-        <shape>
-            <corners android:radius="2dp" />
-
-            <gradient
-                android:angle="270"
-                android:centerColor="#aaa"
-                android:centerY="0.75"
-                android:endColor="#ccc"
-                android:startColor="#eee" />
-        </shape>
-    </item>
-    <item android:id="@android:id/progress">
-        <clip>
-            <shape>
-                <corners android:radius="2dp" />
-
-                <gradient
-                    android:angle="270"
-                    android:endColor="#003760"
-                    android:startColor="#005794" />
-            </shape>
-        </clip>
-    </item>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item android:id="@android:id/background">
+        <shape>
+            <corners android:radius="2dp" />
+
+            <gradient
+                android:angle="270"
+                android:centerColor="#aaa"
+                android:centerY="0.75"
+                android:endColor="#ccc"
+                android:startColor="#eee" />
+        </shape>
+    </item>
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <corners android:radius="2dp" />
+
+                <gradient
+                    android:angle="270"
+                    android:endColor="#003760"
+                    android:startColor="#005794" />
+            </shape>
+        </clip>
+    </item>
+
 </layer-list>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/drawable-xxhdpi/devicepicker_progress.xml b/WicedSense/app/src/main/res/drawable-xxhdpi/devicepicker_progress.xml
index e94d10d9ce585d5a60b95094330c6614b51da6f6..771a07ea71ac28d644f309258fe4836bb9ccd8df 100644
--- a/WicedSense/app/src/main/res/drawable-xxhdpi/devicepicker_progress.xml
+++ b/WicedSense/app/src/main/res/drawable-xxhdpi/devicepicker_progress.xml
@@ -1,47 +1,47 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <item android:id="@android:id/background">
-        <shape>
-            <corners android:radius="2dp" />
-
-            <gradient
-                android:angle="270"
-                android:centerColor="#aaa"
-                android:centerY="0.75"
-                android:endColor="#ccc"
-                android:startColor="#eee" />
-        </shape>
-    </item>
-    <item android:id="@android:id/progress">
-        <clip>
-            <shape>
-                <corners android:radius="2dp" />
-
-                <gradient
-                    android:angle="270"
-                    android:endColor="#003760"
-                    android:startColor="#005794" />
-            </shape>
-        </clip>
-    </item>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item android:id="@android:id/background">
+        <shape>
+            <corners android:radius="2dp" />
+
+            <gradient
+                android:angle="270"
+                android:centerColor="#aaa"
+                android:centerY="0.75"
+                android:endColor="#ccc"
+                android:startColor="#eee" />
+        </shape>
+    </item>
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <corners android:radius="2dp" />
+
+                <gradient
+                    android:angle="270"
+                    android:endColor="#003760"
+                    android:startColor="#005794" />
+            </shape>
+        </clip>
+    </item>
+
 </layer-list>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/drawable/scan_button_toggle.xml b/WicedSense/app/src/main/res/drawable/scan_button_toggle.xml
index b4e1af3bb2724c12c5bb4245609549a8a6aa2984..91f5b78edbc8367e28908fc820da60944b4151e3 100644
--- a/WicedSense/app/src/main/res/drawable/scan_button_toggle.xml
+++ b/WicedSense/app/src/main/res/drawable/scan_button_toggle.xml
@@ -1,24 +1,24 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:drawable="@drawable/ic_menu_stop" android:state_checked="true"/>
-    <item android:drawable="@drawable/ic_menu_refresh" android:state_checked="false"/>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:drawable="@drawable/ic_menu_stop" android:state_checked="true"/>
+    <item android:drawable="@drawable/ic_menu_refresh" android:state_checked="false"/>
+
 </selector>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/activity_fragment.xml b/WicedSense/app/src/main/res/layout/activity_fragment.xml
index 403c281985aa068dcbf091898579bb8d2662d1a7..2c6f82906faf0d5d3e6b135b804bf8b60f106de4 100644
--- a/WicedSense/app/src/main/res/layout/activity_fragment.xml
+++ b/WicedSense/app/src/main/res/layout/activity_fragment.xml
@@ -1,6 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             android:id="@+id/fragment_container"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent">
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:id="@+id/fragment_container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
 </FrameLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/battery_status.xml b/WicedSense/app/src/main/res/layout/battery_status.xml
index 36e53b714d75639c49d9af3610967812d8de074e..79f8e1c11f8531e4a3842ddbf9f2c412c232e354 100644
--- a/WicedSense/app/src/main/res/layout/battery_status.xml
+++ b/WicedSense/app/src/main/res/layout/battery_status.xml
@@ -1,54 +1,54 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:layout_gravity="center"
-    android:clickable="true">
-
-    <View
-        android:id="@+id/center"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:layout_centerInParent="true"
-        android:visibility="invisible" />
-
-    <ImageView
-        android:id="@+id/battery_status_icon"
-        android:layout_width="45dp"
-        android:layout_height="15dp"
-        android:layout_above="@id/center"
-        android:layout_centerHorizontal="true"
-        android:src="@drawable/battery_charge_background" >
-    </ImageView>
-
-    <TextView
-        android:id="@+id/battery_status"
-        android:layout_width="45dp"
-        android:layout_height="25dp"
-        android:layout_below="@id/center"
-        android:layout_centerHorizontal="true"
-        android:gravity="center"
-        android:text="100%" />
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:layout_gravity="center"
+    android:clickable="true">
+
+    <View
+        android:id="@+id/center"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_centerInParent="true"
+        android:visibility="invisible" />
+
+    <ImageView
+        android:id="@+id/battery_status_icon"
+        android:layout_width="45dp"
+        android:layout_height="15dp"
+        android:layout_above="@id/center"
+        android:layout_centerHorizontal="true"
+        android:src="@drawable/battery_charge_background" >
+    </ImageView>
+
+    <TextView
+        android:id="@+id/battery_status"
+        android:layout_width="45dp"
+        android:layout_height="25dp"
+        android:layout_below="@id/center"
+        android:layout_centerHorizontal="true"
+        android:gravity="center"
+        android:text="100%" />
+
 </RelativeLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/compass_fragment.xml b/WicedSense/app/src/main/res/layout/compass_fragment.xml
index ec044479869fac8a38718e9f3de2f48925f923e3..6fbba2698b3653b7fff02e77ac30988962507f96 100644
--- a/WicedSense/app/src/main/res/layout/compass_fragment.xml
+++ b/WicedSense/app/src/main/res/layout/compass_fragment.xml
@@ -1,98 +1,98 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content" >
-
-    <RelativeLayout
-        android:id="@+id/clickable_panel"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:clickable="true" >
-
-        <TextView
-            android:id="@+id/raw_x"
-            style="@style/compass_text_style"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_alignParentTop="true"
-            android:paddingLeft="@dimen/compass_text_margin_w"
-            android:paddingTop="@dimen/compass_text_margin_h"
-            android:visibility="invisible" />
-
-        <TextView
-            android:id="@+id/raw_y"
-            style="@style/compass_text_style"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentRight="true"
-            android:layout_alignParentTop="true"
-            android:paddingRight="@dimen/compass_text_margin_w"
-            android:paddingTop="@dimen/compass_text_margin_h"
-            android:visibility="invisible" />
-
-        <TextView
-            android:id="@+id/raw_z"
-            style="@style/compass_text_style"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true"
-            android:layout_alignParentLeft="true"
-            android:layout_marginBottom="@dimen/compass_text_margin_h"
-            android:layout_marginLeft="@dimen/compass_text_margin_w"
-            android:visibility="invisible" />
-
-        <TextView
-            android:id="@+id/raw_angle"
-            style="@style/compass_text_style"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentBottom="true"
-            android:layout_alignParentRight="true"
-            android:paddingBottom="@dimen/compass_text_margin_h"
-            android:paddingRight="@dimen/compass_text_margin_w"
-            android:visibility="invisible" />
-    </RelativeLayout>
-
-    <ImageView
-        android:id="@+id/compass_bk"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:layout_margin="@dimen/compass_gauge_border"
-        android:src="@drawable/compass_bg" />
-
-    <ImageView
-        android:id="@+id/needle"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:scaleType="centerInside"
-        android:src="@drawable/compass_needle_r" />
-
-    <ImageView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:src="@drawable/compass_center" />
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content" >
+
+    <RelativeLayout
+        android:id="@+id/clickable_panel"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clickable="true" >
+
+        <TextView
+            android:id="@+id/raw_x"
+            style="@style/compass_text_style"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentTop="true"
+            android:paddingLeft="@dimen/compass_text_margin_w"
+            android:paddingTop="@dimen/compass_text_margin_h"
+            android:visibility="invisible" />
+
+        <TextView
+            android:id="@+id/raw_y"
+            style="@style/compass_text_style"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:layout_alignParentTop="true"
+            android:paddingRight="@dimen/compass_text_margin_w"
+            android:paddingTop="@dimen/compass_text_margin_h"
+            android:visibility="invisible" />
+
+        <TextView
+            android:id="@+id/raw_z"
+            style="@style/compass_text_style"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentLeft="true"
+            android:layout_marginBottom="@dimen/compass_text_margin_h"
+            android:layout_marginLeft="@dimen/compass_text_margin_w"
+            android:visibility="invisible" />
+
+        <TextView
+            android:id="@+id/raw_angle"
+            style="@style/compass_text_style"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentRight="true"
+            android:paddingBottom="@dimen/compass_text_margin_h"
+            android:paddingRight="@dimen/compass_text_margin_w"
+            android:visibility="invisible" />
+    </RelativeLayout>
+
+    <ImageView
+        android:id="@+id/compass_bk"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_margin="@dimen/compass_gauge_border"
+        android:src="@drawable/compass_bg" />
+
+    <ImageView
+        android:id="@+id/needle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:scaleType="centerInside"
+        android:src="@drawable/compass_needle_r" />
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:src="@drawable/compass_center" />
+
 </FrameLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/database_output.xml b/WicedSense/app/src/main/res/layout/database_output.xml
index fb3d8a258054c81b274252adffcf37b375659a36..0d297504aa7d6d2c625595c691515684440bd626 100644
--- a/WicedSense/app/src/main/res/layout/database_output.xml
+++ b/WicedSense/app/src/main/res/layout/database_output.xml
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent">
-
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
 </LinearLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/devicepicker_activity.xml b/WicedSense/app/src/main/res/layout/devicepicker_activity.xml
index c1a91ac24b64b0c9234b5a1b880b242cce447e64..5e11c201a94cf0f6853cf9118bc4c25dee9f7c9d 100644
--- a/WicedSense/app/src/main/res/layout/devicepicker_activity.xml
+++ b/WicedSense/app/src/main/res/layout/devicepicker_activity.xml
@@ -1,60 +1,60 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-  -->
-<!-- Layout for Device Picker Activity -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:padding="10dp" >
-
-    <RelativeLayout
-        android:id="@+id/action_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:orientation="vertical" >
-
-        <View
-            android:layout_width="fill_parent"
-            android:layout_height="1dp"
-            android:background="@android:color/darker_gray" />
-
-        <Button
-            android:id="@+id/scan_button"
-            style="@style/DevicePickerButtonStyle"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_centerHorizontal="true"
-            android:paddingBottom="20dp"
-            android:paddingTop="20dp"
-            android:text="@string/menu_scan" />
-    </RelativeLayout>
-
-    <fragment
-        android:id="@+id/device_picker_id"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_above="@id/action_container"
-        android:layout_alignParentTop="true"
-        class="com.broadcom.app.ledevicepicker.DeviceListFragment"
-        android:tag="device_picker_id" />
-
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+  -->
+<!-- Layout for Device Picker Activity -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:padding="10dp" >
+
+    <RelativeLayout
+        android:id="@+id/action_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:orientation="vertical" >
+
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dp"
+            android:background="@android:color/darker_gray" />
+
+        <Button
+            android:id="@+id/scan_button"
+            style="@style/DevicePickerButtonStyle"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:paddingBottom="20dp"
+            android:paddingTop="20dp"
+            android:text="@string/menu_scan" />
+    </RelativeLayout>
+
+    <fragment
+        android:id="@+id/device_picker_id"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_above="@id/action_container"
+        android:layout_alignParentTop="true"
+        class="com.broadcom.app.ledevicepicker.DeviceListFragment"
+        android:tag="device_picker_id" />
+
 </RelativeLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/devicepicker_fragment.xml b/WicedSense/app/src/main/res/layout/devicepicker_fragment.xml
index 1c886998185fe03a90e4988bf86e811e2a04148a..3caf1d122bcb8a1302937b432bbc20dbd107fbc7 100644
--- a/WicedSense/app/src/main/res/layout/devicepicker_fragment.xml
+++ b/WicedSense/app/src/main/res/layout/devicepicker_fragment.xml
@@ -1,37 +1,37 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
-  -->
-<!-- Layout for Device Picker Fragment -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:padding="10dp" >
-
-
-    <fragment
-        android:id="@+id/device_picker_id"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        class="com.broadcom.app.ledevicepicker.DeviceListFragment"
-        android:tag="device_picker_id" />
-
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+  -->
+<!-- Layout for Device Picker Fragment -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:padding="10dp" >
+
+
+    <fragment
+        android:id="@+id/device_picker_id"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        class="com.broadcom.app.ledevicepicker.DeviceListFragment"
+        android:tag="device_picker_id" />
+
 </RelativeLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/devicepicker_listitem.xml b/WicedSense/app/src/main/res/layout/devicepicker_listitem.xml
index 3c3293c370a8af85a72153046133b9a52b0a9c3d..2c3df57920b33b052a1685780046c589d2b022bf 100644
--- a/WicedSense/app/src/main/res/layout/devicepicker_listitem.xml
+++ b/WicedSense/app/src/main/res/layout/devicepicker_listitem.xml
@@ -1,56 +1,56 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<!-- Layout for Device Picker Item in the Device Picker Fragment -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:padding="10dp"
-    android:orientation="horizontal">
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-
-        <TextView
-            android:id="@+id/device_name"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:textColor="#000"
-            android:textSize="24dp" />
-
-        <TextView
-            android:id="@+id/device_addr"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:textColor="#555"
-            android:textSize="14dip" />
-    </LinearLayout>
-
-    <ProgressBar
-        android:id="@+id/device_rssi"
-        android:layout_width="50dp"
-        android:layout_height="14dp"
-        android:layout_marginRight="10dp"
-        android:layout_alignParentRight="true"
-        android:layout_centerVertical="true"
-        android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"
-        android:indeterminateOnly="false"
-        android:progressDrawable="@drawable/devicepicker_progress" />
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<!-- Layout for Device Picker Item in the Device Picker Fragment -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="10dp"
+    android:orientation="horizontal">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/device_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textColor="#000"
+            android:textSize="24dp" />
+
+        <TextView
+            android:id="@+id/device_addr"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textColor="#555"
+            android:textSize="14dip" />
+    </LinearLayout>
+
+    <ProgressBar
+        android:id="@+id/device_rssi"
+        android:layout_width="50dp"
+        android:layout_height="14dp"
+        android:layout_marginRight="10dp"
+        android:layout_alignParentRight="true"
+        android:layout_centerVertical="true"
+        android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"
+        android:indeterminateOnly="false"
+        android:progressDrawable="@drawable/devicepicker_progress" />
 </RelativeLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/dialog_license.xml b/WicedSense/app/src/main/res/layout/dialog_license.xml
index b4c43e221b7f733bcd407d4205ebeecb7168734a..481ad39cbb61a5409f68d37ce7cf587fc7422256 100644
--- a/WicedSense/app/src/main/res/layout/dialog_license.xml
+++ b/WicedSense/app/src/main/res/layout/dialog_license.xml
@@ -1,48 +1,48 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<!-- Layout for License Confirmation Fragment -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/dialog_license"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".LicenseDialog" >
-
-    <ScrollView
-        android:id="@+id/scrollView1"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:paddingBottom="50dp"
-        android:paddingLeft="5dp"
-        android:paddingRight="5dp" >
-
-        <TextView
-            android:id="@+id/license_text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content" />
-    </ScrollView>
-
-    <Button
-        android:id="@+id/btnAccept"
-        android:layout_width="wrap_content"
-        android:layout_height="50dp"
-        android:layout_gravity="bottom|right"
-        android:text="@string/accept_license" />
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<!-- Layout for License Confirmation Fragment -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/dialog_license"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".LicenseDialog" >
+
+    <ScrollView
+        android:id="@+id/scrollView1"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingBottom="50dp"
+        android:paddingLeft="5dp"
+        android:paddingRight="5dp" >
+
+        <TextView
+            android:id="@+id/license_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+    </ScrollView>
+
+    <Button
+        android:id="@+id/btnAccept"
+        android:layout_width="wrap_content"
+        android:layout_height="50dp"
+        android:layout_gravity="bottom|right"
+        android:text="@string/accept_license" />
+
 </FrameLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/gyro_fragment.xml b/WicedSense/app/src/main/res/layout/gyro_fragment.xml
index 893a156a5b82f722cbbb381cc06d24f9f6f56992..9764291f97912db859591a4159949f4e0c20b8bf 100644
--- a/WicedSense/app/src/main/res/layout/gyro_fragment.xml
+++ b/WicedSense/app/src/main/res/layout/gyro_fragment.xml
@@ -1,169 +1,169 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/clickable_panel"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:clickable="true" >
-
-    <TextView
-        style="@style/gyro_text_style"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:paddingLeft="@dimen/gyro_text_margin_w"
-        android:paddingTop="@dimen/gyro_text_margin_h"
-        android:text="@string/gyro_label" />
-
-    <TextView
-        android:id="@+id/raw_x"
-        style="@style/gyro_text_style"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentRight="true"
-        android:layout_alignParentTop="true"
-        android:paddingRight="@dimen/gyro_text_margin_w"
-        android:paddingTop="@dimen/gyro_text_margin_h"
-        android:visibility="invisible" />
-
-    <TextView
-        android:id="@+id/raw_y"
-        style="@style/gyro_text_style"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentLeft="true"
-        android:paddingBottom="@dimen/gyro_text_margin_h"
-        android:paddingLeft="@dimen/gyro_text_margin_w"
-        android:visibility="invisible" />
-
-    <TextView
-        android:id="@+id/raw_z"
-        style="@style/gyro_text_style"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="true"
-        android:paddingBottom="@dimen/gyro_text_margin_h"
-        android:paddingRight="@dimen/gyro_text_margin_w"
-        android:visibility="invisible" />
-
-    <View
-        android:id="@+id/gyro_separator"
-        android:layout_width="1dp"
-        android:layout_height="1dp"
-        android:layout_centerInParent="true" />
-
-    <FrameLayout
-        android:id="@+id/gyro_z"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_above="@+id/gyro_separator"
-        android:layout_below="@+id/raw_x"
-        android:layout_centerHorizontal="true" >
-
-        <ImageView
-           android:id="@+id/gyro_bk_z"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:src="@drawable/gyro_bg" />
-
-        <ImageView
-            android:id="@+id/needle_z"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:scaleType="centerInside"
-            android:src="@drawable/gyro_needle" />
-
-        <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:scaleType="centerInside"
-            android:src="@drawable/gyro_center" />
-    </FrameLayout>
-
-    <FrameLayout
-        android:id="@+id/gyro_x"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_above="@+id/raw_y"
-        android:layout_below="@+id/gyro_separator"
-        android:layout_toLeftOf="@+id/gyro_separator" >
-
-        <ImageView
-            android:id="@+id/gyro_bk_x"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:src="@drawable/gyro_bg" />
-
-        <ImageView
-            android:id="@+id/needle_x"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:scaleType="centerInside"
-            android:src="@drawable/gyro_needle" />
-
-        <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:scaleType="centerInside"
-            android:src="@drawable/gyro_center" />
-    </FrameLayout>
-
-    <FrameLayout
-        android:id="@+id/gyro_y"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_above="@+id/raw_z"
-        android:layout_below="@+id/gyro_separator"
-        android:layout_toRightOf="@+id/gyro_separator" >
-
-        <ImageView
-           android:id="@+id/gyro_bk_y"
-             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:src="@drawable/gyro_bg" />
-
-        <ImageView
-            android:id="@+id/needle_y"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:scaleType="centerInside"
-            android:src="@drawable/gyro_needle" />
-
-        <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:scaleType="centerInside"
-            android:src="@drawable/gyro_center" />
-    </FrameLayout>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/clickable_panel"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clickable="true" >
+
+    <TextView
+        style="@style/gyro_text_style"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:paddingLeft="@dimen/gyro_text_margin_w"
+        android:paddingTop="@dimen/gyro_text_margin_h"
+        android:text="@string/gyro_label" />
+
+    <TextView
+        android:id="@+id/raw_x"
+        style="@style/gyro_text_style"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:paddingRight="@dimen/gyro_text_margin_w"
+        android:paddingTop="@dimen/gyro_text_margin_h"
+        android:visibility="invisible" />
+
+    <TextView
+        android:id="@+id/raw_y"
+        style="@style/gyro_text_style"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentLeft="true"
+        android:paddingBottom="@dimen/gyro_text_margin_h"
+        android:paddingLeft="@dimen/gyro_text_margin_w"
+        android:visibility="invisible" />
+
+    <TextView
+        android:id="@+id/raw_z"
+        style="@style/gyro_text_style"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:paddingBottom="@dimen/gyro_text_margin_h"
+        android:paddingRight="@dimen/gyro_text_margin_w"
+        android:visibility="invisible" />
+
+    <View
+        android:id="@+id/gyro_separator"
+        android:layout_width="1dp"
+        android:layout_height="1dp"
+        android:layout_centerInParent="true" />
+
+    <FrameLayout
+        android:id="@+id/gyro_z"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/gyro_separator"
+        android:layout_below="@+id/raw_x"
+        android:layout_centerHorizontal="true" >
+
+        <ImageView
+           android:id="@+id/gyro_bk_z"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:src="@drawable/gyro_bg" />
+
+        <ImageView
+            android:id="@+id/needle_z"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:scaleType="centerInside"
+            android:src="@drawable/gyro_needle" />
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:scaleType="centerInside"
+            android:src="@drawable/gyro_center" />
+    </FrameLayout>
+
+    <FrameLayout
+        android:id="@+id/gyro_x"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/raw_y"
+        android:layout_below="@+id/gyro_separator"
+        android:layout_toLeftOf="@+id/gyro_separator" >
+
+        <ImageView
+            android:id="@+id/gyro_bk_x"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:src="@drawable/gyro_bg" />
+
+        <ImageView
+            android:id="@+id/needle_x"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:scaleType="centerInside"
+            android:src="@drawable/gyro_needle" />
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:scaleType="centerInside"
+            android:src="@drawable/gyro_center" />
+    </FrameLayout>
+
+    <FrameLayout
+        android:id="@+id/gyro_y"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/raw_z"
+        android:layout_below="@+id/gyro_separator"
+        android:layout_toRightOf="@+id/gyro_separator" >
+
+        <ImageView
+           android:id="@+id/gyro_bk_y"
+             android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:src="@drawable/gyro_bg" />
+
+        <ImageView
+            android:id="@+id/needle_y"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:scaleType="centerInside"
+            android:src="@drawable/gyro_needle" />
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:scaleType="centerInside"
+            android:src="@drawable/gyro_center" />
+    </FrameLayout>
+
 </RelativeLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/humidity_fragment.xml b/WicedSense/app/src/main/res/layout/humidity_fragment.xml
index f8a2a57d8a696a213bf31576de23443af8204f93..7ceb957519395f99df219e7cf5e075d8c261a166 100644
--- a/WicedSense/app/src/main/res/layout/humidity_fragment.xml
+++ b/WicedSense/app/src/main/res/layout/humidity_fragment.xml
@@ -1,118 +1,118 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Humidity Fragment Layout.
-    Shows current, min, max, and average temperatures in a list-view-style format.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/humidity_layout"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical" >
-
-    <TextView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:textSize="36sp"
-        android:paddingTop="30dp"
-        android:paddingBottom="30dp"
-        android:text="@string/humidity_label"
-        style="?android:listSeparatorTextViewStyle" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/current_label" />
-
-        <TextView
-            android:id="@+id/humidity_current"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1.3"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/min_label" />
-
-        <TextView
-            android:id="@+id/humidity_min"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/max_label" />
-
-        <TextView
-            android:id="@+id/humidity_max"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/avg_label" />
-
-        <TextView
-            android:id="@+id/humidity_avg"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Humidity Fragment Layout.
+    Shows current, min, max, and average temperatures in a list-view-style format.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/humidity_layout"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:textSize="36sp"
+        android:paddingTop="30dp"
+        android:paddingBottom="30dp"
+        android:text="@string/humidity_label"
+        style="?android:listSeparatorTextViewStyle" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/current_label" />
+
+        <TextView
+            android:id="@+id/humidity_current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.3"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/min_label" />
+
+        <TextView
+            android:id="@+id/humidity_min"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/max_label" />
+
+        <TextView
+            android:id="@+id/humidity_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/avg_label" />
+
+        <TextView
+            android:id="@+id/humidity_avg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/main_activity.xml b/WicedSense/app/src/main/res/layout/main_activity.xml
index a92d65d6ab7b6c4b2b21fa311c335dc659fdfa66..04e5821168e03887b1b12b1f4906e75b923bdbcd 100644
--- a/WicedSense/app/src/main/res/layout/main_activity.xml
+++ b/WicedSense/app/src/main/res/layout/main_activity.xml
@@ -1,167 +1,167 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Main Fragment Layout.
-    Shows current values of Orientation, Speed, Compass, Air Pressure,
-    Humidity, and Temperature in a list-view-style format.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/temperature_layout"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical" >
-
-    <TextView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:textSize="36sp"
-        android:paddingTop="30dp"
-        android:paddingBottom="30dp"
-        android:text="@string/main_fragment_label"
-        style="?android:listSeparatorTextViewStyle" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="45dp"
-        style="?android:listSeparatorTextViewStyle">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/orientation_label" />
-
-        <TextView
-            android:id="@+id/orientation_current"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="2"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/speed_label" />
-
-        <TextView
-            android:id="@+id/speed_current"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1.5"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/compass_label" />
-
-        <TextView
-            android:id="@+id/temp_max"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="2"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/pressure_label" />
-
-        <TextView
-            android:id="@+id/temp_avg"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="3"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/humidity_label" />
-
-        <TextView
-            android:id="@+id/humidity_current"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="2"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/temperature_label" />
-
-        <TextView
-            android:id="@+id/temp_current"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="3.5"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Main Fragment Layout.
+    Shows current values of Orientation, Speed, Compass, Air Pressure,
+    Humidity, and Temperature in a list-view-style format.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/temperature_layout"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:textSize="36sp"
+        android:paddingTop="30dp"
+        android:paddingBottom="30dp"
+        android:text="@string/main_fragment_label"
+        style="?android:listSeparatorTextViewStyle" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="45dp"
+        style="?android:listSeparatorTextViewStyle">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/orientation_label" />
+
+        <TextView
+            android:id="@+id/orientation_current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="2"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/speed_label" />
+
+        <TextView
+            android:id="@+id/speed_current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.5"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/compass_label" />
+
+        <TextView
+            android:id="@+id/temp_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="2"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/pressure_label" />
+
+        <TextView
+            android:id="@+id/temp_avg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="3"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/humidity_label" />
+
+        <TextView
+            android:id="@+id/humidity_current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="2"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/temperature_label" />
+
+        <TextView
+            android:id="@+id/temp_current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="3.5"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/ota_app_info.xml b/WicedSense/app/src/main/res/layout/ota_app_info.xml
index 5f933488188416f51aff11e56573975301ee1d32..4e2354358bee3f242e8fb20da96c68f143eaea40 100644
--- a/WicedSense/app/src/main/res/layout/ota_app_info.xml
+++ b/WicedSense/app/src/main/res/layout/ota_app_info.xml
@@ -1,118 +1,118 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************
--->
-
-
-<!-- Layout for OTA App Info -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content" >
-
-    <ImageView
-        android:id="@+id/ota_background"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:scaleType="centerInside"
-        android:src="@drawable/ota_background" 
-         android:visibility="invisible"/>
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:baselineAligned="false"
-        android:orientation="vertical"
-        android:paddingBottom="20dp"
-        android:paddingLeft="30dp"
-        android:paddingRight="30dp"
-        android:paddingTop="20dp" >
-
-        <TextView
-            android:id="@+id/label_ota_device_id"
-            style="@android:style/TextAppearance.DeviceDefault.Medium"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/ota_device_id" />
-
-        <TextView
-            android:id="@+id/ota_device_name"
-            style="@android:style/TextAppearance.DeviceDefault.Small"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginBottom="5dp"
-            android:layout_marginLeft="10dp"
-            android:layout_marginRight="10dp"
-            android:layout_marginTop="10dp" />
-
-        <TextView
-            android:id="@+id/ota_device_address"
-            style="@android:style/TextAppearance.DeviceDefault.Small"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginBottom="10dp"
-            android:layout_marginLeft="10dp"
-            android:layout_marginRight="10dp"
-            android:layout_marginTop="5dp" />
-
-        <TextView
-            android:id="@+id/label_ota_app_id"
-            style="@android:style/TextAppearance.DeviceDefault.Medium"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/ota_app_id" />
-
-        <TextView
-            android:id="@+id/ota_app_id"
-            style="@android:style/TextAppearance.DeviceDefault.Small"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_margin="10dp" />
-
-        <TextView
-            android:id="@+id/label_ota_major_version"
-            style="@android:style/TextAppearance.DeviceDefault.Medium"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/ota_major_version" />
-
-        <TextView
-            android:id="@+id/ota_major_version"
-            style="@android:style/TextAppearance.DeviceDefault.Small"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_margin="10dp" />
-
-        <TextView
-            android:id="@+id/label_ota_minor_version"
-            style="@android:style/TextAppearance.DeviceDefault.Medium"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/ota_minor_version" />
-
-        <TextView
-            android:id="@+id/ota_minor_version"
-            style="@android:style/TextAppearance.DeviceDefault.Small"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_margin="10dp" />
-    </LinearLayout>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************
+-->
+
+
+<!-- Layout for OTA App Info -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content" >
+
+    <ImageView
+        android:id="@+id/ota_background"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:scaleType="centerInside"
+        android:src="@drawable/ota_background" 
+         android:visibility="invisible"/>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:baselineAligned="false"
+        android:orientation="vertical"
+        android:paddingBottom="20dp"
+        android:paddingLeft="30dp"
+        android:paddingRight="30dp"
+        android:paddingTop="20dp" >
+
+        <TextView
+            android:id="@+id/label_ota_device_id"
+            style="@android:style/TextAppearance.DeviceDefault.Medium"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/ota_device_id" />
+
+        <TextView
+            android:id="@+id/ota_device_name"
+            style="@android:style/TextAppearance.DeviceDefault.Small"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="5dp"
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginTop="10dp" />
+
+        <TextView
+            android:id="@+id/ota_device_address"
+            style="@android:style/TextAppearance.DeviceDefault.Small"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginTop="5dp" />
+
+        <TextView
+            android:id="@+id/label_ota_app_id"
+            style="@android:style/TextAppearance.DeviceDefault.Medium"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/ota_app_id" />
+
+        <TextView
+            android:id="@+id/ota_app_id"
+            style="@android:style/TextAppearance.DeviceDefault.Small"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp" />
+
+        <TextView
+            android:id="@+id/label_ota_major_version"
+            style="@android:style/TextAppearance.DeviceDefault.Medium"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/ota_major_version" />
+
+        <TextView
+            android:id="@+id/ota_major_version"
+            style="@android:style/TextAppearance.DeviceDefault.Small"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp" />
+
+        <TextView
+            android:id="@+id/label_ota_minor_version"
+            style="@android:style/TextAppearance.DeviceDefault.Medium"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/ota_minor_version" />
+
+        <TextView
+            android:id="@+id/ota_minor_version"
+            style="@android:style/TextAppearance.DeviceDefault.Small"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_margin="10dp" />
+    </LinearLayout>
+
 </FrameLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/pressure_fragment.xml b/WicedSense/app/src/main/res/layout/pressure_fragment.xml
index 33f73e48bea41f2f6390fe814394c7f141ec8228..0252aacb76a92c42589ea70d74fba6def716199b 100644
--- a/WicedSense/app/src/main/res/layout/pressure_fragment.xml
+++ b/WicedSense/app/src/main/res/layout/pressure_fragment.xml
@@ -1,118 +1,118 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Air Pressure Fragment Layout.
-    Shows current, min, max, and average Air Pressure in a list-view-style format.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/temperature_layout"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical" >
-
-    <TextView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:textSize="36sp"
-        android:paddingTop="30dp"
-        android:paddingBottom="30dp"
-        android:text="@string/pressure_label"
-        style="?android:listSeparatorTextViewStyle" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/current_label" />
-
-        <TextView
-            android:id="@+id/pressure_current"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1.3"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/min_label" />
-
-        <TextView
-            android:id="@+id/pressure_min"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/max_label" />
-
-        <TextView
-            android:id="@+id/pressure_max"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/avg_label" />
-
-        <TextView
-            android:id="@+id/pressure_avg"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Air Pressure Fragment Layout.
+    Shows current, min, max, and average Air Pressure in a list-view-style format.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/temperature_layout"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:textSize="36sp"
+        android:paddingTop="30dp"
+        android:paddingBottom="30dp"
+        android:text="@string/pressure_label"
+        style="?android:listSeparatorTextViewStyle" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/current_label" />
+
+        <TextView
+            android:id="@+id/pressure_current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.3"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/min_label" />
+
+        <TextView
+            android:id="@+id/pressure_min"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/max_label" />
+
+        <TextView
+            android:id="@+id/pressure_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/avg_label" />
+
+        <TextView
+            android:id="@+id/pressure_avg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/speed_fragment.xml b/WicedSense/app/src/main/res/layout/speed_fragment.xml
index 4d6cf89bc05763a08c4ff75698b866fd1dafa964..b9e495cb1e2229417dbae087da89e6dc91e46c75 100644
--- a/WicedSense/app/src/main/res/layout/speed_fragment.xml
+++ b/WicedSense/app/src/main/res/layout/speed_fragment.xml
@@ -1,118 +1,118 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Speed Fragment Layout.
-    Shows current, min, max, and average speeds in a list-view-style format.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/speed_layout"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical" >
-
-    <TextView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:textSize="36sp"
-        android:paddingTop="30dp"
-        android:paddingBottom="30dp"
-        android:text="@string/speed_label"
-        style="?android:listSeparatorTextViewStyle" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/current_label" />
-
-        <TextView
-            android:id="@+id/speed_current"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1.3"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/min_label" />
-
-        <TextView
-            android:id="@+id/speed_min"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/max_label" />
-
-        <TextView
-            android:id="@+id/speed_max"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/avg_label" />
-
-        <TextView
-            android:id="@+id/speed_avg"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Speed Fragment Layout.
+    Shows current, min, max, and average speeds in a list-view-style format.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/speed_layout"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:textSize="36sp"
+        android:paddingTop="30dp"
+        android:paddingBottom="30dp"
+        android:text="@string/speed_label"
+        style="?android:listSeparatorTextViewStyle" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/current_label" />
+
+        <TextView
+            android:id="@+id/speed_current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.3"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/min_label" />
+
+        <TextView
+            android:id="@+id/speed_min"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/max_label" />
+
+        <TextView
+            android:id="@+id/speed_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/avg_label" />
+
+        <TextView
+            android:id="@+id/speed_avg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/temperature_fragment.xml b/WicedSense/app/src/main/res/layout/temperature_fragment.xml
index d47a8ffd87007ebfd5c2bb0d05afbd4504c841e2..92782eee571f07405e9c9f624e9edd4437cc5ca9 100644
--- a/WicedSense/app/src/main/res/layout/temperature_fragment.xml
+++ b/WicedSense/app/src/main/res/layout/temperature_fragment.xml
@@ -1,118 +1,118 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Temperature Fragment Layout.
-    Shows current, min, max, and average temperatures in a list-view-style format.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/temperature_layout"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
-
-    <TextView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:textSize="36sp"
-        android:paddingTop="30dp"
-        android:paddingBottom="30dp"
-        android:text="@string/temperature_label"
-        style="?android:listSeparatorTextViewStyle" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/current_label" />
-
-        <TextView
-            android:id="@+id/temp_current"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1.3"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/min_label" />
-
-        <TextView
-            android:id="@+id/temp_min"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/max_label" />
-
-        <TextView
-            android:id="@+id/temp_max"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:paddingTop="15dp"
-        android:paddingBottom="15dp"
-        android:paddingStart="50dp"
-        android:paddingEnd="25dp"
-        style="?android:listSeparatorTextViewStyle" >
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/avg_label" />
-
-        <TextView
-            android:id="@+id/temp_avg"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:text="@string/placeholder" />
-    </LinearLayout>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Temperature Fragment Layout.
+    Shows current, min, max, and average temperatures in a list-view-style format.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/temperature_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:textSize="36sp"
+        android:paddingTop="30dp"
+        android:paddingBottom="30dp"
+        android:text="@string/temperature_label"
+        style="?android:listSeparatorTextViewStyle" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/current_label" />
+
+        <TextView
+            android:id="@+id/temp_current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.3"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/min_label" />
+
+        <TextView
+            android:id="@+id/temp_min"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/max_label" />
+
+        <TextView
+            android:id="@+id/temp_max"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:paddingTop="15dp"
+        android:paddingBottom="15dp"
+        android:paddingStart="50dp"
+        android:paddingEnd="25dp"
+        style="?android:listSeparatorTextViewStyle" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/avg_label" />
+
+        <TextView
+            android:id="@+id/temp_avg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="@string/placeholder" />
+    </LinearLayout>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/layout/temperature_fragment_c.xml b/WicedSense/app/src/main/res/layout/temperature_fragment_c.xml
index bd5c6f9ecac9a8f850c74b43e64376d0b1ea7d3b..aa1c326cd2b7f45a19ff472c07674fe0e1a40d0b 100644
--- a/WicedSense/app/src/main/res/layout/temperature_fragment_c.xml
+++ b/WicedSense/app/src/main/res/layout/temperature_fragment_c.xml
@@ -1,92 +1,92 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/******************************************************************************
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- ******************************************************************************/
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/gauge_layout"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:orientation="vertical" >
-
-    <TextView
-        android:id="@+id/gauge_value"
-        style="@style/thermo_text_style"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:layout_centerHorizontal="true" />
-
-    <TextView
-        android:id="@+id/gauge_label"
-        style="@style/thermo_text_style"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_centerHorizontal="true"
-        android:text="@string/temperature_label" />
-
-    <RelativeLayout
-        android:id="@+id/gauge_frame"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_above="@id/gauge_label"
-        android:layout_below="@id/gauge_value"
-        android:layout_centerVertical="true" >
-
-        <ImageView
-            android:id="@+id/gauge_bg"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_centerInParent="true"
-            android:scaleType="fitCenter"
-            android:src="@drawable/thermo_bg" />
-
-        <FrameLayout
-            android:id="@+id/gauge_level_frame"
-            android:layout_width="@dimen/thermo_level_width"
-            android:layout_height="wrap_content"
-            android:layout_alignBottom="@id/gauge_bg"
-            android:layout_alignTop="@id/gauge_bg"
-            android:layout_centerHorizontal="true"
-            android:layout_marginBottom="@dimen/thermo_range_bottom_margin"
-            android:layout_marginTop="@dimen/thermo_range_top_margin" >
-
-            <View
-                android:id="@+id/gauge_range"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent" >
-            </View>
-
-            <View
-                android:id="@+id/gauge_level"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:background="@color/temp_color" >
-            </View>
-        </FrameLayout>
-
-        <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_centerInParent="true"
-            android:scaleType="fitCenter"
-            android:src="@drawable/temp_c_top" />
-    </RelativeLayout>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/******************************************************************************
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/gauge_layout"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/gauge_value"
+        style="@style/thermo_text_style"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_centerHorizontal="true" />
+
+    <TextView
+        android:id="@+id/gauge_label"
+        style="@style/thermo_text_style"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:text="@string/temperature_label" />
+
+    <RelativeLayout
+        android:id="@+id/gauge_frame"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@id/gauge_label"
+        android:layout_below="@id/gauge_value"
+        android:layout_centerVertical="true" >
+
+        <ImageView
+            android:id="@+id/gauge_bg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:scaleType="fitCenter"
+            android:src="@drawable/thermo_bg" />
+
+        <FrameLayout
+            android:id="@+id/gauge_level_frame"
+            android:layout_width="@dimen/thermo_level_width"
+            android:layout_height="wrap_content"
+            android:layout_alignBottom="@id/gauge_bg"
+            android:layout_alignTop="@id/gauge_bg"
+            android:layout_centerHorizontal="true"
+            android:layout_marginBottom="@dimen/thermo_range_bottom_margin"
+            android:layout_marginTop="@dimen/thermo_range_top_margin" >
+
+            <View
+                android:id="@+id/gauge_range"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" >
+            </View>
+
+            <View
+                android:id="@+id/gauge_level"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:background="@color/temp_color" >
+            </View>
+        </FrameLayout>
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:scaleType="fitCenter"
+            android:src="@drawable/temp_c_top" />
+    </RelativeLayout>
+
 </RelativeLayout>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/menu-land/main.xml b/WicedSense/app/src/main/res/menu-land/main.xml
index 6de6df24b2e349704fab9b1a7c255eb63083beec..2af933ad39bd1606826fc8a8e7c46ba31833295c 100644
--- a/WicedSense/app/src/main/res/menu-land/main.xml
+++ b/WicedSense/app/src/main/res/menu-land/main.xml
@@ -1,50 +1,50 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <item
-        android:id="@+id/action_battery_status"
-        android:actionLayout="@layout/battery_status"
-        android:orderInCategory="100"
-        android:showAsAction="always"
-        android:title=""/>
-    <item
-        android:id="@+id/action_connectdisconnect"
-        android:orderInCategory="100"
-        android:showAsAction="always"
-        android:title="@string/connect"/>
-    <item
-        android:id="@+id/action_pick"
-        android:icon="@drawable/ic_action_search"
-        android:orderInCategory="100"
-        android:showAsAction="ifRoom|withText"
-        android:title="@string/devicepicker_pick"/>
-    <item
-        android:id="@+id/update_fw"
-        android:title="@string/update_fw"/>
-    <item
-        android:id="@+id/get_fw_info"
-        android:title="@string/get_fw_info"/>
-    <item
-        android:id="@+id/action_settings"
-        android:orderInCategory="200"
-        android:title="@string/action_settings"
-        android:titleCondensed="@string/action_settings"/>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_battery_status"
+        android:actionLayout="@layout/battery_status"
+        android:orderInCategory="100"
+        android:showAsAction="always"
+        android:title=""/>
+    <item
+        android:id="@+id/action_connectdisconnect"
+        android:orderInCategory="100"
+        android:showAsAction="always"
+        android:title="@string/connect"/>
+    <item
+        android:id="@+id/action_pick"
+        android:icon="@drawable/ic_action_search"
+        android:orderInCategory="100"
+        android:showAsAction="ifRoom|withText"
+        android:title="@string/devicepicker_pick"/>
+    <item
+        android:id="@+id/update_fw"
+        android:title="@string/update_fw"/>
+    <item
+        android:id="@+id/get_fw_info"
+        android:title="@string/get_fw_info"/>
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="200"
+        android:title="@string/action_settings"
+        android:titleCondensed="@string/action_settings"/>
+
 </menu>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/menu-sw600dp/main.xml b/WicedSense/app/src/main/res/menu-sw600dp/main.xml
index 07ea0fb15f20c7b6c233d4d8fa73a211f84e7eab..fdfe914c0766cf330d9831060812129912737b65 100644
--- a/WicedSense/app/src/main/res/menu-sw600dp/main.xml
+++ b/WicedSense/app/src/main/res/menu-sw600dp/main.xml
@@ -1,50 +1,50 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <item
-        android:id="@+id/action_battery_status"
-        android:actionLayout="@layout/battery_status"
-        android:orderInCategory="100"
-        android:showAsAction="always"
-        android:title=""/>
-    <item
-        android:id="@+id/action_connectdisconnect"
-        android:orderInCategory="100"
-        android:showAsAction="always"
-        android:title="@string/connect"/>
-    <item
-        android:id="@+id/action_pick"
-        android:icon="@drawable/ic_action_search"
-        android:orderInCategory="100"
-        android:showAsAction="always"
-        android:title="@string/devicepicker_pick"/>
-    <item
-        android:id="@+id/update_fw"
-        android:title="@string/update_fw"/>
-    <item
-        android:id="@+id/get_fw_info"
-        android:title="@string/get_fw_info"/>
-    <item
-        android:id="@+id/action_settings"
-        android:orderInCategory="200"
-        android:title="@string/action_settings"
-        android:titleCondensed="@string/action_settings"/>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_battery_status"
+        android:actionLayout="@layout/battery_status"
+        android:orderInCategory="100"
+        android:showAsAction="always"
+        android:title=""/>
+    <item
+        android:id="@+id/action_connectdisconnect"
+        android:orderInCategory="100"
+        android:showAsAction="always"
+        android:title="@string/connect"/>
+    <item
+        android:id="@+id/action_pick"
+        android:icon="@drawable/ic_action_search"
+        android:orderInCategory="100"
+        android:showAsAction="always"
+        android:title="@string/devicepicker_pick"/>
+    <item
+        android:id="@+id/update_fw"
+        android:title="@string/update_fw"/>
+    <item
+        android:id="@+id/get_fw_info"
+        android:title="@string/get_fw_info"/>
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="200"
+        android:title="@string/action_settings"
+        android:titleCondensed="@string/action_settings"/>
+
 </menu>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/menu/device_picker.xml b/WicedSense/app/src/main/res/menu/device_picker.xml
index 5aa1ede241938927bbcce7d3947208f8b326de55..31c51aa9aabe06a4d84ec69c09c6281c9e8c652e 100644
--- a/WicedSense/app/src/main/res/menu/device_picker.xml
+++ b/WicedSense/app/src/main/res/menu/device_picker.xml
@@ -1,36 +1,36 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <item
-        android:id="@+id/menu_scan"
-        android:icon="@drawable/ic_menu_refresh"
-        android:orderInCategory="100"
-        android:showAsAction="ifRoom|withText"
-        android:title="@string/menu_scan">
-    </item>
-    <item
-        android:id="@+id/menu_stop"
-        android:icon="@drawable/ic_menu_stop"
-        android:orderInCategory="110"
-        android:showAsAction="ifRoom|withText"
-        android:title="@string/menu_stop">
-    </item>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/menu_scan"
+        android:icon="@drawable/ic_menu_refresh"
+        android:orderInCategory="100"
+        android:showAsAction="ifRoom|withText"
+        android:title="@string/menu_scan">
+    </item>
+    <item
+        android:id="@+id/menu_stop"
+        android:icon="@drawable/ic_menu_stop"
+        android:orderInCategory="110"
+        android:showAsAction="ifRoom|withText"
+        android:title="@string/menu_stop">
+    </item>
+
 </menu>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/menu/main.xml b/WicedSense/app/src/main/res/menu/main.xml
index 221cefc3b72a11e300cb55f4e6ee984b2984408b..5f856545333c0e9098a044b7704d97608caf024c 100644
--- a/WicedSense/app/src/main/res/menu/main.xml
+++ b/WicedSense/app/src/main/res/menu/main.xml
@@ -1,47 +1,47 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <item
-        android:id="@+id/action_battery_status"
-        android:actionLayout="@layout/battery_status"
-        android:orderInCategory="100"
-        android:showAsAction="always"
-        android:title=""/>
-    <item
-        android:id="@+id/action_pick"
-        android:icon="@drawable/ic_action_search"
-        android:orderInCategory="100"
-        android:showAsAction="always"
-        android:title="@string/devicepicker_pick"/>
-    <item
-        android:id="@+id/data_dump"
-        android:orderInCategory="200"
-        android:title="@string/data_dump"/>
-    <item
-        android:id="@+id/get_fw_info"
-        android:orderInCategory="200"
-        android:title="@string/get_fw_info"/>
-    <item
-        android:id="@+id/action_settings"
-        android:orderInCategory="200"
-        android:title="@string/action_settings"
-        android:titleCondensed="@string/action_settings"/>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_battery_status"
+        android:actionLayout="@layout/battery_status"
+        android:orderInCategory="100"
+        android:showAsAction="always"
+        android:title=""/>
+    <item
+        android:id="@+id/action_pick"
+        android:icon="@drawable/ic_action_search"
+        android:orderInCategory="100"
+        android:showAsAction="always"
+        android:title="@string/devicepicker_pick"/>
+    <item
+        android:id="@+id/data_dump"
+        android:orderInCategory="200"
+        android:title="@string/data_dump"/>
+    <item
+        android:id="@+id/get_fw_info"
+        android:orderInCategory="200"
+        android:title="@string/get_fw_info"/>
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="200"
+        android:title="@string/action_settings"
+        android:titleCondensed="@string/action_settings"/>
+
 </menu>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values-land/sensor_ui_settings.xml b/WicedSense/app/src/main/res/values-land/sensor_ui_settings.xml
index 68d7aa626d8030bf07e997fca6d7e32bbca6efdf..7636dc17bb44e488a4c0be0dfdcb4834cc2c5e8b 100644
--- a/WicedSense/app/src/main/res/values-land/sensor_ui_settings.xml
+++ b/WicedSense/app/src/main/res/values-land/sensor_ui_settings.xml
@@ -1,6 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <dimen name="thermo_range_top_margin">15dp</dimen>
-    <dimen name="thermo_range_bottom_margin">29dp</dimen>
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <dimen name="thermo_range_top_margin">15dp</dimen>
+    <dimen name="thermo_range_bottom_margin">29dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values-sw600dp-land/sensor_ui_settings.xml b/WicedSense/app/src/main/res/values-sw600dp-land/sensor_ui_settings.xml
index 3e0d856a7a15a9d6f4cc186a411890caf54b8bb9..451363ea78676655f7751e4eced46316ff28491e 100644
--- a/WicedSense/app/src/main/res/values-sw600dp-land/sensor_ui_settings.xml
+++ b/WicedSense/app/src/main/res/values-sw600dp-land/sensor_ui_settings.xml
@@ -1,22 +1,22 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <style name="thermo_text_style" parent="@android:style/TextAppearance.Medium.Inverse"/>
-    
-    <!-- Gyro settings -->
-    <style name="gyro_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
-    <dimen name="gyro_text_margin_w">20dp</dimen>
-    <dimen name="gyro_text_margin_h">10dp</dimen>
-    
-    <!-- Accel settings -->
-    <style name="accel_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
-    <dimen name="accel_gauge_border">40dp</dimen>
-    <dimen name="accel_text_margin_w">20dp</dimen>
-    <dimen name="accel_text_margin_h">10dp</dimen>
-
-    <!-- Compass settings -->
-    <style name="compass_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
-    <dimen name="compass_gauge_border">40dp</dimen>
-    <dimen name="compass_text_margin_w">20dp</dimen>
-    <dimen name="compass_text_margin_h">10dp</dimen>
-
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="thermo_text_style" parent="@android:style/TextAppearance.Medium.Inverse"/>
+    
+    <!-- Gyro settings -->
+    <style name="gyro_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
+    <dimen name="gyro_text_margin_w">20dp</dimen>
+    <dimen name="gyro_text_margin_h">10dp</dimen>
+    
+    <!-- Accel settings -->
+    <style name="accel_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
+    <dimen name="accel_gauge_border">40dp</dimen>
+    <dimen name="accel_text_margin_w">20dp</dimen>
+    <dimen name="accel_text_margin_h">10dp</dimen>
+
+    <!-- Compass settings -->
+    <style name="compass_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
+    <dimen name="compass_gauge_border">40dp</dimen>
+    <dimen name="compass_text_margin_w">20dp</dimen>
+    <dimen name="compass_text_margin_h">10dp</dimen>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values-sw600dp/sensor_ui_settings.xml b/WicedSense/app/src/main/res/values-sw600dp/sensor_ui_settings.xml
index 3e0d856a7a15a9d6f4cc186a411890caf54b8bb9..451363ea78676655f7751e4eced46316ff28491e 100644
--- a/WicedSense/app/src/main/res/values-sw600dp/sensor_ui_settings.xml
+++ b/WicedSense/app/src/main/res/values-sw600dp/sensor_ui_settings.xml
@@ -1,22 +1,22 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <style name="thermo_text_style" parent="@android:style/TextAppearance.Medium.Inverse"/>
-    
-    <!-- Gyro settings -->
-    <style name="gyro_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
-    <dimen name="gyro_text_margin_w">20dp</dimen>
-    <dimen name="gyro_text_margin_h">10dp</dimen>
-    
-    <!-- Accel settings -->
-    <style name="accel_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
-    <dimen name="accel_gauge_border">40dp</dimen>
-    <dimen name="accel_text_margin_w">20dp</dimen>
-    <dimen name="accel_text_margin_h">10dp</dimen>
-
-    <!-- Compass settings -->
-    <style name="compass_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
-    <dimen name="compass_gauge_border">40dp</dimen>
-    <dimen name="compass_text_margin_w">20dp</dimen>
-    <dimen name="compass_text_margin_h">10dp</dimen>
-
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="thermo_text_style" parent="@android:style/TextAppearance.Medium.Inverse"/>
+    
+    <!-- Gyro settings -->
+    <style name="gyro_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
+    <dimen name="gyro_text_margin_w">20dp</dimen>
+    <dimen name="gyro_text_margin_h">10dp</dimen>
+    
+    <!-- Accel settings -->
+    <style name="accel_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
+    <dimen name="accel_gauge_border">40dp</dimen>
+    <dimen name="accel_text_margin_w">20dp</dimen>
+    <dimen name="accel_text_margin_h">10dp</dimen>
+
+    <!-- Compass settings -->
+    <style name="compass_text_style" parent="@android:style/TextAppearance.Medium.Inverse" />
+    <dimen name="compass_gauge_border">40dp</dimen>
+    <dimen name="compass_text_margin_w">20dp</dimen>
+    <dimen name="compass_text_margin_h">10dp</dimen>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values-sw720dp-land/sensor_ui_settings.xml b/WicedSense/app/src/main/res/values-sw720dp-land/sensor_ui_settings.xml
index 97151e97b5a05ad523e45258e5a9cfe854833400..feeba3abc4ce58c7d930206df51c1ddaa579898d 100644
--- a/WicedSense/app/src/main/res/values-sw720dp-land/sensor_ui_settings.xml
+++ b/WicedSense/app/src/main/res/values-sw720dp-land/sensor_ui_settings.xml
@@ -1,22 +1,22 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <style name="thermo_text_style" parent="@android:style/TextAppearance.Large.Inverse"/>
-    
-    <!-- Gyro settings -->
-    <style name="gyro_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
-    <dimen name="gyro_text_margin_w">20dp</dimen>
-    <dimen name="gyro_text_margin_h">10dp</dimen>
-    
-    <!-- Accel settings -->
-    <style name="accel_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
-    <dimen name="accel_gauge_border">40dp</dimen>
-    <dimen name="accel_text_margin_w">20dp</dimen>
-    <dimen name="accel_text_margin_h">10dp</dimen>
-
-    <!-- Compass settings -->
-    <style name="compass_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
-    <dimen name="compass_gauge_border">40dp</dimen>
-    <dimen name="compass_text_margin_w">20dp</dimen>
-    <dimen name="compass_text_margin_h">10dp</dimen>
-
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="thermo_text_style" parent="@android:style/TextAppearance.Large.Inverse"/>
+    
+    <!-- Gyro settings -->
+    <style name="gyro_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
+    <dimen name="gyro_text_margin_w">20dp</dimen>
+    <dimen name="gyro_text_margin_h">10dp</dimen>
+    
+    <!-- Accel settings -->
+    <style name="accel_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
+    <dimen name="accel_gauge_border">40dp</dimen>
+    <dimen name="accel_text_margin_w">20dp</dimen>
+    <dimen name="accel_text_margin_h">10dp</dimen>
+
+    <!-- Compass settings -->
+    <style name="compass_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
+    <dimen name="compass_gauge_border">40dp</dimen>
+    <dimen name="compass_text_margin_w">20dp</dimen>
+    <dimen name="compass_text_margin_h">10dp</dimen>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values-sw720dp/sensor_ui_settings.xml b/WicedSense/app/src/main/res/values-sw720dp/sensor_ui_settings.xml
index 97151e97b5a05ad523e45258e5a9cfe854833400..feeba3abc4ce58c7d930206df51c1ddaa579898d 100644
--- a/WicedSense/app/src/main/res/values-sw720dp/sensor_ui_settings.xml
+++ b/WicedSense/app/src/main/res/values-sw720dp/sensor_ui_settings.xml
@@ -1,22 +1,22 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <style name="thermo_text_style" parent="@android:style/TextAppearance.Large.Inverse"/>
-    
-    <!-- Gyro settings -->
-    <style name="gyro_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
-    <dimen name="gyro_text_margin_w">20dp</dimen>
-    <dimen name="gyro_text_margin_h">10dp</dimen>
-    
-    <!-- Accel settings -->
-    <style name="accel_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
-    <dimen name="accel_gauge_border">40dp</dimen>
-    <dimen name="accel_text_margin_w">20dp</dimen>
-    <dimen name="accel_text_margin_h">10dp</dimen>
-
-    <!-- Compass settings -->
-    <style name="compass_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
-    <dimen name="compass_gauge_border">40dp</dimen>
-    <dimen name="compass_text_margin_w">20dp</dimen>
-    <dimen name="compass_text_margin_h">10dp</dimen>
-
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="thermo_text_style" parent="@android:style/TextAppearance.Large.Inverse"/>
+    
+    <!-- Gyro settings -->
+    <style name="gyro_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
+    <dimen name="gyro_text_margin_w">20dp</dimen>
+    <dimen name="gyro_text_margin_h">10dp</dimen>
+    
+    <!-- Accel settings -->
+    <style name="accel_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
+    <dimen name="accel_gauge_border">40dp</dimen>
+    <dimen name="accel_text_margin_w">20dp</dimen>
+    <dimen name="accel_text_margin_h">10dp</dimen>
+
+    <!-- Compass settings -->
+    <style name="compass_text_style" parent="@android:style/TextAppearance.Large.Inverse" />
+    <dimen name="compass_gauge_border">40dp</dimen>
+    <dimen name="compass_text_margin_w">20dp</dimen>
+    <dimen name="compass_text_margin_h">10dp</dimen>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values-v11/styles.xml b/WicedSense/app/src/main/res/values-v11/styles.xml
index e2bd657066ee1393d2ad6ad84ae83b78f9917354..04fdda2e7e1b5121ebabd6e79993b570c898e593 100644
--- a/WicedSense/app/src/main/res/values-v11/styles.xml
+++ b/WicedSense/app/src/main/res/values-v11/styles.xml
@@ -1,31 +1,31 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<resources>
-
-    <!--
-        Base application theme for API 11+. This theme completely replaces
-        AppBaseTheme from res/values/styles.xml on API 11+ devices.
-    -->
-    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
-        <!-- API 11 theme customizations can go here. -->
-    </style>
-
-
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values-v11/styles_devicepicker.xml b/WicedSense/app/src/main/res/values-v11/styles_devicepicker.xml
index 5168890e25c5f54c6f527ef1cdbc9eeab0a0b36d..afa9428fcfb2f5099a8adf1c406345d5817e7974 100644
--- a/WicedSense/app/src/main/res/values-v11/styles_devicepicker.xml
+++ b/WicedSense/app/src/main/res/values-v11/styles_devicepicker.xml
@@ -1,32 +1,32 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<resources>
-
-    <color name="black">#FF000000</color>
-    <color name="whitegrey">#FFF2F2F2</color>
-
-    <style name="DevicePickerButtonStyle" parent="android:style/Widget.Holo.Light.Button.Borderless.Small" />
-
-    <style name="DevicePickerDialogTheme" parent="android:Theme.Holo.Light.Dialog">
-        <item name="android:windowFullscreen">true</item>
-        <item name="@android:windowBackground">@color/whitegrey</item>
-        <item name="@android:textColor">@color/black</item>
-    </style>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<resources>
+
+    <color name="black">#FF000000</color>
+    <color name="whitegrey">#FFF2F2F2</color>
+
+    <style name="DevicePickerButtonStyle" parent="android:style/Widget.Holo.Light.Button.Borderless.Small" />
+
+    <style name="DevicePickerDialogTheme" parent="android:Theme.Holo.Light.Dialog">
+        <item name="android:windowFullscreen">true</item>
+        <item name="@android:windowBackground">@color/whitegrey</item>
+        <item name="@android:textColor">@color/black</item>
+    </style>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values-v14/styles.xml b/WicedSense/app/src/main/res/values-v14/styles.xml
index 1c089a788c5a75c13949344137ed3698f6d2341e..24df58f6505d4500b00830c7ff19b035e60a6a4c 100644
--- a/WicedSense/app/src/main/res/values-v14/styles.xml
+++ b/WicedSense/app/src/main/res/values-v14/styles.xml
@@ -1,5 +1,5 @@
-<resources>
-
-    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
-
+<resources>
+
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/color.xml b/WicedSense/app/src/main/res/values/color.xml
index 8a78f87137fd77556816eff2c0868ff899c308e7..bba7ce1d0c2ca099b8d8c94ea4b6c0aba92137a1 100644
--- a/WicedSense/app/src/main/res/values/color.xml
+++ b/WicedSense/app/src/main/res/values/color.xml
@@ -1,11 +1,11 @@
-<resources>
-    <color name="game_status_failed">#943634</color>
-    <color name="game_status_finished">#355D2A</color>
-    <color name="game_status_date">#000</color>
-    <color name="game_counter_participant">#29AECC</color>
-    <color name="game_counter_finished">#E17900</color>
-    
-    <color name="temp_color">#CE0000</color>
-    <color name="pres_color">#003F99</color>
-    <color name="humd_color">#599900</color>
+<resources>
+    <color name="game_status_failed">#943634</color>
+    <color name="game_status_finished">#355D2A</color>
+    <color name="game_status_date">#000</color>
+    <color name="game_counter_participant">#29AECC</color>
+    <color name="game_counter_finished">#E17900</color>
+    
+    <color name="temp_color">#CE0000</color>
+    <color name="pres_color">#003F99</color>
+    <color name="humd_color">#599900</color>
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/default_ota_fw_info.xml b/WicedSense/app/src/main/res/values/default_ota_fw_info.xml
index 2891058a78190bc1356a5c64b0f1d8f202d26ca5..f2085e36be51718f293b5caad7f806ba4788636e 100644
--- a/WicedSense/app/src/main/res/values/default_ota_fw_info.xml
+++ b/WicedSense/app/src/main/res/values/default_ota_fw_info.xml
@@ -1,26 +1,26 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<!-- This resource file contains the string resources for the default OTA firmware update stored in the res/raw folder -->
-<resources>
-    <string name="default_ota_fw_version_name">WICED Sense firmware 1.3</string>
-    <string name="default_ota_fw_app_id">14880</string>
-    <string name="default_ota_fw_version_major">1</string>
-    <string name="default_ota_fw_version_minor">3</string>
-    <string name="default_ota_fw_mandatory">true</string>
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<!-- This resource file contains the string resources for the default OTA firmware update stored in the res/raw folder -->
+<resources>
+    <string name="default_ota_fw_version_name">WICED Sense firmware 1.3</string>
+    <string name="default_ota_fw_app_id">14880</string>
+    <string name="default_ota_fw_version_major">1</string>
+    <string name="default_ota_fw_version_minor">3</string>
+    <string name="default_ota_fw_mandatory">true</string>
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/sensor_ui_settings.xml b/WicedSense/app/src/main/res/values/sensor_ui_settings.xml
index 4c65830752efc98a47f284bbb3aa09978b78028c..e04b081ac1622b2d98b702d9977d7610c3e201a1 100644
--- a/WicedSense/app/src/main/res/values/sensor_ui_settings.xml
+++ b/WicedSense/app/src/main/res/values/sensor_ui_settings.xml
@@ -1,29 +1,29 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <style name="thermo_text_style" parent="@android:style/TextAppearance.Small.Inverse"/>
-    <dimen name="thermo_range_top_margin">20dp</dimen>
-    <dimen name="thermo_range_bottom_margin">38dp</dimen>
-    <dimen name="thermo_level_width">8dp</dimen>
-    
-    <dimen name="thermo_gauge_height">200dp</dimen>
-    <dimen name="thermo_gauge_width">40dp</dimen>
-    
-    <!-- Gyro settings -->
-    <style name="gyro_text_style" parent="@android:style/TextAppearance.Small.Inverse" />
-    <dimen name="gyro_text_margin_w">10dp</dimen>
-    <dimen name="gyro_text_margin_h">2dp</dimen>
-
-    <!-- Accel settings -->
-    <style name="accel_text_style" parent="@android:style/TextAppearance.Small.Inverse" />
-    <dimen name="accel_text_margin_w">10dp</dimen>
-    <dimen name="accel_text_margin_h">2dp</dimen>
-    <dimen name="accel_gauge_border">20dp</dimen>
-    
-    <!-- Compass settings -->
-    <style name="compass_text_style" parent="@android:style/TextAppearance.Small.Inverse" />
-    <dimen name="compass_text_margin_w">10dp</dimen>
-    <dimen name="compass_text_margin_h">2dp</dimen>
-    <dimen name="compass_gauge_border">20dp</dimen>
-    
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <style name="thermo_text_style" parent="@android:style/TextAppearance.Small.Inverse"/>
+    <dimen name="thermo_range_top_margin">20dp</dimen>
+    <dimen name="thermo_range_bottom_margin">38dp</dimen>
+    <dimen name="thermo_level_width">8dp</dimen>
+    
+    <dimen name="thermo_gauge_height">200dp</dimen>
+    <dimen name="thermo_gauge_width">40dp</dimen>
+    
+    <!-- Gyro settings -->
+    <style name="gyro_text_style" parent="@android:style/TextAppearance.Small.Inverse" />
+    <dimen name="gyro_text_margin_w">10dp</dimen>
+    <dimen name="gyro_text_margin_h">2dp</dimen>
+
+    <!-- Accel settings -->
+    <style name="accel_text_style" parent="@android:style/TextAppearance.Small.Inverse" />
+    <dimen name="accel_text_margin_w">10dp</dimen>
+    <dimen name="accel_text_margin_h">2dp</dimen>
+    <dimen name="accel_gauge_border">20dp</dimen>
+    
+    <!-- Compass settings -->
+    <style name="compass_text_style" parent="@android:style/TextAppearance.Small.Inverse" />
+    <dimen name="compass_text_margin_w">10dp</dimen>
+    <dimen name="compass_text_margin_h">2dp</dimen>
+    <dimen name="compass_gauge_border">20dp</dimen>
+    
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/strings.xml b/WicedSense/app/src/main/res/values/strings.xml
index 6a4483c48406ab5198d11a86624476aff8d686e1..ff8bca8e7e575620e4d7eae6854cb0b6406291c0 100644
--- a/WicedSense/app/src/main/res/values/strings.xml
+++ b/WicedSense/app/src/main/res/values/strings.xml
@@ -1,87 +1,87 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <!-- Main -->
-    <string name="app_name">WICED Sense</string>
-    <string name="title_devicepicker">Select the WICED Sense Kit</string>
-    <string name="title_activity_compass">WICED Sense</string>
-    <!--
-    <string name="temperature_label">TEMP</string>
-    <string name="temperature_value_f">%1$s\u00B0F</string>
-    <string name="temperature_value_c">%1$s\u00B0C</string>
-    <string name="pressure_label">PRES</string>
-    <string name="pressure_value">%1$s</string>
-    <string name="humidity_label">HUMD</string>
-    <string name="humidity_value">%1$s%%</string>
-    -->
-    <string name="gyro_label">GYRO</string>
-    <string name="accelerometer_label">ACCEL</string>
-    <string name="connect">Connect</string>
-    <string name="disconnect">Disconnect</string>
-    <string name="no_device">Device not selected</string>
-    <string name="error_unsupported_device">The selected device is not a WICED Sense Kit.</string>
-    <string name="use_animation">Use animation</string>
-    <string name="update_fw">Check for software updates</string>
-    <string name="get_fw_info">Get sensor info</string>
-
-    <!-- Menu strings -->
-    <string name="action_settings">Settings</string>
-    <!-- Compass -->
-    <string name="compass_raw_angle">%1$s\u00B0</string>
-    <string name="compass_bkg">Compass Background</string>
-    <string name="compass_arrow">Compass Arrow</string>
-
-    <!-- Raw values -->
-    <string name="raw_x">x:%1$s</string>
-    <string name="raw_y">y:%1$s</string>
-    <string name="raw_z">z:%1$s</string>
-    <string name="battery_status_default">--%</string>
-    <string name="battery_status">%1$s%%</string>
-
-    <!-- Settings -->
-    <string name="setting_title_version">Version</string>
-    <string name="setting_title_animation">Animation</string>
-    <string name="setting_title_temperature_scale">Temperature scale</string>
-    <string name="setting_title_gyro">Gyro</string>
-    <string name="setting_title_ecompass">eCompass</string>
-    <string name="setting_title_accelerometer">Accelerometer</string>
-    <string name="data_dump">Data Dump</string>
-    <string name="disconnect_message">Disconnect from Wiced first.</string>
-   
-    <string-array name="temperature_scale_type_names">
-        <item>Fahrenheit</item>
-        <item>Celcius</item>
-    </string-array>
-    
-    <!--  Do not localize -->
-    <string-array name="temperature_scale_type_values">
-        <item>F</item>
-        <item>C</item>
-    </string-array>
-
-
-
-
-
-    <!--Our Variables -->
-
-    <string name="current_label">Current:</string>
-    <string name="min_label">Min:</string>
-    <string name="max_label">Max:</string>
-    <string name="avg_label">Avg:</string>
-    <string name="placeholder">PLACEHOLDER</string>
-
-    <string name="main_fragment_label">Current Readings</string>
-    <string name="orientation_label">Orientation</string>
-    <string name="speed_label">Speed</string>
-    <string name="compass_label">Compass</string>
-    <string name="pressure_label">Air Pressure</string>
-    <string name="humidity_label">Humidity</string>
-    <string name="temperature_label">Temperature</string>
-
-
-
-
-
-
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!-- Main -->
+    <string name="app_name">WICED Sense</string>
+    <string name="title_devicepicker">Select the WICED Sense Kit</string>
+    <string name="title_activity_compass">WICED Sense</string>
+    <!--
+    <string name="temperature_label">TEMP</string>
+    <string name="temperature_value_f">%1$s\u00B0F</string>
+    <string name="temperature_value_c">%1$s\u00B0C</string>
+    <string name="pressure_label">PRES</string>
+    <string name="pressure_value">%1$s</string>
+    <string name="humidity_label">HUMD</string>
+    <string name="humidity_value">%1$s%%</string>
+    -->
+    <string name="gyro_label">GYRO</string>
+    <string name="accelerometer_label">ACCEL</string>
+    <string name="connect">Connect</string>
+    <string name="disconnect">Disconnect</string>
+    <string name="no_device">Device not selected</string>
+    <string name="error_unsupported_device">The selected device is not a WICED Sense Kit.</string>
+    <string name="use_animation">Use animation</string>
+    <string name="update_fw">Check for software updates</string>
+    <string name="get_fw_info">Get sensor info</string>
+
+    <!-- Menu strings -->
+    <string name="action_settings">Settings</string>
+    <!-- Compass -->
+    <string name="compass_raw_angle">%1$s\u00B0</string>
+    <string name="compass_bkg">Compass Background</string>
+    <string name="compass_arrow">Compass Arrow</string>
+
+    <!-- Raw values -->
+    <string name="raw_x">x:%1$s</string>
+    <string name="raw_y">y:%1$s</string>
+    <string name="raw_z">z:%1$s</string>
+    <string name="battery_status_default">--%</string>
+    <string name="battery_status">%1$s%%</string>
+
+    <!-- Settings -->
+    <string name="setting_title_version">Version</string>
+    <string name="setting_title_animation">Animation</string>
+    <string name="setting_title_temperature_scale">Temperature scale</string>
+    <string name="setting_title_gyro">Gyro</string>
+    <string name="setting_title_ecompass">eCompass</string>
+    <string name="setting_title_accelerometer">Accelerometer</string>
+    <string name="data_dump">Data Dump</string>
+    <string name="disconnect_message">Disconnect from Wiced first.</string>
+   
+    <string-array name="temperature_scale_type_names">
+        <item>Fahrenheit</item>
+        <item>Celcius</item>
+    </string-array>
+    
+    <!--  Do not localize -->
+    <string-array name="temperature_scale_type_values">
+        <item>F</item>
+        <item>C</item>
+    </string-array>
+
+
+
+
+
+    <!--Our Variables -->
+
+    <string name="current_label">Current:</string>
+    <string name="min_label">Min:</string>
+    <string name="max_label">Max:</string>
+    <string name="avg_label">Avg:</string>
+    <string name="placeholder">PLACEHOLDER</string>
+
+    <string name="main_fragment_label">Current Readings</string>
+    <string name="orientation_label">Orientation</string>
+    <string name="speed_label">Speed</string>
+    <string name="compass_label">Compass</string>
+    <string name="pressure_label">Air Pressure</string>
+    <string name="humidity_label">Humidity</string>
+    <string name="temperature_label">Temperature</string>
+
+
+
+
+
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/strings_devicepicker.xml b/WicedSense/app/src/main/res/values/strings_devicepicker.xml
index b692b378818d912d855b71e6126a2013a48e59d4..5f2fcee0190e1630dc41b0cd2ca533b09b47e3b2 100644
--- a/WicedSense/app/src/main/res/values/strings_devicepicker.xml
+++ b/WicedSense/app/src/main/res/values/strings_devicepicker.xml
@@ -1,30 +1,30 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<!-- This resource file contains string resources for the device picker component -->
-<resources>
-
-    <string name="notifier_bluetooth_unsupported">Bluetooth is not available on this device.</string>
-    <string name="devicepicker_pick">Select device</string>
-    <string name="default_title">Bluetooth LE Devices</string>
-    <string name="menu_scan">SEARCH FOR DEVICES</string>
-    <string name="menu_stop">STOP SEARCHING</string>
-    <string name="unknown_device">Device name not available</string>
-    <string name="error_internal">An unexpected error occurred while selecting a Bluetooth LE device.</string>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<!-- This resource file contains string resources for the device picker component -->
+<resources>
+
+    <string name="notifier_bluetooth_unsupported">Bluetooth is not available on this device.</string>
+    <string name="devicepicker_pick">Select device</string>
+    <string name="default_title">Bluetooth LE Devices</string>
+    <string name="menu_scan">SEARCH FOR DEVICES</string>
+    <string name="menu_stop">STOP SEARCHING</string>
+    <string name="unknown_device">Device name not available</string>
+    <string name="error_internal">An unexpected error occurred while selecting a Bluetooth LE device.</string>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/strings_exitconfirm.xml b/WicedSense/app/src/main/res/values/strings_exitconfirm.xml
index 16f0eb1b91c7962720854be68470eae70fbf67f9..04cd56245584a8f8e9aa2f55ebf3454bbab2f6db 100644
--- a/WicedSense/app/src/main/res/values/strings_exitconfirm.xml
+++ b/WicedSense/app/src/main/res/values/strings_exitconfirm.xml
@@ -1,28 +1,28 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<!-- This resource file contains string resources for the exit confirmation dialog component -->
-<resources>
-    <!-- Product specific strings -->
-    <string name="exit_title">Are you sure you want to exit?</string>
-    
-    <!-- Strings not dependent on product name -->
-    <string name="exit_ok">OK</string>
-    <string name="exit_cancel">Cancel</string>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<!-- This resource file contains string resources for the exit confirmation dialog component -->
+<resources>
+    <!-- Product specific strings -->
+    <string name="exit_title">Are you sure you want to exit?</string>
+    
+    <!-- Strings not dependent on product name -->
+    <string name="exit_ok">OK</string>
+    <string name="exit_cancel">Cancel</string>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/strings_license.xml b/WicedSense/app/src/main/res/values/strings_license.xml
index 185730701a86000d5a92ef9b3b9ce15d2105ddc0..508bfd3e61c70361040249b15bdd8d0ec034c8ac 100644
--- a/WicedSense/app/src/main/res/values/strings_license.xml
+++ b/WicedSense/app/src/main/res/values/strings_license.xml
@@ -1,25 +1,25 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<!-- This resource file contains string resources for the license confirmation dialog component -->
-<resources>
-
-    <string name="title_license">License Terms &amp; Conditions</string>
-    <string name="accept_license">I ACCEPT</string>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<!-- This resource file contains string resources for the license confirmation dialog component -->
+<resources>
+
+    <string name="title_license">License Terms &amp; Conditions</string>
+    <string name="accept_license">I ACCEPT</string>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/strings_ota.xml b/WicedSense/app/src/main/res/values/strings_ota.xml
index 29c336fa4474562ffa895594fcb0ac3ac1d6ea77..4f636b305c3162aa81ea406496cf613441bf7e50 100644
--- a/WicedSense/app/src/main/res/values/strings_ota.xml
+++ b/WicedSense/app/src/main/res/values/strings_ota.xml
@@ -1,65 +1,65 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<!-- This resource file contains string resources for the OTA components -->
-<resources>
-
-    <!-- Product Specific Strings -->
-    <string name="ota_chooser_title">WICED Sense updates available. Select an update.</string>
-    <string name="ota_dialog_title_available">WICED Sense update available</string>
-    <string name="ota_dialog_title_mandatory">WICED Sense update required</string>
-
-    <string name="ota_dialog_title">WICED Sense update</string>
-    <string name="ota_confirm_msg">Update the WICED Sense  device with %1$s?</string>
-    <string name="ota_dialog_progress_title">WICED Sense update in progress&#8230;</string>
-    <string name="ota_dialog_progress_msg_connecting">Connecting to WICED Sense device&#8230;</string>
-    <string name="ota_app_info_title">WICED Sense device info</string>
-
-    <!-- Strings not dependent on product name -->
-    <string name="ota_lbl_ok">OK</string>
-    <string name="ota_lbl_cancel">Cancel</string>
-    <string name="ota_nofirmware_msg">No update software is available.</string>
-    <string name="ota_dialog_progress_msg_starting">Starting software update&#8230;</string>
-    <string name="ota_dialog_progress_msg_discovering">Finding OTA services&#8230;</string>
-    <string name="ota_dialog_progress_msg_enablenotify">Turning on OTA services&#8230;</string>
-    <string name="ota_dialog_progress_msg_preparing">Preparing for software upload&#8230;</string>
-    <string name="ota_dialog_progress_msg_send_fw_info">Uploading software info&#8230;</string>
-    <string name="ota_dialog_progress_msg_send_fw">Uploading software&#8230;</string>
-    <string name="ota_dialog_progress_msg_verify_fw">Verifying software&#8230;</string>
-    <string name="ota_dialog_completed">Software update complete!</string>
-    <string name="ota_app_id">Application id</string>
-    <string name="ota_major_version">Major version</string>
-    <string name="ota_minor_version">Minor version</string>
-    <string name="ota_error_fw_open_error">Unable to read software.</string>
-    <string name="ota_error_internal">An unexpected error occurred. (error# %1$s)</string>
-    <string name="ota_error_connect">Unable to connect to the device.</string>
-    <string name="ota_error_discover">Unable to find OTA services.</string>
-    <string name="ota_error_timeout">Timeout occurred while upgrading. (state# %1$s)</string>
-    <string name="ota_error_write_char">Unable to write to the OTA service.</string>
-    <string name="ota_error_write_fw_info">Unable to upload the software info.</string>
-    <string name="ota_error_write_fw">Unable to upload the software.</string>
-    <string name="ota_error_bad_fw_info">The software info is corrupted. (error# %1$s)</string>
-    <string name="ota_error_bad_fw">The software is corrupted. (error# %1$s)</string>
-    <string name="ota_error_fw_validate_error">The software is corrupted or has been tampered with. (error# %1$s)</string>
-    <string name="ota_aborted">Software update cancelled.</string>
-    <string name="ota_device_id">Device</string>
-    <string name="ota_select_device">(Select a device)</string>
-    <string name="ota_unknown_device_name">(Unknown device name)</string>
-    <string name="ota_unknown_value">--</string>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<!-- This resource file contains string resources for the OTA components -->
+<resources>
+
+    <!-- Product Specific Strings -->
+    <string name="ota_chooser_title">WICED Sense updates available. Select an update.</string>
+    <string name="ota_dialog_title_available">WICED Sense update available</string>
+    <string name="ota_dialog_title_mandatory">WICED Sense update required</string>
+
+    <string name="ota_dialog_title">WICED Sense update</string>
+    <string name="ota_confirm_msg">Update the WICED Sense  device with %1$s?</string>
+    <string name="ota_dialog_progress_title">WICED Sense update in progress&#8230;</string>
+    <string name="ota_dialog_progress_msg_connecting">Connecting to WICED Sense device&#8230;</string>
+    <string name="ota_app_info_title">WICED Sense device info</string>
+
+    <!-- Strings not dependent on product name -->
+    <string name="ota_lbl_ok">OK</string>
+    <string name="ota_lbl_cancel">Cancel</string>
+    <string name="ota_nofirmware_msg">No update software is available.</string>
+    <string name="ota_dialog_progress_msg_starting">Starting software update&#8230;</string>
+    <string name="ota_dialog_progress_msg_discovering">Finding OTA services&#8230;</string>
+    <string name="ota_dialog_progress_msg_enablenotify">Turning on OTA services&#8230;</string>
+    <string name="ota_dialog_progress_msg_preparing">Preparing for software upload&#8230;</string>
+    <string name="ota_dialog_progress_msg_send_fw_info">Uploading software info&#8230;</string>
+    <string name="ota_dialog_progress_msg_send_fw">Uploading software&#8230;</string>
+    <string name="ota_dialog_progress_msg_verify_fw">Verifying software&#8230;</string>
+    <string name="ota_dialog_completed">Software update complete!</string>
+    <string name="ota_app_id">Application id</string>
+    <string name="ota_major_version">Major version</string>
+    <string name="ota_minor_version">Minor version</string>
+    <string name="ota_error_fw_open_error">Unable to read software.</string>
+    <string name="ota_error_internal">An unexpected error occurred. (error# %1$s)</string>
+    <string name="ota_error_connect">Unable to connect to the device.</string>
+    <string name="ota_error_discover">Unable to find OTA services.</string>
+    <string name="ota_error_timeout">Timeout occurred while upgrading. (state# %1$s)</string>
+    <string name="ota_error_write_char">Unable to write to the OTA service.</string>
+    <string name="ota_error_write_fw_info">Unable to upload the software info.</string>
+    <string name="ota_error_write_fw">Unable to upload the software.</string>
+    <string name="ota_error_bad_fw_info">The software info is corrupted. (error# %1$s)</string>
+    <string name="ota_error_bad_fw">The software is corrupted. (error# %1$s)</string>
+    <string name="ota_error_fw_validate_error">The software is corrupted or has been tampered with. (error# %1$s)</string>
+    <string name="ota_aborted">Software update cancelled.</string>
+    <string name="ota_device_id">Device</string>
+    <string name="ota_select_device">(Select a device)</string>
+    <string name="ota_unknown_device_name">(Unknown device name)</string>
+    <string name="ota_unknown_value">--</string>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/styles.xml b/WicedSense/app/src/main/res/values/styles.xml
index 9d7b67048595561651401a1854062c563c254d73..28d358bb8a7ad8444f73057daa9e661801835e54 100644
--- a/WicedSense/app/src/main/res/values/styles.xml
+++ b/WicedSense/app/src/main/res/values/styles.xml
@@ -1,44 +1,44 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <color name="ltgray">#D3D3D3</color>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="android:Theme.Light">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="AppBaseTheme">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-    <!-- Display selected list item with a background indicator -->
-    <style name="activated" parent="AppTheme"></style>
-
-    <style name="DeviceListTheme"></style>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <color name="ltgray">#D3D3D3</color>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+    <!-- Display selected list item with a background indicator -->
+    <style name="activated" parent="AppTheme"></style>
+
+    <style name="DeviceListTheme"></style>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/values/styles_devicepicker.xml b/WicedSense/app/src/main/res/values/styles_devicepicker.xml
index 70ae8a97a21b7d68d26905c243f1d807ffdcbc2c..86dea28aee4770f91d2a2d530b9d4c493190f689 100644
--- a/WicedSense/app/src/main/res/values/styles_devicepicker.xml
+++ b/WicedSense/app/src/main/res/values/styles_devicepicker.xml
@@ -1,33 +1,33 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- *  Copyright (C) 2013-2014 Broadcom Corporation
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
--->
-<!-- This resource file contains style resources for the device picker component -->
-<resources>
-
-    <color name="black">#FF000000</color>
-    <color name="whitegrey">#FFF2F2F2</color>
-
-    <style name="DevicePickerButtonStyle" />
-
-    <style name="DevicePickerDialogTheme" parent="@android:style/Theme.Dialog">
-        <item name="android:windowFullscreen">true</item>
-        <item name="@android:windowBackground">@color/whitegrey</item>
-        <item name="@android:textColor">@color/black</item>
-    </style>
-
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ *
+ *  Copyright (C) 2013-2014 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+-->
+<!-- This resource file contains style resources for the device picker component -->
+<resources>
+
+    <color name="black">#FF000000</color>
+    <color name="whitegrey">#FFF2F2F2</color>
+
+    <style name="DevicePickerButtonStyle" />
+
+    <style name="DevicePickerDialogTheme" parent="@android:style/Theme.Dialog">
+        <item name="android:windowFullscreen">true</item>
+        <item name="@android:windowBackground">@color/whitegrey</item>
+        <item name="@android:textColor">@color/black</item>
+    </style>
+
 </resources>
\ No newline at end of file
diff --git a/WicedSense/app/src/main/res/xml/settings.xml b/WicedSense/app/src/main/res/xml/settings.xml
index 3049cde5ece15cb2b266a67309cfe221dca90ae9..ac3dba13daf64e76361d824d13feb7785e1362e4 100644
--- a/WicedSense/app/src/main/res/xml/settings.xml
+++ b/WicedSense/app/src/main/res/xml/settings.xml
@@ -1,29 +1,29 @@
-<?xml version="1.0" encoding="utf-8"?>
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <SwitchPreference
-        android:key="settings_animation"
-        android:title="@string/setting_title_animation" />
-
-    <ListPreference
-        android:entries="@array/temperature_scale_type_names"
-        android:entryValues="@array/temperature_scale_type_values"
-        android:key="settings_temperature_scale_type"
-        android:title="@string/setting_title_temperature_scale" />
-
-    <Preference
-        android:key="settings_version"
-        android:title="@string/setting_title_version" />
-    
-    <SwitchPreference
-        android:key="settings_gyro"
-        android:title="@string/setting_title_gyro" />
-    
-    <SwitchPreference
-        android:key="settings_ecompass"
-        android:title="@string/setting_title_ecompass" />
-
-    <SwitchPreference
-        android:key="settings_accelerometer"
-        android:title="@string/setting_title_accelerometer" />
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <SwitchPreference
+        android:key="settings_animation"
+        android:title="@string/setting_title_animation" />
+
+    <ListPreference
+        android:entries="@array/temperature_scale_type_names"
+        android:entryValues="@array/temperature_scale_type_values"
+        android:key="settings_temperature_scale_type"
+        android:title="@string/setting_title_temperature_scale" />
+
+    <Preference
+        android:key="settings_version"
+        android:title="@string/setting_title_version" />
+    
+    <SwitchPreference
+        android:key="settings_gyro"
+        android:title="@string/setting_title_gyro" />
+    
+    <SwitchPreference
+        android:key="settings_ecompass"
+        android:title="@string/setting_title_ecompass" />
+
+    <SwitchPreference
+        android:key="settings_accelerometer"
+        android:title="@string/setting_title_accelerometer" />
 </PreferenceScreen>
\ No newline at end of file
diff --git a/WicedSense/build.gradle b/WicedSense/build.gradle
index 88d246d44a63a396e634c6ea68f88d57e9489e98..0a7f6ce083962fa9ca27501b57c386b65799b7ff 100644
--- a/WicedSense/build.gradle
+++ b/WicedSense/build.gradle
@@ -1,15 +1,15 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-buildscript {
-    repositories {
-        jcenter()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
-    }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-    }
-}
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.2.3'
+    }
+}
+
+allprojects {
+    repositories {
+        jcenter()
+    }
+}
diff --git a/WicedSense/gradle/wrapper/gradle-wrapper.properties b/WicedSense/gradle/wrapper/gradle-wrapper.properties
index 0c71e760dc93830dd3411fe50d6f5c86bf0a8f4d..cdc433f020c5062faecd18d6ff3c0594327a2b8c 100644
--- a/WicedSense/gradle/wrapper/gradle-wrapper.properties
+++ b/WicedSense/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Apr 10 15:27:10 PDT 2013
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
diff --git a/WicedSense/gradlew b/WicedSense/gradlew
index 91a7e269e19dfc62e27137a0b57ef3e430cee4fd..583ae0810ef3ba5dd32079c606b015b653301205 100644
--- a/WicedSense/gradlew
+++ b/WicedSense/gradlew
@@ -1,164 +1,164 @@
-#!/usr/bin/env bash
-
-##############################################################################
-##
-##  Gradle start up script for UN*X
-##
-##############################################################################
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
-    echo "$*"
-}
-
-die ( ) {
-    echo
-    echo "$*"
-    echo
-    exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
-        # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
-    else
-        JAVACMD="$JAVA_HOME/bin/java"
-    fi
-    if [ ! -x "$JAVACMD" ] ; then
-        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-    fi
-else
-    JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
-    # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
-        fi
-        i=$((i+1))
-    done
-    case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
-fi
-
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
-    JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/WicedSense/gradlew.bat b/WicedSense/gradlew.bat
index 8a0b282aa6885fb573c106b3551f7275c5f17e8e..aec99730b4e8fcd90b57a0e8e01544fea7c31a89 100644
--- a/WicedSense/gradlew.bat
+++ b/WicedSense/gradlew.bat
@@ -1,90 +1,90 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem  Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/WicedSense/import-summary.txt b/WicedSense/import-summary.txt
index e7fcfab4c2bf5a553b791d5243859a1486ff2afb..825bd7346257f1fafe02cf3e3792d7d28e20ab8e 100644
--- a/WicedSense/import-summary.txt
+++ b/WicedSense/import-summary.txt
@@ -1,48 +1,48 @@
-ECLIPSE ANDROID PROJECT IMPORT SUMMARY
-======================================
-
-Ignored Files:
---------------
-The following files were *not* copied into the new Gradle project; you
-should evaluate whether these are still needed in your project and if
-so manually move them:
-
-* .idea\
-* .idea\.name
-* .idea\WicedSense.iml
-* .idea\compiler.xml
-* .idea\copyright\
-* .idea\copyright\profiles_settings.xml
-* .idea\misc.xml
-* .idea\modules.xml
-* .idea\vcs.xml
-* .idea\workspace.xml
-* ant.properties
-* build.xml
-* proguard-project.txt
-
-Moved Files:
-------------
-Android Gradle projects use a different directory structure than ADT
-Eclipse projects. Here's how the projects were restructured:
-
-* AndroidManifest.xml => app\src\main\AndroidManifest.xml
-* assets\ => app\src\main\assets\
-* lint.xml => app\lint.xml
-* res\ => app\src\main\res\
-* src\ => app\src\main\java\
-
-Next Steps:
------------
-You can now build the project. The Gradle project needs network
-connectivity to download dependencies.
-
-Bugs:
------
-If for some reason your project does not build, and you determine that
-it is due to a bug or limitation of the Eclipse to Gradle importer,
-please file a bug at http://b.android.com with category
-Component-Tools.
-
-(This import summary is for your information only, and can be deleted
-after import once you are satisfied with the results.)
+ECLIPSE ANDROID PROJECT IMPORT SUMMARY
+======================================
+
+Ignored Files:
+--------------
+The following files were *not* copied into the new Gradle project; you
+should evaluate whether these are still needed in your project and if
+so manually move them:
+
+* .idea\
+* .idea\.name
+* .idea\WicedSense.iml
+* .idea\compiler.xml
+* .idea\copyright\
+* .idea\copyright\profiles_settings.xml
+* .idea\misc.xml
+* .idea\modules.xml
+* .idea\vcs.xml
+* .idea\workspace.xml
+* ant.properties
+* build.xml
+* proguard-project.txt
+
+Moved Files:
+------------
+Android Gradle projects use a different directory structure than ADT
+Eclipse projects. Here's how the projects were restructured:
+
+* AndroidManifest.xml => app\src\main\AndroidManifest.xml
+* assets\ => app\src\main\assets\
+* lint.xml => app\lint.xml
+* res\ => app\src\main\res\
+* src\ => app\src\main\java\
+
+Next Steps:
+-----------
+You can now build the project. The Gradle project needs network
+connectivity to download dependencies.
+
+Bugs:
+-----
+If for some reason your project does not build, and you determine that
+it is due to a bug or limitation of the Eclipse to Gradle importer,
+please file a bug at http://b.android.com with category
+Component-Tools.
+
+(This import summary is for your information only, and can be deleted
+after import once you are satisfied with the results.)
diff --git a/WicedSense/settings.gradle b/WicedSense/settings.gradle
index e7b4def49cb53d9aa04228dd3edb14c9e635e003..d3db1092cf4f5689e1a06500484e3f03ba7a6bf6 100644
--- a/WicedSense/settings.gradle
+++ b/WicedSense/settings.gradle
@@ -1 +1 @@
-include ':app'
+include ':app'