Только с одним конкретным модулем Bluetooth SPP .createRfcommSocketToServiceRecord () внезапно больше не работает, но метод отражения работает - PullRequest
4 голосов
/ 29 января 2012

Мое приложение подключается к модулям Bluetooth SPP, выполняя и обрабатывая подключения в значительной степени, как описано в документации Android Bluetooth .То есть в моем потоке соединения я использовал для создания соединения просто:

socket = device.createRfcommSocketToServiceRecord(MY_UUID)

, где UUID - это «хорошо известный» UPID SPP, 00001101-0000-1000-8000-00805F9B34FB.

Устройства Bluetooth, к которым я подключаюсь, - это маленькие адаптеры Bluetooth / последовательный порт.У меня есть три, которые я использовал для теста.Два из них - это последовательные печатные платы от Bluetooth до TTL уровня Linvor, которые на данный момент находятся на всех eBay и являются идентичными;и третий - полностью закрытый адаптер неизвестного производителя.

За время разработки этого приложения я регулярно тестировал на различных устройствах от Android версии 2.2.1 (мой старый Archos 101) до устройства Archos Honeycomb.Устройство, которое я тестировал в основном, это мой Desire HD, который в настоящее время имеет версию Android 2.3.5.В течение года или около того я работал над этим, я могу с уверенностью сказать, что у меня никогда не было проблем со связью.

Вчера во время тестирования моего Desire HD (2.3.5) я обнаружил, что приложение больше не будет подключаться к моей печатной плате Linvor Bluetooth, с которой я работал в основном в последнее время.После получения сокета, используя приведенную выше строку кода, при попытке socket.connect() я бы немедленно получил IOException из Unable to start discovery.

Следующее, что я сделал, это переключился на другой запасной модуль Linvor и попытался выполнить сопряжение и подключение.Приложение подключено просто отлично.Затем я также поменял свой третий упакованный адаптер Bluetooth, и приложение, подключенное к нему, тоже прекрасно.Возвращаясь к моему первому модулю Linvor, приложение по-прежнему отказывается подключаться.Я гарантирую, что отсоединяю «неисправное» устройство Linvor на своем Desire HD, выключаю Bluetooth, выключаю телефон, вынимаю и снова вставляю аккумулятор, включаю, повторно подключаю и т. Д., А затем повторяю попытку.Приложение по-прежнему отказывается подключаться к этому первому модулю Linvor, но нормально подключается ко второму модулю Linvor и другому адаптеру.

Затем я беру свой Archos 101 (2.2.1) и запускаю несколько более старую сборку моего приложения, которая все еще установлена ​​на нем.Archos 101 немедленно подключается к «неисправному» модулю Linvor.

В этот момент я начинаю задаваться вопросом, может ли какое-либо устройство - т.е. мой Desire HD или, возможно, более вероятно, модуль Linvor - иметь какую-либо поврежденную запись в своей таблице флэш-памяти для сопряженных устройств.Другими словами, что-то в этом первом модуле Linvor, что означает, что он больше не принимает соединение (хотя и принимает сопряжение) с моего Desire HD, и все же он все равно будет принимать соединения от других устройств;и в то же время мой Desire HD может с радостью подключаться к другим устройствам, как это всегда делалось, включая другой запасной модуль Linvor.

После нескольких часов царапин и отчаяния я решил попробовать метод отражения , как описано в ответе Майкла .Об этом я много слышал, и у меня сложилось впечатление, что это применимо к Android 2.2 и ниже.Тем не менее, в течение всего года, когда я работал с Bluetooth SPP с моих различных устройств Android, у меня никогда не было необходимости использовать его, так как .createRfcommSocketToServiceRecord() всегда работал для меня.Поэтому я использую код, приведенный в ответе Майкла на этот вопрос, для создания моего socket, и, к моему изумлению, мой Desire HD подключается к «неисправному» модулю Linvor.

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

В течение прошлого года я смог регулярно использовать .createRfcommSocketToServiceRecord() на своих устройствах 2.2.1 и 2.3.5 дляподключите к моим трем адаптерам Bluetooth SPP.

Затем, в один конкретный день, без каких-либо изменений в программном обеспечении на телефонах или моих адаптерах Bluetooth, первый из адаптеров внезапно требует метода отражения для работы соединения; два других адаптера (один из них того же типа, что и первый) продолжают нормально подключаться к моему приложению, используя .createRfcommSocketToServiceRecord(). Обратите внимание, что в мой код Bluetooth не было внесено абсолютно никаких изменений непосредственно перед этим внезапным изменением поведения.

Что на земле здесь происходит?

Может кто-нибудь посоветовать мне, на каком уровне версии Android требуется «взлом» отражения , а не ? У меня сложилось впечатление, что это больше не нужно, скажем, на 2.3.5 (мой Desire HD). Это правильно?

Является ли / была природа ошибки с .createRfcommSocketToServiceRecord() такой, что соединения обычно работают, но иногда не работают в зависимости от фазы луны?

Вот вывод Logcat, когда происходит сбой соединения с этим конкретным модулем Linvor при использовании .createRfcommSocketToServiceRecord():

<code>
01-29 10:22:00.004: D/View(8165): onTouchEvent: viewFlags: 0x18005001
01-29 10:22:00.014: D/View(8165): onTouchEvent: isFocusable: true, isFocusableInTouchMode: false, isFocused: false; focusTaken: false
01-29 10:22:00.034: D/WindowManagerImpl(8165): finishRemoveViewLocked, mViews<a href="/3079722/problemy-s-podklycheniem-po-bluetooth-android">2</a>: com.android.internal.policy.impl.PhoneWindow$DecorView@406215d8
01-29 10:22:00.074: I/BLZ20_WRAPPER(8165): blz20_wrp_socket: fam 31, type 1, prot BTPROTO_RFCOMM
01-29 10:22:00.084: D/BLZ20_WRAPPER(8165): blz20_init: initializing...
01-29 10:22:00.084: D/BTL_IFC_WRP(8165): wsactive_init: init active list
01-29 10:22:00.084: I/BTL_IFC(8165): main_client_thread: Client main thread starting
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_init: success
01-29 10:22:00.194: I/BTL_IFC(8165): BTL_IFC_RegisterSubSystem: Register subsystem [BTS]
01-29 10:22:00.194: I/BTL_IFC(8165): btl_ifc_ctrl_connect: Connect control channel for subsystem [BTS]
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_create: CTRL
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_alloc_new_sock: wrp_alloc_new_sock sub 1
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_create: 66
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_connect: wrp_sock_connect brcm.bt.btlif:9000 (66)
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_connect: BTLIF_MAKE_LOCAL_SERVER_NAME return name: brcm.bt.btlif.9000
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_sock_connect: wrp_sock_connect ret:0 server name:brcm.bt.btlif.9000
01-29 10:22:00.194: I/BTL_IFC_WRP(8165): wrp_sock_connect: Connected. (66)
01-29 10:22:00.194: I/BTL_IFC(8165): send_ctrl_msg: [BTL_IFC CTRL] send BTLIF_REGISTER_SUBSYS_REQ (BTS) 0 pbytes (hdl 66)
01-29 10:22:00.194: D/BTL_IFC(8165): BTL_IFC_RegisterSubSystem: add new ctrl fd to active set
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_wsock_create: BTS
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_alloc_new_sock: wrp_alloc_new_sock sub 16
01-29 10:22:00.194: D/BTL_IFC_WRP(8165): wrp_wsock_create: 67
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): btsk_alloc_add: success
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): btsk_dump_list:  fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_socket: return 67
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt:  fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: configure rfcomm lm mode 0x26, (master:0, auth 1, enc 1)
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: success
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt:  fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: configure rfcomm sndbuf len 71680 bytes
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_setsockopt: success
01-29 10:22:00.194: D/BLZ20_ASOCKWRP(8165): asocket_init
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: s 67, cmd 3
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_fcntl:  fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: s 67, cmd 4
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_fcntl:  fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.194: D/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: transparant fcntl
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: s 69, cmd 3
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: wsock not found, pass through transparantly
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: s 69, cmd 4
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_wrp_fcntl: wsock not found, pass through transparantly
01-29 10:22:00.194: I/BLZ20_WRAPPER(8165): blz20_set_asocket: success (67,68,69)
01-29 10:22:00.214: I/BluetoothIF(8165): BEGIN mConnectThread
01-29 10:22:00.234: E/BluetoothIF(8165): TP: IOException error: java.io.IOException: Unable to start Service Discovery
01-29 10:22:00.234: E/BluetoothIF(8165): Unable to start Service Discovery
01-29 10:22:00.234: E/BluetoothIF(8165): Unable to start Service Discovery
01-29 10:22:00.234: D/BluetoothSocket(8165): close(): android.bluetooth.BluetoothSocket@405c8f78
01-29 10:22:00.234: D/BLZ20_ASOCKWRP(8165): asocket_abort [67,68,69]
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: s 67, how 2
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_shutdown:  fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: shutdown socket
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_write: wrote 1 bytes out of 1 on fd 69
01-29 10:22:00.234: D/BLZ20_ASOCKWRP(8165): asocket_destroy
01-29 10:22:00.234: D/BLZ20_ASOCKWRP(8165): asocket_abort [67,68,69]
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: s 67, how 2
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_shutdown:  fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_shutdown: shutdown socket
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_write: wrote 1 bytes out of 1 on fd 69
01-29 10:22:00.234: I/BLZ20_WRAPPER(8165): blz20_wrp_close: s 69
01-29 10:22:00.234: D/BLZ20_WRAPPER(8165): blz20_wrp_close: std close (69)
01-29 10:22:00.244: I/BLZ20_WRAPPER(8165): blz20_wrp_close: s 68
01-29 10:22:00.244: D/BLZ20_WRAPPER(8165): blz20_wrp_close: std close (68)
01-29 10:22:00.244: I/BLZ20_WRAPPER(8165): blz20_wrp_close: s 67
01-29 10:22:00.244: D/BLZ20_WRAPPER(8165): blz20_wrp_close:  fd (-1:67), bta -1, rc 0, wflags 0x0, cflags 0x0, port 0
01-29 10:22:00.244: I/BLZ20_WRAPPER(8165): __close_prot_rfcomm: fd 67
01-29 10:22:00.244: I/BTL_IFC(8165): send_ctrl_msg: [BTL_IFC CTRL] send BTLIF_BTS_RFC_CLOSE (BTS) 8 pbytes (hdl 66)
01-29 10:22:00.244: D/BTL_IFC_WRP(8165): wrp_close_s_only: wrp_close_s_only [67] (67:-1) []
01-29 10:22:00.244: D/BTL_IFC_WRP(8165): wrp_close_s_only: data socket closed
01-29 10:22:00.244: D/BTL_IFC_WRP(8165): wsactive_del: delete wsock 67 from active list [ad40f904]
01-29 10:22:00.244: D/BTL_IFC_WRP(8165): wrp_close_s_only: wsock fully closed, return to pool
01-29 10:22:00.244: D/BLZ20_WRAPPER(8165): btsk_free: success

В настоящее время лучший способ действий, который я вижу, состоит в том, чтобы спроектировать мой код так, чтобы в случае немедленного сбоя метода .createRfcommSocketToServiceRecord() с исключением «неспособно начать обнаружение» затем использовался метод выбора, который до сегодняшнего дня Я никогда не нуждался в использовании.

Дополнительная информация: Мое приложение предназначено для уровня API 8. Подозревая, что ошибка подключения RFCOMM влияет на Android 2.2 и ниже, я попытался перейти на уровень API 10, просто чтобы посмотреть, повлияет ли это на поведение .createRfcommSocketToServiceRecord(), но проблема сохранялась: попытки подключиться к одному модулю Linvor привели к немедленному исключению IOException, как описано выше.

Спасибо - Трев

Ответы [ 2 ]

1 голос
/ 07 августа 2015

Линвор 1.8 здесь.
Я много борюсь с этим устройством. Ваша конкретная проблема - одна из проблем, с которыми я столкнулся.
Это можно решить, потянув булавку сброса вниз (переместите штырек к GND с помощью перемычки), когда устройство полностью запитано.
Контакт сброса - это третий контакт слева внизу от устройства.
Для меня это позволит мне подключиться к устройству один раз без раздумий, но это может снова вернуться к плохому поведению.
Мое предложение состоит в том, чтобы вы реализовали сторожевой пинг с android на устройство и запускаете команду сброса с оставшимся выводом GPIO, когда таймер достиг.
Что касается того, почему и что вызвало поведение. Я все еще не знаю, но, надеюсь, кто-нибудь это поймет.

Я подозреваю, что устройство застряло в неизвестном состоянии.
reset pin

1 голос
/ 14 января 2013

Борется с той же проблемой.Использование API 10 на 2 телефона.Оба с Android 4.0.4.Один телефон постоянно выходит из строя с «Невозможно начать обнаружение», но работает с отражением.Второй телефон с разрешением «Отказано в разрешении», но работает с createRfcommSocketToServiceRecord ().

И для исследования я проверил источники Android.Таким образом, здесь происходит сбой в BluetoothSocket.java:

    boolean inProgress = false;
    try {
        inProgress = service.fetchRemoteUuids(device.getAddress(), uuid, this);
    } catch (RemoteException e) {Log.e(TAG, "", e);}

    if (!inProgress) throw new IOException("Unable to start Service Discovery");

Но fetchRemoteUuids () имеет много точек сбоя, и нет, они не выдают исключения, просто возвращают false.BluetoothService.java:

public synchronized boolean fetchRemoteUuids(String address, ParcelUuid uuid,
        IBluetoothCallback callback) {
    mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
    if (!BluetoothAdapter.checkBluetoothAddress(address)) {
        return false;
    }

    RemoteService service = new RemoteService(address, uuid);
    if (uuid != null && mUuidCallbackTracker.get(service) != null) {
        // An SDP query for this address & uuid is already in progress
        // Do not add this callback for the uuid
        return false;
    }

    if (mUuidIntentTracker.contains(address)) {
        // An SDP query for this address is already in progress
        // Add this uuid onto the in-progress SDP query
        if (uuid != null) {
            mUuidCallbackTracker.put(new RemoteService(address, uuid), callback);
        }
        return true;
    }

    boolean ret;
    if (getBondState(address) == BluetoothDevice.BOND_BONDED) {
        String path = getObjectPathFromAddress(address);
        if (path == null) return false;

        // Use an empty string for the UUID pattern
        ret = discoverServicesNative(path, "");
    } else {
        ret = createDeviceNative(address);
    }

    mUuidIntentTracker.add(address);
    if (uuid != null) {
        mUuidCallbackTracker.put(new RemoteService(address, uuid), callback);
    }

    Message message = mHandler.obtainMessage(MESSAGE_UUID_INTENT);
    message.obj = address;
    mHandler.sendMessageDelayed(message, UUID_INTENT_DELAY);
    return ret;
}

Любой родной метод не помогает, что приводит нас к драйверам?Или часть «uuid уже выполняется» завершается ошибкой, потому что я не вижу даже попытки подключить / отсканировать uuid, просто мгновенно получаю исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...