This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2640: Missing to find Broadcaster while observing.

Part Number: CC2640

Hi all,

I am using CC2640 observer code for Accessing the Advertisement of Broadcaster. Here Broadcaster Broadcasts Advertisement after every 1 Sec.

Observer is Scanning for the duration of 100msec. And interval of scanning is 1 msec. Means after scanning if observer is not able to find broadcaster then within 1msec it needs to start scan again.

Here observer is able to find the broadcaster, but it may miss out of 10 at 2 times. And as a programmer i don't want any missing of finding the observer advertisement. 

I checked the broadcaster advertisement on the sniffer tool, it advertised as per requirement, but observer is not able to found the exact broadcaster.

Even i checked the scanning also in the sniffer tool. it is also fine according to sets values. 

So, here observer why its missing the getting the advertisement from broadcaster?

Thanks.

Anil D.

  • Anil,

    What version of the SDK are you using?

    What scanning and advertising parameters are you using? To be sure to catch all advertisements the scan window should be greater than the advertisment interval. Read more here: dev.ti.com/.../ble_scan_adv_basic.html

    Are you scanning on all three channels as well as advertising on all three channels?
  • Hello Evan,

    I am using Simplelink_CC2640r2_sdk_1_40_00_45 SDk for programming of Observer and broadcaster code too.

    I think i already Mention Parameters for Observer............
    1) DEFAULT_SCAN_DURATION                        100                        means its 100msec
    2) DEFAULT_DISCOVERY_MODE                     DEVDISC_MODE_ALL
    3) DEFAULT_DISCOVERY_ACTIVE_SCAN       FALSE
    4) DEFAULT_DISCOVERY_WHITE_LIST           FALSE
    5) DEFAULT_SCAN_INTERVAL                         10                          means its a 10msec


    Broadcaster Parameter.........
    It broadcasts Advertisement for every 10sec , I checked for 1 sec too.

    But observer may missed to get every advertisement.


    And as you are saying that "to catch all advertisement the scan window should be greater than the Advertisement interval". But Observer is not interested for each device which is in range of observer. Observer only takes care of specific Broadcaster means that for specific
    broadcaster only observer don't wants to miss any advertisement. Observer should catch all advertisement of a specific Broadcaster.

    How can i Confirm that Observer is scanning on all three channels as well as advertising on all three channels?



    Thanks,
    Anil D.

  • Anil,

    You can find the channel map setting in broadcaster.c in the function gapRole_init. gapRoleAdvChanMap is the variable.

    A few questions to clear up, are you trying to do directed advertising or undirected advertising? Your wording around saying "specific broadcaster" makes me wonder if you are trying to do directed advertising. 

    Also, you have not provided your scan window setting. The scan window represents how long the device scans on each channel. Setting the scan window larger than the advertising interval should thus ensure that all advertisement packets are received. Make sure that your scan window (DEFAULT_SCAN_WINDOW in simple_observer.c) is larger than your advertising interval set by the variable DEFAULT_ADVERTISING_INTERVAL in your simple_broadcaster.c file. 

  • Evan,

    1) I checked the Advertisement channels, its says "GAP_ADVCHAN_ALL", Means it taken all channels to advertise.

    2) Observer may found 1,2,3,4 .......8 Broadcasters nearby. so it may sense all. But here as a Developer my intention to Catch only specific Advertisement which is i required. Its OK to get Device Info of all, but i don't want to miss the specific Broadcasters Advertisement. If Advertisement is 10 Sec then also observer needs to catch the specific advertisement for every 10 sec.

    3) Here in the Observer code there is no term of DEFAULT_SCAN_WINDOW. Default code i have taken from the SDK which is mentioned above. So can you please provide a more details regarding to the DEFAULT_SCAN_WINDOW, like where i need to define and where i need to call to add this?
    DEFAULT_ADVERTISING_INTERVAL 16000 means its 10 sec.


    Major thing is observer don't bother about all device, My intention to do the program like to catch every advertisement of a SPECIFIC device(Broadcaster) . I don't care about all other nearby advertisements.

    Regards,
    Anil
  • Anil,

    My apologies. I was referencing code in a project that I had modified.

    Basically, i recommend that you modify simple_observer similarly to the way we recommend in Task 1 of Scanning in the scanning and advertising lab I linked.
    dev.ti.com/.../ble_scan_adv_basic.html

    Create a variable for SCAN_INTERVAL and SCAN_WINDOW and set them appropriately.

    In SimpleBLEObserver_init(), you can use GAP_SetParamValue() to modify TGAP_GEN_DISC_SCAN_WIND and TGAP_GEN_DISC_SCAN_INT and others to move away from using the default values. here you can set your scan window to be as larger or larger than your advertising interval so you can be sure to catch all the advertisements as the advertiser will be on three different channels in those 10 seconds.

    You will probably need to change your scan duration to 0 to scan indefinitely as well as currently it's set to only be on for 100ms. (re, Scanning Task 3 in the SLA).

    With regards to your last point on only caring about specific broadcasters, you will either need to utilize a whitelist and manually add it to the whitelist, or you will need to handle it in your application layer some how.
  • EVAN,

    According to your explanation i did programming, but i didn't get the advertisement of broadcaster. So let me explain you about my project.

    See Near By Observer there are several Broadcasters are available. But as a Observer i can search up to 8(as per the Example given in the SDK) .
    But Observer intention to sense only specific Broadcasters advertisement and do some operation according. But if supposed that observer may miss to catch the particular observers advertisement then observer could not able to take decision for the particular time. So here my requirement is that to not miss a single advertisements of specific broadcaster.

    Now also with the below settings observer is able to get the advertisement but it may miss some time. And that only i don't want.

    Settings for Observer :
    TGAP_GEN_DISC_SCAN 50 means its 50 msec
    TGAP_LIM_DISC_SCAN 50 means its 50 msec
    TGAP_GEN_DISC_SCAN_INT 48 means its 48*0.625msec = 30 msec
    TGAP_LIM_DISC_SCAN_INT 48 means its 48*0.625msec = 30 msec
    TGAP_GEN_DISC_SCAN_WIND 48 means its 48*0.625msec = 30 msec
    TGAP_LIM_DISC_SCAN_WIND 48 means its 48*0.625msec = 30 msec

    And i am running one clock(Timer ) for after 100msec i need to call again "GAPObserverRole_StartDiscovery" Function if observer is not able to get a specific Broadcaster and even able to get also i am starting again scanning(StartDiscovering).

    Broadcaster is broadcasting advertisement interval for every 10 sec.

    As per you are saying that keep the scan window more than Broadcasters advertisement interval, if i kept that things its not working properly(Means Observer not able to detect also).

    And as you are saying that related to White List. I also tried with While list. Like by keeping..in Observer
    DEFAULT_DISCOVERY_WHITE_LIST TRUE
    but then also Observer is not able to get the advertisement.


    Can you give me a another solution for my this situations.

    Regards,
    Anil
  • Anil,

    Thanks for trying that. Let's try something else then.

    Can you adjust your advertising interval to be shorter? As in, advertise more frequently. I'm concerned that the following may be happening:

    1) You may be reaching your max number of scanned devices in your duration.

    2) Since advertising and scanning is an opportunistic event, you can't guarantee that all advertising events from a specific advertiser can be caught, especially in a noisy environment. If you have anything else advertising around it, each time you receive an event from an advertiser, you have to add it to the scan report, and this takes time. While you do this processing, you can't listen for other advertising events until youre done processing.

    While you can't guarantee it, you can increase the probability of seeing the advertising event you want. To do this, increase your advertising interval and try to utilize the white list. To the whitelist portion of your post, are you adding the device you want to see to the whitelist via something similar to the code below?

    static void SimpleBLEPeripheral_init(void)
    {
    // ...
    // === SOLUTION [Change filter policy] ===
      //set ADV filter policy to allow scan and connect request from white list only
      uint8_t advFilterPolicy = GAP_FILTER_POLICY_WHITE;
    
      static uint8 bdAddressPeer[6] = {0x00,0x90,0x78,0x56,0x34,0x12};
      HCI_LE_AddWhiteListCmd(ADDRMODE_PUBLIC, bdAddressPeer);
    
      GAPRole_SetParameter(GAPROLE_ADV_FILTER_POLICY, sizeof(uint8_t), &advFilterPolicy);
    
    // ==== END SOLUTION ====
      // Set the GAP Characteristics
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    // ...
  • Evan,

    Thanks for the Suggestions, just go through the attached code. Still i am trying to do by your and mine way, But just look at the code.

    ..

    /******************************************************************************
    
     @file       simple_observer.c
    
     @brief This file contains the Simple Observer sample application for use
            with the CC2650 Bluetooth Low Energy Protocol Stack.
    
     Group: CMCU, SCS
     Target Device: CC2640R2
    
     ******************************************************************************
    
     Copyright (c) 2011-2017, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
     Release Name: simplelink_cc2640r2_sdk_1_40_00_45
     Release Date: 2017-07-20 17:16:59
     *****************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/display/Display.h>
    
    #include <icall.h>
    #include "util.h"
    /* This Header file contains all BLE API and icall structure definition */
    #include "icall_ble_api.h"
    
    #include "observer.h"
    #include "board_key.h"
    #include "board.h"
    #include "UARTAPP.h"
    
    #include "simple_observer.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    // Maximum number of scan responses
    #define DEFAULT_MAX_SCAN_RES                  8
    
    // Scan duration in ms
    #define DEFAULT_SCAN_DURATION                 50
    
    //n*0.625mSec Scanning window for scanning each channel for this time
    #define DEFAULT_SCAN_WINDOW                   48
    
    //n*0.625mSec Scanning Interval between 2 channels
    #define DEFAULT_SCAN_INT                      48
    
    // Discovery mode (limited, general, all)
    #define DEFAULT_DISCOVERY_MODE                DEVDISC_MODE_ALL
    
    // TRUE to use active scan
    #define DEFAULT_DISCOVERY_ACTIVE_SCAN         FALSE
    
    // TRUE to use white list during discovery
    #define DEFAULT_DISCOVERY_WHITE_LIST          FALSE
    
    // Type of Display to open
    #if !defined(Display_DISABLE_ALL)
    #if defined(BOARD_DISPLAY_USE_LCD) && (BOARD_DISPLAY_USE_LCD!=0)
    #define SBO_DISPLAY_TYPE Display_Type_LCD
    #elif defined (BOARD_DISPLAY_USE_UART) && (BOARD_DISPLAY_USE_UART!=0)
    #define SBO_DISPLAY_TYPE Display_Type_UART
    #else // !BOARD_DISPLAY_USE_LCD && !BOARD_DISPLAY_USE_UART
    #define SBO_DISPLAY_TYPE 0 // Option not supported
    #endif // BOARD_DISPLAY_USE_LCD && BOARD_DISPLAY_USE_UART
    #else // BOARD_DISPLAY_USE_LCD && BOARD_DISPLAY_USE_UART
    #define SBO_DISPLAY_TYPE 0 // No Display
    #endif // Display_DISABLE_ALL
    
    // Task configuration
    #define SBO_TASK_PRIORITY                     1
    
    #ifndef SBO_TASK_STACK_SIZE
    #define SBO_TASK_STACK_SIZE                   660
    #endif
    
    #define SBO_STATE_CHANGE_EVT                  0x0001
    #define SBO_KEY_CHANGE_EVT                    0x0002
    
    // Internal Events for RTOS application
    #define SBO_ICALL_EVT                         ICALL_MSG_EVENT_ID // Event_Id_31
    #define SBO_QUEUE_EVT                         UTIL_QUEUE_EVENT_ID // Event_Id_30
    #define SBO_ATT_Scanning_EVT                  Event_Id_03           // Event for Scanning
    #define SBO_ATT_Decision_EVT                  Event_Id_04           // Event for Decision taking
    
    #define SBO_ALL_EVENTS                        (SBO_ICALL_EVT | SBO_QUEUE_EVT | SBO_ATT_Scanning_EVT  | SBO_ATT_Decision_EVT)
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from profiles.
    typedef struct
    {
        appEvtHdr_t hdr; // event header
        uint8_t *pData;  // event data
    } sboEvt_t;
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    
    // Display Interface
    Display_Handle dispHandle = NULL;
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    static ICall_SyncHandle syncEvent;
    
    // Clock object used to signal timeout
    static Clock_Struct keyChangeClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    // Task configuration
    Task_Struct sboTask;
    Char sboTaskStack[SBO_TASK_STACK_SIZE];
    
    // GAP GATT Attributes
    //static const uint8 simpleBLEDeviceName[GAP_DEVICE_NAME_LEN] = "Simple Observer";
    
    // Number of scan results and scan result index
    static uint8 scanRes = 0 ;
    static int8 scanIdx = -1;
    
    // Scan result list
    static gapDevRec_t devList[DEFAULT_MAX_SCAN_RES];
    
    // Scanning state
    static uint8 scanning = FALSE;
    
    Clock_Struct Scanning_Interval_Clock;
    Clock_Struct Decision_taking_Clock;
    
    //Default ATT_Scanning_DELAY in ms
    #define DEFAULT_ATT_Scanning_DELAY           1
    
    //Default ATT_Decision_taking_DELAY in ms
    #define DEFAULT_ATT_Decision_DELAY           30000
    
    uint8 Peripheral_MAC_ID[6] = {0};
    char KEYCHAIN_MAC_ID[6]={0};
    char MAC_ID_COUNT=0;
    extern bool Kaychain_ID;
    int Scan_Count=0;
    static bool Device_found=0;
    int count=0;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void SimpleBLEObserver_init(void);
    static void SimpleBLEObserver_taskFxn(UArg a0, UArg a1);
    
    static void SimpleBLEObserver_handleKeys(uint8_t shift, uint8_t keys);
    static void SimpleBLEObserver_processStackMsg(ICall_Hdr *pMsg);
    static void SimpleBLEObserver_processAppMsg(sboEvt_t *pMsg);
    static void SimpleBLEObserver_processRoleEvent(gapObserverRoleEvent_t *pEvent);
    static void SimpleBLEObserver_addDeviceInfo(uint8 *pAddr, uint8 addrType);
    
    static uint8_t SimpleBLEObserver_eventCB(gapObserverRoleEvent_t *pEvent);
    
    static uint8_t SimpleBLEObserver_enqueueMsg(uint8_t event, uint8_t status,
                                                uint8_t *pData);
    
    void SimpleBLEObserver_initKeys(void);
    
    void SimpleBLEObserver_keyChangeHandler(uint8 keys);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static const gapObserverRoleCB_t simpleBLERoleCB =
    {
     SimpleBLEObserver_eventCB  // Event callback
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_createTask
     *
     * @brief   Task creation function for the Simple Observer.
     *
     * @param   none
     *
     * @return  none
     */
    void SimpleBLEObserver_createTask(void)
    {
        Task_Params taskParams;
    
        // Configure task
        Task_Params_init(&taskParams);
        taskParams.stack = sboTaskStack;
        taskParams.stackSize = SBO_TASK_STACK_SIZE;
        taskParams.priority = SBO_TASK_PRIORITY;
    
        Task_construct(&sboTask, SimpleBLEObserver_taskFxn, &taskParams, NULL);
    }
    
    
    
    void SimpleBLEObserver_ATT_Scanning_HANDLER(UArg a0)
    {
        Event_post(syncEvent, SBO_ATT_Scanning_EVT);
    }
    
    
    void SimpleBLEObserver_ATT_Decision_HANDLER(UArg a0)
    {
        Event_post(syncEvent, SBO_ATT_Decision_EVT);
    }
    
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_init
     *
     * @brief   Initialization function for the Simple Observer App Task.
     *          This is called during initialization and should contain
     *          any application specific initialization (ie. hardware
     *          initialization/setup, table initialization, power up
     *          notification).
     *
     * @param   none
     *
     * @return  none
     */
    void SimpleBLEObserver_init(void)
    {
        Uart_Init();
    
        UART_write(uart, "iBot\n" , 5);
        // ******************************************************************
        // NO STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
        // ******************************************************************
        // Register the current thread as an ICall dispatcher application
        // so that the application can send and receive messages.
        ICall_registerApp(&selfEntity, &syncEvent);
    
        // Hard code the DB Address till CC2650 board gets its own IEEE address
        //uint8 bdAddress[B_ADDR_LEN] = { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 };
        //HCI_EXT_SetBDADDRCmd(bdAddress);
    
        // Create an RTOS queue for message from profile to be sent to app.
        appMsgQueue = Util_constructQueue(&appMsg);
    
        Board_initKeys(SimpleBLEObserver_keyChangeHandler);
    
        Util_constructClock(&Scanning_Interval_Clock, SimpleBLEObserver_ATT_Scanning_HANDLER,DEFAULT_ATT_Scanning_DELAY, 0, false, SBO_ATT_Scanning_EVT);       // Event for Scanning peripheral
    
        Util_constructClock(&Decision_taking_Clock, SimpleBLEObserver_ATT_Decision_HANDLER,DEFAULT_ATT_Decision_DELAY, 0, false, SBO_ATT_Decision_EVT);       // Event for Decision taking peripheral
    
        dispHandle = Display_open(SBO_DISPLAY_TYPE, NULL);
    
        // Setup Observer Profile
        {
            uint8 scanRes = DEFAULT_MAX_SCAN_RES;
            GAPObserverRole_SetParameter(GAPOBSERVERROLE_MAX_SCAN_RES, sizeof(uint8_t),
                                         &scanRes );
        }
    
        // Setup GAP
        GAP_SetParamValue(TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION);
        GAP_SetParamValue(TGAP_LIM_DISC_SCAN, DEFAULT_SCAN_DURATION);
    
        GAP_SetParamValue(TGAP_GEN_DISC_SCAN_INT, DEFAULT_SCAN_INT);
        GAP_SetParamValue(TGAP_LIM_DISC_SCAN_INT, DEFAULT_SCAN_INT);
    
        GAP_SetParamValue(TGAP_LIM_DISC_SCAN_WIND, DEFAULT_SCAN_WINDOW);
        GAP_SetParamValue(TGAP_GEN_DISC_SCAN_WIND, DEFAULT_SCAN_WINDOW);
    
        // Start the Device
        VOID GAPObserverRole_StartDevice((gapObserverRoleCB_t *)&simpleBLERoleCB);
    
        Display_print0(dispHandle, 0, 0, "BLE Observer");
    
        Util_startClock( &Scanning_Interval_Clock);
        Util_startClock( &Decision_taking_Clock);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_taskFxn
     *
     * @brief   Application task entry point for the Simple Observer.
     *
     * @param   none
     *
     * @return  none
     */
    static void SimpleBLEObserver_taskFxn(UArg a0, UArg a1)
    {
    
        // Initialize application
        SimpleBLEObserver_init();
    
        // Application main loop
        for (;;)
        {
            uint32_t events;
    
            events = Event_pend(syncEvent, Event_Id_NONE, SBO_ALL_EVENTS,
                                ICALL_TIMEOUT_FOREVER);
    
            if (events)
            {
                ICall_EntityID dest;
                ICall_ServiceEnum src;
                ICall_HciExtEvt *pMsg = NULL;
    
                if (ICall_fetchServiceMsg(&src, &dest,
                                          (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
                {
                    if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
                    {
                        // Process inter-task message
                        SimpleBLEObserver_processStackMsg((ICall_Hdr *)pMsg);
                    }
    
                    if (pMsg)
                    {
                        ICall_freeMsg(pMsg);
                    }
                }
            }
    
            // If RTOS queue is not empty, process app message
            if (events & SBO_QUEUE_EVT)
            {
                while (!Queue_empty(appMsgQueue))
                {
                    sboEvt_t *pMsg = (sboEvt_t *)Util_dequeueMsg(appMsgQueue);
                    if (pMsg)
                    {
                        // Process message
                        SimpleBLEObserver_processAppMsg(pMsg);
    
                        // Free the space from the message
                        ICall_free(pMsg);
                    }
                }
            }
    
    
            if (events & SBO_ATT_Scanning_EVT)
            {
                Device_found = 0;
                events &= ~SBO_ATT_Scanning_EVT;
                Util_stopClock( &Scanning_Interval_Clock);
    
                GAPObserverRole_StartDiscovery(DEFAULT_DISCOVERY_MODE,
                                               DEFAULT_DISCOVERY_ACTIVE_SCAN,
                                               DEFAULT_DISCOVERY_WHITE_LIST);
    
                count++;
           }
    
            if (events & SBO_ATT_Decision_EVT)              // EVent For "If Slave not available for 30 sec then say KEY missing
            {
                Util_stopClock( &Decision_taking_Clock);
                UART_write(uart,"KEY_MISS",8);
                UART_write(uart,"\n",1);
                Util_startClock( &Decision_taking_Clock);
    
           }
        }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_processStackMsg
     *
     * @brief   Process an incoming task message.
     *
     * @param   pMsg - message to process
     *
     * @return  none
     */
    static void SimpleBLEObserver_processStackMsg(ICall_Hdr *pMsg)
    {
        switch (pMsg->event)
        {
        case GAP_MSG_EVENT:
            SimpleBLEObserver_processRoleEvent((gapObserverRoleEvent_t *)pMsg);
            break;
    
        default:
            break;
        }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_processAppMsg
     *
     * @brief   Central application event processing function.
     *
     * @param   pMsg - pointer to event structure
     *
     * @return  none
     */
    static void SimpleBLEObserver_processAppMsg(sboEvt_t *pMsg)
    {
        switch (pMsg->hdr.event)
        {
        case SBO_STATE_CHANGE_EVT:
            SimpleBLEObserver_processStackMsg((ICall_Hdr *)pMsg->pData);
    
            // Free the stack message
            ICall_freeMsg(pMsg->pData);
            break;
    
        case SBO_KEY_CHANGE_EVT:
            SimpleBLEObserver_handleKeys(0, pMsg->hdr.state);
            break;
    
        default:
            // Do nothing.
            break;
        }
    }
    
    char hexDigit(unsigned n)
    {
        if (n < 10)
            return n + '0';
        else
            return (n - 10) + 'A';
    }
    
    void charToHex(char c,char Length)
    {
        char hex[3]={0};
        hex[0] = hexDigit(c / 0x10);
        hex[1] = hexDigit(c % 0x10);
    
        UART_write(uart, hex , Length*2);
    
    }
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_processRoleEvent
     *
     * @brief   Observer role event processing function.
     *
     * @param   pEvent - pointer to event structure
     *
     * @return  none
     */
    static void SimpleBLEObserver_processRoleEvent(gapObserverRoleEvent_t *pEvent)
    {
        uint8 KDS[31]={0};
        char buffer[3]={0};
        char UART_MAC_ID[3]={0};
    
        switch ( pEvent->gap.opcode )
        {
        case GAP_DEVICE_INIT_DONE_EVENT:
        {
            Display_print0(dispHandle, 1, 0, Util_convertBdAddr2Str(pEvent->initDone.devAddr));
            Display_print0(dispHandle, 2, 0, "Initialized");
    
            // Prompt user to begin scanning.
            Display_print0(dispHandle, 5, 0, "Discover ->");
        }
        break;
    
        case GAP_DEVICE_INFO_EVENT:
        {
            SimpleBLEObserver_addDeviceInfo(pEvent->deviceInfo.addr,
                                            pEvent->deviceInfo.addrType);
    
            osal_snv_read(0x81, 3, UART_MAC_ID);
            if(UART_MAC_ID[0] == '1')
            {
                osal_snv_read(0x80, 6, KEYCHAIN_MAC_ID);
            }
    
    
            memset(KDS,0x00,sizeof(KDS));
            memcpy(KDS,pEvent->deviceInfo.pEvtData,pEvent->deviceInfo.dataLen);                                  //here i am checking for the Advertisement data
    
    //        if(( memcmp(KEYCHAIN_MAC_ID,pEvent->deviceInfo.addr,6) == 0))
    //        {
    //            charToHex(pEvent->deviceInfo.addr[5], 1);
    //            charToHex(pEvent->deviceInfo.addr[4], 1);
    //            charToHex(pEvent->deviceInfo.addr[3], 1);
    //            charToHex(pEvent->deviceInfo.addr[2], 1);
    //            charToHex(pEvent->deviceInfo.addr[1], 1);
    //            charToHex(pEvent->deviceInfo.addr[0], 1);
    //            UART_write(uart,"\n",1);
    //        }
    
            if((memcmp(KDS+5,"KDS",3)==0) && (UART_MAC_ID[0] == '1') && (( memcmp(KEYCHAIN_MAC_ID,pEvent->deviceInfo.addr,6) == 0)))                // Searching for KDS data here
            {
                ltoa(count,buffer);
                UART_write(uart,buffer,strlen(buffer));
                UART_write(uart,"\n",1);
                count=0;
    
    
                if((pEvent->deviceInfo.rssi) < -90 )
                {
                    UART_write(uart,"KEY_MISS",8);
                    UART_write(uart,"\n",1);
    //                break;
                }
    //            memcpy(Peripheral_MAC_ID,pEvent->deviceInfo.addr,6);
    //            UART_write(uart, "KDS\n" , 5);
    
                int32 My_RSSI = (pEvent->deviceInfo.rssi);
                UART_write(uart, "RSSI: " , 6);              // According to Advertisement I need to check for Distance here.
                ltoa(My_RSSI,buffer);
                UART_write(uart, buffer , strlen(buffer));
                UART_write(uart,"\n",1);
                UART_write(uart, "Volt: " , 6);
                UART_write(uart,KDS+8, 3);
                UART_write(uart,"\n",1);
                Device_found = 1;
    
                Util_startClock( &Scanning_Interval_Clock);
    
                Util_stopClock( &Decision_taking_Clock);
                Util_startClock( &Decision_taking_Clock);
    
            }
                Util_startClock( &Scanning_Interval_Clock);
        }
        break;
    
        case GAP_DEVICE_DISCOVERY_EVENT:
        {
            if(!Device_found)
            {
                Util_startClock( &Scanning_Interval_Clock);
            }
    
            // Discovery complete.
            scanning = FALSE;
    
            // Copy results.
            scanRes = pEvent->discCmpl.numDevs;
            memcpy(devList, pEvent->discCmpl.pDevList,
                   (sizeof(gapDevRec_t) * pEvent->discCmpl.numDevs));
    
            Display_print1(dispHandle, 2, 0, "Devices Found %d", scanRes);
    
            if ( scanRes > 0 )
            {
                Display_print0(dispHandle, 3, 0, "<- To Select");
            }
    
           // Initialize scan index.
            scanIdx = -1;
    
            // Prompt user that re-performing scanning at this state is possible.
            Display_print0(dispHandle, 5, 0, "Discover ->");
    
        }
        break;
    
        default:
            break;
        }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_eventCB
     *
     * @brief   Observer event callback function.
     *
     * @param   pEvent - pointer to event structure
     *
     * @return  TRUE if safe to deallocate event message, FALSE otherwise.
     */
    static uint8_t SimpleBLEObserver_eventCB(gapObserverRoleEvent_t *pEvent)
    {
        // Forward the role event to the application
        if (SimpleBLEObserver_enqueueMsg(SBO_STATE_CHANGE_EVT,
                                         SUCCESS, (uint8_t *)pEvent))
        {
            // App will process and free the event
            return FALSE;
        }
    
        // Caller should free the event
        return TRUE;
    }
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_addDeviceInfo
     *
     * @brief   Add a device to the device discovery result list
     *
     * @return  none
     */
    static void SimpleBLEObserver_addDeviceInfo(uint8 *pAddr, uint8 addrType)
    {
        uint8 i;
    
        // If result count not at max
        if ( scanRes < DEFAULT_MAX_SCAN_RES )
        {
            // Check if device is already in scan results
            for ( i = 0; i < scanRes; i++ )
            {
                if (memcmp(pAddr, devList[i].addr, B_ADDR_LEN) == 0)
                {
                    return;
                }
            }
    
            // Add addr to scan result list
            memcpy(devList[scanRes].addr, pAddr, B_ADDR_LEN );
            devList[scanRes].addrType = addrType;
    
            // Increment scan result count
            scanRes++;
        }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_keyChangeHandler
     *
     * @brief   Key event handler function
     *
     * @param   keys pressed
     *
     * @return  none
     */
    void SimpleBLEObserver_keyChangeHandler(uint8 keys)
    {
        SimpleBLEObserver_enqueueMsg(SBO_KEY_CHANGE_EVT, keys, NULL);
    }
    
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event - message event.
     * @param   state - message state.
     * @param   pData - message data pointer.
     *
     * @return  TRUE or FALSE
     */
    static uint8_t SimpleBLEObserver_enqueueMsg(uint8_t event, uint8_t state,
                                                uint8_t *pData)
    {
        sboEvt_t *pMsg;
    
        // Create dynamic pointer to message.
        if (pMsg = ICall_malloc(sizeof(sboEvt_t)))
        {
            pMsg->hdr.event = event;
            pMsg->hdr.state = state;
            pMsg->pData = pData;
    
            // Enqueue the message.
            return Util_enqueueMsg(appMsgQueue, syncEvent, (uint8_t *)pMsg);
        }
    
        return FALSE;
    }
    
    
    
    /*********************************************************************
     * @fn      SimpleBLEObserver_handleKeys
     *
     * @brief   Handles all key events for this device.
     *
     * @param   shift - true if in shift/alt.
     * @param   keys - bit field for key events. Valid entries:
     *                 HAL_KEY_SW_2
     *                 HAL_KEY_SW_1
     *
     * @return  none
     */
    static void SimpleBLEObserver_handleKeys(uint8 shift, uint8 keys)
    {
        (void)shift;  // Intentionally unreferenced parameter
    
        // Left key determines action to take
        if (keys & KEY_LEFT)
        {
            if (!scanning)
            {
                // Increment index
                scanIdx++;
    
                if (scanIdx >= scanRes)
                {
                    // Prompt the user to begin scanning again.
                    scanIdx = -1;
                    Display_print0(dispHandle, 2, 0, "");
                    Display_print0(dispHandle, 3, 0, "");
                    Display_print0(dispHandle, 5, 0, "Discover ->");
                }
                else
                {
                    // Display the indexed scanned device.
                    Display_print1(dispHandle, 2, 0, "Device %d", (scanIdx + 1));
                    Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(devList[scanIdx].addr));
                    Display_print0(dispHandle, 5, 0, "");
                    Display_print0(dispHandle, 6, 0, "<- Next Option");
                }
            }
        }
    
        // Right key takes the actio the user has selected.
        if (keys & KEY_RIGHT)
        {
            if (scanIdx == -1)
            {
                if (!scanning)
                {
                    scanning = TRUE;
                    scanRes = 0;
    
                    Display_print0(dispHandle, 2, 0, "Discovering...");
                    Display_print0(dispHandle, 3, 0, "");
                    Display_print0(dispHandle, 4, 0, "");
                    Display_print0(dispHandle, 5, 0, "Cancel Discovery ->");
                    Display_print0(dispHandle, 6, 0, "");
    
                    GAPObserverRole_StartDiscovery(DEFAULT_DISCOVERY_MODE,
                                                   DEFAULT_DISCOVERY_ACTIVE_SCAN,
                                                   DEFAULT_DISCOVERY_WHITE_LIST);
                }
                else
                {
                    // Cancel Scanning
                    GAPObserverRole_CancelDiscovery();
                }
            }
        }
    }
    
    /*********************************************************************
     *********************************************************************/
    

    Thanks 

    Anil.