Commit message: None
CVE: CVE-2016-3837
CWE: CWE-200
Vulnerability description: service/jni/com_android_server_wifi_WifiNative.cpp in Wi-Fi in Android 5.0.x before 5.0.2, 5.1.x before 5.1.1, and 6.x before 2016-08-01 allows attackers to obtain sensitive information via a crafted application that provides a MAC address with too few characters, aka internal bug 28164077.

Project: Android

jint Java_com_android_server_wifi_WifiNative_registerNatives(JNIEnv* env, jclass clazz) {
 return AndroidRuntime::registerNativeMethods(env,
 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
}

Project: Android

static jboolean android_net_wifi_cancelRange(
 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("cancelling rtt request [%d] = %p", id, handle);

    mac_addr addrs[MaxRttConfigs];
    memset(&addrs, 0, sizeof(addrs));

 int len = helper.getArrayLength((jobjectArray)params);
 if (len > MaxRttConfigs) {
 return false;
 }

 for (int i = 0; i < len; i++) {

 JNIObject<jobject> param = helper.getObjectArrayElement(params, i);
 if (param == NULL) {
            ALOGD("could not get element %d", i);
 continue;
 }

        parseMacAddress(env, param, addrs[i]);
 }

 return hal_fn.wifi_rtt_range_cancel(id, handle, len, addrs) == WIFI_SUCCESS;
}

Project: Android

static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject)
{
 ::wifi_close_supplicant_connection();
}

Project: Android

static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject)
{
 return (::wifi_connect_to_supplicant() == 0);
}

Project: Android

static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) {
 return doBooleanCommand(env, javaCommand);
}

Project: Android

static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) {
 return doIntCommand(env, javaCommand);
}

Project: Android

static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) {
 return doStringCommand(env,javaCommand);
}

Project: Android

static jboolean android_net_wifi_enable_disable_tdls(JNIEnv *env,jclass cls, jint iface,
        jboolean enable, jstring addr) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    mac_addr address;
    parseMacAddress(env, addr, address);
    wifi_tdls_handler tdls_handler;

 if(enable) {
 return (hal_fn.wifi_enable_tdls(handle, address, NULL, tdls_handler) == WIFI_SUCCESS);
 } else {
 return (hal_fn.wifi_disable_tdls(handle, address) == WIFI_SUCCESS);
 }
}

Project: Android

static jstring android_net_wifi_getInterfaceName(JNIEnv *env, jclass cls, jint i) {

 char buf[EVENT_BUF_SIZE];

 JNIHelper helper(env);

    jlong value = helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, i);
    wifi_interface_handle handle = (wifi_interface_handle) value;
 int result = hal_fn.wifi_get_iface_name(handle, buf, sizeof(buf));
 if (result < 0) {
 return NULL;
 } else {
 JNIObject<jstring> name = helper.newStringUTF(buf);
 return name.detach();
 }
}

Project: Android

static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) {
 int n = 0;

 JNIHelper helper(env);

    wifi_handle halHandle = getWifiHandle(helper, cls);
    wifi_interface_handle *ifaceHandles = NULL;
 int result = hal_fn.wifi_get_ifaces(halHandle, &n, &ifaceHandles);
 if (result < 0) {
 return result;
 }

 if (n < 0) {
        THROW(helper,"android_net_wifi_getInterfaces no interfaces");
 return 0;
 }

 if (ifaceHandles == NULL) {
       THROW(helper,"android_net_wifi_getInterfaces null interface array");
 return 0;
 }

 if (n > 8) {
        THROW(helper,"Too many interfaces");
 return 0;
 }

    jlongArray array = (env)->NewLongArray(n);
 if (array == NULL) {
        THROW(helper,"Error in accessing array");
 return 0;
 }

    jlong elems[8];
 for (int i = 0; i < n; i++) {
        elems[i] = reinterpret_cast<jlong>(ifaceHandles[i]);
 }

    helper.setLongArrayRegion(array, 0, n, elems);
    helper.setStaticLongArrayField(cls, WifiIfaceHandleVarName, array);

 return (result < 0) ? result : n;
}

Project: Android

static jboolean android_net_wifi_getScanCapabilities(
 JNIEnv *env, jclass cls, jint iface, jobject capabilities) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    wifi_gscan_capabilities c;
    memset(&c, 0, sizeof(c));
 int result = hal_fn.wifi_get_gscan_capabilities(handle, &c);
 if (result != WIFI_SUCCESS) {
        ALOGD("failed to get capabilities : %d", result);
 return JNI_FALSE;
 }

    helper.setIntField(capabilities, "max_scan_cache_size", c.max_scan_cache_size);
    helper.setIntField(capabilities, "max_scan_buckets", c.max_scan_buckets);
    helper.setIntField(capabilities, "max_ap_cache_per_scan", c.max_ap_cache_per_scan);
    helper.setIntField(capabilities, "max_rssi_sample_size", c.max_rssi_sample_size);
    helper.setIntField(capabilities, "max_scan_reporting_threshold", c.max_scan_reporting_threshold);
    helper.setIntField(capabilities, "max_hotlist_bssids", c.max_hotlist_bssids);
    helper.setIntField(capabilities, "max_significant_wifi_change_aps",
                c.max_significant_wifi_change_aps);

 return JNI_TRUE;
}

Project: Android

static jint android_net_wifi_getSupportedFeatures(JNIEnv *env, jclass cls, jint iface) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    feature_set set = 0;

    wifi_error result = WIFI_SUCCESS;
 /*
    set = WIFI_FEATURE_INFRA
        | WIFI_FEATURE_INFRA_5G
        | WIFI_FEATURE_HOTSPOT
        | WIFI_FEATURE_P2P
        | WIFI_FEATURE_SOFT_AP
        | WIFI_FEATURE_GSCAN
        | WIFI_FEATURE_PNO
        | WIFI_FEATURE_TDLS
        | WIFI_FEATURE_EPR;
    */

    result = hal_fn.wifi_get_supported_feature_set(handle, &set);
 if (result == WIFI_SUCCESS) {
 return set;
 } else {
        ALOGE("wifi_get_supported_feature_set returned error = 0x%x", result);
 return 0;
 }
}

Project: Android

static jobject android_net_wifi_get_driver_version(JNIEnv *env, jclass cls, jint iface) {
 JNIHelper helper(env);
 int buffer_length = 256;
 char *buffer = (char *)malloc(buffer_length);
 if (!buffer) return NULL;
    memset(buffer, 0, buffer_length);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    ALOGD("android_net_wifi_get_driver_version = %p", handle);

 if (handle == 0) {
 return NULL;
 }

    wifi_error result = hal_fn.wifi_get_driver_version(handle, buffer, buffer_length);

 if (result == WIFI_SUCCESS) {
        ALOGD("buffer is %p, length is %d", buffer, buffer_length);
 JNIObject<jstring> driver_version = helper.newStringUTF(buffer);
        free(buffer);
 return driver_version.detach();
 } else {
        ALOGD("Fail to get driver version");
        free(buffer);
 return NULL;
 }
}

Project: Android

static jobject android_net_wifi_get_firmware_version(JNIEnv *env, jclass cls, jint iface) {

 JNIHelper helper(env);
 int buffer_length = 256;
 char *buffer = (char *)malloc(buffer_length);
 if (!buffer) return NULL;
    memset(buffer, 0, buffer_length);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    ALOGD("android_net_wifi_get_firmware_version = %p", handle);

 if (handle == 0) {
 return NULL;
 }

    wifi_error result = hal_fn.wifi_get_firmware_version(handle, buffer, buffer_length);

 if (result == WIFI_SUCCESS) {
        ALOGD("buffer is %p, length is %d", buffer, buffer_length);
 JNIObject<jstring> firmware_version = helper.newStringUTF(buffer);
        free(buffer);
 return firmware_version.detach();
 } else {
        ALOGD("Fail to get Firmware version");
        free(buffer);
 return NULL;
 }
}

Project: Android

static jboolean android_net_wifi_get_fw_memory_dump(JNIEnv *env, jclass cls, jint iface){

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

 if (handle == NULL) {
        ALOGE("Can not get wifi_interface_handle");
 return false;
 }

    wifi_firmware_memory_dump_handler fw_dump_handle;
    fw_dump_handle.on_firmware_memory_dump = on_firmware_memory_dump;
 int result = hal_fn.wifi_get_firmware_memory_dump(handle, fw_dump_handle);
 return result == WIFI_SUCCESS;

}

Project: Android

static jboolean android_net_wifi_get_ring_buffer_data(JNIEnv *env, jclass cls, jint iface,
        jstring ring_name) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

 ScopedUtfChars chars(env, ring_name);
 const char* ring_name_const_char = chars.c_str();
 int result = hal_fn.wifi_get_ring_data(handle, const_cast<char *>(ring_name_const_char));
 return result == WIFI_SUCCESS;
}

Project: Android

static jobject android_net_wifi_get_ring_buffer_status (JNIEnv *env, jclass cls, jint iface) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    ALOGD("android_net_wifi_get_ring_buffer_status = %p", handle);

 if (handle == 0) {
 return NULL;
 }

    u32 num_rings = 10;
    wifi_ring_buffer_status *status =
 (wifi_ring_buffer_status *)malloc(sizeof(wifi_ring_buffer_status) * num_rings);
 if (!status) return NULL;
    memset(status, 0, sizeof(wifi_ring_buffer_status) * num_rings);
    wifi_error result = hal_fn.wifi_get_ring_buffers_status(handle, &num_rings, status);
 if (result == WIFI_SUCCESS) {
        ALOGD("status is %p, number is %d", status, num_rings);

 JNIObject<jobjectArray> ringBuffersStatus = helper.newObjectArray(
            num_rings, "com/android/server/wifi/WifiNative$RingBufferStatus", NULL);

        wifi_ring_buffer_status *tmp = status;

 for(u32 i = 0; i < num_rings; i++, tmp++) {

 JNIObject<jobject> ringStatus = helper.createObject(
 "com/android/server/wifi/WifiNative$RingBufferStatus");

 if (ringStatus == NULL) {
                ALOGE("Error in creating ringBufferStatus");
                free(status);
 return NULL;
 }

 char name[32];
 for(int j = 0; j < 32; j++) {
                name[j] = tmp->name[j];
 }

            helper.setStringField(ringStatus, "name", name);
            helper.setIntField(ringStatus, "flag", tmp->flags);
            helper.setIntField(ringStatus, "ringBufferId", tmp->ring_id);
            helper.setIntField(ringStatus, "ringBufferByteSize", tmp->ring_buffer_byte_size);
            helper.setIntField(ringStatus, "verboseLevel", tmp->verbose_level);
            helper.setIntField(ringStatus, "writtenBytes", tmp->written_bytes);
            helper.setIntField(ringStatus, "readBytes", tmp->read_bytes);
            helper.setIntField(ringStatus, "writtenRecords", tmp->written_records);

            helper.setObjectArrayElement(ringBuffersStatus, i, ringStatus);
 }

        free(status);
 return ringBuffersStatus.detach();
 } else {
        free(status);
 return NULL;
 }
}

Project: Android

static jobject android_net_wifi_get_rtt_capabilities(JNIEnv *env, jclass cls, jint iface) {

 JNIHelper helper(env);
    wifi_rtt_capabilities rtt_capabilities;
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    wifi_error ret = hal_fn.wifi_get_rtt_capabilities(handle, &rtt_capabilities);

 if(WIFI_SUCCESS == ret) {
 JNIObject<jobject> capabilities = helper.createObject(
 "android/net/wifi/RttManager$RttCapabilities");
         helper.setBooleanField(capabilities, "oneSidedRttSupported",
                 rtt_capabilities.rtt_one_sided_supported == 1);
         helper.setBooleanField(capabilities, "twoSided11McRttSupported",
                 rtt_capabilities.rtt_ftm_supported == 1);
         helper.setBooleanField(capabilities, "lciSupported",
                 rtt_capabilities.lci_support);
         helper.setBooleanField(capabilities, "lcrSupported",
                 rtt_capabilities.lcr_support);
         helper.setIntField(capabilities, "preambleSupported",
                 rtt_capabilities.preamble_support);
         helper.setIntField(capabilities, "bwSupported",
                 rtt_capabilities.bw_support);
         ALOGD("One side RTT is: %s", rtt_capabilities.rtt_one_sided_supported ==1 ? "support" :
 "not support");
         ALOGD("Two side RTT is: %s", rtt_capabilities.rtt_ftm_supported == 1 ? "support" :
 "not support");
         ALOGD("LCR is: %s", rtt_capabilities.lcr_support == 1 ? "support" : "not support");

         ALOGD("LCI is: %s", rtt_capabilities.lci_support == 1 ? "support" : "not support");

         ALOGD("Support Preamble is : %d support BW is %d", rtt_capabilities.preamble_support,
                 rtt_capabilities.bw_support);
 return capabilities.detach();
 } else {
 return NULL;
 }
}

Project: Android

static jobject android_net_wifi_get_tdls_capabilities(JNIEnv *env, jclass cls, jint iface) {

 JNIHelper helper(env);
    wifi_tdls_capabilities tdls_capabilities;
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    wifi_error ret = hal_fn.wifi_get_tdls_capabilities(handle, &tdls_capabilities);

 if (WIFI_SUCCESS == ret) {
 JNIObject<jobject> capabilities = helper.createObject(
 "com/android/server/wifi/WifiNative$TdlsCapabilities");
         helper.setIntField(capabilities, "maxConcurrentTdlsSessionNumber",
                 tdls_capabilities.max_concurrent_tdls_session_num);
         helper.setBooleanField(capabilities, "isGlobalTdlsSupported",
                 tdls_capabilities.is_global_tdls_supported == 1);
         helper.setBooleanField(capabilities, "isPerMacTdlsSupported",
                 tdls_capabilities.is_per_mac_tdls_supported == 1);
         helper.setBooleanField(capabilities, "isOffChannelTdlsSupported",
                 tdls_capabilities.is_off_channel_tdls_supported);

         ALOGD("TDLS Max Concurrent Tdls Session Number is: %d",
                 tdls_capabilities.max_concurrent_tdls_session_num);
         ALOGD("Global Tdls is: %s", tdls_capabilities.is_global_tdls_supported == 1 ? "support" :
 "not support");
         ALOGD("Per Mac Tdls is: %s", tdls_capabilities.is_per_mac_tdls_supported == 1 ? "support" :
 "not support");
         ALOGD("Off Channel Tdls is: %s", tdls_capabilities.is_off_channel_tdls_supported == 1 ?
 "support" : "not support");

 return capabilities.detach();
 } else {
 return NULL;
 }
}

Project: Android

static jobject android_net_wifi_get_tdls_status(JNIEnv *env,jclass cls, jint iface,jstring addr) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    mac_addr address;
    parseMacAddress(env, addr, address);

    wifi_tdls_status status;

    wifi_error ret;
    ret = hal_fn.wifi_get_tdls_status(handle, address, &status );

 if (ret != WIFI_SUCCESS) {
 return NULL;
 } else {
 JNIObject<jobject> tdls_status = helper.createObject(
 "com/android/server/wifi/WifiNative$TdlsStatus");
        helper.setIntField(tdls_status, "channel", status.channel);
        helper.setIntField(tdls_status, "global_operating_class", status.global_operating_class);
        helper.setIntField(tdls_status, "state", status.state);
        helper.setIntField(tdls_status, "reason", status.reason);
 return tdls_status.detach();
 }
}

Project: Android

void android_net_wifi_hal_cleaned_up_handler(wifi_handle handle) {
    ALOGD("In wifi cleaned up handler");

 JNIHelper helper(mVM);
    helper.setStaticLongField(mCls, WifiHandleVarName, 0);

    helper.deleteGlobalRef(mCls);
    mCls = NULL;
    mVM  = NULL;
}

Project: Android

static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
{
 return (::is_wifi_driver_loaded() == 1);
}

Project: Android

static jboolean android_net_wifi_is_get_channels_for_band_supported(JNIEnv *env, jclass cls){
 return (hal_fn.wifi_get_valid_channels == wifi_get_valid_channels_stub);
}

Project: Android

static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
{
 return (::wifi_stop_supplicant(p2pSupported) == 0);
}

Project: Android

static jboolean android_net_wifi_requestRange(
 JNIEnv *env, jclass cls, jint iface, jint id, jobject params) {

 JNIHelper helper(env);

    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("sending rtt request [%d] = %p", id, handle);

    wifi_rtt_config configs[MaxRttConfigs];
    memset(&configs, 0, sizeof(configs));

 int len = helper.getArrayLength((jobjectArray)params);
 if (len > MaxRttConfigs) {
 return false;
 }

 for (int i = 0; i < len; i++) {

 JNIObject<jobject> param = helper.getObjectArrayElement((jobjectArray)params, i);
 if (param == NULL) {
            ALOGD("could not get element %d", i);
 continue;
 }

        wifi_rtt_config &config = configs[i];

        parseMacAddress(env, param, config.addr);
        config.type = (wifi_rtt_type)helper.getIntField(param, "requestType");
        config.peer = (rtt_peer_type)helper.getIntField(param, "deviceType");
        config.channel.center_freq = helper.getIntField(param, "frequency");
        config.channel.width = (wifi_channel_width) helper.getIntField(param, "channelWidth");
        config.channel.center_freq0 = helper.getIntField(param, "centerFreq0");
        config.channel.center_freq1 = helper.getIntField(param, "centerFreq1");

        config.num_burst = helper.getIntField(param, "numberBurst");
        config.burst_period = (unsigned) helper.getIntField(param, "interval");
        config.num_frames_per_burst = (unsigned) helper.getIntField(param, "numSamplesPerBurst");
        config.num_retries_per_rtt_frame = (unsigned) helper.getIntField(param,
 "numRetriesPerMeasurementFrame");
        config.num_retries_per_ftmr = (unsigned) helper.getIntField(param, "numRetriesPerFTMR");
        config.LCI_request = helper.getBoolField(param, "LCIRequest") ? 1 : 0;
        config.LCR_request = helper.getBoolField(param, "LCRRequest") ? 1 : 0;
        config.burst_duration = (unsigned) helper.getIntField(param, "burstTimeout");
        config.preamble = (wifi_rtt_preamble) helper.getIntField(param, "preamble");
        config.bw = (wifi_rtt_bw) helper.getIntField(param, "bandwidth");

        ALOGD("RTT request destination %d: type is %d, peer is %d, bw is %d, center_freq is %d ", i,
                config.type,config.peer, config.channel.width,  config.channel.center_freq);
        ALOGD("center_freq0 is %d, center_freq1 is %d, num_burst is %d,interval is %d",
                config.channel.center_freq0, config.channel.center_freq1, config.num_burst,
                config.burst_period);
        ALOGD("frames_per_burst is %d, retries of measurement frame is %d, retries_per_ftmr is %d",
                config.num_frames_per_burst, config.num_retries_per_rtt_frame,
                config.num_retries_per_ftmr);
        ALOGD("LCI_requestis %d, LCR_request is %d,  burst_timeout is %d, preamble is %d, bw is %d",
                config.LCI_request, config.LCR_request, config.burst_duration, config.preamble,
                config.bw);
 }

    wifi_rtt_event_handler handler;
    handler.on_rtt_results = &onRttResults;

 return hal_fn.wifi_rtt_range_request(id, handle, len, configs, handler) == WIFI_SUCCESS;
}

Project: Android

static jboolean android_net_wifi_resetHotlist(JNIEnv *env, jclass cls, jint iface, jint id) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("resetting hotlist on interface[%d] = %p", iface, handle);

 return hal_fn.wifi_reset_bssid_hotlist(id, handle) == WIFI_SUCCESS;
}

Project: Android

static jboolean android_net_wifi_reset_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    ALOGD("android_net_wifi_reset_alert_handler = %p", handle);
 int result = hal_fn.wifi_reset_alert_handler(id, handle);
 if (result != WIFI_SUCCESS) {
        ALOGE(" Fail to reset alert handler");
 return false;
 }

    ALOGD("android_net_wifi_reset_log_handler = %p", handle);
    result = hal_fn.wifi_reset_log_handler(id, handle);
 if (result != WIFI_SUCCESS) {
        ALOGE("Fail to reset logging handler");
 return false;
 }

 return true;
}

Project: Android

static jboolean android_net_wifi_setDfsFlag(JNIEnv *env, jclass cls, jint iface, jboolean dfs) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("setting dfs flag to %s, %p", dfs ? "true" : "false", handle);

    u32 nodfs = dfs ? 0 : 1;
    wifi_error result = hal_fn.wifi_set_nodfs_flag(handle, nodfs);
 return result == WIFI_SUCCESS;
}

Project: Android

static jboolean android_net_wifi_setLazyRoam(
 JNIEnv *env, jclass cls, jint iface, jint id, jboolean enabled, jobject roam_param) {

 JNIHelper helper(env);
    wifi_error status = WIFI_SUCCESS;
    wifi_roam_params params;
    memset(&params, 0, sizeof(params));

    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("configure lazy roam request [%d] = %p", id, handle);

 if (roam_param != NULL) {
        params.A_band_boost_threshold  = helper.getIntField(roam_param, "A_band_boost_threshold");
        params.A_band_penalty_threshold  = helper.getIntField(roam_param, "A_band_penalty_threshold");
        params.A_band_boost_factor = helper.getIntField(roam_param, "A_band_boost_factor");
        params.A_band_penalty_factor  = helper.getIntField(roam_param, "A_band_penalty_factor");
        params.A_band_max_boost  = helper.getIntField(roam_param, "A_band_max_boost");
        params.lazy_roam_hysteresis = helper.getIntField(roam_param, "lazy_roam_hysteresis");
        params.alert_roam_rssi_trigger = helper.getIntField(roam_param, "alert_roam_rssi_trigger");
        status = hal_fn.wifi_set_gscan_roam_params(id, handle, &params);
 }
    ALOGE("android_net_wifi_setLazyRoam configured params status=%d\n", status);

 if (status >= 0) {
 int doEnable = enabled ? 1 : 0;
        status = hal_fn.wifi_enable_lazy_roam(id, handle, doEnable);
        ALOGE("android_net_wifi_setLazyRoam enabled roam status=%d\n", status);
 }
 return status >= 0;
}

Project: Android

static jboolean android_net_wifi_setPnoListNative(
 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {

 JNIHelper helper(env);
    wifi_epno_handler handler;
    handler.on_network_found = &onPnoNetworkFound;

    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("configure ePno list request [%d] = %p", id, handle);

 if (list == NULL) {
 int result = hal_fn.wifi_set_epno_list(id, handle, 0, NULL, handler);
        ALOGE(" setPnoListNative: STOP result = %d", result);
 return result >= 0;
 }

    wifi_epno_network net_list[MAX_PNO_SSID];
    memset(&net_list, 0, sizeof(net_list));

 size_t len = helper.getArrayLength((jobjectArray)list);
 if (len > (size_t)MAX_PNO_SSID) {
 return false;
 }

 for (unsigned int i = 0; i < len; i++) {

 JNIObject<jobject> pno_net = helper.getObjectArrayElement((jobjectArray)list, i);
 if (pno_net == NULL) {
            ALOGD("setPnoListNative: could not get element %d", i);
 continue;
 }

 JNIObject<jstring> sssid = helper.getStringField(pno_net, "SSID");
 if (sssid == NULL) {
              ALOGE("Error setPnoListNative: getting ssid field");
 return false;
 }

 ScopedUtfChars chars(env, (jstring)sssid.get());
 const char *ssid = chars.c_str();
 if (ssid == NULL) {
             ALOGE("Error setPnoListNative: getting ssid");
 return false;
 }
 int ssid_len = strnlen((const char*)ssid, 33);
 if (ssid_len > 32) {
           ALOGE("Error setPnoListNative: long ssid %u", strnlen((const char*)ssid, 256));
 return false;
 }

 if (ssid_len > 1 && ssid[0] == '"' && ssid[ssid_len-1])
 {
            ssid++;
            ssid_len-=2;
 }
 if (ssid_len == 0) {
            ALOGE("Error setPnoListNative: zero length ssid, skip it");
 continue;
 }
        memcpy(net_list[i].ssid, ssid, ssid_len);

 int rssit = helper.getIntField(pno_net, "rssi_threshold");
        net_list[i].rssi_threshold = (byte)rssit;
 int a = helper.getIntField(pno_net, "auth");
        net_list[i].auth_bit_field = a;
 int f = helper.getIntField(pno_net, "flags");
        net_list[i].flags = f;
        ALOGE(" setPnoListNative: idx %u rssi %d/%d auth %x/%x flags %x/%x [%s]", i,
 (signed)net_list[i].rssi_threshold, net_list[i].rssi_threshold,
                net_list[i].auth_bit_field, a, net_list[i].flags, f, net_list[i].ssid);
 }

 int result = hal_fn.wifi_set_epno_list(id, handle, len, net_list, handler);
    ALOGE(" setPnoListNative: result %d", result);

 return result >= 0;
}

Project: Android

static jboolean android_net_wifi_setScanningMacOui(JNIEnv *env, jclass cls,
        jint iface, jbyteArray param) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("setting scan oui %p", handle);

 static const unsigned oui_len = 3; /* OUI is upper 3 bytes of mac_address */
 int len = helper.getArrayLength(param);
 if (len != oui_len) {
        ALOGE("invalid oui length %d", len);
 return false;
 }

 ScopedBytesRO paramBytes(env, param);
 const jbyte* bytes = paramBytes.get();
 if (bytes == NULL) {
        ALOGE("failed to get array");
 return false;
 }

 return hal_fn.wifi_set_scanning_mac_oui(handle, (byte *)bytes) == WIFI_SUCCESS;
}

Project: Android

static jboolean android_net_wifi_setSsidWhitelist(
 JNIEnv *env, jclass cls, jint iface, jint id, jobject list) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("configure SSID white list request [%d] = %p", id, handle);
    wifi_ssid *ssids = NULL;
 int num_ssids = 0;
 if (list != NULL) {
 size_t len = helper.getArrayLength((jobjectArray)list);
 if (len > 0) {
            ssids = (wifi_ssid *)malloc(len * sizeof (wifi_ssid));
 if (!ssids) return false;
            memset(ssids, 0, len * sizeof (wifi_ssid));
 for (unsigned int i = 0; i < len; i++) {

 JNIObject<jobject> jssid = helper.getObjectArrayElement(list, i);
 if (jssid == NULL) {
                    ALOGD("configure SSID whitelist: could not get element %d", i);
                    free(ssids);
 return false;
 }

 ScopedUtfChars chars(env, (jstring)jssid.get());
 const char *utf = chars.c_str();
 if (utf == NULL) {
                    ALOGE("Error getting sssid");
                    free(ssids);
 return false;
 }

 int slen = strnlen(utf, 33);
 if (slen <= 0 || slen > 32) {
                    ALOGE("Error wrong ssid length %d", slen);
                    free(ssids);
 return false;
 }

                memcpy(ssids[i].ssid, utf, slen);
                num_ssids++;
                ALOGD("SSID white list: added ssid %s", utf);
 }
 }
 }

    ALOGD("android_net_wifi_setSsidWhitelist Added %d sssids", num_ssids);
 return hal_fn.wifi_set_ssid_white_list(id, handle, num_ssids, ssids) == WIFI_SUCCESS;
}

Project: Android

static jboolean android_net_wifi_set_Country_Code_Hal(JNIEnv *env,jclass cls, jint iface,
        jstring country_code) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

 ScopedUtfChars chars(env, country_code);
 const char *country = chars.c_str();

    ALOGD("set country code: %s", country);
    wifi_error res = hal_fn.wifi_set_country_code(handle, country);
 return res == WIFI_SUCCESS;
}

Project: Android

static jboolean android_net_wifi_set_log_handler(JNIEnv *env, jclass cls, jint iface, jint id) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("android_net_wifi_set_log_handler = %p", handle);

    wifi_ring_buffer_data_handler handler;
    handler.on_ring_buffer_data = &on_ring_buffer_data;
 int result = hal_fn.wifi_set_log_handler(id, handle, handler);
 if (result != WIFI_SUCCESS) {
        ALOGE("Fail to set logging handler");
 return false;
 }

    wifi_alert_handler alert_handler;
    alert_handler.on_alert = &on_alert_data;
    result = hal_fn.wifi_set_alert_handler(id, handle, alert_handler);
 if (result != WIFI_SUCCESS) {
        ALOGE(" Fail to set alert handler");
 return false;
 }

 return true;
}

Project: Android

static jboolean android_net_wifi_startHal(JNIEnv* env, jclass cls) {
 JNIHelper helper(env);
    wifi_handle halHandle = getWifiHandle(helper, cls);
 if (halHandle == NULL) {

 if(init_wifi_hal_func_table(&hal_fn) != 0 ) {
            ALOGD("Can not initialize the basic function pointer table");
 return false;
 }

        wifi_error res = init_wifi_vendor_hal_func_table(&hal_fn);
 if (res != WIFI_SUCCESS) {
            ALOGD("Can not initialize the vendor function pointer table");
 return false;
 }

 int ret = set_iface_flags("wlan0", 1);
 if(ret != 0) {
 return false;
 }

        res = hal_fn.wifi_initialize(&halHandle);
 if (res == WIFI_SUCCESS) {
            helper.setStaticLongField(cls, WifiHandleVarName, (jlong)halHandle);
            ALOGD("Did set static halHandle = %p", halHandle);
 }
        env->GetJavaVM(&mVM);
        mCls = (jclass) env->NewGlobalRef(cls);
        ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
 return res == WIFI_SUCCESS;
 } else {
 return (set_iface_flags("wlan0", 1) == 0);
 }
}

Project: Android

static jboolean android_net_wifi_startScan(
 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    wifi_scan_cmd_params params;
    memset(&params, 0, sizeof(params));

    params.base_period = helper.getIntField(settings, "base_period_ms");
    params.max_ap_per_scan = helper.getIntField(settings, "max_ap_per_scan");
    params.report_threshold_percent = helper.getIntField(settings, "report_threshold_percent");
    params.report_threshold_num_scans = helper.getIntField(settings, "report_threshold_num_scans");

    ALOGD("Initialized common fields %d, %d, %d, %d", params.base_period, params.max_ap_per_scan,
            params.report_threshold_percent, params.report_threshold_num_scans);

 const char *bucket_array_type = "[Lcom/android/server/wifi/WifiNative$BucketSettings;";
 const char *channel_array_type = "[Lcom/android/server/wifi/WifiNative$ChannelSettings;";

    params.num_buckets = helper.getIntField(settings, "num_buckets");


 for (int i = 0; i < params.num_buckets; i++) {
 JNIObject<jobject> bucket = helper.getObjectArrayField(
                settings, "buckets", bucket_array_type, i);

        params.buckets[i].bucket = helper.getIntField(bucket, "bucket");
        params.buckets[i].band = (wifi_band) helper.getIntField(bucket, "band");
        params.buckets[i].period = helper.getIntField(bucket, "period_ms");

 int report_events = helper.getIntField(bucket, "report_events");
        params.buckets[i].report_events = report_events;

        ALOGD("bucket[%d] = %d:%d:%d:%d", i, params.buckets[i].bucket,
                params.buckets[i].band, params.buckets[i].period, report_events);

        params.buckets[i].num_channels = helper.getIntField(bucket, "num_channels");

 for (int j = 0; j < params.buckets[i].num_channels; j++) {
 JNIObject<jobject> channel = helper.getObjectArrayField(
                    bucket, "channels", channel_array_type, j);

            params.buckets[i].channels[j].channel = helper.getIntField(channel, "frequency");
            params.buckets[i].channels[j].dwellTimeMs = helper.getIntField(channel, "dwell_time_ms");

 bool passive = helper.getBoolField(channel, "passive");
            params.buckets[i].channels[j].passive = (passive ? 1 : 0);

 }
 }


    wifi_scan_result_handler handler;
    memset(&handler, 0, sizeof(handler));
    handler.on_scan_results_available = &onScanResultsAvailable;
    handler.on_full_scan_result = &onFullScanResult;
    handler.on_scan_event = &onScanEvent;

 return hal_fn.wifi_start_gscan(id, handle, params, handler) == WIFI_SUCCESS;
}

Project: Android

static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
{
 return (::wifi_start_supplicant(p2pSupported) == 0);
}

Project: Android

static jboolean android_net_wifi_start_logging_ring_buffer(JNIEnv *env, jclass cls, jint iface,
        jint verbose_level,jint flags, jint max_interval,jint min_data_size, jstring ring_name) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);

    ALOGD("android_net_wifi_start_logging_ring_buffer = %p", handle);

 if (handle == 0) {
 return false;
 }

 ScopedUtfChars chars(env, ring_name);
 const char* ring_name_const_char = chars.c_str();
 int ret = hal_fn.wifi_start_logging(handle, verbose_level,
            flags, max_interval, min_data_size, const_cast<char *>(ring_name_const_char));

 if (ret != WIFI_SUCCESS) {
        ALOGE("Fail to start logging for ring %s", ring_name_const_char);
 } else {
        ALOGD("start logging for ring %s", ring_name_const_char);
 }

 return ret == WIFI_SUCCESS;
}

Project: Android

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) {
 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("Start packet offload [%d] = %p", idx, handle);
    wifi_error ret;
    wifi_request_id id = idx;
 
 ScopedBytesRO pktBytes(env, pkt), srcMacBytes(env, srcMac), dstMacBytes(env, dstMac);

    byte * pkt_data = (byte*) pktBytes.get();
 unsigned short pkt_len = env->GetArrayLength(pkt);
    byte* src_mac_addr = (byte*) srcMacBytes.get();
    byte* dst_mac_addr = (byte*) dstMacBytes.get();
 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;
}

Project: Android

static void android_net_wifi_stopHal(JNIEnv* env, jclass cls) {
    ALOGD("In wifi stop Hal");

 JNIHelper helper(env);
    wifi_handle halHandle = getWifiHandle(helper, cls);
 if (halHandle == NULL)
 return;

    ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
    hal_fn.wifi_cleanup(halHandle, android_net_wifi_hal_cleaned_up_handler);
}

Project: Android

static jint android_net_wifi_stop_sending_offloaded_packet(JNIEnv *env, jclass cls,
                    jint iface, jint idx) {
 int ret;
 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, 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;
}

Project: Android

static jboolean android_net_wifi_toggle_interface(JNIEnv* env, jclass cls, int toggle) {
 return(set_iface_flags("wlan0", toggle) == 0);
}

Project: Android

static jboolean android_net_wifi_trackSignificantWifiChange(
 JNIEnv *env, jclass cls, jint iface, jint id, jobject settings) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("tracking significant wifi change on interface[%d] = %p", iface, handle);

    wifi_significant_change_params params;
    memset(&params, 0, sizeof(params));

    params.rssi_sample_size = helper.getIntField(settings, "rssiSampleSize");
    params.lost_ap_sample_size = helper.getIntField(settings, "lostApSampleSize");
    params.min_breaching = helper.getIntField(settings, "minApsBreachingThreshold");

 const char *bssid_info_array_type = "[Landroid/net/wifi/WifiScanner$BssidInfo;";
 JNIObject<jobjectArray> bssids = helper.getArrayField(
            settings, "bssidInfos", bssid_info_array_type);
    params.num_bssid = helper.getArrayLength(bssids);

 if (params.num_bssid == 0) {
        ALOGE("Error in accessing array");
 return false;
 }

    ALOGD("Initialized common fields %d, %d, %d, %d", params.rssi_sample_size,
            params.lost_ap_sample_size, params.min_breaching, params.num_bssid);

 for (int i = 0; i < params.num_bssid; i++) {
 JNIObject<jobject> objAp = helper.getObjectArrayElement(bssids, i);

 JNIObject<jstring> macAddrString = helper.getStringField(objAp, "bssid");
 if (macAddrString == NULL) {
            ALOGE("Error getting bssid field");
 return false;
 }

 ScopedUtfChars chars(env, macAddrString.get());
 const char *bssid = chars.c_str();
 if (bssid == NULL) {
            ALOGE("Error getting bssid");
 return false;
 }

        mac_addr addr;
        parseMacAddress(bssid, addr);
        memcpy(params.ap[i].bssid, addr, sizeof(mac_addr));

 char bssidOut[32];
        sprintf(bssidOut, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1],
            addr[2], addr[3], addr[4], addr[5]);

        params.ap[i].low = helper.getIntField(objAp, "low");
        params.ap[i].high = helper.getIntField(objAp, "high");

        ALOGD("Added bssid %s, [%04d, %04d]", bssidOut, params.ap[i].low, params.ap[i].high);
 }

    ALOGD("Added %d bssids", params.num_bssid);

    wifi_significant_change_handler handler;
    memset(&handler, 0, sizeof(handler));

    handler.on_significant_change = &onSignificantWifiChange;
 return hal_fn.wifi_set_significant_change_handler(id, handle, params, handler) == WIFI_SUCCESS;
}

Project: Android

static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
{
 return (::wifi_unload_driver() == 0);
}

Project: Android

static jboolean android_net_wifi_untrackSignificantWifiChange(
 JNIEnv *env, jclass cls, jint iface, jint id) {

 JNIHelper helper(env);
    wifi_interface_handle handle = getIfaceHandle(helper, cls, iface);
    ALOGD("resetting significant wifi change on interface[%d] = %p", iface, handle);

 return hal_fn.wifi_reset_significant_change_handler(id, handle) == WIFI_SUCCESS;
}

Project: Android

static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
{
 char buf[EVENT_BUF_SIZE];
 int nread = ::wifi_wait_for_event(buf, sizeof buf);
 if (nread > 0) {
 return env->NewStringUTF(buf);
 } else {
 return NULL;
 }
}

Project: Android

static void android_net_wifi_waitForHalEvents(JNIEnv* env, jclass cls) {

    ALOGD("waitForHalEvents called, vm = %p, obj = %p, env = %p", mVM, mCls, env);

 JNIHelper helper(env);
    wifi_handle halHandle = getWifiHandle(helper, cls);
    hal_fn.wifi_event_loop(halHandle);
    set_iface_flags("wlan0", 0);
}

Project: Android

static int compare_scan_result_timestamp(const void *v1, const void *v2) {
 const wifi_scan_result *result1 = static_cast<const wifi_scan_result *>(v1);
 const wifi_scan_result *result2 = static_cast<const wifi_scan_result *>(v2);
 return result1->ts - result2->ts;
}

Project: Android

static JNIObject<jobject> createScanResult(JNIHelper &helper, wifi_scan_result *result) {


 JNIObject<jobject> scanResult = helper.createObject("android/net/wifi/ScanResult");
 if (scanResult == NULL) {
        ALOGE("Error in creating scan result");
 return JNIObject<jobject>(helper, NULL);
 }

    ALOGV("setting SSID to %s", result->ssid);

 if (!setSSIDField(helper, scanResult, result->ssid)) {
        ALOGE("Error on set SSID");
 return JNIObject<jobject>(helper, NULL);
 }

 char bssid[32];
    sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->bssid[0], result->bssid[1],
        result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5]);

    helper.setStringField(scanResult, "BSSID", bssid);

    helper.setIntField(scanResult, "level", result->rssi);
    helper.setIntField(scanResult, "frequency", result->channel);
    helper.setLongField(scanResult, "timestamp", result->ts);

 return scanResult;
}

Project: Android

static jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) {
 char reply[REPLY_BUF_SIZE];
 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
 return JNI_FALSE;
 }
    jboolean result = (strcmp(reply, "OK") == 0);
 if (!result) {
 ScopedUtfChars command(env, javaCommand);
        ALOGI("command '%s' returned '%s", command.c_str(), reply);
 }
 return result;
}

Project: Android

static bool doCommand(JNIEnv* env, jstring javaCommand,
 char* reply, size_t reply_len) {
 ScopedUtfChars command(env, javaCommand);
 if (command.c_str() == NULL) {
 return false; // ScopedUtfChars already threw on error.
 }

 if (DBG) {
        ALOGD("doCommand: %s", command.c_str());
 }

 --reply_len; // Ensure we have room to add NUL termination.
 if (::wifi_command(command.c_str(), reply, &reply_len) != 0) {
 return false;
 }

 if (reply_len > 0 && reply[reply_len-1] == '\n') {
        reply[reply_len-1] = '\0';
 } else {
        reply[reply_len] = '\0';
 }
 return true;
}

Project: Android

static jint doIntCommand(JNIEnv* env, jstring javaCommand) {
 char reply[REPLY_BUF_SIZE];
 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
 return -1;
 }
 return static_cast<jint>(atoi(reply));
}

Project: Android

static jstring doStringCommand(JNIEnv* env, jstring javaCommand) {
 char reply[REPLY_BUF_SIZE];
 if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
 return NULL;
 }
 return env->NewStringUTF(reply);
}

Project: Android

static wifi_interface_handle getIfaceHandle(JNIHelper &helper, jclass cls, jint index) {
 return (wifi_interface_handle) helper.getStaticLongArrayField(cls, WifiIfaceHandleVarName, index);
}

Project: Android

static wifi_handle getWifiHandle(JNIHelper &helper, jclass cls) {
 return (wifi_handle) helper.getStaticLongField(cls, WifiHandleVarName);
}

Project: Android

int init_wifi_hal_func_table(wifi_hal_fn *hal_fn) {
 if (hal_fn == NULL) {
 return -1;
 }
    hal_fn->wifi_initialize = wifi_initialize_stub;
    hal_fn->wifi_cleanup = wifi_cleanup_stub;
    hal_fn->wifi_event_loop = wifi_event_loop_stub;
    hal_fn->wifi_get_error_info = wifi_get_error_info_stub;
    hal_fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set_stub;
    hal_fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix_stub;
    hal_fn->wifi_set_scanning_mac_oui =  wifi_set_scanning_mac_oui_stub;
    hal_fn->wifi_get_supported_channels = wifi_get_supported_channels_stub;
    hal_fn->wifi_is_epr_supported = wifi_is_epr_supported_stub;
    hal_fn->wifi_get_ifaces = wifi_get_ifaces_stub;
    hal_fn->wifi_get_iface_name = wifi_get_iface_name_stub;
    hal_fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler_stub;
    hal_fn->wifi_start_gscan = wifi_start_gscan_stub;
    hal_fn->wifi_stop_gscan = wifi_stop_gscan_stub;
    hal_fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results_stub;
    hal_fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist_stub;
    hal_fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist_stub;
    hal_fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler_stub;
    hal_fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler_stub;
    hal_fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities_stub;
    hal_fn->wifi_set_link_stats = wifi_set_link_stats_stub;
    hal_fn->wifi_get_link_stats = wifi_get_link_stats_stub;
    hal_fn->wifi_clear_link_stats = wifi_clear_link_stats_stub;
    hal_fn->wifi_get_valid_channels = wifi_get_valid_channels_stub;
    hal_fn->wifi_rtt_range_request = wifi_rtt_range_request_stub;
    hal_fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel_stub;
    hal_fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities_stub;
    hal_fn->wifi_start_logging = wifi_start_logging_stub;
    hal_fn->wifi_set_epno_list = wifi_set_epno_list_stub;
    hal_fn->wifi_set_country_code = wifi_set_country_code_stub;
    hal_fn->wifi_enable_tdls = wifi_enable_tdls_stub;
    hal_fn->wifi_disable_tdls = wifi_disable_tdls_stub;
    hal_fn->wifi_get_tdls_status = wifi_get_tdls_status_stub;
    hal_fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities_stub;
    hal_fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag_stub;
    hal_fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump_stub;
    hal_fn->wifi_set_log_handler = wifi_set_log_handler_stub;
    hal_fn->wifi_reset_log_handler = wifi_reset_log_handler_stub;
    hal_fn->wifi_set_alert_handler = wifi_set_alert_handler_stub;
    hal_fn->wifi_reset_alert_handler = wifi_reset_alert_handler_stub;
    hal_fn->wifi_get_firmware_version = wifi_get_firmware_version_stub;
    hal_fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status_stub;
    hal_fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set_stub;
    hal_fn->wifi_get_ring_data = wifi_get_ring_data_stub;
    hal_fn->wifi_get_driver_version = wifi_get_driver_version_stub;
    hal_fn->wifi_set_ssid_white_list = wifi_set_ssid_white_list_stub;
    hal_fn->wifi_set_gscan_roam_params = wifi_set_gscan_roam_params_stub;
    hal_fn->wifi_set_bssid_preference = wifi_set_bssid_preference_stub;
    hal_fn->wifi_enable_lazy_roam = wifi_enable_lazy_roam_stub;
    hal_fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist_stub;
    hal_fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet_stub;
    hal_fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet_stub;
 return 0;
}

Project: Android

static void onFullScanResult(wifi_request_id id, wifi_scan_result *result) {

 JNIHelper helper(mVM);


 JNIObject<jobject> scanResult = createScanResult(helper, result);


 JNIObject<jbyteArray> elements = helper.newByteArray(result->ie_length);
 if (elements == NULL) {
        ALOGE("Error in allocating array");
 return;
 }


    jbyte *bytes = (jbyte *)&(result->ie_data[0]);
    helper.setByteArrayRegion(elements, 0, result->ie_length, bytes);


    helper.reportEvent(mCls, "onFullScanResult", "(ILandroid/net/wifi/ScanResult;[B)V", id,
            scanResult.get(), elements.get());
}

Project: Android

static void onHotlistApFound(wifi_request_id id,
 unsigned num_results, wifi_scan_result *results) {

 JNIHelper helper(mVM);
    ALOGD("onHotlistApFound called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results);

 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results,
 "android/net/wifi/ScanResult", NULL);
 if (scanResults == NULL) {
        ALOGE("Error in allocating array");
 return;
 }

 for (unsigned i = 0; i < num_results; i++) {

 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
 if (scanResult == NULL) {
            ALOGE("Error in creating scan result");
 return;
 }

        helper.setObjectArrayElement(scanResults, i, scanResult);

        ALOGD("Found AP %32s", results[i].ssid);
 }

    helper.reportEvent(mCls, "onHotlistApFound", "(I[Landroid/net/wifi/ScanResult;)V",
        id, scanResults.get());
}

Project: Android

static void onHotlistApLost(wifi_request_id id,
 unsigned num_results, wifi_scan_result *results) {

 JNIHelper helper(mVM);
    ALOGD("onHotlistApLost called, vm = %p, obj = %p, num_results = %d", mVM, mCls, num_results);

 JNIObject<jobjectArray> scanResults = helper.newObjectArray(num_results,
 "android/net/wifi/ScanResult", NULL);
 if (scanResults == NULL) {
        ALOGE("Error in allocating array");
 return;
 }

 for (unsigned i = 0; i < num_results; i++) {

 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
 if (scanResult == NULL) {
            ALOGE("Error in creating scan result");
 return;
 }

        helper.setObjectArrayElement(scanResults, i, scanResult);

        ALOGD("Lost AP %32s", results[i].ssid);
 }

    helper.reportEvent(mCls, "onHotlistApLost", "(I[Landroid/net/wifi/ScanResult;)V",
        id, scanResults.get());
}

Project: Android

void onLinkStatsResults(wifi_request_id id, wifi_iface_stat *iface_stat,
 int num_radios, wifi_radio_stat *radio_stats)
{
 if (iface_stat != 0) {
        memcpy(&link_stat, iface_stat, sizeof(wifi_iface_stat));
 } else {
        memset(&link_stat, 0, sizeof(wifi_iface_stat));
 }

 if (num_radios > 0 && radio_stats != 0) {
        memcpy(&radio_stat, radio_stats, sizeof(wifi_radio_stat));
 } else {
        memset(&radio_stat, 0, sizeof(wifi_radio_stat));
 }
}

Project: Android

static void onPnoNetworkFound(wifi_request_id id,
 unsigned num_results, wifi_scan_result *results) {

 JNIHelper helper(mVM);

    ALOGD("onPnoNetworkFound called, vm = %p, obj = %p, num_results %u", mVM, mCls, num_results);

 if (results == 0 || num_results == 0) {
       ALOGE("onPnoNetworkFound: Error no results");
 return;
 }

    jbyte *bytes;
 JNIObject<jobjectArray> scanResults(helper, NULL);

 for (unsigned i=0; i<num_results; i++) {

 JNIObject<jobject> scanResult = createScanResult(helper, &results[i]);
 if (i == 0) {
            scanResults = helper.newObjectArray(
                    num_results, "android/net/wifi/ScanResult", scanResult);
 if (scanResults == 0) {
                ALOGD("cant allocate array");
 } else {
                ALOGD("allocated array %u", helper.getArrayLength(scanResults));
 }
 } else {
            helper.setObjectArrayElement(scanResults, i, scanResult);
 }

        ALOGD("Scan result with ie length %d, i %u, <%s> rssi=%d %02x:%02x:%02x:%02x:%02x:%02x",
                results->ie_length, i, results[i].ssid, results[i].rssi, results[i].bssid[0],
                results[i].bssid[1],results[i].bssid[2], results[i].bssid[3], results[i].bssid[4],
                results[i].bssid[5]);

 /*elements = helper.newByteArray(results->ie_length);
        if (elements == NULL) {
            ALOGE("Error in allocating array");
            return;
        }*/



 }


    ALOGD("calling report");

    helper.reportEvent(mCls, "onPnoNetworkFound", "(I[Landroid/net/wifi/ScanResult;)V", id,
               scanResults.get());
        ALOGD("free ref");
}

Project: Android

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]);
 JNIHelper helper(mVM);
    helper.reportEvent(mCls, "onRssiThresholdBreached", "(IB)V", id, cur_rssi);
}

Project: Android

static void onRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* results[]) {

 JNIHelper helper(mVM);

    ALOGD("onRttResults called, vm = %p, obj = %p", mVM, mCls);

 JNIObject<jobjectArray> rttResults = helper.newObjectArray(
            num_results, "android/net/wifi/RttManager$RttResult", NULL);
 if (rttResults == NULL) {
        ALOGE("Error in allocating array");
 return;
 }

 for (unsigned i = 0; i < num_results; i++) {

        wifi_rtt_result *result = results[i];

 JNIObject<jobject> rttResult = helper.createObject("android/net/wifi/RttManager$RttResult");
 if (rttResult == NULL) {
            ALOGE("Error in creating rtt result");
 return;
 }

 char bssid[32];
        sprintf(bssid, "%02x:%02x:%02x:%02x:%02x:%02x", result->addr[0], result->addr[1],
            result->addr[2], result->addr[3], result->addr[4], result->addr[5]);

        helper.setStringField(rttResult, "bssid", bssid);
        helper.setIntField( rttResult, "burstNumber",              result->burst_num);
        helper.setIntField( rttResult, "measurementFrameNumber",   result->measurement_number);
        helper.setIntField( rttResult, "successMeasurementFrameNumber",   result->success_number);
        helper.setIntField(rttResult, "frameNumberPerBurstPeer",   result->number_per_burst_peer);
        helper.setIntField( rttResult, "status",                   result->status);
        helper.setIntField( rttResult, "measurementType",          result->type);
        helper.setIntField(rttResult, "retryAfterDuration",       result->retry_after_duration);
        helper.setLongField(rttResult, "ts",                       result->ts);
        helper.setIntField( rttResult, "rssi",                     result->rssi);
        helper.setIntField( rttResult, "rssiSpread",               result->rssi_spread);
        helper.setIntField( rttResult, "txRate",                   result->tx_rate.bitrate);
        helper.setIntField( rttResult, "rxRate",                   result->rx_rate.bitrate);
        helper.setLongField(rttResult, "rtt",                      result->rtt);
        helper.setLongField(rttResult, "rttStandardDeviation",     result->rtt_sd);
        helper.setIntField( rttResult, "distance",                 result->distance);
        helper.setIntField( rttResult, "distanceStandardDeviation", result->distance_sd);
        helper.setIntField( rttResult, "distanceSpread",           result->distance_spread);
        helper.setIntField( rttResult, "burstDuration",             result->burst_duration);
        helper.setIntField( rttResult, "negotiatedBurstNum",      result->negotiated_burst_num);

 JNIObject<jobject> LCI = helper.createObject(
 "android/net/wifi/RttManager$WifiInformationElement");
 if (result->LCI != NULL && result->LCI->len > 0) {
            ALOGD("Add LCI in result");
            helper.setByteField(LCI, "id", result->LCI->id);
 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len);
            jbyte *bytes = (jbyte *)&(result->LCI->data[0]);
            helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes);
            helper.setObjectField(LCI, "data", "[B", elements);
 } else {
            ALOGD("No LCI in result");
            helper.setByteField(LCI, "id", (byte)(0xff));
 }
        helper.setObjectField(rttResult, "LCI",
 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCI);

 JNIObject<jobject> LCR = helper.createObject(
 "android/net/wifi/RttManager$WifiInformationElement");
 if (result->LCR != NULL && result->LCR->len > 0) {
            ALOGD("Add LCR in result");
            helper.setByteField(LCR, "id",           result->LCR->id);
 JNIObject<jbyteArray> elements = helper.newByteArray(result->LCI->len);
            jbyte *bytes = (jbyte *)&(result->LCR->data[0]);
            helper.setByteArrayRegion(elements, 0, result->LCI->len, bytes);
            helper.setObjectField(LCR, "data", "[B", elements);
 } else {
            ALOGD("No LCR in result");
            helper.setByteField(LCR, "id", (byte)(0xff));
 }
        helper.setObjectField(rttResult, "LCR",
 "Landroid/net/wifi/RttManager$WifiInformationElement;", LCR);

        helper.setObjectArrayElement(rttResults, i, rttResult);
 }

    helper.reportEvent(mCls, "onRttResults", "(I[Landroid/net/wifi/RttManager$RttResult;)V",
        id, rttResults.get());
}

Project: Android

static void onScanEvent(wifi_scan_event event, unsigned status) {

 JNIHelper helper(mVM);


    helper.reportEvent(mCls, "onScanStatus", "(I)V", event);
}

Project: Android

static void onScanResultsAvailable(wifi_request_id id, unsigned num_results) {

 JNIHelper helper(mVM);


    helper.reportEvent(mCls, "onScanResultsAvailable", "(I)V", id);
}

Project: Android

static void on_alert_data(wifi_request_id id, char *buffer, int buffer_size, int err_code){

 JNIHelper helper(mVM);
    ALOGD("on_alert_data called, vm = %p, obj = %p, buffer_size = %d, error code = %d"
 , mVM, mCls, buffer_size, err_code);

 if (buffer_size > 0) {
 JNIObject<jbyteArray> records = helper.newByteArray(buffer_size);
        jbyte *bytes = (jbyte *) buffer;
        helper.setByteArrayRegion(records, 0,buffer_size, bytes);
        helper.reportEvent(mCls,"onWifiAlert","([BI)V", records.get(), err_code);
 } else {
        helper.reportEvent(mCls,"onWifiAlert","([BI)V", NULL, err_code);
 }
}

Project: Android

void on_firmware_memory_dump(char *buffer, int buffer_size) {

 JNIHelper helper(mVM);
 /* ALOGD("on_firmware_memory_dump called, vm = %p, obj = %p, env = %p buffer_size = %d"
            , mVM, mCls, env, buffer_size); */

 if (buffer_size > 0) {
 JNIObject<jbyteArray> dump = helper.newByteArray(buffer_size);
        jbyte *bytes = (jbyte *) (buffer);
        helper.setByteArrayRegion(dump, 0, buffer_size, bytes);
        helper.reportEvent(mCls,"onWifiFwMemoryAvailable","([B)V", dump.get());
 }
}

Project: Android

static void on_ring_buffer_data(char *ring_name, char *buffer, int buffer_size,
        wifi_ring_buffer_status *status) {

 if (!ring_name || !buffer || !status ||
 (unsigned int)buffer_size <= sizeof(wifi_ring_buffer_entry)) {
        ALOGE("Error input for on_ring_buffer_data!");
 return;
 }


 JNIHelper helper(mVM);
 /* ALOGD("on_ring_buffer_data called, vm = %p, obj = %p, env = %p buffer size = %d", mVM,
            mCls, env, buffer_size); */

 JNIObject<jobject> ringStatus = helper.createObject(
 "com/android/server/wifi/WifiNative$RingBufferStatus");
 if (status == NULL) {
        ALOGE("Error in creating ringBufferStatus");
 return;
 }

    helper.setStringField(ringStatus, "name", ring_name);
    helper.setIntField(ringStatus, "flag", status->flags);
    helper.setIntField(ringStatus, "ringBufferId", status->ring_id);
    helper.setIntField(ringStatus, "ringBufferByteSize", status->ring_buffer_byte_size);
    helper.setIntField(ringStatus, "verboseLevel", status->verbose_level);
    helper.setIntField(ringStatus, "writtenBytes", status->written_bytes);
    helper.setIntField(ringStatus, "readBytes", status->read_bytes);
    helper.setIntField(ringStatus, "writtenRecords", status->written_records);

 JNIObject<jbyteArray> bytes = helper.newByteArray(buffer_size);
    helper.setByteArrayRegion(bytes, 0, buffer_size, (jbyte*)buffer);

    helper.reportEvent(mCls,"onRingBufferData",
 "(Lcom/android/server/wifi/WifiNative$RingBufferStatus;[B)V",
            ringStatus.get(), bytes.get());
}

Project: Android

static byte parseHexChar(char ch) {
 if (isdigit(ch))
 return ch - '0';
 else if ('A' <= ch && ch <= 'F')
 return ch - 'A' + 10;
 else if ('a' <= ch && ch <= 'f')
 return ch - 'a' + 10;
 else {
        ALOGE("invalid character in bssid %c", ch);
 return 0;
 }

 }

Project: Android

static bool parseMacAddress(JNIEnv *env, jobject obj, mac_addr addr) {
 JNIHelper helper(env);
 JNIObject<jstring> macAddrString = helper.getStringField(obj, "bssid");
 if (macAddrString == NULL) {
        ALOGE("Error getting bssid field");
 return false;
 }

 ScopedUtfChars chars(env, macAddrString);
 const char *bssid = chars.c_str();
 if (bssid == NULL) {
        ALOGE("Error getting bssid");
 return false;
 }

    parseMacAddress(bssid, addr);
 return true;
}

Project: Android

int register_android_net_wifi_WifiNative(JNIEnv* env) {
 return AndroidRuntime::registerNativeMethods(env,
 "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
}

Project: Android

jboolean setSSIDField(JNIHelper helper, jobject scanResult, const char *rawSsid) {

 int len = strlen(rawSsid);

 if (len > 0) {
 JNIObject<jbyteArray> ssidBytes = helper.newByteArray(len);
        helper.setByteArrayRegion(ssidBytes, 0, len, (jbyte *) rawSsid);
        jboolean ret = helper.callStaticMethod(mCls,
 "setSsid", "([BLandroid/net/wifi/ScanResult;)Z", ssidBytes.get(), scanResult);
 return ret;
 } else {
 return true;
 }
}

Project: Android

int set_iface_flags(const char *ifname, int dev_up) {
 struct ifreq ifr;
 int ret;
 int sock = socket(PF_INET, SOCK_DGRAM, 0);
 if (sock < 0) {
        ALOGD("Bad socket: %d\n", sock);
 return -errno;
 }


    memset(&ifr, 0, sizeof(ifr));
    strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);


 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
      ret = errno ? -errno : -999;
      ALOGE("Could not read interface %s flags: %d\n", ifname, errno);
      close(sock);
 return ret;
 } else {
 }

 if (dev_up) {
 if (ifr.ifr_flags & IFF_UP) {
        close(sock);
 return 0;
 }
      ifr.ifr_flags |= IFF_UP;
 } else {
 if (!(ifr.ifr_flags & IFF_UP)) {
        close(sock);
 return 0;
 }
      ifr.ifr_flags &= ~IFF_UP;
 }

 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
      ALOGE("Could not set interface %s flags: %d\n", ifname, errno);
      ret = errno ? -errno : -999;
      close(sock);
 return ret;
 } else {
      ALOGD("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
 }
    close(sock);
 return 0;
}