Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLE: Nordic pal client implementation #5739

Merged
merged 12 commits into from Jan 11, 2018
Merged

Conversation

pan-
Copy link
Member

@pan- pan- commented Dec 20, 2017

Description

This patch get rid of the old client implementation present present on Nordic targets and replace it by an implementation based on the platform adaptation result. As a result all the missing GATT procedures are implemented:

  • Discover Primary Service By Service UUID
  • Find Included Service
  • Read Using Characteristic UUID
  • Read Multiple Characteristics
  • Queue Prepare Write
  • Execute Write

The motivation behind this submission is the discovery of bugs in a new example for the GattClient ARMmbed/mbed-os-example-ble#111 ; The bug was well buried inside the logic of the previous GattClient (improper queuing and order of operations). It was easier to provide the new implementation than rewriting all the internal.

Status

READY

Migrations

NO

@pan-
Copy link
Member Author

pan- commented Dec 20, 2017

@nvlsianpu @paul-szczepanek-arm Could you review ?

GattProcedure* _procedures[max_procedures_count];
};

} // cordio

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nordic?

static const size_t max_procedures_count =
CENTRAL_LINK_COUNT + PERIPHERAL_LINK_COUNT;

// Note: Ideally we would have used an array of variant here

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what this comment means, is this a todo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really a todo, I won't implement a compliant variant in C++03; it requires an heavy TMP machinery. However if we have a variant type added in mbed platform then pointers can be replaced by a variant.

* The concept of procedures for Gatt operations formalize the process. A
* procedure lifecycle is defined by three function:
* - start: Launch of the procedure. It initiate the first request to send to
* the peer. It must be implemented by Procedure childs.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

childs -> derived classes

characteristic_value_handle,
/* offset */ 0,
static_cast<uint16_t>(value.size()),
const_cast<uint8_t*>(value.data())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's with the juggling of consts? is const or not?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nordic API is not const correct; the data passed in the write params won't be modified by the API.

/**
* A regular procedure is a procedure that follows Gatt specification.
*
* It initiate a single request to the peer and except a single response. This

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expects


const ble_gattc_evt_read_rsp_t &rsp = evt.params.read_rsp;

uint16_t expected_handle = bytes_to_u16(&response[idx][0]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do all those numbers like 0, 16, 4 mean something? maybe they should be consts

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offset 0 is explicit enough otherwise we can add static const variable for loong uuid length (16) and long uuid offset in read by group type response.

/**
* Extract an uint16_t value from a memory location.
*/
static uint16_t bytes_to_u16(const void* b)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed? alignment problems?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to avoid alignment issues. Load instructions works with unaligned data however it is not the case for Load Multiple instructions. Depending on the code, the compiler is free to use LDM instructions which raise a processor exception on unaligned data. Since it is compiler dependent, an update of the compiler, or a change in optimizations flags may issue code that don't work anymore.

@nvlsianpu
Copy link
Contributor

I'm really happy seeing this :D I hope I'll find time too look on this soon.

abort();
}

uint8_t *it = buffer;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this supposed to continue past abort()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, good catch!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few more aborts that continue, you might want to have a quick look

* invalid namespace name documentation
* vocabulary
* typo
* Add constants to improve readability
* Fix abort usages
@pan-
Copy link
Member Author

pan- commented Dec 21, 2017

@paul-szczepanek-arm I addressed your comments.

@cmonr
Copy link
Contributor

cmonr commented Dec 28, 2017

/morph build

@mbed-ci
Copy link

mbed-ci commented Dec 28, 2017

Build : FAILURE

Build number : 766
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/5739/

@cmonr
Copy link
Contributor

cmonr commented Dec 28, 2017

@pan- Some more work on this PR is needed. Reference the last Build Failure.

Several IAR targets are failing to build, and all NRF52840_DK targets failed to build as well.

);

switch (err) {
case NRF_SUCCESS:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe:

if (err == NRF_SUCCESS) {
    nordic_uuid.uuid = bytes_to_u16(uuid.getBaseUUID() + 12);
}

return convert_sd_error(err);


ble_error_t nRF5XGattClient::exchange_mtu(connection_handle_t connection)
{
// Note: Not supported by the current softdevice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not supported by SD 13x 2.x.x.
Is supported by SD 140 5.x.x (call sd_ble_gattc_exchange_mtu_request)

}
}

typedef uint8_t packed_discovery_response_t[20];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the cause for have 20 here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attribute data present in the read by group type response will be 20 bytes long:

  • Attribute handle: 2 bytes
  • End group handle: 2 bytes
  • Attribute value (128bits UUID): 16 bytes

I will clarify the code.

@nvlsianpu
Copy link
Contributor

@pan- Can you point me how are implemented discovery of characteristic/service of long UUID? I mean the difference between API of SD v 2.x.xx and 5.x.x. For old-port was implemented here https://github.com/ARMmbed/mbed-os/blob/master/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NRF5/source/nRF5xServiceDiscovery.cpp#L292 and few line below.

@nvlsianpu
Copy link
Contributor

@pan- #5739 (comment) is not contended.

@pan-
Copy link
Member Author

pan- commented Jan 9, 2018

@nvlsianpu I'm not sure to understand: Incompatibilities between softdevices is handled by e9ba841 .

@mbed-ci
Copy link

mbed-ci commented Jan 9, 2018

@mbed-ci
Copy link

mbed-ci commented Jan 9, 2018

@nvlsianpu
Copy link
Contributor

In old port sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter is used for API >=3. I don't see this here.

@pan-
Copy link
Member Author

pan- commented Jan 9, 2018

@nvlsianpu SimpleAttReadByTypeResponse handle parsing of the payload of handle_value. There is no need to use sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter.

@nvlsianpu
Copy link
Contributor

thanks for explanation - I had limited timed for dig in. So PR LGTM.

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 10, 2018

/morph export-build

@mbed-ci
Copy link

mbed-ci commented Jan 10, 2018

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 10, 2018

CI issue the latest one

/morph export-build

@mbed-ci
Copy link

mbed-ci commented Jan 10, 2018

Read By group type response can return 4 descriptor discovered when the remote server have 4 descriptors with a 16 bit UUID. The handle, UUID pair get stored in a ble_gattc_desc_t that is 20 bytes long.

This PR increase buffer size to handle this use case.
@pan-
Copy link
Member Author

pan- commented Jan 10, 2018

BLE testing revealed few issues with this pr: the reset strategy of the GattClient was not handled correctly and a bug in the Nordic SDK has been revealed.

@nvlsianpu Could you review 3105327 ?
@paul-szczepanek-arm Could you review 3061db2, 29988d5 and d33b028 ?

@paul-szczepanek-arm
Copy link
Member

looks good, I don't seem to be able to re-approve it so I guess it's all good to go already

@cmonr
Copy link
Contributor

cmonr commented Jan 10, 2018

Rerunning tests due to small changes with recent commits.

/morph build

@mbed-ci
Copy link

mbed-ci commented Jan 10, 2018

Build : SUCCESS

Build number : 837
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/5739/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build

@mbed-ci
Copy link

mbed-ci commented Jan 10, 2018

@cmonr
Copy link
Contributor

cmonr commented Jan 10, 2018

/morph uvisor-test
/morph export-build

@mbed-ci
Copy link

mbed-ci commented Jan 10, 2018

@mbed-ci
Copy link

mbed-ci commented Jan 10, 2018

@pan-
Copy link
Member Author

pan- commented Jan 11, 2018

yes, it is a bug in SDK v11, it is fixed in SDK v13 (hence the change in the type holding discovered descriptors).

@cmonr cmonr merged commit b32828b into ARMmbed:master Jan 11, 2018
@pan- pan- deleted the nordic-new-client branch November 14, 2018 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants