Не могу включить точку доступа на ноутбуке

Не могу включить точку доступа на ноутбуке

Какая цель?

Создайте точку доступа с Android-устройством (Nexus 7 в моем случае). Конечной целью является подключение карты WiFly к этой созданной сети и обмен данными между этими устройствами.

Оборудование:

  • Nexus 7 с Android 4.2.2 с корневым с ROM CyanogenMod 10.1
  • Карта WiFly: щит Arduino с тем же расположением, что и карты Zigbee, использующие Wifi (продукт)

Программное обеспечение:

Я понял, что версия Android 4.2.2 не позволяет создать точку доступа (услуга отключена программно). Вот почему я укрепил свое устройство с ПЗУ от CyanogenMod. Это ПЗУ включает эту службу.

Google скрыл некоторые методы из класса WifiManager. В частности, метод setWifiApEnabled. Вот почему я использую отражение для вызова методов в коде ниже.

Исходный код массивный! Сосредоточьтесь на методе createAccessPoint(). Я решил поставить весь исходный код, чтобы помочь людям, которые хотят знать, как я сделал все это.

public class TestAccessPoint extends Activity {

static final String TAG = "AP_TEST";
static final String SSID = "\"Awesome Access Point\"";
static final String PSK = "\"helloworld\"";
String numberOfClientsConnected;
String wifiApEnable;
String wifiApState;
WifiConfiguration wifiApConfig;
WifiManager wifiManager;
WifiConfiguration wifiConfiguration;
BroadcastReceiver receiver;
BroadcastReceiver receiverWifiDisabled;
TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.accesspoint_test);
    textView = (TextView) findViewById(R.id.textView);

    wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    wifiConfiguration = new WifiConfiguration();

    if(wifiManager.isWifiEnabled()) {
        createAccessPoint();
    } else {
        Log.d(TAG, "Set wifi Enable");
        wifiManager.setWifiEnabled(true);
        receiverWifiDisabled = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
                if ( wifiState == WifiManager.WIFI_STATE_ENABLED ) {
                    Log.d(TAG, "Wifi enable");
                    createAccessPoint();
                }
            }
        };
        registerReceiver(receiverWifiDisabled, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
    }

    final Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    textView.setText(
                        wifiApEnable + "\n" + 
                        wifiApState + "\n" +
                        "Nb of clients connected: " + numberOfClientsConnected + "\n" + 
                        "Wifi AP configuration: " + "\n" +
                        wifiApConfig.toString() + "\n" +
                        "WifiManager connection info: " +  "\n" + 
                        wifiManager.getConnectionInfo().toString() +
                        "DHCP state: " + wifiManager.getDhcpInfo().toString()
                    );
                break;
            }
        }
    };

    Thread thread = new Thread(new Runnable() {
        boolean alive = true;
        @Override
        public void run() {
            while(alive) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) { e.printStackTrace(); }

                numberOfClientsConnected = numberOfClientsConnected();
                wifiApEnable = isWifiApEnabled();
                wifiApState = getWifiApState();
                wifiApConfig = getWifiApConfiguration();

                mHandler.sendMessage(mHandler.obtainMessage(1));
            }
        }
    });
    thread.start();
}

@Override 
public void onDestroy() {
    super.onDestroy();
    if(receiver != null) {
        unregisterReceiver(receiver);
    }
    if(receiverWifiDisabled != null) {
        unregisterReceiver(receiverWifiDisabled);
    }
}

protected void createAccessPoint() {
    // Check if the Wifi configuration already exists
    List list = wifiManager.getConfiguredNetworks();
    int networkID = -1;
    if(list != null){
        for(WifiConfiguration conf : list) {
            Log.d(TAG, "Network ID: " + String.valueOf(conf.networkId) + " ; Network SSID: " + conf.SSID);
            if(conf.SSID.equals(SSID)) {
                Log.d(TAG, "SSID found");
                networkID = conf.networkId;
                wifiConfiguration = conf;
                break;
            }
        } 
    } else
        Log.d(TAG, "List of WifiConfiguration is null");

    // If the configuration exists, remove it to recreate it from scratch
    if(networkID != -1) {
        wifiManager.removeNetwork(networkID);
    }

    // Create a new WiFi configuration
    wifiConfiguration.SSID = SSID;
    wifiConfiguration.preSharedKey = PSK;
    wifiConfiguration.hiddenSSID = false;
    wifiConfiguration.status = WifiConfiguration.Status.ENABLED;

    wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
    wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

    wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
    wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

    wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
    wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

    wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

    // Catch Enumeration IpAssignment and ProxySettings from WifiConfiguration
    Enum ipAssignment = catchEnumIpAssignmentFromWifiConfiguration();
    Enum proxySettings = catchEnumProxySettingsFromWifiConfiguration();

    // Set IP address, gateway, DNS, etc
    try {
        Log.d(TAG, "Try to set IP, gateway and DNS");
        setIpAssignment(ipAssignment, wifiConfiguration);
        Log.d(TAG, "IpAssignment: Ok");
        setProxySettings(proxySettings, wifiConfiguration);
        Log.d(TAG, "ProxySettings: Ok");
        setIpAddress(InetAddress.getByName("192.168.2.100"), 24, wifiConfiguration);
        Log.d(TAG, "IpAddress: Ok");
        setGateway(InetAddress.getByName("192.168.2.1"), wifiConfiguration);
        Log.d(TAG, "Gateway: Ok");
        setDNS(InetAddress.getByName("192.168.2.1"), wifiConfiguration);
        Log.d(TAG, "DNS: Ok");
    } catch(Exception e) {
        e.printStackTrace();
    }

    // Add this new configuration to the wpa_supplicant file
    networkID = wifiManager.addNetwork(wifiConfiguration);
    if(networkID != -1)
        Log.d(TAG, "Succeed to update the WiFi configuration: " + networkID);
    else
        Log.d(TAG, "Failed to update the WiFi configuration");

    // Save the new configuration on the wpa_supplicant
    if(wifiManager.saveConfiguration())
        Log.d(TAG, "Succeed to save the wpa_supplicant");
    else
        Log.d(TAG, "Failed to save the wpa_supplicant");

    // Set the Wifi disable to be able to start the Access Point
    Log.d(TAG, "Set wifi disable");
    wifiManager.setWifiEnabled(false);

    receiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
            if ( wifiState == WifiManager.WIFI_STATE_DISABLED ) {
                Log.d(TAG, "Wifi disabled");
                // When the Wifi is disable
                // Create the Access Point with the WiFi configuration
                try {
                    Method m = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
                    boolean succeed = (Boolean) m.invoke(wifiManager, wifiConfiguration, true);
                    if(succeed)
                        Log.d(TAG, "Succeed to set wifi AP");
                    else
                        Log.d(TAG, "A problem occured while setting the wifi AP");
                } catch (Exception e) {
                    Log.e(TAG, "Failed to set wifi AP", e);
                }
            }
        }
    };
    registerReceiver(receiver, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
}

protected String getWifiApState() {
    try {
        Method m3 = wifiManager.getClass().getMethod("getWifiApState");
        return "WiFi Ap State: " + String.valueOf(m3.invoke(wifiManager));
    } catch (NoSuchMethodException e1) {    e1.printStackTrace();
    } catch (IllegalArgumentException e) {  e.printStackTrace();
    } catch (IllegalAccessException e) {    e.printStackTrace();
    } catch (InvocationTargetException e) { e.printStackTrace(); }
    return null;
}

protected WifiConfiguration getWifiApConfiguration() {
    WifiConfiguration wifiConfiguration = null;
    try {
        Method m4 = wifiManager.getClass().getMethod("getWifiApConfiguration");
        wifiConfiguration = (WifiConfiguration) m4.invoke(wifiManager);
    } catch (Exception e) { e.printStackTrace(); }
    return wifiConfiguration;
}

protected String isWifiApEnabled() {
    try {
        Method m = wifiManager.getClass().getMethod("isWifiApEnabled");
        if((Boolean) m.invoke(wifiManager))
            return "WiFiAP enabled";
        else
            return "WiFiAP not enabled";
    } catch (Exception e) { e.printStackTrace(); }
    return null;
}

protected String numberOfClientsConnected() {
    int macCount = 0;
    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader("/proc/net/arp"));
        String line;
        while ((line = br.readLine()) != null) {
            String[] splitted = line.split(" +");
            if (splitted != null && splitted.length >= 4) {
                String mac = splitted[3];
                if (mac.matches("..:..:..:..:..:..")) {
                    macCount++;
                } 
            }
        }
    } catch (Exception e) { e.printStackTrace();
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return String.valueOf(macCount);        
}

@SuppressWarnings({ "unchecked", "rawtypes" })
protected Enum catchEnumIpAssignmentFromWifiConfiguration() {
    Enum DHCP = null;
    try {
        Class enumIpAssignment = (Class) Class.forName("android.net.wifi.WifiConfiguration$IpAssignment");
        DHCP = Enum.valueOf(enumIpAssignment, "DHCP");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return DHCP;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
protected Enum catchEnumProxySettingsFromWifiConfiguration() {
    Enum ProxySet = null;
    try {
        Class enumProxySettings = (Class) Class.forName("android.net.wifi.WifiConfiguration$ProxySettings");
        ProxySet = Enum.valueOf(enumProxySettings, "NONE");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return ProxySet;
}

public static void setIpAssignment(Object assign , WifiConfiguration wifiConf)
        throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException {
    setEnumField(wifiConf, assign, "ipAssignment");     
}

public static void setProxySettings(Object assign , WifiConfiguration wifiConf)
        throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException {
    setEnumField(wifiConf, assign, "proxySettings");     
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public static void setIpAddress(InetAddress addr, int prefixLength, WifiConfiguration wifiConf)
        throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException,
        NoSuchMethodException, ClassNotFoundException, InstantiationException, InvocationTargetException {
    Object linkProperties = getField(wifiConf, "linkProperties");
    if(linkProperties == null) return;
    Class laClass = Class.forName("android.net.LinkAddress");
    Constructor laConstructor = laClass.getConstructor(new Class[]{InetAddress.class, int.class});
    Object linkAddress = laConstructor.newInstance(addr, prefixLength);

    ArrayList mLinkAddresses = (ArrayList)getDeclaredField(linkProperties, "mLinkAddresses");
    mLinkAddresses.clear();
    mLinkAddresses.add(linkAddress);     
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public static void setGateway(InetAddress gateway, WifiConfiguration wifiConf)
        throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException, 
        ClassNotFoundException, NoSuchMethodException, InstantiationException, InvocationTargetException {
    Object linkProperties = getField(wifiConf, "linkProperties");
    if(linkProperties == null)return;
    Class routeInfoClass = Class.forName("android.net.RouteInfo");
    Constructor routeInfoConstructor = routeInfoClass.getConstructor(new Class[]{InetAddress.class});
    Object routeInfo = routeInfoConstructor.newInstance(gateway);

    ArrayList mRoutes = (ArrayList)getDeclaredField(linkProperties, "mRoutes");
    mRoutes.clear();
    mRoutes.add(routeInfo);
}

@SuppressWarnings("unchecked")
public static void setDNS(InetAddress dns, WifiConfiguration wifiConf)
        throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException {
    Object linkProperties = getField(wifiConf, "linkProperties");
    if(linkProperties == null)return;

    ArrayList mDnses = (ArrayList)getDeclaredField(linkProperties, "mDnses");
    mDnses.clear();
    mDnses.add(dns); 
}

public static Object getField(Object obj, String name)
        throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    Field f = obj.getClass().getField(name);
    Object out = f.get(obj);
    return out;
}

public static Object getDeclaredField(Object obj, String name)
        throws SecurityException, NoSuchFieldException,
        IllegalArgumentException, IllegalAccessException {
    Field f = obj.getClass().getDeclaredField(name);
    f.setAccessible(true);
    Object out = f.get(obj);
    return out;
}  

public static void setEnumField(Object obj, Object value, String name)
        throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    Field f = obj.getClass().getField(name);
    f.set(obj, value);
}
}

Этот код отлично работает на моем Nexus 7. Он создает точку доступа. Мой ноутбук видит сетевую ссылку: Изображение 72310

Он просит меня ввести ключ WPA. Мне нужно записать его в кавычки, если он не работает ("helloworld").

После этого мой ноутбук подключен к сети, но с программным обеспечением Xirrus Я понял, что модуль DHCP не дает любой IP-адрес.

Logs:

Я получаю два интересных журнала. Это когда я запускаю приложение:

E/hostapd(): Configuration file: /data/misc/wifi/hostapd.conf
E/hostapd(): HT (IEEE 802.11n) in 11b mode is not allowed, disabling HT capabilites
I/hostapd(): rfkill: Cannot open RFKILL control device
W/hostapd(): wlan0: Could not connect to kernel driver
E/hostapd(): Using interface wlan0 with hwaddr 02:1a:11:fd:32:58 and ssid "\"Awesome Access Point\""
E/hostapd(): random: Cannot read from /dev/random: Try again
I/hostapd(): random: Only 0/20 bytes of strong random data available from /dev/random
I/hostapd(): random: Allow operation to proceed based on internal entropy

И это когда я подключаю и отсоединяю свой ноутбук от/до точки доступа:

I/hostapd(): wlan0: AP-STA-DISCONNECTED 00:27:10:ca:f0:80
I/hostapd(): wlan0: AP-STA-CONNECTED 00:27:10:ca:f0:80

Содержание

    Один из лидеров среди производителей смартфонов, прочно занимающий 4 строчку мирового рейтинга — китайская компания Xiaomi Corporation. Среди российских пользователей  продукция этого бренда нарасхват. Модели отличаются отличной производительностью, быстрым доступом к глобальной сети, а также могут раздавать Wi-Fi. То, как раздать интернет на Ксиоми, часто интересует счастливых обладателей китайского чуда техники.

    Продукты Xiaomi

    Продукция бренда Ксиоми или Сяоми, как его еще называют в России, отличается надежностью, практичностью, привлекательным дизайном. Это давно уже не те китайские подделки, которые переставали включаться через пару месяцев после покупки. Теперь заводской продукт из Поднебесной — это качество и добротность.

    Неудивительно, что многие россияне предпочитают Xiaomi более дорогому Самсунгу и даже Айфону. Из последних новинок бренда — смартфон Mi Note 10 Lite с мощным процессором, впечатляющей камерой и отличной батареей. Существенный плюс Ми Ноут 10 Лайт — быстрая зарядка. Еще один яркий «выпускник» Ксиоми 2020 года —  Xiaomi Mi Note 10. Новая модель — мечта всех любителей фото, ведь количество мегапикселей в камере рекордное — 108, плюс масса дополнительных возможностей.

    Как раздавать интернет с телефона Xiaomi

    Впервые столкнувшись с вопросом, как раздать интернет на Сяоми, некоторые владельцы смартфонов не могут справиться своими силами и начинают клеймить производителя. А зря  — если четко следовать алгоритму, устройство начинает раздавать беспроводной сигнал без сбоев.

    Путей включения раздачи Wi-Fi на Ксиоми несколько:

    • через USB, используя режим модема;
    • посредством Bluetooth;
    • с помощью Wi-Fi.

    Включение режима модема на устройстве и раздача интернета через USB

    Как и большинство флагманских смартфонов, практически все телефоны модельной линейки компании Xiaomi способны работать в режиме портативного модулятора и раздавать интернет в деревне окружающим. Для этого нужно знать, как включить режим модема на Xiaomi.

    Схема следующая:

    1. Перед тем как включить USB модем на Xiaomi, нужно подключить телефон к ПК или ноутбуку и установить режим зарядки.
    2. Перейти в верхнее меню, потянув «шторку» вниз и нажать на значок шестеренки, расположенный в верхнем углу справа.
    3. Выбрать «Дополнительные функции».
    4. Кликнуть «USB модем».

    Готово — компьютер получает трафик со смартфона. Эта функция незаменима в поездках или на даче, где нет возможности подключиться к проводному интернету, но есть отличный сигнал от вышки мобильного оператора. Главное запомнить, как на Сяоми включить режим модема.

    Раздача интернета через Wi-Fi

    Ксиоми умеет работать и как роутер, предоставляя беспроводным устройствам доступ к глобальной сети. Для этого нужно:

    1. Перейти в «Настройки».
    2. Выбрать «Точка доступа Wi-Fi».
    3. Кликнуть на раздел «Точка доступа…(здесь будет указана модель устройства)».

    Чтобы защитить сеть от сторонних подключений, необходимо вручную выставить параметры, доступные во вкладке «Настройка точки доступа Wi-Fi.

    Алгоритм следующий:

    1. Во вкладке SSID ввести название сети. Устройство по умолчанию предложит название модели.
    2. Перейти в раздел «Защита».
    3. Выбрать режим WPA2 PSK.
    4. Задать пароль.
    5. Перейти в поле «Идентификация устройства».
    6. Выбрать диапазон частот — 2,4 ГГц либо 5 ГГц. По умолчанию смартфон выберет первую.
    7. Нажать на галочку в правом верхнем углу экрана.

    Затем необходимо установить лимит трафика. Инструкция такова:

    1. Раздел «Точка доступа Wi-Fi».
    2. Активировать «Однократный лимит трафика».
    3. Перейти в «Лимит трафика».
    4. Кликнуть на «Особый».
    5. Выставить количество.
    6. Клацнуть «При превышении».
    7. Выбрать действие. Доступные — отключение или уведомление об израсходованном трафике.

    Теперь для того чтобы получить активную точку доступа, эту функцию достаточно включить простым нажатием на кнопку. Также можно установить режим автоотключения. Он сработает, когда гаджеты, использующие вай-фай, отключатся.

    Раздача интернета через Bluetooth

    Также Xiaomi можно использовать как Bluetooth-модем. Для этого нужно:

    1. В папке «Настройки» выбрать «Дополнительные функции».
    2. Кликнуть на раздел «Bluetooth модем».
    3. Затем на компьютере или ноутбуке нужно активировать Bluetooth и кликнуть «Добавление устройства».
    4. После того как оборудование найдет смартфон, нажать кнопку «Связать» и подтвердить действие на обоих устройствах путем введения пин-кода.

    При таком способе связи интернетом можно будет пользоваться только с подключенного устройства.