// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
//
void core_scan_list_c::remove_entries_by_age(
    u32_t age )
    {
    DEBUG1( "core_scan_list_c::remove_entries_by_age() - removing entries older than %u microsecond(s)",
        age );

    u64_t timestamp(
        core_am_tools_c::timestamp() );

    core_type_list_iterator_c<core_scan_list_entry_s> iter( scan_list_m );
    for( core_scan_list_entry_s* current = iter.first(); current; current = iter.next() )
        {
        if ( static_cast<u32_t>( timestamp - current->timestamp ) > age )
            {
#ifdef _DEBUG
            core_mac_address_s bssid(
                current->ap_data->bssid() );

            DEBUG7( "core_scan_list_c::remove_entries_by_age() - BSSID %02X:%02X:%02X:%02X:%02X:%02X [%u second(s)] removed",
                bssid.addr[0], bssid.addr[1], bssid.addr[2],
                bssid.addr[3], bssid.addr[4], bssid.addr[5],
                static_cast<u32_t>( timestamp - current->timestamp ) / SECONDS_FROM_MICROSECONDS );
#endif // _DEBUG

            iter.remove();

            delete current->ap_data;
            delete current;
            current = NULL;
            }
        }
    }
static jboolean android_net_wifi_addToBlacklistCommand(JNIEnv* env, jobject, jstring javaBssid)
{
    ScopedUtfChars bssid(env, javaBssid);
    if (bssid.c_str() == NULL) {
        return JNI_FALSE;
    }
    return doBooleanCommand("OK", "BLACKLIST %s", bssid.c_str());
}
static jstring android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject, jstring javaBssid)
{
    ScopedUtfChars bssid(env, javaBssid);
    if (bssid.c_str() == NULL) {
        return NULL;
    }
    return doStringCommand(env, "WPS_PIN %s", bssid.c_str());
}
static jboolean android_net_wifi_wpsPbcCommand(JNIEnv* env, jobject, jstring javaBssid)
{
    ScopedUtfChars bssid(env, javaBssid);
    if (bssid.c_str() == NULL) {
        return JNI_FALSE;
    }
    return doBooleanCommand("OK", "WPS_PBC %s", bssid.c_str());
}
static jboolean android_net_wifi_setHotlist(
        JNIEnv *env, jclass cls, jint iface, jint id, jobject ap)  {

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

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

    jobjectArray array = (jobjectArray) getObjectField(env, ap,
            "bssidInfos", "[Landroid/net/wifi/WifiScanner$BssidInfo;");
    params.num_ap = env->GetArrayLength(array);

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

    for (int i = 0; i < params.num_ap; i++) {
        jobject objAp = env->GetObjectArrayElement(array, i);

        jstring macAddrString = (jstring) getObjectField(
                env, objAp, "bssid", "Ljava/lang/String;");
        if (macAddrString == NULL) {
            ALOGE("Error getting bssid field");
            return false;
        }

        ScopedUtfChars bssid(env, macAddrString);
        if (bssid.c_str() == NULL) {
            ALOGE("Error getting bssid");
            return false;
        }
        parseMacAddress(bssid.c_str(), params.ap[i].bssid);

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

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

        ALOGD("Added bssid %s", bssidOut);

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

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

    handler.on_hotlist_ap_found = &onHotlistApFound;
    return wifi_set_bssid_hotlist(id, handle, params, handler) == WIFI_SUCCESS;
}
static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject,
        jstring javaBssid, jstring javaApPin)
{
    ScopedUtfChars bssid(env, javaBssid);
    if (bssid.c_str() == NULL) {
        return JNI_FALSE;
    }
    ScopedUtfChars apPin(env, javaApPin);
    if (apPin.c_str() == NULL) {
        return JNI_FALSE;
    }
    return doBooleanCommand("OK", "WPS_REG %s %s", bssid.c_str(), apPin.c_str());
}
static bool parseMacAddress(JNIEnv *env, jobject obj, mac_addr addr) {
    jstring macAddrString = (jstring) getObjectField(
            env, obj, "bssid", "Ljava/lang/String;");

    if (macAddrString == NULL) {
        ALOGE("Error getting bssid field");
        return false;
    }

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

    parseMacAddress(bssid.c_str(), addr);
    return true;
}
static jboolean android_net_wifi_trackSignificantWifiChange(
        JNIEnv *env, jclass cls, jint iface, jint id, jobject settings)  {

    wifi_interface_handle handle = getIfaceHandle(env, 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 = getIntField(env, settings, "rssiSampleSize");
    params.lost_ap_sample_size = getIntField(env, settings, "lostApSampleSize");
    params.min_breaching = getIntField(env, settings, "minApsBreachingThreshold");

    const char *bssid_info_array_type = "[Landroid/net/wifi/WifiScanner$BssidInfo;";
    jobjectArray bssids = (jobjectArray)getObjectField(
                env, settings, "bssidInfos", bssid_info_array_type);
    params.num_ap = env->GetArrayLength(bssids);

    if (params.num_ap == 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_ap);

    for (int i = 0; i < params.num_ap; i++) {
        jobject objAp = env->GetObjectArrayElement(bssids, i);

        jstring macAddrString = (jstring) getObjectField(
                env, objAp, "bssid", "Ljava/lang/String;");
        if (macAddrString == NULL) {
            ALOGE("Error getting bssid field");
            return false;
        }

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

        mac_addr addr;
        parseMacAddress(bssid.c_str(), 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 = getIntField(env, objAp, "low");
        params.ap[i].high = getIntField(env, objAp, "high");

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

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

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

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