Private random resolvable address and bonding between PSoC4 peripheral and a smartphone

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
manusharian
Level 4
Level 4
25 replies posted 10 replies posted 10 questions asked

Hello everybody,

I am trying to implement the following scenario: using a PSoC 4 BLE peripheral I updated the privacy example and I am trying to use it in my project. I start the peripheral using a public address; then I connect with an android smartphone to the device, pair it using a fixed passkey, bond the device and afterwards the phone disconnects. After the disconnecting event, the address of my peripheral becomes private random resolvable which is what I want, it even changes ones at a couple of minutes again if there is no connection or every time a connection/disconnection event arrived. Everything is good, but my problem is the following, after I disconnect with the smartphone from the peripheral and the address become private I am not able to reconnect with my smartphone again. Does anyone know if android itself can resolve an address or if the application should scan every time for a device and try to resolve itself the address? I would like to reconnect to a bonded device without scanning, but I do not know if this is possible.

If anyone experienced this, a hint is more than welcomed.

Thank you,

Marian

Update info: The security of my device is set to Mode 1, authenticated pairing with encryption, Strict pairing, Display as IO capability(even if this is not entirely correct, the device has no i/o capabilities but I want to use a fixed passkey for this). I observe that the bonding initiated by the smartphone and the exchange of keys is ok. After disconnect event and the address become private I can scan all devices, find the one I need with the orivate address and can connect to it without any bonding. The problem is now the following: after connection and accessing a service(ex. battery level) I am no longer able to do anything. If I try a read than the pairing winodw will pop up again and no matter what I enter the device disconnects.

Update info 2:

Here is a new Update and the project attached. I eliminate all the code except my two state machines that handle this bonding and privacy tasks. Please note in BLEHandler.c that some code is commented since it makes no sense in this test project, especially the fact that remove bonding is done by pressing a button and in the project it is done at reset.

The battery level as it is in SIG has encryption and authenticated on Read. Therefore indeed that may trigger the pairing window again. I am not an expert in how Android or iOS will treat this but if I remove the encryption an authentication than everything is fine. But I do not want to modify this, and I still want some privacy on other custom characteristics, even if after a bonding only that phone can resolve the address.

Other Info: with the cypress dongle and cysmart on PC, when reconnect to the private address, it will pop up the pairing but after ok it says paring completed without the entering pin.

One of my other questions will be: Is there something wrong in how I handle this process in the peripheral? Is there a problem with the application on android and there I should invest some time?

It would be great if someone can point me in a more correct direction. Thank you!

Message was edited by: Marian-Emanuel Ionascu

0 Likes
1 Solution

Thank you for help. I found this AN http://www.cypress.com/file/224826/download  which point to an example for privacy. It seems that this example works fine with Iphone devices, I still have trouble with a lecagy 4.1 device but I will analyze more this AN and hopefully it will solve the problem. I will come back with other findings after an analyze of this document.

View solution in original post

0 Likes
11 Replies
Anonymous
Not applicable

Before update: The peripheral should be spitting out a random address that is resolveable by the phone; I'm not sure how the address resolution process works exactly, but requiring scanning either passively or actively to find the new random address of the peripheral would make the most sense to me personally

After update: You could double check the service/attributes settings for access (either encryption, authentication, etc.) If you have the unit requiring encryption for access, then you will need to go through the pairing process on connection to encrypt communication before the peripheral allows attributes to be read or written. I would lean towards that as being a possible problem source.

  • If the device is crashing after having an attribute read, then perhaps you have invalid code running to handle the attribute access that is crashing the device, or causing spurious behavior?
  • Since the pairing window is popping up again, I would guess that the peripheral is not encrypted/paired or something.
  • When you say "no matter what", with a code to enter for successful pairing, you would be lucky to get the right number code entered if it is not using the correct one 😕

Hello,

Your last update is similar with what I encountered last night. To answer to your possible problem hints:

1) the device is not crashing but it will ask for passkey again. The code running does nothing to handle read request as I believe this is automatically done, nor writes and notification in this moment.

2) the peripheral indeed has encryption, it has only the SIG battery service without modifications.

3) the code is still the default one, 123456, but the peripheral is bonded to the phone when it has a public address after that it should not ask for passkey. I am not completely sure why it will not accept again the passkey and it disconnects. Please note that peripheral has Link layer privacy checked.

I will update the main text with the test project and some info in a sec.

Marian

0 Likes
Anonymous
Not applicable

Hmmm, from the looks of it the issue lies in the authentication/encryption handshake/steps.

I'm not sure if it is peripheral or android-side, but when you request read of the battery-level service and it requires encryption, then the phone will get an error/response indicating it needs to pair with the peripheral. The peripheral should then either initiate the pairing request itself, or wait for the phone to initiate the pairing process (note: The pairing process is not the same as the bonding process).

Generally I believe the central device is setup to request/ensure encryption/pairing handshake initiation, and the peripheral acts as dumb as possible.

Some events to check/handle that might help in the BLEHandler.c:

  • CYBLE_EVT_HCI_STATUS
  • CYBLE_EVT_GATTC_ERROR_RSP
  • CYBLE_EVT_GAP_SMP_NEGOTIATED_AUTH_INFO
  • CYBLE_EVT_TIMEOUT

The first two are error events, the third is a change in encryption notification. Not that I would expect any of those three to fire, but it may help to look at them...

The last event is a generic timeout for various causes...

For why the device disconnects after the phone tries to access the battery service: It could be that either the phone isn't reusing the password key from before correctly, or the peripheral is incorrectly comparing/running comparison code to check the phone response and crashes/disconnects afterwards.

Also, check the return value from all of your CyBle_ function calls, as they return codes based on their success/failure. If you are trying to call the CyBle_GappAuthReqReply() function and it returns a failure for example, then obviously the encryption/authentication would fail, and the phone might be disconnecting due to android behavior in response to the failure, or vice versa.

0 Likes

Ok. I have tried what you suggested. I do not get CYBLE_EVT_HCI_STATUS and CYBLE_EVT_GATTC_ERROR_RSP is a client event and I do not have it generated, my peripheral is a server.  I do receive the CYBLE_EVT_GAP_SMP_NEGOTIATED_AUTH_INFO every time I got the CYBLE_EVT_GAP_AUTH_REQ, therefore I got it first with public address and also when I try to read from battery characteristic after bonding. I also receive CYBLE_EVT_TIMEOUT with code 70 immediately after advertising starts but I think this is a general timeout, since I got it regularly if I do not do anything.

I also took your advise and I print everything, therefore I got the following problem: the function CyBle_GappAuthReqReply returns an error code 2 which is CYBLE_ERROR_INVALID_OPERATION. This is interesting since in the description this function can only return 0,1,3,4 and 7

as error codes, but it returns 2 every time I call it. I also printed the field CYBLE_GAP_AUTH_FAILED_REASON_T of CYBLE_GAP_AUTH_INFO_T variable and it has a failed code 1 -> which is CYBLE_GAP_AUTH_ERROR_PASSKEY_ENTRY_FAILED. Now I am stuck as I have no idea why this is the case for that field, maybe it is linked to the fact that I try to simulate the display by setting a fix pass key and this cause all the problem, or maybe I call the function wrongly, etc.

Thank you!

0 Likes
Anonymous
Not applicable

Yay!

Moving onwards:

Looking at your BLE component settings, it looks like you have strict pairing on. If the phone is not being strict with the security as well, could that cause the issue? (Based on the documentation here: http://www.cypress.com/file/224826/download look for the phrase "strict pairing")

Could it be that the cyBle_authInfo structure is using the wrong values? This is how I'm calling the function personally:

result = CyBle_GappAuthReqReply(cyBle_connHandle.bdHandle, &cyBle_authInfo);//Accept request

But that looks the same as your call, but I have the I/O functionality set to "No Display, No Input" and strict pairing is turned off (but I manually check pairing when I reconnect).

The example 100 projects in 100 days might help you figure out what you are doing wrong:

PSoC-4-BLE/100_Projects_in_100_Days/Day014_Whitelist at master · cypresssemiconductorco/PSoC-4-BLE ·...

PSoC-4-BLE/100_Projects_in_100_Days/Day015_Bonding at master · cypresssemiconductorco/PSoC-4-BLE · G...

PSoC-4-BLE/100_Projects_in_100_Days/Day016_Authentication at master · cypresssemiconductorco/PSoC-4-...

From the looks of it, the whitelist/bonding is being setup correctly and working, but looking at their Authentication example, you might be missing a step or two for authenticating.

0 Likes

Hello,

The strict paring did not affect the behavior, I tried without it but from an Iphone 6 and 7, and android 5.1 perspectives this does not have any impact. The code just behaves like with strict pairing. I also go again through authentication example and add another prints and events from there but the behavior is the same. With cypress dongle everything is ok but with ios or android it is not. I need to investigate more, but in this moment I am unable to figure it ou. I will come with other info as soon as I have some. This is my last project with all the printing and the unpair at press of a button (P2.7 since I am testing now on the dev board and not on our custom board).

0 Likes
Anonymous
Not applicable

There are unique BLE requirements for iOS and Android from what I remember. It could be that one of those requirements is causing the behavioral difference (CySmart Dongle doesn't have very strict behavior).

Apple's information: https://developer.apple.com/hardwaredrivers/BluetoothDesignGuidelines.pdf

Android's information: Bluetooth Low Energy | Android Developers

Android example for interfacing: Android Things - Communicating with Bluetooth Low Energy devices

0 Likes

Thank you for help. I found this AN http://www.cypress.com/file/224826/download  which point to an example for privacy. It seems that this example works fine with Iphone devices, I still have trouble with a lecagy 4.1 device but I will analyze more this AN and hopefully it will solve the problem. I will come back with other findings after an analyze of this document.

0 Likes
Anonymous
Not applicable

Alright, let me know if you find anything else you have questions on

0 Likes

A small update on this:

The AN attached on my last post is indeed very helpful and adapting this to my scenario seems to work very good with devices that have 4.2 and LE secure as security(mode 1 level 4). However I still have some problems:

1) when I encounter a device with security mode 1 level 3(authenticated with encryption) I am able to connect and reconnect as expected but I cannot perform operation due to insufficient authenticated information. This is strange but maybe I miss something. If I set the mode to level 3 in the creator then this problem is resolved. Is there any way I can update the level from code during a pairing in order to keep the level on level 4 and only when the peer have level 3 to downgrade? I tried in CYBLE_EVT_GAP_SMP_NEGOTIATED_AUTH_INFO to changed the cyBle_authInfo to level 3 but unsuccessfully.

2) Setting the security to level 3 I tried a older device with ble 4.0. In this case the peer irk received is only 0's therefore the smartphone is unable to resolve the address and I cannot find my peripheral anymore until unpair. Do someone know why I receive 00?

Test for 1: the attach code can be load in the dev board after pair and bond from a device with level 3 read the battery level, it should not receive the level.

Test for 2: setting the level in creator to mode 1 level 3 authenticated, connect to a 4.0 ble device(I used a philips smartphone). Everything is ok, then disconnect. The device will start the private advertising. The phone will be unable to resolve the address.

Thanks again!

0 Likes
Anonymous
Not applicable

The "level 3" and the "level 4" are two different encryption/pairing methods, hence why they are different selections. If you use one it will not work with the other afaik.

You can probably change the security level to 3, but only if the BLE radio is not active I would guess. So you would have to stop activity, change to level 3, restart, and then retry connection with the device that has level 3 set.

0 Likes