2 Replies Latest reply on Jul 26, 2016 7:41 AM by user_257403943

    How to limit server to bonding with just one client?


      On the BLE 4.2 component Configure dialog I have the following set on the GAP Security page:


      Security mode: Mode 1; Security level: Unauthenticated pairing with encryption; I/O capabilities: No Input No Output; Bonding requirement: Bonding.


      I want to set Maximum bonded devices: 1, but for some reason that setting is fixed at 4 and grayed out. The data sheet says this setting is enabled only when Bonding is enabled, and that it is not available in "the BLE v3.10" (sic). So it should be available, but it is not!


      I also tried to do it in code: use CyBle_GapGetBondedDevicesList to get the count of bound devices with a view to declining the bond request if it is > 0. This works fine, except I cannot work out how to decline the request! CYBLE_EVT_GAP_AUTH_REQ gets triggered in my event handler, but even if I set the 'authErr' code in eventParam the pairing still completes and I have two devices in the bonded list. If this did prevent bonding, I'm not sure that would work anyway since CYBLE_EVT_GAP_AUTH_REQ seems to get triggered when a device already in the bonded list gets re-connected as well.


      What I am trying to achieve is to set a bonding between one client and one server without requiring a passkey etc. To bond a server to a new client, you have to delete the existing bonding record in the server, requiring physical access, but it looks like the only way to achieve that is to bond with three additional devices and then lock them away in a drawer so the fixed size bond list is full!


      Can anyone give me a way forward on this?

        • 1. Re: How to limit server to bonding with just one client?
          Madhu Lakshmipathy



          Once, you have bonded with the expected device, you can simple set the cyBle_authInfo.bonding =  CYBLE_GAP_BONDING_NONE;




          - Madhu Sudhan

          • 2. Re: How to limit server to bonding with just one client?

            Thanks again Madhu.


            However I note that this is not documented in the API help file.


            I took the following alternative approach in the end:


            In configuration/GAP Settings/Advertisement settings set Filter Policy: 'Scan request: Any | Connect request: White list'.


            In CYBLE_EVT_GAP_AUTH_COMPLETE: and CYBLE_EVT_STACK_ON: Used CyBle_GapGetBondedDevicesList and CyBle_GapAddDeviceToWhiteList to copy the device address from the bond list to the white list.


            Copied the API function CyBle_GappStartAdvertisement into my own version and modified it as follows:


            uint8 blegcp_advFilterPolicy = 0xFFu;
            CYBLE_API_RESULT_T blegcp_GappStartAdvertisement(uint8 advertisingIntervalType, uint8 bypassFilter)
                CYBLE_API_RESULT_T apiResult;
                // JH: Added these lines to version copied from the API:
                if (blegcp_advFilterPolicy == 0xFFu) blegcp_advFilterPolicy = cyBle_discoveryModeInfo.advParam->advFilterPolicy;
                cyBle_discoveryModeInfo.advParam->advFilterPolicy = (bypassFilter)? CYBLE_GAPP_SCAN_ANY_CONN_ANY : blegcp_advFilterPolicy;
                // ****
                if(advertisingIntervalType > CYBLE_ADVERTISING_CUSTOM)
                    apiResult = CYBLE_ERROR_INVALID_PARAMETER;
                else if((CYBLE_STATE_DISCONNECTED == CyBle_GetState()) && ((cyBle_eventHandlerFlag & CYBLE_START_FLAG) == 0u))
                    if(advertisingIntervalType == CYBLE_ADVERTISING_FAST)
                        cyBle_discoveryModeInfo.advTo = CYBLE_FAST_ADV_TIMEOUT;
                        cyBle_discoveryModeInfo.advParam->advIntvMin = CYBLE_FAST_ADV_INT_MIN;
                        cyBle_discoveryModeInfo.advParam->advIntvMax = CYBLE_FAST_ADV_INT_MAX;
                    else if(advertisingIntervalType == CYBLE_ADVERTISING_SLOW)
                        cyBle_discoveryModeInfo.advTo = CYBLE_SLOW_ADV_TIMEOUT;
                        cyBle_discoveryModeInfo.advParam->advIntvMin = CYBLE_SLOW_ADV_INT_MIN;
                        cyBle_discoveryModeInfo.advParam->advIntvMax = CYBLE_SLOW_ADV_INT_MAX;
                    else /* Do not update advertising intervals */
                    cyBle_advertisingIntervalType = advertisingIntervalType;
                    apiResult = CyBle_GappEnterDiscoveryMode(&cyBle_discoveryModeInfo);
                    if(CYBLE_ERROR_OK == apiResult)
                        cyBle_eventHandlerFlag |= CYBLE_START_FLAG;
                    apiResult = CYBLE_ERROR_INVALID_STATE;
                return (apiResult);

            Now I can override the filter when the bond list is empty and apply it as set in configuration when the bond has already been made, preventing any other device from connecting and therefore from bonding.


            It is irritating though that one cannot do this sort of stuff through the published API. I found (the hard way) that you have to set a Filter policy using the white list in configuration otherwise CyBle_GapAddDeviceToWhiteList fails, so you cannot start without a filter policy and then set one once bonded, which would have been more natural.


            - John