BLE: Implement Generic GattClient reset logic.

pull/5739/head
Vincent Coubard 2018-01-10 14:31:52 +00:00
parent 29988d5265
commit d33b02818a
2 changed files with 55 additions and 6 deletions

View File

@ -137,6 +137,7 @@ private:
pal::GattClient* const _pal_client; pal::GattClient* const _pal_client;
ServiceDiscovery::TerminationCallback_t _termination_callback; ServiceDiscovery::TerminationCallback_t _termination_callback;
mutable ProcedureControlBlock* control_blocks; mutable ProcedureControlBlock* control_blocks;
bool _is_reseting;
}; };
} }

View File

@ -74,6 +74,11 @@ struct GenericGattClient::ProcedureControlBlock {
*/ */
virtual void handle_timeout_error(GenericGattClient* client) = 0; virtual void handle_timeout_error(GenericGattClient* client) = 0;
/**
* Function called when the procedure is aborted
*/
virtual void abort(GenericGattClient *client) = 0;
procedure_type_t type; procedure_type_t type;
Gap::Handle_t connection_handle; Gap::Handle_t connection_handle;
ProcedureControlBlock* next; ProcedureControlBlock* next;
@ -111,6 +116,10 @@ struct GenericGattClient::DiscoveryControlBlock : public ProcedureControlBlock {
terminate(client); terminate(client);
} }
virtual void abort(GenericGattClient *client) {
terminate(client);
}
virtual void handle(GenericGattClient* client, const AttServerMessage& message) { virtual void handle(GenericGattClient* client, const AttServerMessage& message) {
// if end of discovery has been requested, ends it immediately // if end of discovery has been requested, ends it immediately
if (done) { if (done) {
@ -436,6 +445,19 @@ struct GenericGattClient::ReadControlBlock : public ProcedureControlBlock {
terminate(client, response); terminate(client, response);
} }
virtual void abort(GenericGattClient *client) {
GattReadCallbackParams response = {
connection_handle,
attribute_handle,
offset,
0, // size of 0
NULL, // no data
BLE_ERROR_INVALID_STATE,
};
terminate(client, response);
}
void terminate(GenericGattClient* client, const GattReadCallbackParams& response) { void terminate(GenericGattClient* client, const GattReadCallbackParams& response) {
client->remove_control_block(this); client->remove_control_block(this);
client->processReadResponse(&response); client->processReadResponse(&response);
@ -617,6 +639,17 @@ struct GenericGattClient::WriteControlBlock : public ProcedureControlBlock {
terminate(client, response); terminate(client, response);
} }
virtual void abort(GenericGattClient *client) {
GattWriteCallbackParams response = {
connection_handle,
attribute_handle,
GattWriteCallbackParams::OP_WRITE_REQ,
BLE_ERROR_INVALID_STATE,
0x00
};
terminate(client, response);
}
void terminate(GenericGattClient* client, const GattWriteCallbackParams& response) { void terminate(GenericGattClient* client, const GattWriteCallbackParams& response) {
client->remove_control_block(this); client->remove_control_block(this);
client->processWriteResponse(&response); client->processWriteResponse(&response);
@ -814,6 +847,10 @@ struct GenericGattClient::DescriptorDiscoveryControlBlock : public ProcedureCont
terminate(client, BLE_ERROR_UNSPECIFIED); terminate(client, BLE_ERROR_UNSPECIFIED);
} }
virtual void abort(GenericGattClient *client) {
terminate(client, BLE_ERROR_INVALID_STATE);
}
virtual void handle(GenericGattClient* client, const AttServerMessage& message) { virtual void handle(GenericGattClient* client, const AttServerMessage& message) {
if (done) { if (done) {
terminate(client, BLE_ERROR_NONE); terminate(client, BLE_ERROR_NONE);
@ -892,7 +929,8 @@ struct GenericGattClient::DescriptorDiscoveryControlBlock : public ProcedureCont
GenericGattClient::GenericGattClient(pal::GattClient* pal_client) : GenericGattClient::GenericGattClient(pal::GattClient* pal_client) :
_pal_client(pal_client), _pal_client(pal_client),
_termination_callback(), _termination_callback(),
control_blocks(NULL) { control_blocks(NULL),
_is_reseting(false) {
_pal_client->when_server_message_received( _pal_client->when_server_message_received(
mbed::callback(this, &GenericGattClient::on_server_message_received) mbed::callback(this, &GenericGattClient::on_server_message_received)
); );
@ -909,7 +947,7 @@ ble_error_t GenericGattClient::launchServiceDiscovery(
const UUID& matching_characteristic_uuid const UUID& matching_characteristic_uuid
) { ) {
// verify that there is no other procedures going on this connection // verify that there is no other procedures going on this connection
if (get_control_block(connection_handle)) { if (_is_reseting || get_control_block(connection_handle)) {
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
@ -988,7 +1026,7 @@ ble_error_t GenericGattClient::read(
uint16_t offset) const uint16_t offset) const
{ {
// verify that there is no other procedures going on this connection // verify that there is no other procedures going on this connection
if (get_control_block(connection_handle)) { if (_is_reseting || get_control_block(connection_handle)) {
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
@ -1032,7 +1070,7 @@ ble_error_t GenericGattClient::write(
const uint8_t* value const uint8_t* value
) const { ) const {
// verify that there is no other procedures going on this connection // verify that there is no other procedures going on this connection
if (get_control_block(connection_handle)) { if (_is_reseting || get_control_block(connection_handle)) {
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
@ -1111,7 +1149,7 @@ ble_error_t GenericGattClient::discoverCharacteristicDescriptors(
const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
) { ) {
// verify that there is no other procedures going on this connection // verify that there is no other procedures going on this connection
if (get_control_block(characteristic.getConnectionHandle())) { if (_is_reseting || get_control_block(characteristic.getConnectionHandle())) {
return BLE_ERROR_INVALID_STATE; return BLE_ERROR_INVALID_STATE;
} }
@ -1186,7 +1224,17 @@ void GenericGattClient::terminateCharacteristicDescriptorDiscovery(
} }
ble_error_t GenericGattClient::reset(void) { ble_error_t GenericGattClient::reset(void) {
return BLE_ERROR_NOT_IMPLEMENTED;
// _is_reseting prevent executions of new procedure while the instance resets.
// otherwise new procedures can be launched from callbacks generated by the
// reset.
_is_reseting = true;
while (control_blocks) {
control_blocks->abort(this);
}
_is_reseting = false;
return BLE_ERROR_NONE;
} }
void GenericGattClient::on_termination(Gap::Handle_t connection_handle) { void GenericGattClient::on_termination(Gap::Handle_t connection_handle) {