- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
i'm chasing an example of unauthenticated pairing with encryption, but for a GAP central, not peripheral as all the examples seem to be.
kind regards,
Damian
Solved! Go to Solution.
- Labels:
-
BLE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I did get a central GAP unauthenticated pairing project working, but I can't disclose the project to you unfortunately. I can however help you with implementing your own
To find, connect to, and then discover the attributes of a unit:
//Note, you will want to use the correct information when starting discovery if you want to use whitelisting
CyBle_GapcStartDiscovery()
//Once you find the device you want, either by advertisement data or address data, then call
CyBle_GapcStopDiscovery()
//next connect to the device you want to
CyBle_GapcConnectDevice()
//then discover the primary services of the device
CyBle_GattcDiscoverPrimaryServiceByUuid()
//then discover all the characteristics of the service you want attributes for
CyBle_GattcDiscoverAllCharacteristics()
//You should now have handles for the services, attributes, and the device that you are interested in.
Events you will need to handle in the BLE callback handler:
//handle discovered devices to determine if you found the one(s) you want
case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT:
//standard events for BLE examples
case CYBLE_EVT_STACK_ON:
case CYBLE_EVT_GAP_DEVICE_CONNECTED:
case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
//signals the start or stop of advertising/scanning (depending on if you have central/peripheral)
case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
case CYBLE_EVT_GAPC_SCAN_START_STOP:
//Events for connection parameter changes
case CYBLE_EVT_GAP_SMP_NEGOTIATED_AUTH_INFO:;
case CYBLE_EVT_GAP_ENCRYPT_CHANGE:;
case CYBLE_EVT_GATTS_XCNHG_MTU_REQ:
//Events to handle the authentication part of the connection
case CYBLE_EVT_GAP_AUTH_REQ: //CyBle_GapAuthReq() is the API to initiate encryption for the connection
case CYBLE_EVT_GAP_AUTH_COMPLETE: //if encryption succeeded
case CYBLE_EVT_GAP_AUTH_FAILED: //if encryption failed
//service handle from unit
case CYBLE_EVT_GATTC_FIND_BY_TYPE_VALUE_RSP:;
//characteristic handles from service
case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP:;
//Used for detecting GATTC error, or when finished discovering services/characteristics
case CYBLE_EVT_GATTC_ERROR_RSP:;
//You don't necessarily need to handle the EVT_HCI status, but it will be useful for detecting errors and development
case CYBLE_EVT_HCI_STATUS:;
//you don't necessarily need to handle the timeout, but you should
case CYBLE_EVT_TIMEOUT:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I did get a central GAP unauthenticated pairing project working, but I can't disclose the project to you unfortunately. I can however help you with implementing your own
To find, connect to, and then discover the attributes of a unit:
//Note, you will want to use the correct information when starting discovery if you want to use whitelisting
CyBle_GapcStartDiscovery()
//Once you find the device you want, either by advertisement data or address data, then call
CyBle_GapcStopDiscovery()
//next connect to the device you want to
CyBle_GapcConnectDevice()
//then discover the primary services of the device
CyBle_GattcDiscoverPrimaryServiceByUuid()
//then discover all the characteristics of the service you want attributes for
CyBle_GattcDiscoverAllCharacteristics()
//You should now have handles for the services, attributes, and the device that you are interested in.
Events you will need to handle in the BLE callback handler:
//handle discovered devices to determine if you found the one(s) you want
case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT:
//standard events for BLE examples
case CYBLE_EVT_STACK_ON:
case CYBLE_EVT_GAP_DEVICE_CONNECTED:
case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
//signals the start or stop of advertising/scanning (depending on if you have central/peripheral)
case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
case CYBLE_EVT_GAPC_SCAN_START_STOP:
//Events for connection parameter changes
case CYBLE_EVT_GAP_SMP_NEGOTIATED_AUTH_INFO:;
case CYBLE_EVT_GAP_ENCRYPT_CHANGE:;
case CYBLE_EVT_GATTS_XCNHG_MTU_REQ:
//Events to handle the authentication part of the connection
case CYBLE_EVT_GAP_AUTH_REQ: //CyBle_GapAuthReq() is the API to initiate encryption for the connection
case CYBLE_EVT_GAP_AUTH_COMPLETE: //if encryption succeeded
case CYBLE_EVT_GAP_AUTH_FAILED: //if encryption failed
//service handle from unit
case CYBLE_EVT_GATTC_FIND_BY_TYPE_VALUE_RSP:;
//characteristic handles from service
case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP:;
//Used for detecting GATTC error, or when finished discovering services/characteristics
case CYBLE_EVT_GATTC_ERROR_RSP:;
//You don't necessarily need to handle the EVT_HCI status, but it will be useful for detecting errors and development
case CYBLE_EVT_HCI_STATUS:;
//you don't necessarily need to handle the timeout, but you should
case CYBLE_EVT_TIMEOUT:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
thank you for your reply.
At which point should i call the CyBle_GapAuthReq() function to begin the pairing process?
Upon successful GATT connection or after discovering services and characteristics?
I do have a successful GAP central / GATT client project working just without the pairing, so a lot of what you've written makes sense.
I appreciate your time.
kind regards,
Damian
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Damian,
Depending on your application, you may want to try accessing data,etc. without encryption, for which case you would only do the CyBle_GapAuthReq() when you need it. If you want the entire connection encrypted (start-to-finish), then you will probably want to call it after receiving the CYBLE_EVT_GAP_DEVICE_CONNECTED event (I call it directly inside the callback handler for that event and it's happy with it, but however you want)
Keep in mind however, that the peripheral may request authentication/encryption in response to a request. This is why I included the CYBLE_EVT_GAP_AUTH_REQ event as one of the ones you should handle.
The auth/encrypt will stay active until a CYBLE_EVT_GAP_ENCRYPT_CHANGE event occurs to change the settings, or until you disconnect/get disconnected from the device. Note: you will want to make sure the BLE attributes are set to encryption/pairing required for access if you want to prevent unencrypted communication of data over the connection.
Pratt
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Pratt,
Sorry for the delay, i've only now had a chance to experiment.
Ok so i've set my project to discover services and characteristics.
Then i call CyBle_GapAuthReq() with the following parameters:
authData.security = (CYBLE_GAP_SEC_MODE_1 | CYBLE_GAP_SEC_LEVEL_2);
authData.bonding = CYBLE_GAP_BONDING_NONE;
authData.ekeySize = 7;
authData.pairingProperties = 0;
i wasn't sure what to set the ekeySize and pairingProperties to.
sure enough i'm receiving an error: Invalid parameter.
any thoughts?
kind regards,
Damian
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Damian,
no worries for the delay; I get busy and can't reply sometimes too
I believe I set the settings under the BLE component, and then used the cyBle_authInfo() to get the "default" settings. I didn't have a need for more than one security setting, but I'm sure you can modify it without problems
Here's the current default settings that I saw:
CYBLE_GAP_AUTH_INFO_T cyBle_authInfo =
{
(CYBLE_GAP_SEC_MODE_1 | CYBLE_GAP_SEC_LEVEL_2 ), /* uint8 security */
CYBLE_GAP_BONDING, /* uint8 bonding */
0x10u, /* uint8 ekeySize */
CYBLE_GAP_AUTH_ERROR_NONE, /* CYBLE_AUTH_FAILED_REASON_T authErr */
0x00u, /* uint8 pairingProperties */
};
You can find this under the BLE_eventHandler.c file at about line 222.
One thing to note; I believe there was a limitation with the BLE implementation so that you had to have bonding enabled in order to use pairing, thus forcing you to deal with bonding even though it isn't something that you necessarily would want. Try enabling the bonding and adding a layer/handler for the bonding operations and see if that makes it work fully.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Pratt,
thanks for all your help - finally it worked out.
The main issue was due to me not setting the authErr parameter, which the data sheet says you can ignore.
Quote below:
"The 'authErr' parameter in
CYBLE_GAP_AUTH_INFO_T should be ignored as it is not used in this
function"
Once i set this to CYBLE_GAP_AUTH_ERROR_NONE as you suggested it was fine.
On a side note i found i could set the bonding to CYBLE_GAP_BONDING_NONE and it worked for me.
thanks again and all the best,
Damian
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Damian,
Hmmm; I'll have to remember that the "ignored" error isn't truly ignored
Huh, I'll have to look into the pairing not requiring bonding anymore; Pragmatically, that would be a pretty silly requirement, but I guess I was thinking of the standard applications where you want bonded devices 😕
Glad you got it all figured out, and happy hunting
Pratt
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
did it work for you?
Chris
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Damian, thanks for an awesome example, my questions is the KEY?
We have a peripheral with fixed passkey, our mobile app connects and works fine, our customer requested a key fob (I know, why?, but hey its their dime) so it has to be a central, and again your example is awesome.
So where in the embedded code on the central device, do I place the same pass key? I am sure it is obvious, but I just am not seeing it!