Merge "am 463899f..97dde46 from mirror-m-wireless-internal-release"
diff --git a/Common/src/com/googlecode/android_scripting/facade/EventFacade.java b/Common/src/com/googlecode/android_scripting/facade/EventFacade.java
index 4b65c99..00b0866 100644
--- a/Common/src/com/googlecode/android_scripting/facade/EventFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/EventFacade.java
@@ -250,7 +250,7 @@
         result = futureEvent.get();

     }

     //TODO(navtej) Remove log.

-    Log.v(String.format("Removeing observer (%s) got event  (%s)", observer, result ));

+    Log.v(String.format("Removing observer (%s) got event  (%s)", observer, result ));

     if (observer != null) {

       removeEventObserver(observer); // Make quite sure this goes away.

     }

diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
index acde364..e453906 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattFacade.java
@@ -568,35 +568,6 @@
         }
     }
 
-
-    /**
-     * Writes a given characteristic and its values to the associated remote device.
-     *
-     * @param index the bluetooth gatt index
-     * @param characteristicIndex the characteristic index
-     * @return true, if the write operation was initiated successfully
-     * @throws Exception
-     */
-    @Rpc(description = "Writes a given characteristic and its values to the associated remote device.")
-    public boolean gattWriteCharacteristic(
-            @RpcParameter(name = "index")
-            Integer index,
-            @RpcParameter(name = "characteristicIndex")
-            Integer characteristicIndex
-            ) throws Exception {
-        if (mBluetoothGattList.get(index) != null) {
-            if (mCharacteristicList.get(characteristicIndex) != null) {
-                return mBluetoothGattList.get(index).writeCharacteristic(
-                        mCharacteristicList.get(characteristicIndex));
-            } else {
-                throw new Exception("Invalid characteristicIndex input:"
-                        + characteristicIndex);
-            }
-        } else {
-            throw new Exception("Invalid index input:" + index);
-        }
-    }
-
     /**
      * Reads the value for a given descriptor from the associated remote device
      * @param gattIndex - the gatt index to use
@@ -643,6 +614,8 @@
      * Write the value of a given descriptor to the associated remote device
      *
      * @param index the bluetooth gatt index
+     * @param serviceIndex the service index to write to
+     * @param characteristicUuid the uuid where the descriptor lives
      * @param descriptorIndex the descriptor index
      * @return true, if the write operation was initiated successfully
      * @throws Exception
@@ -682,12 +655,12 @@
     /**
      * Write the value to a discovered descriptor.
      * @param gattIndex - the gatt index to use
-     * @param discoveredServiceListIndex - the discvered serivice list index
-     * @param serviceIndex - the servce index of the discoveredServiceListIndex
+     * @param discoveredServiceListIndex - the discovered service list index
+     * @param serviceIndex - the service index of the discoveredServiceListIndex
      * @param characteristicUuid - the characteristic uuid in which the descriptor is
      * @param descriptorUuid - the descriptor uuid to read
      * @param value - the value to set the descriptor to
-     * @return
+     * @return true is the value was set to the descriptor
      * @throws Exception
      */
     @Rpc(description = "Write the value of a given descriptor to the associated remote device")
@@ -724,6 +697,77 @@
     }
 
     /**
+     * Write the value of a given characteristic to the associated remote device
+     *
+     * @param index the bluetooth gatt index
+     * @param serviceIndex the service where the characteristic lives
+     * @param characteristicUuid the characteristic uuid to write to
+     * @return true, if the write operation was successful
+     * @throws Exception
+     */
+    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
+    public boolean gattWriteCharacteristic(@RpcParameter(name = "gattIndex") Integer gattIndex,
+        @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
+        @RpcParameter(name = "serviceIndex") Integer serviceIndex,
+        @RpcParameter(name = "characteristicUuid") String characteristicUuid) throws Exception {
+      BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex);
+      if (bluetoothGatt == null) {
+        throw new Exception("Invalid gattIndex " + gattIndex);
+      }
+      List<BluetoothGattService> discoveredServiceList =
+          mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
+      if (discoveredServiceList == null) {
+        throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
+      }
+      BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
+      if (gattService == null) {
+        throw new Exception("Invalid serviceIndex " + serviceIndex);
+      }
+      UUID cUuid = UUID.fromString(characteristicUuid);
+      BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
+      if (gattCharacteristic == null) {
+        throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
+      }
+      return bluetoothGatt.writeCharacteristic(gattCharacteristic);
+    }
+
+    /**
+     * Write the value to a discovered characteristic.
+     * @param gattIndex - the gatt index to use
+     * @param discoveredServiceListIndex - the discovered service list index
+     * @param serviceIndex - the service index of the discoveredServiceListIndex
+     * @param characteristicUuid - the characteristic uuid in which the descriptor is
+     * @param value - the value to set the characteristic to
+     * @return true, if the value was set to the characteristic
+     * @throws Exception
+     */
+    @Rpc(description = "Write the value of a given characteristic to the associated remote device")
+    public boolean gattCharacteristicSetValue(@RpcParameter(name = "gattIndex") Integer gattIndex,
+        @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex,
+        @RpcParameter(name = "serviceIndex") Integer serviceIndex,
+        @RpcParameter(name = "characteristicUuid") String characteristicUuid,
+        @RpcParameter(name = "value") String value) throws Exception {
+      if (mBluetoothGattList.get(gattIndex) == null) {
+        throw new Exception("Invalid gattIndex " + gattIndex);
+      }
+      List<BluetoothGattService> discoveredServiceList =
+          mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex);
+      if (discoveredServiceList == null) {
+        throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex);
+      }
+      BluetoothGattService gattService = discoveredServiceList.get(serviceIndex);
+      if (gattService == null) {
+        throw new Exception("Invalid serviceIndex " + serviceIndex);
+      }
+      UUID cUuid = UUID.fromString(characteristicUuid);
+      BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid);
+      if (gattCharacteristic == null) {
+        throw new Exception("Invalid characteristic uuid: " + characteristicUuid);
+      }
+      byte[] byteArray = ConvertUtils.convertStringToByteArray(value);
+      return gattCharacteristic.setValue(byteArray);
+    }
+    /**
      * Read the RSSI for a connected remote device
      *
      * @param index the bluetooth gatt index
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
index 37e7231..c6089ee 100755
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java
@@ -50,7 +50,6 @@
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.security.spec.X509EncodedKeySpec;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 
 import org.json.JSONException;
@@ -552,6 +551,16 @@
         return mWifi.isWifiApEnabled();
     }
 
+    @Rpc(description = "Check if Device-to-AP RTT is supported.")
+    public Boolean wifiIsDeviceToApRttSupported() {
+        return mWifi.isDeviceToApRttSupported();
+    }
+
+    @Rpc(description = "Check if Device-to-device RTT is supported.")
+    public Boolean wifiIsDeviceToDeviceRttSupported() {
+        return mWifi.isDeviceToDeviceRttSupported();
+    }
+
     @Rpc(description = "Check if this adapter supports advanced power/performance counters.")
     public Boolean wifiIsEnhancedPowerReportingSupported() {
         return mWifi.isEnhancedPowerReportingSupported();
@@ -562,6 +571,11 @@
         return mWifi.isWifiScannerSupported();
     }
 
+    @Rpc(description = "Check if tdls is supported on this device.")
+    public Boolean wifiIsTdlsSupported() {
+        return mWifi.isTdlsSupported();
+    }
+
     @Rpc(description = "Acquires a full Wifi lock.")
     public void wifiLockAcquireFull() {
         makeLock(WifiManager.WIFI_MODE_FULL);
@@ -630,6 +644,14 @@
         }
     }
 
+    @Rpc(description = "Enable/disable tdls with a mac address.")
+    public void wifiSetTdlsEnabledWithMacAddress(
+            @RpcParameter(name = "remoteMacAddress") String remoteMacAddress,
+            @RpcParameter(name = "enable") Boolean enable
+            ) {
+        mWifi.setTdlsEnabledWithMacAddress(remoteMacAddress, enable);
+    }
+
     @Rpc(description = "Starts a scan for Wifi access points.",
             returns = "True if the scan was initiated successfully.")
     public Boolean wifiStartScan() {
diff --git a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java
index 58c3fb6..0b94ad3 100644
--- a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java
@@ -4,7 +4,6 @@
 import android.app.Service;
 import android.content.Context;
 import android.net.wifi.RttManager;
-import android.net.wifi.RttManager.Capabilities;
 import android.net.wifi.RttManager.RttCapabilities;
 import android.net.wifi.RttManager.RttListener;
 import android.net.wifi.RttManager.RttParams;
@@ -145,6 +144,9 @@
         if (j.has("numberBurst")) {
             result.numberBurst = j.getInt("numberBurst");
         }
+        if (j.has("burstTimeout")) {
+            result.burstTimeout = j.getInt("burstTimeout");
+        }
         if (j.has("interval")) {
             result.interval = j.getInt("interval");
         }
diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index 26be011..b30aa76 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -58,8 +58,8 @@
 import android.telephony.CellLocation;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.SmsMessage;
-import android.telephony.gsm.GsmCellLocation;
 import android.telephony.SubscriptionInfo;
+import android.telephony.gsm.GsmCellLocation;
 import android.util.DisplayMetrics;
 import android.util.SparseArray;
 
@@ -477,23 +477,35 @@
         result.put("level", scanResult.level);
         result.put("capabilities", scanResult.capabilities);
         result.put("timestamp", scanResult.timestamp);
-        // The following fields are hidden for now, uncomment when they're
-        // unhidden
-        // result.put("seen", scanResult.seen);
-        // result.put("distanceCm", scanResult.distanceCm);
-        // result.put("distanceSdCm", scanResult.distanceSdCm);
-        // if (scanResult.informationElements != null){
-        // JSONArray infoEles = new JSONArray();
-        // for(ScanResult.InformationElement ie :
-        // scanResult.informationElements) {
-        // JSONObject infoEle = new JSONObject();
-        // infoEle.put("id", ie.id);
-        // infoEle.put("bytes", Base64Codec.encodeBase64(ie.bytes));
-        // infoEles.put(infoEle);
-        // }
-        // result.put("InfomationElements", infoEles);
-        // } else
-        // result.put("InfomationElements", null);
+        result.put("autoJoinStatus", scanResult.autoJoinStatus);
+        result.put("blackListTimestamp", scanResult.blackListTimestamp);
+        result.put("centerFreq0", scanResult.centerFreq0);
+        result.put("centerFreq1", scanResult.centerFreq1);
+        result.put("channelWidth", scanResult.channelWidth);
+        result.put("distanceCm", scanResult.distanceCm);
+        result.put("distanceSdCm", scanResult.distanceSdCm);
+        result.put("is80211McRTTResponder", scanResult.is80211McRTTResponder);
+        result.put("isAutoJoinCandidate", scanResult.isAutoJoinCandidate);
+        result.put("numConnection", scanResult.numConnection);
+        result.put("passpointNetwork", scanResult.passpointNetwork);
+        result.put("numIpConfigFailures", scanResult.numIpConfigFailures);
+        result.put("numUsage", scanResult.numUsage);
+        result.put("seen", scanResult.seen);
+        result.put("untrusted", scanResult.untrusted);
+        result.put("operatorFriendlyName", scanResult.operatorFriendlyName);
+        result.put("venueName", scanResult.venueName);
+        if (scanResult.informationElements != null) {
+            JSONArray infoEles = new JSONArray();
+            for (ScanResult.InformationElement ie : scanResult.informationElements) {
+                JSONObject infoEle = new JSONObject();
+                infoEle.put("id", ie.id);
+                infoEle.put("bytes", Base64Codec.encodeBase64(ie.bytes).toString());
+                infoEles.put(infoEle);
+            }
+            result.put("InfomationElements", infoEles);
+        } else {
+            result.put("InfomationElements", null);
+        }
         return result;
     }
 
diff --git a/ScriptingLayerForAndroid/AndroidManifest.xml b/ScriptingLayerForAndroid/AndroidManifest.xml
index 50c5f34..1fea90a 100644
--- a/ScriptingLayerForAndroid/AndroidManifest.xml
+++ b/ScriptingLayerForAndroid/AndroidManifest.xml
@@ -39,6 +39,9 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
+    <uses-permission android:name="android.permission.BLUETOOTH_MAP" />
+    <uses-permission android:name="android.permission.BLUETOOTH_STACK" />
+    <uses-permission android:name="android.permission.NET_ADMIN" />
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />