BluetoothGattServer всегда отключается через 30 секунд
Я пытался выяснить, как заставить эти телефоны общаться друг с другом через Bluetooth. У меня телефон Android настроен как периферийное устройство, и на моем iPhone запущено приложение nrf connect. Я могу рекламировать и подключаться к телефону Android с iPhone, и я могу подписаться на уведомления и видеть обновленную характеристику. Проблема в том, что если я не отправляю характерное уведомление, примерно через 7-10 секунд соединение теряется. Я получаю ответный звонок на connectionStateChanged
обработчик обратного вызова, и я не могу понять, что является причиной этого. Я не думаю, что это приложение NRF, потому что я связан с другими вещами, и он просто остается на связи всегда. Я что-то упускаю?
Вот некоторый код:
private BluetoothManager bluetoothManager;
private BluetoothGattServer gattServer;
private BluetoothGattCharacteristic test_characteristic;
private BluetoothDevice connected_device;
private BluetoothGattServerCallback gattServerCallback = new BluetoothGattServerCallback() {
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
super.onConnectionStateChange(device, status, newState);
if (newState == 2){ //CONNECTED
connected_device = device;
}
Log.i("chase", "Connection state changed: "+newState);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BluetoothRegulator.sharedInstance().appContext = getApplicationContext();
bluetoothManager = (android.bluetooth.BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothRegulator.sharedInstance().initialize(bluetoothManager);
if( ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
}
gattServer = bluetoothManager.openGattServer(this, gattServerCallback);
String uuid_string = "92D9D153-9BE6-43FF-9672-3E2904628B9D";
BluetoothGattService service = new BluetoothGattService(UUID.fromString(uuid_string), BluetoothGattService.SERVICE_TYPE_PRIMARY);
uuid_string = "43FF0001-9BE6-43FF-9672-3E2904628B9D";
test_characteristic = new BluetoothGattCharacteristic(
UUID.fromString(uuid_string),
BluetoothGattCharacteristic.PROPERTY_BROADCAST | BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_WRITE,
BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
test_characteristic.setValue( ""+System.currentTimeMillis() );
service.addCharacteristic(test_characteristic);
gattServer.addService(service);
findViewById(R.id.send_data_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
shot_detected_characteristic.setValue( ""+System.currentTimeMillis() );
gattServer.notifyCharacteristicChanged(connected_device, shot_detected_characteristic, false);
}
});
findViewById(R.id.advertise).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
advertise();
}
});
}
private void advertise() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
BluetoothLeAdvertiser advertiser = adapter.getBluetoothLeAdvertiser();
AdvertiseSettings settings = new AdvertiseSettings.Builder()
.setAdvertiseMode( AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY )
.setTxPowerLevel( AdvertiseSettings.ADVERTISE_TX_POWER_HIGH )
.setConnectable( true )
.build();
String uuid_string = "92C9D164-9BE6-43FF-9672-3E2804618B9C";
ParcelUuid pUuid = new ParcelUuid( UUID.fromString( uuid_string ) );
AdvertiseData data = new AdvertiseData.Builder()
.setIncludeDeviceName( true )
.addServiceData( pUuid, "TEST".getBytes( Charset.forName( "UTF-8" ) ) )
.build();
AdvertiseCallback advertisingCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
Log.e( "BLE", "Advertising Started");
super.onStartSuccess(settingsInEffect);
}
@Override
public void onStartFailure(int errorCode) {
Log.e( "BLE", "Advertising onStartFailure: " + errorCode );
super.onStartFailure(errorCode);
}
};
advertiser.startAdvertising( settings, data, advertisingCallback );
}
Редактировать: На самом деле, я заметил, что это не имеет никакого отношения к бездействию. Это на самом деле отключение почти на 30 секунд каждый раз.
1 ответ
Согласно спецификации ядра, для ATT
Срок действия транзакции, не завершенной в течение 30 секунд, истекает.
На практике это обычно проявляется как разъединение одной стороной соединения.
Для некоторых типов запросов GATT требуются ответы (например, индикация, запросы на чтение, запросы на запись). Не похоже, что вы реализуете обратные вызовы, такие как onCharacteristicReadRequest
& onCharacteristicWriteRequest
в вашей реализации сервера Gatt, которая может привести к этой проблеме.