resolved conflicts for merge of ee0a0132 to mnc-dr-dev

Change-Id: I61046edb56b9b54a759e4964762fa7b01d4eaba1
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 899529d..d762f47 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -36,6 +36,8 @@
 import android.util.LocalLog;
 import android.util.Log;
 
+import com.android.server.connectivity.KeepalivePacketData;
+
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -2391,4 +2393,84 @@
             }
         }
     }
+
+    private native static int startSendingOffloadedPacketNative(int iface, int idx,
+                                    byte[] srcMac, byte[] dstMac, byte[] pktData, int period);
+
+    synchronized public int
+    startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket, int period) {
+        Log.d(TAG, "startSendingOffloadedPacket slot=" + slot + " period=" + period);
+
+        String[] macAddrStr = getMacAddress().split(":");
+        byte[] srcMac = new byte[6];
+        for(int i = 0; i < 6; i++) {
+            Integer hexVal = Integer.parseInt(macAddrStr[i], 16);
+            srcMac[i] = hexVal.byteValue();
+        }
+        synchronized (mLock) {
+            if (isHalStarted()) {
+                return startSendingOffloadedPacketNative(sWlan0Index, slot, srcMac,
+                                keepAlivePacket.dstMac, keepAlivePacket.data, period);
+            } else {
+                return -1;
+            }
+        }
+    }
+
+    private native static int stopSendingOffloadedPacketNative(int iface, int idx);
+
+    synchronized public int
+    stopSendingOffloadedPacket(int slot) {
+        Log.d(TAG, "stopSendingOffloadedPacket " + slot);
+        synchronized (mLock) {
+            if (isHalStarted()) {
+                return stopSendingOffloadedPacketNative(sWlan0Index, slot);
+            } else {
+                return -1;
+            }
+        }
+    }
+
+    public static interface WifiRssiEventHandler {
+        void onRssiThresholdBreached(byte curRssi);
+    }
+
+    private static WifiRssiEventHandler sWifiRssiEventHandler;
+
+    synchronized static void onRssiThresholdBreached(int id, byte curRssi) {
+        sWifiRssiEventHandler.onRssiThresholdBreached(curRssi);
+    }
+
+    private native static int startRssiMonitoringNative(int iface, int id,
+                                        byte maxRssi, byte minRssi);
+
+    private static int sRssiMonitorCmdId = 0;
+
+    synchronized public int startRssiMonitoring(byte maxRssi, byte minRssi,
+                                                WifiRssiEventHandler rssiEventHandler) {
+        Log.d(TAG, "startRssiMonitoring: maxRssi=" + maxRssi + " minRssi=" + minRssi);
+        sWifiRssiEventHandler = rssiEventHandler;
+        synchronized (mLock) {
+            if (isHalStarted()) {
+                sRssiMonitorCmdId = getNewCmdIdLocked();
+                Log.d(TAG, "sRssiMonitorCmdId = " + sRssiMonitorCmdId);
+                return startRssiMonitoringNative(sWlan0Index, sRssiMonitorCmdId, maxRssi, minRssi);
+            } else {
+                return -1;
+            }
+        }
+    }
+
+    private native static int stopRssiMonitoringNative(int iface, int idx);
+
+    synchronized public int stopRssiMonitoring() {
+        Log.d(TAG, "stopRssiMonitoring, cmdId " + sRssiMonitorCmdId);
+        synchronized (mLock) {
+            if (isHalStarted()) {
+                return stopRssiMonitoringNative(sWlan0Index, sRssiMonitorCmdId);
+            } else {
+                return -1;
+            }
+        }
+    }
 }
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 60148be..aa1750c 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -110,6 +110,7 @@
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.server.connectivity.KeepalivePacketData;
 import com.android.server.net.NetlinkTracker;
 import com.android.server.wifi.hotspot2.NetworkDetail;
 import com.android.server.wifi.hotspot2.SupplicantBridge;
@@ -125,6 +126,7 @@
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -147,7 +149,8 @@
  *
  * @hide
  */
-public class WifiStateMachine extends StateMachine implements WifiNative.WifiPnoEventHandler {
+public class WifiStateMachine extends StateMachine implements WifiNative.WifiPnoEventHandler,
+    WifiNative.WifiRssiEventHandler {
 
     private static final String NETWORKTYPE = "WIFI";
     private static final String NETWORKTYPE_UNTRUSTED = "WIFI_UT";
@@ -269,6 +272,34 @@
         mRestartAutoJoinOffloadCounter++;
     }
 
+    @Override
+    public void onRssiThresholdBreached(byte curRssi) {
+        if (DBG) {
+            Log.e(TAG, "onRssiThresholdBreach event. Cur Rssi = " + curRssi);
+        }
+        sendMessage(CMD_RSSI_THRESHOLD_BREACH, curRssi);
+    }
+
+    public void processRssiThreshold(byte curRssi) {
+        for (int i = 0; i < mRssiRanges.length; i++) {
+            if (curRssi < mRssiRanges[i]) {
+                // Assume sorted values(ascending order) for rssi,
+                // bounded by high(127) and low(-127) at extremeties
+                byte maxRssi = mRssiRanges[i];
+                byte minRssi = mRssiRanges[i-1];
+                Log.d(TAG, "Re-program rssi thresholds" + "maxRssi=" + maxRssi
+                        + " minRssi=" + minRssi + " curRssi=" + curRssi);
+                // This value of hw has to be believed as this value is averaged and has breached
+                // the rssi thresholds and raised event to host. This would be eggregious if this
+                // value is invalid
+                mWifiInfo.setRssi((int) curRssi);
+                updateCapabilities(getCurrentWifiConfiguration());
+                int ret = startRssiMonitoringOffload(maxRssi, minRssi);
+                Log.d(TAG, "Post re-programming rssi threshold ret = " + ret);
+                break;
+            }
+        }
+    }
     public void registerNetworkDisabled(int netId) {
         // Restart legacy PNO and autojoin offload if needed
         sendMessage(CMD_RESTART_AUTOJOIN_OFFLOAD, 0,
@@ -542,6 +573,8 @@
 
     private String[] mWhiteListedSsids = null;
 
+    private byte[] mRssiRanges;
+
     // Keep track of various statistics, for retrieval by System Apps, i.e. under @SystemApi
     // We should really persist that into the networkHistory.txt file, and read it back when
     // WifiStateMachine starts up
@@ -786,6 +819,22 @@
     /* used to log if GSCAN was started */
     static final int CMD_STARTED_GSCAN_DBG                              = BASE + 159;
 
+    /* used to offload sending IP packet */
+    static final int CMD_START_IP_PACKET_OFFLOAD                        = BASE + 160;
+
+    /* used to stop offload sending IP packet */
+    static final int CMD_STOP_IP_PACKET_OFFLOAD                         = BASE + 161;
+
+    /* used to start rssi monitoring in hw */
+    static final int CMD_START_RSSI_MONITORING_OFFLOAD                  = BASE + 162;
+
+    /* used to stop rssi moniroting in hw */
+    static final int CMD_STOP_RSSI_MONITORING_OFFLOAD                   = BASE + 163;
+
+    /* used to indicated RSSI threshold breach in hw */
+    static final int CMD_RSSI_THRESHOLD_BREACH                          = BASE + 164;
+
+
 
     /* Wifi state machine modes of operation */
     /* CONNECT_MODE - connect to any 'known' AP when it becomes available */
@@ -1783,6 +1832,22 @@
         }
     }
 
+    int startWifiIPPacketOffload(int slot, KeepalivePacketData packetData, int intervalSeconds) {
+        return mWifiNative.startSendingOffloadedPacket(slot, packetData, intervalSeconds * 1000);
+    }
+
+    int stopWifiIPPacketOffload(int slot) {
+        return mWifiNative.stopSendingOffloadedPacket(slot);
+    }
+
+    int startRssiMonitoringOffload(byte maxRssi, byte minRssi) {
+        return mWifiNative.startRssiMonitoring(maxRssi, minRssi, WifiStateMachine.this);
+    }
+
+    int stopRssiMonitoringOffload() {
+        return mWifiNative.stopRssiMonitoring();
+    }
+
     // If workSource is not null, blame is given to it, otherwise blame is given to callingUid.
     private void noteScanStart(int callingUid, WorkSource workSource) {
         long now = System.currentTimeMillis();
@@ -2316,6 +2381,14 @@
         sendMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0);
     }
 
+    public int stopRssiMonitoring(AsyncChannel channel) {
+        Message resultMsg = channel.sendMessageSynchronously(CMD_STOP_RSSI_MONITORING_OFFLOAD,
+                                    mRssiRanges);
+        int ret = (int)resultMsg.obj;
+        resultMsg.recycle();
+        return ret;
+    }
+
     /**
      * Set the country code
      *
@@ -4014,11 +4087,13 @@
              */
             int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, WifiManager.RSSI_LEVELS);
             if (newSignalLevel != mLastSignalLevel) {
+                updateCapabilities(getCurrentWifiConfiguration());
                 sendRssiChangeBroadcast(newRssi);
             }
             mLastSignalLevel = newSignalLevel;
         } else {
             mWifiInfo.setRssi(WifiInfo.INVALID_RSSI);
+            updateCapabilities(getCurrentWifiConfiguration());
         }
 
         if (newLinkSpeed != -1) {
@@ -5243,6 +5318,19 @@
         }).start();
     }
 
+    private byte[] macAddressFromString(String macString) {
+        String[] macBytes = macString.split(":");
+        if (macBytes.length != 6) {
+            throw new IllegalArgumentException("MAC address should be 6 bytes long!");
+        }
+        byte[] mac = new byte[6];
+        for (int i = 0; i < macBytes.length; i++) {
+            Integer hexVal = Integer.parseInt(macBytes[i], 16);
+            mac[i] = hexVal.byteValue();
+        }
+        return mac;
+    }
+
     /*
      * Read a MAC address in /proc/arp/table, used by WifistateMachine
      * so as to record MAC address of default gateway.
@@ -5592,6 +5680,22 @@
                 case CMD_REMOVE_USER_CONFIGURATIONS:
                     deferMessage(message);
                     break;
+                case CMD_START_IP_PACKET_OFFLOAD:
+                    if (mNetworkAgent != null) mNetworkAgent.onPacketKeepaliveEvent(
+                            message.arg1,
+                            ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
+                    break;
+                case CMD_STOP_IP_PACKET_OFFLOAD:
+                    if (mNetworkAgent != null) mNetworkAgent.onPacketKeepaliveEvent(
+                            message.arg1,
+                            ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
+                    break;
+                case CMD_START_RSSI_MONITORING_OFFLOAD:
+                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
+                    break;
+                case CMD_STOP_RSSI_MONITORING_OFFLOAD:
+                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
+                    break;
                 default:
                     loge("Error! unhandled message" + message);
                     break;
@@ -6299,6 +6403,14 @@
                 case WifiMonitor.ANQP_DONE_EVENT:
                     mWifiConfigStore.notifyANQPDone((Long) message.obj, message.arg1 != 0);
                     break;
+                case CMD_STOP_IP_PACKET_OFFLOAD: {
+                    int slot = message.arg1;
+                    int ret = stopWifiIPPacketOffload(slot);
+                    if (mNetworkAgent != null) {
+                        mNetworkAgent.onPacketKeepaliveEvent(slot, ret);
+                    }
+                    break;
+                }
                 default:
                     return NOT_HANDLED;
             }
@@ -6856,6 +6968,21 @@
             case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION:
                 s = "CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION";
                 break;
+            case CMD_START_IP_PACKET_OFFLOAD:
+                s = "CMD_START_IP_PACKET_OFFLOAD";
+                break;
+            case CMD_STOP_IP_PACKET_OFFLOAD:
+                s = "CMD_STOP_IP_PACKET_OFFLOAD";
+                break;
+            case CMD_START_RSSI_MONITORING_OFFLOAD:
+                s = "CMD_START_RSSI_MONITORING_OFFLOAD";
+                break;
+            case CMD_STOP_RSSI_MONITORING_OFFLOAD:
+                s = "CMD_STOP_RSSI_MONITORING_OFFLOAD";
+                break;
+            case CMD_RSSI_THRESHOLD_BREACH:
+                s = "CMD_RSSI_THRESHOLD_BREACH";
+                break;
             default:
                 s = "what:" + Integer.toString(what);
                 break;
@@ -7740,6 +7867,10 @@
                 case CMD_PNO_NETWORK_FOUND:
                     processPnoNetworkFound((ScanResult[])message.obj);
                     break;
+                case CMD_RSSI_THRESHOLD_BREACH:
+                    byte curRssi = (byte)message.arg1;
+                    processRssiThreshold(curRssi);
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -7755,6 +7886,8 @@
             mNetworkCapabilities.addCapability(
                     NetworkCapabilities.NET_CAPABILITY_TRUSTED);
         }
+        mNetworkCapabilities.setSignalStrength(mWifiInfo.getRssi() != WifiInfo.INVALID_RSSI ?
+                mWifiInfo.getRssi() : NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED);
         mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
     }
 
@@ -7792,6 +7925,52 @@
         }
 
         @Override
+        protected void startPacketKeepalive(Message msg) {
+            WifiStateMachine.this.sendMessage(
+                    CMD_START_IP_PACKET_OFFLOAD, msg.arg1, msg.arg2, msg.obj);
+        }
+
+        @Override
+        protected void stopPacketKeepalive(Message msg) {
+            WifiStateMachine.this.sendMessage(
+                    CMD_STOP_IP_PACKET_OFFLOAD, msg.arg1, msg.arg2, msg.obj);
+        }
+
+        @Override
+        protected void setSignalStrengthThresholds(int[] thresholds) {
+            // 1. Tell the hardware to start RSSI monitoring here, possibly adding MIN_VALUE and
+            //    MAX_VALUE at the start/end of the thresholds array if necessary.
+            // 2. Ensure that when the hardware event fires, we fetch the RSSI from the hardware
+            //    event, call mWifiInfo.setRssi() with it, and call updateCapabilities(), and then
+            //    re-arm the hardware event. This needs to be done on the state machine thread to
+            //    avoid race conditions. The RSSI used to re-arm the event (and perhaps also the one
+            //    sent in the NetworkCapabilities) must be the one received from the hardware event
+            //    received, or we might skip callbacks.
+            // 3. Ensure that when we disconnect, RSSI monitoring is stopped.
+            log("Received signal strength thresholds: " + Arrays.toString(thresholds));
+            int [] rssiVals = Arrays.copyOf(thresholds, thresholds.length + 2);
+            rssiVals[rssiVals.length - 2] = Byte.MIN_VALUE;
+            rssiVals[rssiVals.length - 1] = Byte.MAX_VALUE;
+            Arrays.sort(rssiVals);
+            byte[] rssiRange = new byte[rssiVals.length];
+            for (int i = 0; i < rssiVals.length; i++) {
+                int val = rssiVals[i];
+                if (val <= Byte.MAX_VALUE && val >= Byte.MIN_VALUE) {
+                    rssiRange[i] = (byte) val;
+                } else {
+                    Log.e(TAG, "Illegal values for rssi thresholds " + val);
+                }
+            }
+            // ToDo: Do we quash rssi values in this sorted array which are very close?
+            mRssiRanges = rssiRange;
+            //In the degenerate case when the input range has no values, the
+            //rssiRange will have only 2 values(127, -128), which when armed to
+            //any chipset can never trigger a rssi breach
+            WifiStateMachine.this.sendMessage(CMD_START_RSSI_MONITORING_OFFLOAD,
+                    mWifiInfo.getRssi());
+        }
+
+        @Override
         protected void preventAutomaticReconnect() {
             if (this != mNetworkAgent) return;
             unwantedNetwork(NETWORK_STATUS_UNWANTED_DISABLE_AUTOJOIN);
@@ -8907,6 +9086,34 @@
                         break;
                     }
                     break;
+                case CMD_START_IP_PACKET_OFFLOAD: {
+                        int slot = message.arg1;
+                        int intervalSeconds = message.arg2;
+                        KeepalivePacketData pkt = (KeepalivePacketData) message.obj;
+                        byte[] dstMac;
+                        try {
+                            InetAddress gateway = RouteInfo.selectBestRoute(
+                                    mLinkProperties.getRoutes(), pkt.dstAddress).getGateway();
+                            String dstMacStr = macAddressFromRoute(gateway.getHostAddress());
+                            dstMac = macAddressFromString(dstMacStr);
+                        } catch (NullPointerException|IllegalArgumentException e) {
+                            loge("Can't find MAC address for next hop to " + pkt.dstAddress);
+                            mNetworkAgent.onPacketKeepaliveEvent(slot,
+                                    ConnectivityManager.PacketKeepalive.ERROR_INVALID_IP_ADDRESS);
+                            break;
+                        }
+                        pkt.dstMac = dstMac;
+                        int result = startWifiIPPacketOffload(slot, pkt, intervalSeconds);
+                        mNetworkAgent.onPacketKeepaliveEvent(slot, result);
+                        break;
+                    }
+                case CMD_START_RSSI_MONITORING_OFFLOAD:
+                    byte currRssi = (byte)message.arg1;
+                    processRssiThreshold(currRssi);
+                    break;
+                case CMD_STOP_RSSI_MONITORING_OFFLOAD:
+                    stopRssiMonitoringOffload();
+                    break;
                 default:
                     return NOT_HANDLED;
             }
diff --git a/service/jni/com_android_server_wifi_WifiNative.cpp b/service/jni/com_android_server_wifi_WifiNative.cpp
index 7556b1e..92bd3cd 100644
--- a/service/jni/com_android_server_wifi_WifiNative.cpp
+++ b/service/jni/com_android_server_wifi_WifiNative.cpp
@@ -2114,6 +2114,82 @@
     return hal_fn.wifi_set_ssid_white_list(id, handle, num_ssids, ssids) == WIFI_SUCCESS;
 }
 
+static jint android_net_wifi_start_sending_offloaded_packet(JNIEnv *env, jclass cls, jint iface,
+                    jint idx, jbyteArray srcMac, jbyteArray dstMac, jbyteArray pkt, jint period)  {
+    wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
+    ALOGD("Start packet offload [%d] = %p", idx, handle);
+    wifi_error ret;
+    wifi_request_id id = idx;
+    byte * pkt_data =  (byte *)env->GetByteArrayElements(pkt, NULL);
+    unsigned short pkt_len = env->GetArrayLength(pkt);
+    byte* src_mac_addr = (byte *)env->GetByteArrayElements(srcMac, NULL);
+    byte* dst_mac_addr = (byte *)env->GetByteArrayElements(dstMac, NULL);
+    int i;
+    char macAddr[32];
+    sprintf(macAddr, "%0x:%0x:%0x:%0x:%0x:%0x", src_mac_addr[0], src_mac_addr[1],
+            src_mac_addr[2], src_mac_addr[3], src_mac_addr[4], src_mac_addr[5]);
+    ALOGD("src_mac_addr %s", macAddr);
+    sprintf(macAddr, "%0x:%0x:%0x:%0x:%0x:%0x", dst_mac_addr[0], dst_mac_addr[1],
+            dst_mac_addr[2], dst_mac_addr[3], dst_mac_addr[4], dst_mac_addr[5]);
+    ALOGD("dst_mac_addr %s", macAddr);
+    ALOGD("pkt_len %d\n", pkt_len);
+    ALOGD("Pkt data : ");
+    for(i = 0; i < pkt_len; i++) {
+        ALOGD(" %x ", pkt_data[i]);
+    }
+    ALOGD("\n");
+    ret =  hal_fn.wifi_start_sending_offloaded_packet(id, handle, pkt_data, pkt_len,
+                src_mac_addr, dst_mac_addr, period);
+    ALOGD("ret= %d\n", ret);
+    return ret;
+}
+
+static jint android_net_wifi_stop_sending_offloaded_packet(JNIEnv *env, jclass cls,
+                    jint iface, jint idx) {
+    int ret;
+    wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
+    ALOGD("Stop packet offload [%d] = %p", idx, handle);
+    ret =  hal_fn.wifi_stop_sending_offloaded_packet(idx, handle);
+    ALOGD("ret= %d\n", ret);
+    return ret;
+}
+
+static void onRssiThresholdbreached(wifi_request_id id, u8 *cur_bssid, s8 cur_rssi) {
+
+    ALOGD("RSSI threshold breached, cur RSSI - %d!!\n", cur_rssi);
+    ALOGD("BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
+            cur_bssid[0], cur_bssid[1], cur_bssid[2],
+            cur_bssid[3], cur_bssid[4], cur_bssid[5]);
+    JNIEnv *env = NULL;
+    mVM->AttachCurrentThread(&env, NULL);
+    //ALOGD("onRssiThresholdbreached called, vm = %p, obj = %p, env = %p", mVM, mCls, env);
+    reportEvent(env, mCls, "onRssiThresholdBreached", "(IB)V", id, cur_rssi);
+}
+
+static jint android_net_wifi_start_rssi_monitoring_native(JNIEnv *env, jclass cls, jint iface,
+        jint idx, jbyte maxRssi, jbyte minRssi) {
+
+    wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
+    ALOGD("Start Rssi monitoring = %p", handle);
+    ALOGD("MinRssi %d MaxRssi %d", minRssi, maxRssi);
+    wifi_error ret;
+    wifi_request_id id = idx;
+    wifi_rssi_event_handler eh;
+    eh.on_rssi_threshold_breached = onRssiThresholdbreached;
+    ret = hal_fn.wifi_start_rssi_monitoring(id, handle, maxRssi, minRssi, eh);
+    return ret;
+}
+
+static jint android_net_wifi_stop_rssi_monitoring_native(JNIEnv *env, jclass cls,
+        jint iface, jint idx) {
+    wifi_interface_handle handle = getIfaceHandle(env, cls, iface);
+    ALOGD("Stop Rssi monitoring = %p", handle);
+    wifi_error ret;
+    wifi_request_id id = idx;
+    ret = hal_fn.wifi_stop_rssi_monitoring(id, handle);
+    return ret;
+}
+
 // ----------------------------------------------------------------------------
 
 /*
@@ -2201,6 +2277,14 @@
             (void*)android_net_wifi_setSsidWhitelist},
     {"setLoggingEventHandlerNative", "(II)Z", (void *) android_net_wifi_set_log_handler},
     {"resetLogHandlerNative", "(II)Z", (void *) android_net_wifi_reset_log_handler},
+    { "startSendingOffloadedPacketNative", "(II[B[B[BI)I",
+             (void*)android_net_wifi_start_sending_offloaded_packet},
+    { "stopSendingOffloadedPacketNative", "(II)I",
+             (void*)android_net_wifi_stop_sending_offloaded_packet},
+    {"startRssiMonitoringNative", "(IIBB)I",
+            (void*)android_net_wifi_start_rssi_monitoring_native},
+    {"stopRssiMonitoringNative", "(II)I",
+            (void*)android_net_wifi_stop_rssi_monitoring_native},
     {"isGetChannelsForBandSupportedNative", "()Z",
             (void*)android_net_wifi_is_get_channels_for_band_supported}
 };