Commit c8aad835 authored by Ovidio Henriquez's avatar Ovidio Henriquez Committed by Commit Bot

bluetooth: SetNextUnsubscribeFromNotifications

This change implements the SetNextUnsubscribeFromNotifications function
for fake characteristics.

BUG=569709

Change-Id: I99c59a4caffd524e727921fcb54f48cc868d545f
Reviewed-on: https://chromium-review.googlesource.com/988223
Commit-Queue: Ovidio Henriquez <odejesush@chromium.org>
Reviewed-by: default avatarOliver Chang <ochang@chromium.org>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548544}
parent 5f83d227
......@@ -288,6 +288,28 @@ interface FakeCentral {
string service_id,
string peripheral_address) => (bool success);
// Sets the next unsubscribe from notifications response for characteristic
// with |characteristic_id| in |service_id| and in |peripheral_address| to
// |code|. |code| could be a GATT Error Response from BT 4.2 Vol 3
// Part F 3.4.1.1 Error Response or a number outside that range returned by
// specific platforms e.g. Android returns 0x101 to signal a GATT failure.
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE
// Calls callback with false if there was any error when simulating the next
// response.
SetNextUnsubscribeFromNotificationsResponse(
uint16 gatt_code,
string characteristic_id,
string service_id,
string peripheral_address) => (bool success);
// Returns whether or not a client has subscribed to notifications for a
// characteristic with |characteristic_id| in |service_id| in
// |peripheral_address|. If the value can't be retrieved, calls its callback
// with false.
IsNotifying(string characteristic_id,
string service_id,
string peripheral_address) => (bool success, bool is_notifying);
// Gets the last successfully written value to the characteristic with
// |characteristics_id| in |service_id| and in |peripheral_address|.
// If the value can't be retrieved calls its callback with false. Calls its
......
......@@ -317,6 +317,38 @@ void FakeCentral::SetNextSubscribeToNotificationsResponse(
std::move(callback).Run(true);
}
void FakeCentral::SetNextUnsubscribeFromNotificationsResponse(
uint16_t gatt_code,
const std::string& characteristic_id,
const std::string& service_id,
const std::string& peripheral_address,
SetNextUnsubscribeFromNotificationsResponseCallback callback) {
FakeRemoteGattCharacteristic* fake_remote_gatt_characteristic =
GetFakeRemoteGattCharacteristic(peripheral_address, service_id,
characteristic_id);
if (fake_remote_gatt_characteristic == nullptr) {
std::move(callback).Run(false);
}
fake_remote_gatt_characteristic->SetNextUnsubscribeFromNotificationsResponse(
gatt_code);
std::move(callback).Run(true);
}
void FakeCentral::IsNotifying(const std::string& characteristic_id,
const std::string& service_id,
const std::string& peripheral_address,
IsNotifyingCallback callback) {
FakeRemoteGattCharacteristic* fake_remote_gatt_characteristic =
GetFakeRemoteGattCharacteristic(peripheral_address, service_id,
characteristic_id);
if (!fake_remote_gatt_characteristic) {
std::move(callback).Run(false, false);
}
std::move(callback).Run(true, fake_remote_gatt_characteristic->IsNotifying());
}
void FakeCentral::GetLastWrittenCharacteristicValue(
const std::string& characteristic_id,
const std::string& service_id,
......
......@@ -98,7 +98,17 @@ class FakeCentral : public mojom::FakeCentral, public device::BluetoothAdapter {
const std::string& characteristic_id,
const std::string& service_id,
const std::string& peripheral_address,
SetNextWriteCharacteristicResponseCallback callback) override;
SetNextSubscribeToNotificationsResponseCallback callback) override;
void SetNextUnsubscribeFromNotificationsResponse(
uint16_t gatt_code,
const std::string& characteristic_id,
const std::string& service_id,
const std::string& peripheral_address,
SetNextUnsubscribeFromNotificationsResponseCallback callback) override;
void IsNotifying(const std::string& characteristic_id,
const std::string& service_id,
const std::string& peripheral_address,
IsNotifyingCallback callback) override;
void GetLastWrittenCharacteristicValue(
const std::string& characteristic_id,
const std::string& service_id,
......
......@@ -91,6 +91,12 @@ void FakeRemoteGattCharacteristic::SetNextSubscribeToNotificationsResponse(
next_subscribe_to_notifications_response_.emplace(gatt_code);
}
void FakeRemoteGattCharacteristic::SetNextUnsubscribeFromNotificationsResponse(
uint16_t gatt_code) {
DCHECK(!next_unsubscribe_from_notifications_response_);
next_unsubscribe_from_notifications_response_.emplace(gatt_code);
}
bool FakeRemoteGattCharacteristic::AllResponsesConsumed() {
// TODO(crbug.com/569709): Update this when
// SetNextUnsubscribeFromNotificationsResponse is implemented.
......@@ -192,7 +198,11 @@ void FakeRemoteGattCharacteristic::UnsubscribeFromNotifications(
device::BluetoothRemoteGattDescriptor* ccc_descriptor,
const base::Closure& callback,
const ErrorCallback& error_callback) {
NOTREACHED();
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FakeRemoteGattCharacteristic::
DispatchUnsubscribeFromNotificationsResponse,
weak_ptr_factory_.GetWeakPtr(), callback, error_callback));
}
void FakeRemoteGattCharacteristic::DispatchReadResponse(
......@@ -258,4 +268,23 @@ void FakeRemoteGattCharacteristic::DispatchSubscribeToNotificationsResponse(
}
}
void FakeRemoteGattCharacteristic::DispatchUnsubscribeFromNotificationsResponse(
const base::Closure& callback,
const ErrorCallback& error_callback) {
DCHECK(next_unsubscribe_from_notifications_response_);
uint16_t gatt_code = next_unsubscribe_from_notifications_response_.value();
next_unsubscribe_from_notifications_response_.reset();
switch (gatt_code) {
case mojom::kGATTSuccess:
callback.Run();
break;
case mojom::kGATTInvalidHandle:
error_callback.Run(device::BluetoothGattService::GATT_ERROR_FAILED);
break;
default:
NOTREACHED();
}
}
} // namespace bluetooth
......@@ -59,6 +59,11 @@ class FakeRemoteGattCharacteristic
// call its error callback.
void SetNextSubscribeToNotificationsResponse(uint16_t gatt_code);
// If |gatt_code| is mojom::kGATTSuccess the next unsubscribe to notifications
// with response request will call its success callback. Otherwise it will
// call its error callback.
void SetNextUnsubscribeFromNotificationsResponse(uint16_t gatt_code);
// Returns true if there are no pending responses for this characteristc or
// any of its descriptors.
bool AllResponsesConsumed();
......@@ -108,6 +113,9 @@ class FakeRemoteGattCharacteristic
void DispatchSubscribeToNotificationsResponse(
const base::Closure& callback,
const ErrorCallback& error_callback);
void DispatchUnsubscribeFromNotificationsResponse(
const base::Closure& callback,
const ErrorCallback& error_callback);
const std::string characteristic_id_;
const device::BluetoothUUID characteristic_uuid_;
......@@ -130,6 +138,10 @@ class FakeRemoteGattCharacteristic
// SubscribeToNotifications is called.
base::Optional<uint16_t> next_subscribe_to_notifications_response_;
// Used to decide which callback should be called when
// UnsubscribeFromNotifications is called.
base::Optional<uint16_t> next_unsubscribe_from_notifications_response_;
size_t last_descriptor_id_;
using FakeDescriptorMap =
......
......@@ -6,20 +6,26 @@
<script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script>
<script>
'use strict';
bluetooth_test(() => {
return setBluetoothFakeAdapter('HeartRateAdapter')
.then(() => requestDeviceWithTrustedClick({
filters: [{services: ['heart_rate']}]}))
.then(device => device.gatt.connect())
.then(gattServer => gattServer.getPrimaryService('heart_rate'))
.then(service => service.getCharacteristic('heart_rate_measurement'))
.then(characteristic => {
return characteristic.startNotifications()
.then(() => characteristic.stopNotifications())
const test_desc = 'The characteristic should be able to start and stop ' +
'notifications multiple times in a row.';
let characteristic, fake_characteristic;
let startStopNotifications = () => {
return fake_characteristic.setNextSubscribeToNotificationsResponse(
HCI_SUCCESS)
.then(() => characteristic.startNotifications())
.then(() => characteristic.stopNotifications());
});
// TODO(ortuno): Assert that notifications are not active.
// http://crbug.com/600762
}, 'Start -> stop -> start -> stop.');
.then(() => fake_characteristic.isNotifying())
.then(isNotifying => assert_true(isNotifying))
.then(() =>
fake_characteristic.setNextUnsubscribeFromNotificationsResponse(
HCI_SUCCESS))
.then(() => characteristic.stopNotifications())
.then(() => fake_characteristic.isNotifying())
.then(isNotifying => assert_false(isNotifying));
}
bluetooth_test(() => getMeasurementIntervalCharacteristic()
.then(_ => ({characteristic, fake_characteristic} = _))
.then(() => startStopNotifications())
.then(() => startStopNotifications()),
test_desc);
</script>
......@@ -2896,6 +2896,306 @@
encoder.skip(1);
encoder.skip(1);
};
function FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initDefaults_ = function() {
this.gattCode = 0;
this.characteristicId = null;
this.serviceId = null;
this.peripheralAddress = null;
};
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 40}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.characteristicId
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
if (err !== validator.validationError.NONE)
return err;
// validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.serviceId
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
if (err !== validator.validationError.NONE)
return err;
// validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.peripheralAddress
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false)
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize = codec.kStructHeaderSize + 32;
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.decode = function(decoder) {
var packed;
var val = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.gattCode = decoder.decodeStruct(codec.Uint16);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
val.characteristicId = decoder.decodeStruct(codec.String);
val.serviceId = decoder.decodeStruct(codec.String);
val.peripheralAddress = decoder.decodeStruct(codec.String);
return val;
};
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize);
encoder.writeUint32(0);
encoder.encodeStruct(codec.Uint16, val.gattCode);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.encodeStruct(codec.String, val.characteristicId);
encoder.encodeStruct(codec.String, val.serviceId);
encoder.encodeStruct(codec.String, val.peripheralAddress);
};
function FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initDefaults_ = function() {
this.success = false;
};
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.decode = function(decoder) {
var packed;
var val = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
packed = decoder.readUint8();
val.success = (packed >> 0) & 1 ? true : false;
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
return val;
};
FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize);
encoder.writeUint32(0);
packed = 0;
packed |= (val.success & 1) << 0
encoder.writeUint8(packed);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
};
function FakeCentral_IsNotifying_Params(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeCentral_IsNotifying_Params.prototype.initDefaults_ = function() {
this.characteristicId = null;
this.serviceId = null;
this.peripheralAddress = null;
};
FakeCentral_IsNotifying_Params.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeCentral_IsNotifying_Params.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 32}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
// validate FakeCentral_IsNotifying_Params.characteristicId
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
if (err !== validator.validationError.NONE)
return err;
// validate FakeCentral_IsNotifying_Params.serviceId
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
if (err !== validator.validationError.NONE)
return err;
// validate FakeCentral_IsNotifying_Params.peripheralAddress
err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false)
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeCentral_IsNotifying_Params.encodedSize = codec.kStructHeaderSize + 24;
FakeCentral_IsNotifying_Params.decode = function(decoder) {
var packed;
var val = new FakeCentral_IsNotifying_Params();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
val.characteristicId = decoder.decodeStruct(codec.String);
val.serviceId = decoder.decodeStruct(codec.String);
val.peripheralAddress = decoder.decodeStruct(codec.String);
return val;
};
FakeCentral_IsNotifying_Params.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeCentral_IsNotifying_Params.encodedSize);
encoder.writeUint32(0);
encoder.encodeStruct(codec.String, val.characteristicId);
encoder.encodeStruct(codec.String, val.serviceId);
encoder.encodeStruct(codec.String, val.peripheralAddress);
};
function FakeCentral_IsNotifying_ResponseParams(values) {
this.initDefaults_();
this.initFields_(values);
}
FakeCentral_IsNotifying_ResponseParams.prototype.initDefaults_ = function() {
this.success = false;
this.isNotifying = false;
};
FakeCentral_IsNotifying_ResponseParams.prototype.initFields_ = function(fields) {
for(var field in fields) {
if (this.hasOwnProperty(field))
this[field] = fields[field];
}
};
FakeCentral_IsNotifying_ResponseParams.validate = function(messageValidator, offset) {
var err;
err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
if (err !== validator.validationError.NONE)
return err;
var kVersionSizes = [
{version: 0, numBytes: 16}
];
err = messageValidator.validateStructVersion(offset, kVersionSizes);
if (err !== validator.validationError.NONE)
return err;
return validator.validationError.NONE;
};
FakeCentral_IsNotifying_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;
FakeCentral_IsNotifying_ResponseParams.decode = function(decoder) {
var packed;
var val = new FakeCentral_IsNotifying_ResponseParams();
var numberOfBytes = decoder.readUint32();
var version = decoder.readUint32();
packed = decoder.readUint8();
val.success = (packed >> 0) & 1 ? true : false;
val.isNotifying = (packed >> 1) & 1 ? true : false;
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
decoder.skip(1);
return val;
};
FakeCentral_IsNotifying_ResponseParams.encode = function(encoder, val) {
var packed;
encoder.writeUint32(FakeCentral_IsNotifying_ResponseParams.encodedSize);
encoder.writeUint32(0);
packed = 0;
packed |= (val.success & 1) << 0
packed |= (val.isNotifying & 1) << 1
encoder.writeUint8(packed);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
encoder.skip(1);
};
function FakeCentral_GetLastWrittenCharacteristicValue_Params(values) {
this.initDefaults_();
this.initFields_(values);
......@@ -3786,10 +4086,12 @@
var kFakeCentral_SetNextReadCharacteristicResponse_Name = 12;
var kFakeCentral_SetNextWriteCharacteristicResponse_Name = 13;
var kFakeCentral_SetNextSubscribeToNotificationsResponse_Name = 14;
var kFakeCentral_GetLastWrittenCharacteristicValue_Name = 15;
var kFakeCentral_SetNextReadDescriptorResponse_Name = 16;
var kFakeCentral_SetNextWriteDescriptorResponse_Name = 17;
var kFakeCentral_GetLastWrittenDescriptorValue_Name = 18;
var kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name = 15;
var kFakeCentral_IsNotifying_Name = 16;
var kFakeCentral_GetLastWrittenCharacteristicValue_Name = 17;
var kFakeCentral_SetNextReadDescriptorResponse_Name = 18;
var kFakeCentral_SetNextWriteDescriptorResponse_Name = 19;
var kFakeCentral_GetLastWrittenDescriptorValue_Name = 20;
function FakeCentralPtr(handleOrPtrInfo) {
this.ptr = new bindings.InterfacePtrController(FakeCentral,
......@@ -4211,6 +4513,61 @@
});
}.bind(this));
};
FakeCentralPtr.prototype.setNextUnsubscribeFromNotificationsResponse = function() {
return FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse
.apply(this.ptr.getProxy(), arguments);
};
FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
var params = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params();
params.gattCode = gattCode;
params.characteristicId = characteristicId;
params.serviceId = serviceId;
params.peripheralAddress = peripheralAddress;
return new Promise(function(resolve, reject) {
var builder = new codec.MessageV1Builder(
kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name,
codec.align(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize),
codec.kMessageExpectsResponse, 0);
builder.encodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params, params);
var message = builder.finish();
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
var reader = new codec.MessageReader(message);
var responseParams =
reader.decodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams);
resolve(responseParams);
}).catch(function(result) {
reject(Error("Connection error: " + result));
});
}.bind(this));
};
FakeCentralPtr.prototype.isNotifying = function() {
return FakeCentralProxy.prototype.isNotifying
.apply(this.ptr.getProxy(), arguments);
};
FakeCentralProxy.prototype.isNotifying = function(characteristicId, serviceId, peripheralAddress) {
var params = new FakeCentral_IsNotifying_Params();
params.characteristicId = characteristicId;
params.serviceId = serviceId;
params.peripheralAddress = peripheralAddress;
return new Promise(function(resolve, reject) {
var builder = new codec.MessageV1Builder(
kFakeCentral_IsNotifying_Name,
codec.align(FakeCentral_IsNotifying_Params.encodedSize),
codec.kMessageExpectsResponse, 0);
builder.encodeStruct(FakeCentral_IsNotifying_Params, params);
var message = builder.finish();
this.receiver_.acceptAndExpectResponse(message).then(function(message) {
var reader = new codec.MessageReader(message);
var responseParams =
reader.decodeStruct(FakeCentral_IsNotifying_ResponseParams);
resolve(responseParams);
}).catch(function(result) {
reject(Error("Connection error: " + result));
});
}.bind(this));
};
FakeCentralPtr.prototype.getLastWrittenCharacteristicValue = function() {
return FakeCentralProxy.prototype.getLastWrittenCharacteristicValue
.apply(this.ptr.getProxy(), arguments);
......@@ -4374,6 +4731,12 @@
FakeCentralStub.prototype.setNextSubscribeToNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
return this.delegate_ && this.delegate_.setNextSubscribeToNotificationsResponse && this.delegate_.setNextSubscribeToNotificationsResponse(gattCode, characteristicId, serviceId, peripheralAddress);
}
FakeCentralStub.prototype.setNextUnsubscribeFromNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) {
return this.delegate_ && this.delegate_.setNextUnsubscribeFromNotificationsResponse && this.delegate_.setNextUnsubscribeFromNotificationsResponse(gattCode, characteristicId, serviceId, peripheralAddress);
}
FakeCentralStub.prototype.isNotifying = function(characteristicId, serviceId, peripheralAddress) {
return this.delegate_ && this.delegate_.isNotifying && this.delegate_.isNotifying(characteristicId, serviceId, peripheralAddress);
}
FakeCentralStub.prototype.getLastWrittenCharacteristicValue = function(characteristicId, serviceId, peripheralAddress) {
return this.delegate_ && this.delegate_.getLastWrittenCharacteristicValue && this.delegate_.getLastWrittenCharacteristicValue(characteristicId, serviceId, peripheralAddress);
}
......@@ -4637,6 +5000,39 @@
responder.accept(message);
});
return true;
case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name:
var params = reader.decodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params);
this.setNextUnsubscribeFromNotificationsResponse(params.gattCode, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
var responseParams =
new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams();
responseParams.success = response.success;
var builder = new codec.MessageV1Builder(
kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name,
codec.align(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize),
codec.kMessageIsResponse, reader.requestID);
builder.encodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams,
responseParams);
var message = builder.finish();
responder.accept(message);
});
return true;
case kFakeCentral_IsNotifying_Name:
var params = reader.decodeStruct(FakeCentral_IsNotifying_Params);
this.isNotifying(params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
var responseParams =
new FakeCentral_IsNotifying_ResponseParams();
responseParams.success = response.success;
responseParams.isNotifying = response.isNotifying;
var builder = new codec.MessageV1Builder(
kFakeCentral_IsNotifying_Name,
codec.align(FakeCentral_IsNotifying_ResponseParams.encodedSize),
codec.kMessageIsResponse, reader.requestID);
builder.encodeStruct(FakeCentral_IsNotifying_ResponseParams,
responseParams);
var message = builder.finish();
responder.accept(message);
});
return true;
case kFakeCentral_GetLastWrittenCharacteristicValue_Name:
var params = reader.decodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_Params);
this.getLastWrittenCharacteristicValue(params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) {
......@@ -4772,6 +5168,14 @@
if (message.expectsResponse())
paramsClass = FakeCentral_SetNextSubscribeToNotificationsResponse_Params;
break;
case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name:
if (message.expectsResponse())
paramsClass = FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params;
break;
case kFakeCentral_IsNotifying_Name:
if (message.expectsResponse())
paramsClass = FakeCentral_IsNotifying_Params;
break;
case kFakeCentral_GetLastWrittenCharacteristicValue_Name:
if (message.expectsResponse())
paramsClass = FakeCentral_GetLastWrittenCharacteristicValue_Params;
......@@ -4858,6 +5262,14 @@
if (message.isResponse())
paramsClass = FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams;
break;
case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name:
if (message.isResponse())
paramsClass = FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams;
break;
case kFakeCentral_IsNotifying_Name:
if (message.isResponse())
paramsClass = FakeCentral_IsNotifying_ResponseParams;
break;
case kFakeCentral_GetLastWrittenCharacteristicValue_Name:
if (message.isResponse())
paramsClass = FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams;
......
......@@ -393,6 +393,30 @@ class FakeRemoteGATTCharacteristic {
if (!success) throw 'setNextSubscribeToNotificationsResponse failed';
}
// Sets the next unsubscribe to notifications response for characteristic with
// |characteristic_id| in |service_id| and in |peripheral_address| to
// |code|. |code| could be a GATT Error Response from BT 4.2 Vol 3 Part F
// 3.4.1.1 Error Response or a number outside that range returned by
// specific platforms e.g. Android returns 0x101 to signal a GATT failure.
async setNextUnsubscribeFromNotificationsResponse(gatt_code) {
let {success} =
await this.fake_central_ptr_.setNextUnsubscribeFromNotificationsResponse(
gatt_code, ...this.ids_);
if (!success) throw 'setNextUnsubscribeToNotificationsResponse failed';
}
// Returns true if notifications from the characteristic have been subscribed
// to.
async isNotifying() {
let {success, isNotifying} =
await this.fake_central_ptr_.isNotifying(...this.ids_);
if (!success) throw 'isNotifying failed';
return isNotifying;
}
// Gets the last successfully written value to the characteristic.
// Returns null if no value has yet been written to the characteristic.
async getLastWrittenValue() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment