Невозможно использовать «libnl» изначально на Android. Не удалось получить драйвер nl80211 с помощью `genl_ctrl_resolve()`

Моя цель — использовать libnl. в приложении Android, чтобы получить список кадров маяков, полученных при последнем сканировании сети, и распечатать (отобразить) связанные метаданные, такие как AP SSID, AP BSSID и т. д.

Следуя основным учебным пособиям и рекомендациям, подход выглядит следующим образом:

  1. Кросс-компиляция libnl для всех поддерживаемых Android ABI, поскольку libnl поставляется со своими собственными ./configure и Makefile
  2. Импортируйте скомпилированные архивы в мой собственный код C/C++ как PREBUILT_STATIC_LIBRARY или PREBUILT_SHARED_LIBRARY
  3. Используйте методы libnl в нативном коде

Среда разработки и конфигурация:

  • IDE: Android Studio 3.1.2
  • Версия NDK: Android NDK версии 17b.
  • Внешние инструменты: Gradle, CMake.
  • Версия MinSDK: API 14
  • Целевая версия SDK: API 21
  • Источник библиотеки: Libnl 3.2.25 — ссылка
  • ОС: Ubuntu 18.04 LTS

  1. Кросс-компиляция:
    мне удалось успешно выполнить кросс-компиляцию libnl для всех ABI (armeabi-v7a, arm64-v8a, x86, x86_64) с помощью задокументированного метода NDK Standalone Toolchains здесь. Это дает мне .a скомпилированных файлов для библиотеки.

  2. Импорт библиотек и компиляция.
    Это было сделано в соответствии с примерами кода из Google (github) - в частности, пример "hello-libs".

ПРИМЕЧАНИЕ. Я считаю, что шаги 1 и 2 выполнены правильно, потому что библиотека успешно компонуется с моим исходным кодом C/C++ при компиляции и запуске приложения. Кроме того, я могу вызывать методы libnl из исходного кода C/C++. Я не получаю UnsatisfiedLinkError или Undefined Reference to ....

  1. Используя методы libnl, как и в Linux
    , я отладил проблему с оператором, используя метод libnl genl_ctrl_resolve для получения идентификатора драйвера для драйвера nl80211. Это возвращает код ошибки -12, означающий «Объект не найден».

    ...
    struct nl_sock *socket = init_socket();
    driver_id = genl_ctrl_resolve(socket, "nl80211");
    ...
    

Мои конкретные сомнения:

  1. Верен ли мой подход? Если нет, любая помощь или понимание приветствуется.
  2. Есть ли альтернативный подход?
  3. Требуется ли моему приложению доступ root для получения идентификатора водителя?
  4. Любые хорошие ресурсы для получения дополнительной информации о Native Android Development.

Любая помощь приветствуется. Спасибо в ожидании.


PS..

  • Я просмотрел веб-сайт разработчика Android
  • Я имел в виду Android NDK Beginner's Guide by Sylvain Ratabouil и Pro Android Apps Performance Optimization by Herve´ Guihot
  • Также пытался создать проект с нуля, используя Eclipse (ADT) и более старый SDK (r24.4.1), NDK (r10e).

person Gursimran Singh    schedule 24.07.2018    source источник


Ответы (2)


Если для libnl требуется доступ для чтения к /dev или /proc, вы можете забыть о доступе к нему из NDK на нерутированных устройствах.

Google блокирует Android с нескольких выпусков, а начиная с Android 7, любой доступ для чтения за пределами каталога установки APK строго запрещен, так как приложения должны читать файлы косвенно через SAF.

https://developer.android.com/about/versions/nougat/android-7.0-changes#permfilesys

https://developer.android.com/guide/topics/providers/document-provider

Лучше использовать сетевые интерфейсы Framework через JNI.

person Paulo Pinto    schedule 25.07.2018
comment
Спасибо за ваш ответ. Краткое исследование показывает, что структура сетевых интерфейсов не может получить доступ к информации уровня кадра (где существуют кадры-маяки), но больше связана с сетевым уровнем. Я обновлю больше после того, как углублюсь в это. - person Gursimran Singh; 25.07.2018

libnl общается с ядром через сокет. Вы просите ядро ​​предоставить вам доступ к интерфейсу драйвера для вашего Wi-Fi. На этом этапе было бы уместно узнать, какое ядро ​​​​использует ваше устройство и какой конкретный драйвер он использует для Wi-Fi. В Android они зависят от производителя, поэтому вы не можете полагаться на конкретные детали, основанные на уровне API.

Основываясь на подробностях, которые вы предоставили, я могу предположить, что: 1. Ядро понимает ваш запрос 2. Драйвер не имеет интерфейса nl80211. Вы могли бы попытаться прослушать сообщения расширения беспроводной сети?

В общем, это может работать на некоторых устройствах, а не на других, независимо от уровня API.

person Mihai Timar    schedule 17.06.2020