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.

CC2650 Advertising on/off in all states -simpleBLEPeripheral

I am stuck it seems....

Getting Advertising to go from one state to another doesn't seem to be an issue using:

//ON

en=1;
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, 1, &en ); // 1=on

or

//OFF

en=0;
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, 1, &en ); // 0=off

Where I am getting issues is that when I place function within SimpleBLEPeripheral_performPeriodicTask(); it leads to just allowing me to turn off the radio if when I connect it runs the clock for this task. Never on again.... 

So in the other state if I setup a function to be called from anywhere else .... say a task that is not waiting for a semaphore and is just sleeping and running continuously. If the uint8_t initialAdvertEnable = FALSE; this function will turn on the advertising. Yet the OFF function will not work now within the PerodicTask(); even if I just call the task once to turn on the radio it will only turn it on from a false state from the initial setup not really toggling the radio..... 

//Example for turning on the Advertising after 10 seconds if the Advertising was FALSE during setup

while(1){

Task_sleep(10000); 
en=1;
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, 1, &en ); // 1=on   }

Basically what I am getting at is for some reason when I place conditions on the advertisement in starting up == false and then I enable the advertising...
It will stay on even if I have the off statement within the PeriodicTask();

The inverse issue is that if I have the starting up advertising set too == true and I call the statement to turn off the advertising... this will happen but I can no longer turn the advertising back on.... 

Ideally I would like to accomplish this if possible through whatever means necessary 

1) Start-off without advertising (Setting uint8_t initialAdvertEnable = FALSE; does this for me)

2) After some condition setup advertising to start (ON referenced above can do this within the SimpleBLEPeripheral.c as a function not within PeriodicTask(); due to this not being enabled yet without a connection) 

3) The ability to terminate a connection and turn off advertising || just turn off advertising even if a connection has not been made... ** This is the step I am having issues with->  It seems that no matter what I do I cannot get both the ability to turn on or the ability to turn off the advertising at the same time... 

Thanks in advance I will provide some more reference code if needed 


Here is reference to the two previous posts that I have been using  to try solve my problem with thus far:

  • Can you post your code snippet so we can better assist you?
  • You bet using the previous reference here is an example of what I am trying to attempt to do.... 

    /**************************************************************************************************
      Filename:       simpleBLEPeripheral.c
      Revised:        $Date: 2015-01-28 17:22:05 -0800 (Wed, 28 Jan 2015) $
      Revision:       $Revision: 42106 $
    
      Description:    This file contains the Simple BLE Peripheral sample application
                      for use with the CC2650 Bluetooth Low Energy Protocol Stack.
    
      Copyright 2013 - 2015 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    **************************************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    #include <xdc/std.h>
    
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Queue.h>
    
    #include <ICall.h>
    
    #include "gatt.h"
    #include "hci.h"
    
    #include "gapgattserver.h"
    #include "gattservapp.h"
    #include "devinfoservice.h"
    #include "simpleGATTprofile.h"
    
    #ifdef FEATURE_OAD
    #include "oad_target.h"
    #include "oad.h"
    #endif
    
    #include "peripheral.h"
    #include "gapbondmgr.h"
    
    #include "osal_snv.h"
    #include "ICallBleAPIMSG.h"
    
    #include "util.h"
    #include "board_lcd.h"
    #include "board_key.h"
    #include "Board.h"
    
    #include "simpleBLEPeripheral.h"
    
    #include <ti/drivers/lcd/LCDDogm1286.h>
    /*********************************************************************
     * CONSTANTS
     */
    // Advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // Limited discoverable mode advertises for 30.72s, and then stops
    // General discoverable mode advertises indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    
    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter
    // update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // Whether to enable automatic parameter update request when a connection is
    // formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE
    
    // Connection Pause Peripheral time value (in seconds)
    #define DEFAULT_CONN_PAUSE_PERIPHERAL         6
    
    // How often to perform periodic event (in msec)
    #define SBP_PERIODIC_EVT_PERIOD               300 //5000
    
    // Task configuration
    #define SBP_TASK_PRIORITY                     1
    
    
    #ifndef SBP_TASK_STACK_SIZE
    #define SBP_TASK_STACK_SIZE                   644
    #endif
    
    // Internal Events for RTOS application
    #define SBP_STATE_CHANGE_EVT                  0x0001
    #define SBP_CHAR_CHANGE_EVT                   0x0002
    #define SBP_PERIODIC_EVT                      0x0004
    #ifdef FEATURE_OAD
    #define SBP_OAD_WRITE_EVT                     0x0008
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from profiles.
    typedef struct
    {
      uint8_t event;  // Which profile's event
      uint8_t status; // New status
    } sbpEvt_t;
    
    /*********************************************************************
     * PUBLIC VARIABLES
     */
     
     uint8_t initialAdvertEnable = FALSE;
     uint8_t BLE_FLAG=0;
     uint8 en = 1;
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Semaphore globally used to post events to the application thread
    static ICall_Semaphore sem;
    
    // Clock instances for internal periodic events.
    static Clock_Struct periodicClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    
    // events flag for internal application events.
    static uint16_t events;
    
    // Task configuration
    Task_Struct sbpTask;
    Char sbpTaskStack[SBP_TASK_STACK_SIZE];
    
    // Profile state and parameters
    //static gaprole_States_t gapProfileState = GAPROLE_INIT;
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8_t scanRspData[] =
    {
      // complete name
      0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x50,   // 'P'
      0x65,   // 'e'
      0x72,   // 'r'
      0x69,   // 'i'
      0x70,   // 'p'
      0x68,   // 'h'
      0x65,   // 'e'
      0x72,   // 'r'
      0x61,   // 'a'
      0x6c,   // 'l'
    
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),   // 100ms
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),   // 1s
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8_t advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
      0x03,   // length of this data
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
    #ifdef FEATURE_OAD
      LO_UINT16(OAD_SERVICE_UUID),
      HI_UINT16(OAD_SERVICE_UUID)
    #else
      LO_UINT16(SIMPLEPROFILE_SERV_UUID),
      HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    #endif //!FEATURE_OAD
    };
    
    // GAP GATT Attributes
    static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral";
    
    #if FEATURE_OAD
    // Event data from OAD profile.
    static oadTargetWrite_t oadWriteEventData;
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void SimpleBLEPeripheral_init( void );
    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states);
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1);
    
    static void SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg);
    static void SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg);
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState);
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
    static void SimpleBLEPeripheral_performPeriodicTask(void);
    
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState);
    #ifndef FEATURE_OAD
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID);
    #endif //!FEATURE_OAD
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t status);
    
    #ifdef FEATURE_OAD
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData);
    #endif //FEATURE_OAD
    
    static void SimpleBLEPeripheral_clockHandler(UArg arg);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs =
    {
      SimpleBLEPeripheral_stateChangeCB,    // Profile State Change Callbacks
      NULL                                  // When a valid RSSI is read from
                                            // controller (not used by app)
    };
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
    {
      NULL, // Passcode callback (not used by application)
      NULL  // Pairing / Bonding state Callback (not used by application)
    };
    
    // Simple GATT Profile Callbacks
    #ifndef FEATURE_OAD
    static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs =
    {
      SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback
    };
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
    static oadTargetCBs_t simpleBLEPeripheral_oadCBs =
    {
      NULL,                                 // Read Callback.  Optional.
      SimpleBLEPeripheral_processOadWriteCB // Write Callback.  Mandatory.
    };
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states){
    	if(states==1)
    	{
    	en=1;
    	BLE_FLAG=1;
    	}
    	if(states==0)
    	{
    	en=0;
    	BLE_FLAG=1;
    	}
    	
    }
     
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_createTask
     *
     * @brief   Task creation function for the Simple BLE Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = sbpTaskStack;
      taskParams.stackSize = SBP_TASK_STACK_SIZE;
      taskParams.priority = SBP_TASK_PRIORITY;
    
      Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_init(void)
    {
    	// ******************************************************************
      // N0 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, &sem);
    
      // Hard code the BD Address till CC2650 board gets its own IEEE address
     // uint8 bdAddress[B_ADDR_LEN] = { 0xF0, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA };
     // HCI_EXT_SetBDADDRCmd(bdAddress);
    
      // Set device's Sleep Clock Accuracy
      //HCI_EXT_SetSCACmd(40);
    
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueue = Util_constructQueue(&appMsg);
    
      // Create one-shot clocks for internal periodic events.
      Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
                          SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
    
      Board_openLCD();
    
      // Setup the GAP
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);
    
      // Setup the GAP Peripheral Role Profile
      {
        // For all hardware platforms, device starts advertising upon initialization
        
    
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16_t advertOffTime = 0;
    
        uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
        uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    
        // Set the GAP Role Parameters
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                             &initialAdvertEnable);
        GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
                             &advertOffTime);
    
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                             scanRspData);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
    
        GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),
                             &enableUpdateRequest);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMaxInterval);
        GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
                             &desiredSlaveLatency);
        GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),
                             &desiredConnTimeout);
      }
    
      // Set the GAP Characteristics
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    
      // Set advertising interval
      {
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
    
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
      }
    
      // Setup the GAP Bond Manager
      {
        uint32_t passkey = 0; // passkey "000000"
        uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8_t mitm = TRUE;
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8_t bonding = TRUE;
    
        GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),
                                &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
      }
    
       // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
      DevInfo_AddService();                        // Device Information Service
    
    #ifndef FEATURE_OAD
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
      VOID OAD_addService();                 // OAD Profile
      OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
    #endif
    
    #ifndef FEATURE_OAD
      // Setup the SimpleProfile Characteristic Values
      {
        uint8_t charValue1 = 1;
        uint8_t charValue2 = 2;
        uint8_t charValue3 = 3;
        uint8_t charValue4 = 4;
        uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
                                   &charValue1);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
                                   &charValue2);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
                                   &charValue3);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &charValue4);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
                                   charValue5);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs);
    #endif //!FEATURE_OAD
    
      // Start the Device
      VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);
    
      // Start Bond Manager
      VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs);
    
    #if defined FEATURE_OAD
    #if defined (HAL_IMAGE_A)
      LCD_WRITE_STRING("BLE Peripheral A", LCD_PAGE0);
    #else
      LCD_WRITE_STRING("BLE Peripheral B", LCD_PAGE0);
    #endif // HAL_IMAGE_A
    #else
      LCD_WRITE_STRING("BLE Peripheral", LCD_PAGE0);
    #endif // FEATURE_OAD
      
      Util_startClock(&periodicClock);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_taskFxn
     *
     * @brief   Application task entry point for the Simple BLE Peripheral.
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      SimpleBLEPeripheral_init();
    
      // Application main loop
      for (;;)
      {
        // Waits for a signal to the semaphore associated with the calling thread.
        // Note that the semaphore associated with a thread is signaled when a
        // message is queued to the message receive queue of the thread or when
        // ICall_signal() function is called onto the semaphore.
        ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
        if (errno == ICALL_ERRNO_SUCCESS)
        {
          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
              SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg);
            }
    
            if (pMsg)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message.
          if (!Queue_empty(appMsgQueue))
          {
            sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
            if (pMsg)
            {
              // Process message.
              SimpleBLEPeripheral_processAppMsg(pMsg);
    
              // Free the space from the message.
              ICall_free(pMsg);
            }
          }
        }
    
        if (events & SBP_PERIODIC_EVT)
        {
          events &= ~SBP_PERIODIC_EVT;
    
          Util_startClock(&periodicClock);
    
          // Perform periodic application task
          SimpleBLEPeripheral_performPeriodicTask();
        }
    
    #ifdef FEATURE_OAD
        if (events & SBP_OAD_WRITE_EVT)
        {
          events &= ~SBP_OAD_WRITE_EVT;
    
          // Identify new image.
          if (oadWriteEventData.event == OAD_WRITE_IDENTIFY_REQ)
          {
            OAD_imgIdentifyWrite(oadWriteEventData.connHandle,
                                       oadWriteEventData.pData);
          }
          // Write a next block request.
          else if (oadWriteEventData.event == OAD_WRITE_BLOCK_REQ)
          {
            OAD_imgBlockWrite(oadWriteEventData.connHandle, oadWriteEventData.pData);
          }
    
          // Free buffer.
          ICall_free(oadWriteEventData.pData);
        }
    #endif //FEATURE_OAD
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStackMsg
     *
     * @brief   Process an incoming stack message.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg)
    {
      switch (pMsg->event)
      {
        case GATT_MSG_EVENT:
          // Process GATT message
          SimpleBLEPeripheral_processGATTMsg((gattMsgEvent_t *)pMsg);
          break;
    
        default:
          // do nothing
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processGATTMsg
     *
     * @brief   Process GATT messages
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
    {
      GATT_bm_free(&pMsg->msg, pMsg->method);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg)
    {
      switch (pMsg->event)
      {
        case SBP_STATE_CHANGE_EVT:
          SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg->status);
          break;
    
        case SBP_CHAR_CHANGE_EVT:
          SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->status);
          break;
    
        default:
          // Do nothing.
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_stateChangeCB
     *
     * @brief   Callback from GAP Role indicating a role state change.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStateChangeEvt
     *
     * @brief   Process a pending GAP Role state change event.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
    {
    #ifdef PLUS_BROADCASTER
      static bool firstConnFlag = false;
    #endif // PLUS_BROADCASTER
    
      switch ( newState )
      {
        case GAPROLE_STARTED:
          {
            uint8_t ownAddress[B_ADDR_LEN];
            uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
            GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = ownAddress[0];
            systemId[1] = ownAddress[1];
            systemId[2] = ownAddress[2];
    
            // set middle bytes to zero
            systemId[4] = 0x00;
            systemId[3] = 0x00;
    
            // shift three bytes up
            systemId[7] = ownAddress[5];
            systemId[6] = ownAddress[4];
            systemId[5] = ownAddress[3];
    
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
    
            // Display device address
            LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1);
            LCD_WRITE_STRING("Initialized", LCD_PAGE2);
          }
          break;
    
        case GAPROLE_ADVERTISING:
          LCD_WRITE_STRING("Advertising", LCD_PAGE2);
          break;
    
        case GAPROLE_CONNECTED:
          {
            uint8_t peerAddress[B_ADDR_LEN];
    
            GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);        
    
            LCD_WRITE_STRING("Connected", LCD_PAGE2);
            LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddress), LCD_PAGE3);
    
            #ifdef PLUS_BROADCASTER
              // Only turn advertising on for this state when we first connect
              // otherwise, when we go from connected_advertising back to this state
              // we will be turning advertising back on.
              if (firstConnFlag == false)
              {
                uint8_t advertEnabled = TRUE; // Turn on Advertising
    
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                firstConnFlag = true;
              }
            #endif // PLUS_BROADCASTER
          }
          break;
    
        case GAPROLE_CONNECTED_ADV:
          LCD_WRITE_STRING("Connected Advertising", LCD_PAGE2);
          break;
    
        case GAPROLE_WAITING:
          LCD_WRITE_STRING("Disconnected", LCD_PAGE2);
    
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          LCD_WRITE_STRING("Timed Out", LCD_PAGE2);
    
          #ifdef PLUS_BROADCASTER
            // Reset flag for next connection.
            firstConnFlag = false;
          #endif //#ifdef (PLUS_BROADCASTER)
          break;
    
        case GAPROLE_ERROR:
          LCD_WRITE_STRING("Error", LCD_PAGE2);
          break;
    
        default:
          LCD_WRITE_STRING("", LCD_PAGE2);
          break;
      }
    
      // Update the state
      //gapProfileState = newState;
    }
    
    #ifndef FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_charValueChangeCB
     *
     * @brief   Callback from Simple Profile indicating a characteristic
     *          value change.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID);
    }
    #endif //!FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processCharValueChangeEvt
     *
     * @brief   Process a pending Simple Profile characteristic value change
     *          event.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
    {
    #ifndef FEATURE_OAD
      uint8_t newValue;
    
      switch(paramID)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 1:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        case SIMPLEPROFILE_CHAR3:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 3:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        default:
          // should not reach here!
          break;
      }
    #endif //!FEATURE_OAD
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_performPeriodicTask
     *
     * @brief   Perform a periodic application task. This function gets called
     *          every five seconds (SBP_PERIODIC_EVT_PERIOD). In this example,
     *          the value of the third characteristic in the SimpleGATTProfile
     *          service is retrieved from the profile, and then copied into the
     *          value of the the fourth characteristic.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {
      //turn off advertising
      //en ^= 1;
      if(BLE_FLAG){
    	  BLE_FLAG=0;
    	GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, &en);  
      }
      
    
      
      }
    
    
    #if FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processOadWriteCB
     *
     * @brief   Process a write request to the OAD profile.
     *
     * @param   event      - event type:
     *                       OAD_WRITE_IDENTIFY_REQ
     *                       OAD_WRITE_BLOCK_REQ
     * @param   connHandle - the connection Handle this request is from.
     * @param   pData      - pointer to data for processing and/or storing.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData)
    {
      uint8_t numOfBytes = (event == OAD_WRITE_IDENTIFY_REQ) ? 8 : 18;
    
      // Store OAD Identify Request dynamically.
      if (oadWriteEventData.pData = ICall_malloc(sizeof(uint8_t) * numOfBytes))
      {
        // Set the event.
        events |= SBP_OAD_WRITE_EVT;
    
        oadWriteEventData.event = event;
        oadWriteEventData.connHandle = connHandle;
    
        memcpy(oadWriteEventData.pData, pData, numOfBytes);
    
        // Post the application's semaphore.
        Semaphore_post(sem);
      }
    }
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_clockHandler
     *
     * @brief   Handler function for clock timeouts.
     *
     * @param   arg - event type
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_clockHandler(UArg arg)
    {
      // Store the event.
      events |= arg;
    
      // Wake up the application.
      Semaphore_post(sem);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event  - message event.
     * @param   status - message status.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t status)
    {
      sbpEvt_t *pMsg;
    
      // Create dynamic pointer to message.
      if (pMsg = ICall_malloc(sizeof(sbpEvt_t)))
      {
        pMsg->event = event;
        pMsg->status = status;
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    /*********************************************************************
    *********************************************************************/
    

  • Sure so look at this...

    /*********************************************************************
    * PUBLIC VARIABLES
    */

    uint8_t initialAdvertEnable = FALSE;
    uint8_t BLE_FLAG=0;
    uint8 en = 1;

    /*********************************************************************
    * PUBLIC FUNCTIONS
    */
    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states){
    if(states==1)
    {
    en=1;
    BLE_FLAG=1;
    }
    if(states==0)
    {
    en=0;
    BLE_FLAG=1;
    }
    }


    /*********************************************************************
    * @fn SimpleBLEPeripheral_performPeriodicTask
    */
    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {
    //turn off advertising
    //en ^= 1;
    if(BLE_FLAG){
    BLE_FLAG=0;
    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, &en);
    } }
  • How I understand this is that whenever I call the function that I have made SimpleBLEPeripheral_BLE_RADIO(uint8_t states) I will setup a flag for the periodic task to consider... this will place the correct "en" into GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, &en); to turn the radio on or off.....

    I have tried this as well..... and this gave me very similar inconclusive results for being able to control advertising
    /*********************************************************************
    * PUBLIC FUNCTIONS
    */
    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states){
    if(states==1)
    {
    en=1;
    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, &en);
    }
    if(states==0)
    {
    en=0;
    GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, &en);
    }
    }
  • Can you send me the c file instead. Attach the whole file is a bit difficult for me to do function search...
  • Please note that the function that would call the BLE_FLAG to trigger would be accessed possibly outside the c file.... Basically very similar to a clock cycling through as a timer could work as a trigger 

    Also reference the 2 posts above for the altered sections of the code

    /**************************************************************************************************
      Filename:       simpleBLEPeripheral.c
      Revised:        $Date: 2015-01-28 17:22:05 -0800 (Wed, 28 Jan 2015) $
      Revision:       $Revision: 42106 $
    
      Description:    This file contains the Simple BLE Peripheral sample application
                      for use with the CC2650 Bluetooth Low Energy Protocol Stack.
    
      Copyright 2013 - 2015 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    **************************************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    #include <xdc/std.h>
    
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Queue.h>
    
    #include <ICall.h>
    
    #include "gatt.h"
    #include "hci.h"
    
    #include "gapgattserver.h"
    #include "gattservapp.h"
    #include "devinfoservice.h"
    #include "simpleGATTprofile.h"
    
    #ifdef FEATURE_OAD
    #include "oad_target.h"
    #include "oad.h"
    #endif
    
    #include "peripheral.h"
    #include "gapbondmgr.h"
    
    #include "osal_snv.h"
    #include "ICallBleAPIMSG.h"
    
    #include "util.h"
    #include "board_lcd.h"
    #include "board_key.h"
    #include "Board.h"
    
    #include "simpleBLEPeripheral.h"
    
    #include <ti/drivers/lcd/LCDDogm1286.h>
    /*********************************************************************
     * CONSTANTS
     */
    // Advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // Limited discoverable mode advertises for 30.72s, and then stops
    // General discoverable mode advertises indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    
    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter
    // update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // Whether to enable automatic parameter update request when a connection is
    // formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE
    
    // Connection Pause Peripheral time value (in seconds)
    #define DEFAULT_CONN_PAUSE_PERIPHERAL         6
    
    // How often to perform periodic event (in msec)
    #define SBP_PERIODIC_EVT_PERIOD               300 //5000
    
    // Task configuration
    #define SBP_TASK_PRIORITY                     1
    
    
    #ifndef SBP_TASK_STACK_SIZE
    #define SBP_TASK_STACK_SIZE                   644
    #endif
    
    // Internal Events for RTOS application
    #define SBP_STATE_CHANGE_EVT                  0x0001
    #define SBP_CHAR_CHANGE_EVT                   0x0002
    #define SBP_PERIODIC_EVT                      0x0004
    #ifdef FEATURE_OAD
    #define SBP_OAD_WRITE_EVT                     0x0008
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from profiles.
    typedef struct
    {
      uint8_t event;  // Which profile's event
      uint8_t status; // New status
    } sbpEvt_t;
    
    /*********************************************************************
     * PUBLIC VARIABLES
     */
     
     uint8_t initialAdvertEnable = FALSE;
     uint8_t BLE_FLAG=0;
     uint8 en = 1;
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Semaphore globally used to post events to the application thread
    static ICall_Semaphore sem;
    
    // Clock instances for internal periodic events.
    static Clock_Struct periodicClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    
    // events flag for internal application events.
    static uint16_t events;
    
    // Task configuration
    Task_Struct sbpTask;
    Char sbpTaskStack[SBP_TASK_STACK_SIZE];
    
    // Profile state and parameters
    //static gaprole_States_t gapProfileState = GAPROLE_INIT;
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8_t scanRspData[] =
    {
      // complete name
      0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x50,   // 'P'
      0x65,   // 'e'
      0x72,   // 'r'
      0x69,   // 'i'
      0x70,   // 'p'
      0x68,   // 'h'
      0x65,   // 'e'
      0x72,   // 'r'
      0x61,   // 'a'
      0x6c,   // 'l'
    
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),   // 100ms
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),   // 1s
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8_t advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
      0x03,   // length of this data
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
    #ifdef FEATURE_OAD
      LO_UINT16(OAD_SERVICE_UUID),
      HI_UINT16(OAD_SERVICE_UUID)
    #else
      LO_UINT16(SIMPLEPROFILE_SERV_UUID),
      HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    #endif //!FEATURE_OAD
    };
    
    // GAP GATT Attributes
    static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral";
    
    #if FEATURE_OAD
    // Event data from OAD profile.
    static oadTargetWrite_t oadWriteEventData;
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void SimpleBLEPeripheral_init( void );
    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states);
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1);
    
    static void SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg);
    static void SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg);
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState);
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
    static void SimpleBLEPeripheral_performPeriodicTask(void);
    
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState);
    #ifndef FEATURE_OAD
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID);
    #endif //!FEATURE_OAD
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t status);
    
    #ifdef FEATURE_OAD
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData);
    #endif //FEATURE_OAD
    
    static void SimpleBLEPeripheral_clockHandler(UArg arg);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs =
    {
      SimpleBLEPeripheral_stateChangeCB,    // Profile State Change Callbacks
      NULL                                  // When a valid RSSI is read from
                                            // controller (not used by app)
    };
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
    {
      NULL, // Passcode callback (not used by application)
      NULL  // Pairing / Bonding state Callback (not used by application)
    };
    
    // Simple GATT Profile Callbacks
    #ifndef FEATURE_OAD
    static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs =
    {
      SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback
    };
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
    static oadTargetCBs_t simpleBLEPeripheral_oadCBs =
    {
      NULL,                                 // Read Callback.  Optional.
      SimpleBLEPeripheral_processOadWriteCB // Write Callback.  Mandatory.
    };
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states){
        if(states==1)
        {
        en=1;
        BLE_FLAG=1;
        }
        if(states==0)
        {
        en=0;
        BLE_FLAG=1;
        }
        
    }
     
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_createTask
     *
     * @brief   Task creation function for the Simple BLE Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = sbpTaskStack;
      taskParams.stackSize = SBP_TASK_STACK_SIZE;
      taskParams.priority = SBP_TASK_PRIORITY;
    
      Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_init(void)
    {
        // ******************************************************************
      // N0 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, &sem);
    
      // Hard code the BD Address till CC2650 board gets its own IEEE address
     // uint8 bdAddress[B_ADDR_LEN] = { 0xF0, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA };
     // HCI_EXT_SetBDADDRCmd(bdAddress);
    
      // Set device's Sleep Clock Accuracy
      //HCI_EXT_SetSCACmd(40);
    
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueue = Util_constructQueue(&appMsg);
    
      // Create one-shot clocks for internal periodic events.
      Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
                          SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
    
      Board_openLCD();
    
      // Setup the GAP
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);
    
      // Setup the GAP Peripheral Role Profile
      {
        // For all hardware platforms, device starts advertising upon initialization
        
    
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16_t advertOffTime = 0;
    
        uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
        uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    
        // Set the GAP Role Parameters
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                             &initialAdvertEnable);
        GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
                             &advertOffTime);
    
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                             scanRspData);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
    
        GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),
                             &enableUpdateRequest);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMaxInterval);
        GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
                             &desiredSlaveLatency);
        GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),
                             &desiredConnTimeout);
      }
    
      // Set the GAP Characteristics
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    
      // Set advertising interval
      {
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
    
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
      }
    
      // Setup the GAP Bond Manager
      {
        uint32_t passkey = 0; // passkey "000000"
        uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8_t mitm = TRUE;
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8_t bonding = TRUE;
    
        GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),
                                &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
      }
    
       // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
      DevInfo_AddService();                        // Device Information Service
    
    #ifndef FEATURE_OAD
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
      VOID OAD_addService();                 // OAD Profile
      OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
    #endif
    
    #ifndef FEATURE_OAD
      // Setup the SimpleProfile Characteristic Values
      {
        uint8_t charValue1 = 1;
        uint8_t charValue2 = 2;
        uint8_t charValue3 = 3;
        uint8_t charValue4 = 4;
        uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
                                   &charValue1);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
                                   &charValue2);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
                                   &charValue3);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &charValue4);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
                                   charValue5);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs);
    #endif //!FEATURE_OAD
    
      // Start the Device
      VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);
    
      // Start Bond Manager
      VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs);
    
    #if defined FEATURE_OAD
    #if defined (HAL_IMAGE_A)
      LCD_WRITE_STRING("BLE Peripheral A", LCD_PAGE0);
    #else
      LCD_WRITE_STRING("BLE Peripheral B", LCD_PAGE0);
    #endif // HAL_IMAGE_A
    #else
      LCD_WRITE_STRING("BLE Peripheral", LCD_PAGE0);
    #endif // FEATURE_OAD
      
      Util_startClock(&periodicClock);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_taskFxn
     *
     * @brief   Application task entry point for the Simple BLE Peripheral.
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      SimpleBLEPeripheral_init();
    
      // Application main loop
      for (;;)
      {
        // Waits for a signal to the semaphore associated with the calling thread.
        // Note that the semaphore associated with a thread is signaled when a
        // message is queued to the message receive queue of the thread or when
        // ICall_signal() function is called onto the semaphore.
        ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
        if (errno == ICALL_ERRNO_SUCCESS)
        {
          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
              SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg);
            }
    
            if (pMsg)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message.
          if (!Queue_empty(appMsgQueue))
          {
            sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
            if (pMsg)
            {
              // Process message.
              SimpleBLEPeripheral_processAppMsg(pMsg);
    
              // Free the space from the message.
              ICall_free(pMsg);
            }
          }
        }
    
        if (events & SBP_PERIODIC_EVT)
        {
          events &= ~SBP_PERIODIC_EVT;
    
          Util_startClock(&periodicClock);
    
          // Perform periodic application task
          SimpleBLEPeripheral_performPeriodicTask();
        }
    
    #ifdef FEATURE_OAD
        if (events & SBP_OAD_WRITE_EVT)
        {
          events &= ~SBP_OAD_WRITE_EVT;
    
          // Identify new image.
          if (oadWriteEventData.event == OAD_WRITE_IDENTIFY_REQ)
          {
            OAD_imgIdentifyWrite(oadWriteEventData.connHandle,
                                       oadWriteEventData.pData);
          }
          // Write a next block request.
          else if (oadWriteEventData.event == OAD_WRITE_BLOCK_REQ)
          {
            OAD_imgBlockWrite(oadWriteEventData.connHandle, oadWriteEventData.pData);
          }
    
          // Free buffer.
          ICall_free(oadWriteEventData.pData);
        }
    #endif //FEATURE_OAD
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStackMsg
     *
     * @brief   Process an incoming stack message.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg)
    {
      switch (pMsg->event)
      {
        case GATT_MSG_EVENT:
          // Process GATT message
          SimpleBLEPeripheral_processGATTMsg((gattMsgEvent_t *)pMsg);
          break;
    
        default:
          // do nothing
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processGATTMsg
     *
     * @brief   Process GATT messages
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
    {
      GATT_bm_free(&pMsg->msg, pMsg->method);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg)
    {
      switch (pMsg->event)
      {
        case SBP_STATE_CHANGE_EVT:
          SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg->status);
          break;
    
        case SBP_CHAR_CHANGE_EVT:
          SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->status);
          break;
    
        default:
          // Do nothing.
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_stateChangeCB
     *
     * @brief   Callback from GAP Role indicating a role state change.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStateChangeEvt
     *
     * @brief   Process a pending GAP Role state change event.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
    {
    #ifdef PLUS_BROADCASTER
      static bool firstConnFlag = false;
    #endif // PLUS_BROADCASTER
    
      switch ( newState )
      {
        case GAPROLE_STARTED:
          {
            uint8_t ownAddress[B_ADDR_LEN];
            uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
            GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = ownAddress[0];
            systemId[1] = ownAddress[1];
            systemId[2] = ownAddress[2];
    
            // set middle bytes to zero
            systemId[4] = 0x00;
            systemId[3] = 0x00;
    
            // shift three bytes up
            systemId[7] = ownAddress[5];
            systemId[6] = ownAddress[4];
            systemId[5] = ownAddress[3];
    
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
    
            // Display device address
            LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1);
            LCD_WRITE_STRING("Initialized", LCD_PAGE2);
          }
          break;
    
        case GAPROLE_ADVERTISING:
          LCD_WRITE_STRING("Advertising", LCD_PAGE2);
          break;
    
        case GAPROLE_CONNECTED:
          {
            uint8_t peerAddress[B_ADDR_LEN];
    
            GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);        
    
            LCD_WRITE_STRING("Connected", LCD_PAGE2);
            LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddress), LCD_PAGE3);
    
            #ifdef PLUS_BROADCASTER
              // Only turn advertising on for this state when we first connect
              // otherwise, when we go from connected_advertising back to this state
              // we will be turning advertising back on.
              if (firstConnFlag == false)
              {
                uint8_t advertEnabled = TRUE; // Turn on Advertising
    
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                firstConnFlag = true;
              }
            #endif // PLUS_BROADCASTER
          }
          break;
    
        case GAPROLE_CONNECTED_ADV:
          LCD_WRITE_STRING("Connected Advertising", LCD_PAGE2);
          break;
    
        case GAPROLE_WAITING:
          LCD_WRITE_STRING("Disconnected", LCD_PAGE2);
    
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          LCD_WRITE_STRING("Timed Out", LCD_PAGE2);
    
          #ifdef PLUS_BROADCASTER
            // Reset flag for next connection.
            firstConnFlag = false;
          #endif //#ifdef (PLUS_BROADCASTER)
          break;
    
        case GAPROLE_ERROR:
          LCD_WRITE_STRING("Error", LCD_PAGE2);
          break;
    
        default:
          LCD_WRITE_STRING("", LCD_PAGE2);
          break;
      }
    
      // Update the state
      //gapProfileState = newState;
    }
    
    #ifndef FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_charValueChangeCB
     *
     * @brief   Callback from Simple Profile indicating a characteristic
     *          value change.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID);
    }
    #endif //!FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processCharValueChangeEvt
     *
     * @brief   Process a pending Simple Profile characteristic value change
     *          event.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
    {
    #ifndef FEATURE_OAD
      uint8_t newValue;
    
      switch(paramID)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 1:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        case SIMPLEPROFILE_CHAR3:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 3:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        default:
          // should not reach here!
          break;
      }
    #endif //!FEATURE_OAD
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_performPeriodicTask
     *
     * @brief   Perform a periodic application task. This function gets called
     *          every five seconds (SBP_PERIODIC_EVT_PERIOD). In this example,
     *          the value of the third characteristic in the SimpleGATTProfile
     *          service is retrieved from the profile, and then copied into the
     *          value of the the fourth characteristic.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {
      //turn off advertising
      //en ^= 1;
      if(BLE_FLAG){
          BLE_FLAG=0;
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, &en);  
      }
      
    
      
      }
    
    
    #if FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processOadWriteCB
     *
     * @brief   Process a write request to the OAD profile.
     *
     * @param   event      - event type:
     *                       OAD_WRITE_IDENTIFY_REQ
     *                       OAD_WRITE_BLOCK_REQ
     * @param   connHandle - the connection Handle this request is from.
     * @param   pData      - pointer to data for processing and/or storing.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData)
    {
      uint8_t numOfBytes = (event == OAD_WRITE_IDENTIFY_REQ) ? 8 : 18;
    
      // Store OAD Identify Request dynamically.
      if (oadWriteEventData.pData = ICall_malloc(sizeof(uint8_t) * numOfBytes))
      {
        // Set the event.
        events |= SBP_OAD_WRITE_EVT;
    
        oadWriteEventData.event = event;
        oadWriteEventData.connHandle = connHandle;
    
        memcpy(oadWriteEventData.pData, pData, numOfBytes);
    
        // Post the application's semaphore.
        Semaphore_post(sem);
      }
    }
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_clockHandler
     *
     * @brief   Handler function for clock timeouts.
     *
     * @param   arg - event type
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_clockHandler(UArg arg)
    {
      // Store the event.
      events |= arg;
    
      // Wake up the application.
      Semaphore_post(sem);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event  - message event.
     * @param   status - message status.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t status)
    {
      sbpEvt_t *pMsg;
    
      // Create dynamic pointer to message.
      if (pMsg = ICall_malloc(sizeof(sbpEvt_t)))
      {
        pMsg->event = event;
        pMsg->status = status;
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    /*********************************************************************
    *********************************************************************/

  • Hi,

    Can you answer some of my questions?
    1. are you using BLE stack 2.1.1 or BLE stack 2.0?
    2. What's the reason behind on deleting SBP_CONN_EVET_END_EVT? You can always add more user defined events.
    3. Do you have PLUS_BROADCASTER defined?
  • You bet and thank you for your time!

    1) 2.1.1 Is what I am using.
    2) Does simpleBLEPeripheral.c come with that naturally?
    3) Not that I am aware of I mainly want the ability to turn off advertising and on again as I wish does this need to be enabled to allow this?
  • It looks to me you deleted quite a lot of functions in your simpleBLEPeripheral.c. ex: delete stack process msg...

    Can you reinstall ble stack 2.1.1 and add the toggling on top of that. Try not to delete stuff if you don't have to.
  • Here is the modified C file from a new download of the simpleBLEPeripheral.c file

    /*******************************************************************************
      Filename:       simpleBLEPeripheral.c
      Revised:        $Date: 2016-01-07 16:59:59 -0800 (Thu, 07 Jan 2016) $
      Revision:       $Revision: 44594 $
    
      Description:    This file contains the Simple BLE Peripheral sample 
                      application for use with the CC2650 Bluetooth Low Energy 
                      Protocol Stack.
    
      Copyright 2013 - 2015 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    *******************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/knl/Queue.h>
    
    #include "hci_tl.h"
    #include "gatt.h"
    #include "gapgattserver.h"
    #include "gattservapp.h"
    #include "devinfoservice.h"
    #include "simpleGATTprofile.h"
    
    #if defined(SENSORTAG_HW)
    #include "bsp_spi.h"
    #endif // SENSORTAG_HW
    
    #if defined(FEATURE_OAD) || defined(IMAGE_INVALIDATE)
    #include "oad_target.h"
    #include "oad.h"
    #endif //FEATURE_OAD || IMAGE_INVALIDATE
    
    #include "peripheral.h"
    #include "gapbondmgr.h"
    
    #include "osal_snv.h"
    #include "ICallBleAPIMSG.h"
    
    #include "util.h"
    #include "board_lcd.h"
    #include "board_key.h"
    #include "Board.h"
    
    #include "simpleBLEPeripheral.h"
    
    #include <ti/drivers/lcd/LCDDogm1286.h>
    
    /*********************************************************************
     * CONSTANTS
     */
    // Advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // Limited discoverable mode advertises for 30.72s, and then stops
    // General discoverable mode advertises indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    #ifndef FEATURE_OAD
    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    #else
    // Minimum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     8
    
    // Maximum connection interval (units of 1.25ms, 8=10ms) if automatic
    // parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     8
    #endif // FEATURE_OAD
    
    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter
    // update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // Whether to enable automatic parameter update request when a connection is
    // formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE
    
    // Connection Pause Peripheral time value (in seconds)
    #define DEFAULT_CONN_PAUSE_PERIPHERAL         6
    
    // How often to perform periodic event (in msec)
    #define SBP_PERIODIC_EVT_PERIOD               5000
    
    #ifdef FEATURE_OAD
    // The size of an OAD packet.
    #define OAD_PACKET_SIZE                       ((OAD_BLOCK_SIZE) + 2)
    #endif // FEATURE_OAD
    
    // Task configuration
    #define SBP_TASK_PRIORITY                     1
    
    #ifndef SBP_TASK_STACK_SIZE
    #define SBP_TASK_STACK_SIZE                   644
    #endif
    
    // Internal Events for RTOS application
    #define SBP_STATE_CHANGE_EVT                  0x0001
    #define SBP_CHAR_CHANGE_EVT                   0x0002
    #define SBP_PERIODIC_EVT                      0x0004
    #define SBP_CONN_EVT_END_EVT                  0x0008
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from profiles.
    typedef struct
    {
      appEvtHdr_t hdr;  // event header.
    } sbpEvt_t;
    
    /*********************************************************************
     * PUBLIC VARIABLES
     */
     
     uint8_t initialAdvertEnable = FALSE;
     uint8_t BLE_FLAG=0;
     uint8 en = 1;
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Semaphore globally used to post events to the application thread
    static ICall_Semaphore sem;
    
    // Clock instances for internal periodic events.
    static Clock_Struct periodicClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    #if defined(FEATURE_OAD)
    // Event data from OAD profile.
    static Queue_Struct oadQ;
    static Queue_Handle hOadQ;
    #endif //FEATURE_OAD
    
    // events flag for internal application events.
    static uint16_t events;
    
    // Task configuration
    Task_Struct sbpTask;
    Char sbpTaskStack[SBP_TASK_STACK_SIZE];
    
    // Profile state and parameters
    //static gaprole_States_t gapProfileState = GAPROLE_INIT;
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8_t scanRspData[] =
    {
      // complete name
      0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x50,   // 'P'
      0x65,   // 'e'
      0x72,   // 'r'
      0x69,   // 'i'
      0x70,   // 'p'
      0x68,   // 'h'
      0x65,   // 'e'
      0x72,   // 'r'
      0x61,   // 'a'
      0x6c,   // 'l'
    
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),   // 100ms
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),   // 1s
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8_t advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
      0x03,   // length of this data
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
    #ifdef FEATURE_OAD
      LO_UINT16(OAD_SERVICE_UUID),
      HI_UINT16(OAD_SERVICE_UUID)
    #else
      LO_UINT16(SIMPLEPROFILE_SERV_UUID),
      HI_UINT16(SIMPLEPROFILE_SERV_UUID),
    #endif //!FEATURE_OAD
    };
    
    // GAP GATT Attributes
    static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral";
    
    // Globals used for ATT Response retransmission
    static gattMsgEvent_t *pAttRsp = NULL;
    static uint8_t rspTxRetry = 0;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void SimpleBLEPeripheral_init( void );
    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states);
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1);
    
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg);
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg);
    static void SimpleBLEPeripheral_processStateChangeEvt(
                                                         gaprole_States_t newState);
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
    static void SimpleBLEPeripheral_performPeriodicTask(void);
    
    static void SimpleBLEPeripheral_sendAttRsp(void);
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status);
    
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState);
    #ifndef FEATURE_OAD
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID);
    #endif //!FEATURE_OAD
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state);
    
    #ifdef FEATURE_OAD
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData);
    #endif //FEATURE_OAD
    
    static void SimpleBLEPeripheral_clockHandler(UArg arg);
    
    
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs =
    {
      SimpleBLEPeripheral_stateChangeCB     // Profile State Change Callbacks
    };
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
    {
      NULL, // Passcode callback (not used by application)
      NULL  // Pairing / Bonding state Callback (not used by application)
    };
    
    // Simple GATT Profile Callbacks
    #ifndef FEATURE_OAD
    static simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs =
    {
      SimpleBLEPeripheral_charValueChangeCB // Characteristic value change callback
    };
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
    static oadTargetCBs_t simpleBLEPeripheral_oadCBs =
    {
      SimpleBLEPeripheral_processOadWriteCB // Write Callback.
    };
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states){
        if(states==1)
        {
        en=1;
        BLE_FLAG=1;
        }
        if(states==0)
        {
        en=0;
        BLE_FLAG=1;
        }
        
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_createTask
     *
     * @brief   Task creation function for the Simple BLE Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = sbpTaskStack;
      taskParams.stackSize = SBP_TASK_STACK_SIZE;
      taskParams.priority = SBP_TASK_PRIORITY;
    
      Task_construct(&sbpTask, SimpleBLEPeripheral_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_init(void)
    {
      // ******************************************************************
      // N0 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, &sem);
    
      // Hard code the BD Address till CC2650 board gets its own IEEE address
      //uint8 bdAddress[B_ADDR_LEN] = { 0xAD, 0xD0, 0x0A, 0xAD, 0xD0, 0x0A };
      //HCI_EXT_SetBDADDRCmd(bdAddress);
    
      // Set device's Sleep Clock Accuracy
      //HCI_EXT_SetSCACmd(500);
      
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueue = Util_constructQueue(&appMsg);
    
      // Create one-shot clocks for internal periodic events.
      Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
                          SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
      
    #ifndef SENSORTAG_HW
      Board_openLCD();
    #endif //SENSORTAG_HW
      
    #if SENSORTAG_HW
      // Setup SPI bus for serial flash and Devpack interface
      bspSpiOpen();
    #endif //SENSORTAG_HW
      
      // Setup the GAP
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);
    
      // Setup the GAP Peripheral Role Profile
      {
        // For all hardware platforms, device starts advertising upon initialization
       // uint8_t initialAdvertEnable = TRUE;
    
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16_t advertOffTime = 0;
    
        uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
        uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
        uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
        uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
        uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    
        // Set the GAP Role Parameters
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                             &initialAdvertEnable);
        GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
                             &advertOffTime);
    
        GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                             scanRspData);
        GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
    
        GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),
                             &enableUpdateRequest);
        GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMinInterval);
        GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t),
                             &desiredMaxInterval);
        GAPRole_SetParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
                             &desiredSlaveLatency);
        GAPRole_SetParameter(GAPROLE_TIMEOUT_MULTIPLIER, sizeof(uint16_t),
                             &desiredConnTimeout);
      }
    
      // Set the GAP Characteristics
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    
      // Set advertising interval
      {
        uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
    
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
        GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
      }
    
      // Setup the GAP Bond Manager
      {
        uint32_t passkey = 0; // passkey "000000"
        uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8_t mitm = TRUE;
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8_t bonding = TRUE;
    
        GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),
                                &passkey);
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
      }
    
       // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT attributes
      DevInfo_AddService();                        // Device Information Service
    
    #ifndef FEATURE_OAD
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    #endif //!FEATURE_OAD
    
    #ifdef FEATURE_OAD
      VOID OAD_addService();                 // OAD Profile
      OAD_register((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
      hOadQ = Util_constructQueue(&oadQ);
    #endif
    
    #ifdef IMAGE_INVALIDATE
      Reset_addService();
    #endif //IMAGE_INVALIDATE
      
      
    #ifndef FEATURE_OAD
      // Setup the SimpleProfile Characteristic Values
      {
        uint8_t charValue1 = 1;
        uint8_t charValue2 = 2;
        uint8_t charValue3 = 3;
        uint8_t charValue4 = 4;
        uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
                                   &charValue1);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
                                   &charValue2);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
                                   &charValue3);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &charValue4);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
                                   charValue5);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&SimpleBLEPeripheral_simpleProfileCBs);
    #endif //!FEATURE_OAD
      
      // Start the Device
      VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);
      
      // Start Bond Manager
      VOID GAPBondMgr_Register(&simpleBLEPeripheral_BondMgrCBs);
    
      // Register with GAP for HCI/Host messages
      GAP_RegisterForMsgs(selfEntity);
      
      // Register for GATT local events and ATT Responses pending for transmission
      GATT_RegisterForMsgs(selfEntity);
      
    #if defined FEATURE_OAD
    #if defined (HAL_IMAGE_A)
      LCD_WRITE_STRING("BLE Peripheral A", LCD_PAGE0);
    #else
      LCD_WRITE_STRING("BLE Peripheral B", LCD_PAGE0);
    #endif // HAL_IMAGE_A
    #else
      LCD_WRITE_STRING("BLE Peripheral", LCD_PAGE0);
    #endif // FEATURE_OAD
    }       
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_taskFxn
     *
     * @brief   Application task entry point for the Simple BLE Peripheral.
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      SimpleBLEPeripheral_init();
    
      // Application main loop
      for (;;)
      {
        // Waits for a signal to the semaphore associated with the calling thread.
        // Note that the semaphore associated with a thread is signaled when a
        // message is queued to the message receive queue of the thread or when
        // ICall_signal() function is called onto the semaphore.
        ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
        if (errno == ICALL_ERRNO_SUCCESS)
        {
          ICall_EntityID dest;
          ICall_ServiceEnum src;
          ICall_HciExtEvt *pMsg = NULL;
    
          if (ICall_fetchServiceMsg(&src, &dest,
                                    (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
          {
            uint8 safeToDealloc = TRUE;
            
            if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
            {
              ICall_Event *pEvt = (ICall_Event *)pMsg;
              
              // Check for BLE stack events first
              if (pEvt->signature == 0xffff)
              {
                if (pEvt->event_flag & SBP_CONN_EVT_END_EVT)
                {
                  // Try to retransmit pending ATT Response (if any)
                  SimpleBLEPeripheral_sendAttRsp();
                }
              }
              else
              {
                // Process inter-task message
                safeToDealloc = SimpleBLEPeripheral_processStackMsg(
                                                                 (ICall_Hdr *)pMsg);
              }
            }
    
            if (pMsg && safeToDealloc)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message.
          while (!Queue_empty(appMsgQueue))
          {
            sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
            if (pMsg)
            {
              // Process message.
              SimpleBLEPeripheral_processAppMsg(pMsg);
    
              // Free the space from the message.
              ICall_free(pMsg);
            }
          }
        }
    
        if (events & SBP_PERIODIC_EVT)
        {
          events &= ~SBP_PERIODIC_EVT;
    
          Util_startClock(&periodicClock);
    
          // Perform periodic application task
          SimpleBLEPeripheral_performPeriodicTask();
        }
        
    #ifdef FEATURE_OAD
        while (!Queue_empty(hOadQ))
        {
          oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ);
    
          // Identify new image.
          if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
          {
            OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
          // Write a next block request.
          else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
          {
            OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
          }
    
          // Free buffer.
          ICall_free(oadWriteEvt);
        }
    #endif //FEATURE_OAD
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStackMsg
     *
     * @brief   Process an incoming stack message.
     *
     * @param   pMsg - message to process
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg)
    {
      uint8_t safeToDealloc = TRUE;
        
      switch (pMsg->event)
      {
        case GATT_MSG_EVENT:
          // Process GATT message
          safeToDealloc = SimpleBLEPeripheral_processGATTMsg(
                                                            (gattMsgEvent_t *)pMsg);
          break;
    
        case HCI_GAP_EVENT_EVENT:
          {
            // Process HCI message
            switch(pMsg->status)
            {
              case HCI_COMMAND_COMPLETE_EVENT_CODE:
                // Process HCI Command Complete Event
                break;
                
              default:
                break;
            }
          }
          break;
          
        default:
          // do nothing
          break;
      }
      
      return (safeToDealloc);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processGATTMsg
     *
     * @brief   Process GATT messages and events.
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
    {
      // See if GATT server was unable to transmit an ATT response
      if (pMsg->hdr.status == blePending)
      {
        // No HCI buffer was available. Let's try to retransmit the response
        // on the next connection event.
        if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity,
                                       SBP_CONN_EVT_END_EVT) == SUCCESS)
        {
          // First free any pending response
          SimpleBLEPeripheral_freeAttRsp(FAILURE);
          
          // Hold on to the response message for retransmission
          pAttRsp = pMsg;
          
          // Don't free the response message yet
          return (FALSE);
        }
      }
      else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
      {
        // ATT request-response or indication-confirmation flow control is
        // violated. All subsequent ATT requests or indications will be dropped.
        // The app is informed in case it wants to drop the connection.
        
        // Display the opcode of the message that caused the violation.
        LCD_WRITE_STRING_VALUE("FC Violated:", pMsg->msg.flowCtrlEvt.opcode,
                               10, LCD_PAGE5);
      }    
      else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
      {
        // MTU size updated
        LCD_WRITE_STRING_VALUE("MTU Size:", pMsg->msg.mtuEvt.MTU, 10, LCD_PAGE5);
      }
      
      // Free message payload. Needed only for ATT Protocol messages
      GATT_bm_free(&pMsg->msg, pMsg->method);
      
      // It's safe to free the incoming message
      return (TRUE);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_sendAttRsp
     *
     * @brief   Send a pending ATT response message.
     *
     * @param   none
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_sendAttRsp(void)
    {
      // See if there's a pending ATT Response to be transmitted
      if (pAttRsp != NULL)
      {
        uint8_t status;
        
        // Increment retransmission count
        rspTxRetry++;
        
        // Try to retransmit ATT response till either we're successful or
        // the ATT Client times out (after 30s) and drops the connection.
        status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, 
                              &(pAttRsp->msg));
        if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL))
        {
          // Disable connection event end notice
          HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0);
          
          // We're done with the response message
          SimpleBLEPeripheral_freeAttRsp(status);
        }
        else
        {
          // Continue retrying
          LCD_WRITE_STRING_VALUE("Rsp send retry:", rspTxRetry, 10, LCD_PAGE5);
        }
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_freeAttRsp
     *
     * @brief   Free ATT response message.
     *
     * @param   status - response transmit status
     *
     * @return  none
     */
    static void SimpleBLEPeripheral_freeAttRsp(uint8_t status)
    {
      // See if there's a pending ATT response message
      if (pAttRsp != NULL)
      {
        // See if the response was sent out successfully
        if (status == SUCCESS)
        {
          LCD_WRITE_STRING_VALUE("Rsp sent, retry:", rspTxRetry, 10, LCD_PAGE5);
        }
        else
        {
          // Free response payload
          GATT_bm_free(&pAttRsp->msg, pAttRsp->method);
          
          LCD_WRITE_STRING_VALUE("Rsp retry failed:", rspTxRetry, 10, LCD_PAGE5);
        }
        
        // Free response message
        ICall_freeMsg(pAttRsp);
        
        // Reset our globals
        pAttRsp = NULL;
        rspTxRetry = 0;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg)
    {
      switch (pMsg->hdr.event)
      {
        case SBP_STATE_CHANGE_EVT:
          SimpleBLEPeripheral_processStateChangeEvt((gaprole_States_t)pMsg->
                                                    hdr.state);
          break;
    
        case SBP_CHAR_CHANGE_EVT:
          SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);
          break;
    
        default:
          // Do nothing.
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_stateChangeCB
     *
     * @brief   Callback from GAP Role indicating a role state change.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_stateChangeCB(gaprole_States_t newState)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processStateChangeEvt
     *
     * @brief   Process a pending GAP Role state change event.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
    {
    #ifdef PLUS_BROADCASTER
      static bool firstConnFlag = false;
    #endif // PLUS_BROADCASTER
    
      switch ( newState )
      {
        case GAPROLE_STARTED:
          {
            uint8_t ownAddress[B_ADDR_LEN];
            uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
            GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = ownAddress[0];
            systemId[1] = ownAddress[1];
            systemId[2] = ownAddress[2];
    
            // set middle bytes to zero
            systemId[4] = 0x00;
            systemId[3] = 0x00;
    
            // shift three bytes up
            systemId[7] = ownAddress[5];
            systemId[6] = ownAddress[4];
            systemId[5] = ownAddress[3];
    
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, 
                                 systemId);
    
            // Display device address
            LCD_WRITE_STRING(Util_convertBdAddr2Str(ownAddress), LCD_PAGE1);
            LCD_WRITE_STRING("Initialized", LCD_PAGE2);
          }
          break;
    
        case GAPROLE_ADVERTISING:
          LCD_WRITE_STRING("Advertising", LCD_PAGE2);
          break;
    
    #ifdef PLUS_BROADCASTER   
        /* After a connection is dropped a device in PLUS_BROADCASTER will continue
         * sending non-connectable advertisements and shall sending this change of 
         * state to the application.  These are then disabled here so that sending 
         * connectable advertisements can resume.
         */
        case GAPROLE_ADVERTISING_NONCONN:
          {
            uint8_t advertEnabled = FALSE;
          
            // Disable non-connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                               &advertEnabled);
          
            advertEnabled = TRUE;
          
            // Enabled connectable advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabled);
            
            // Reset flag for next connection.
            firstConnFlag = false;
            
            SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          }
          break;
    #endif //PLUS_BROADCASTER   
    
        case GAPROLE_CONNECTED:
          {
            uint8_t peerAddress[B_ADDR_LEN];
    
            GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
    
            Util_startClock(&periodicClock);
            
            LCD_WRITE_STRING("Connected", LCD_PAGE2);
            LCD_WRITE_STRING(Util_convertBdAddr2Str(peerAddress), LCD_PAGE3);
    
            #ifdef PLUS_BROADCASTER
              // Only turn advertising on for this state when we first connect
              // otherwise, when we go from connected_advertising back to this state
              // we will be turning advertising back on.
              if (firstConnFlag == false)
              {
                uint8_t advertEnabled = FALSE; // Turn on Advertising
    
                // Disable connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                
                // Set to true for non-connectabel advertising.
                advertEnabled = TRUE;
    
                // Enable non-connectable advertising.
                GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
                                     &advertEnabled);
                firstConnFlag = true;
              }
            #endif // PLUS_BROADCASTER
          }
          break;
    
        case GAPROLE_CONNECTED_ADV:
          LCD_WRITE_STRING("Connected Advertising", LCD_PAGE2);
          break;
    
        case GAPROLE_WAITING:
          Util_stopClock(&periodicClock);
          
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
    
          LCD_WRITE_STRING("Disconnected", LCD_PAGE2);
    
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          LCD_WRITE_STRING("", LCD_PAGE5);
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
          
          LCD_WRITE_STRING("Timed Out", LCD_PAGE2);
          
          // Clear remaining lines
          LCD_WRITE_STRING("", LCD_PAGE3);
          LCD_WRITE_STRING("", LCD_PAGE4);
          LCD_WRITE_STRING("", LCD_PAGE5);
    
          #ifdef PLUS_BROADCASTER
            // Reset flag for next connection.
            firstConnFlag = false;
          #endif //#ifdef (PLUS_BROADCASTER)
          break;
    
        case GAPROLE_ERROR:
          LCD_WRITE_STRING("Error", LCD_PAGE2);
          break;
    
        default:
          LCD_WRITE_STRING("", LCD_PAGE2);
          break;
      }
    
      // Update the state
      //gapProfileState = newState;
    }
    
    #ifndef FEATURE_OAD
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_charValueChangeCB
     *
     * @brief   Callback from Simple Profile indicating a characteristic
     *          value change.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID)
    {
      SimpleBLEPeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID);
    }
    #endif //!FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processCharValueChangeEvt
     *
     * @brief   Process a pending Simple Profile characteristic value change
     *          event.
     *
     * @param   paramID - parameter ID of the value that was changed.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
    {
    #ifndef FEATURE_OAD
      uint8_t newValue;
    
      switch(paramID)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 1:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        case SIMPLEPROFILE_CHAR3:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
    
          LCD_WRITE_STRING_VALUE("Char 3:", (uint16_t)newValue, 10, LCD_PAGE4);
          break;
    
        default:
          // should not reach here!
          break;
      }
    #endif //!FEATURE_OAD
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_performPeriodicTask
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_performPeriodicTask(void)
    {
      //turn off advertising
      //en ^= 1;
      if(BLE_FLAG){
          BLE_FLAG=0;
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, 1, &en);  
      }
      
    
      
      }
    
    
    #if defined(FEATURE_OAD)
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_processOadWriteCB
     *
     * @brief   Process a write request to the OAD profile.
     *
     * @param   event      - event type:
     *                       OAD_WRITE_IDENTIFY_REQ
     *                       OAD_WRITE_BLOCK_REQ
     * @param   connHandle - the connection Handle this request is from.
     * @param   pData      - pointer to data for processing and/or storing.
     *
     * @return  None.
     */
    void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
                                               uint8_t *pData)
    {
      oadTargetWrite_t *oadWriteEvt = ICall_malloc( sizeof(oadTargetWrite_t) + \
                                                 sizeof(uint8_t) * OAD_PACKET_SIZE);
      
      if ( oadWriteEvt != NULL )
      {
        oadWriteEvt->event = event;
        oadWriteEvt->connHandle = connHandle;
        
        oadWriteEvt->pData = (uint8_t *)(&oadWriteEvt->pData + 1);
        memcpy(oadWriteEvt->pData, pData, OAD_PACKET_SIZE);
    
        Queue_enqueue(hOadQ, (Queue_Elem *)oadWriteEvt);
        
        // Post the application's semaphore.
        Semaphore_post(sem);
      }
      else
      {
        // Fail silently.
      }
    }
    #endif //FEATURE_OAD
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_clockHandler
     *
     * @brief   Handler function for clock timeouts.
     *
     * @param   arg - event type
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_clockHandler(UArg arg)
    {
      // Store the event.
      events |= arg;
    
      // Wake up the application.
      Semaphore_post(sem);
    }
    
    /*********************************************************************
     * @fn      SimpleBLEPeripheral_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event - message event.
     * @param   state - message state.
     *
     * @return  None.
     */
    static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state)
    {
      sbpEvt_t *pMsg;
    
      // Create dynamic pointer to message.
      if ((pMsg = ICall_malloc(sizeof(sbpEvt_t))))
      {
        pMsg->hdr.event = event;
        pMsg->hdr.state = state;
    
        // Enqueue the message.
        Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
      }
    }
    
    
    /*********************************************************************
    *********************************************************************/
    

  • The new file you sent does not show how to enable advertising.

    You can create a clock object and say after 5s, then you set the GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, xxxx, xxxx ); to True.

    When you connect to the device, the periodic clock will start and then brings it to the SimpleBLEPeripheral_performPeriodicTask eventually. In the function, you can disable the adverting eventho you will not be able to tell until you lost your connection.
  • Perfect this leads to a few questions...

    Do I need to use a clock object to do this?
    -Or can I just call the function in a task attached say to a semaphore?

    Say that I terminate the connection will I be able to reset the advertising using this method?
    -Say I start off with advertising off ... then I turn it on ... I do not connect thus I turn it off.... after some time I turn it on again this time I connect and then after that connection is done I turn off the advertising again..... then repeat this pattern as needed.
    --This question is asking will this function work within all these states? (Non-connected on, Non-connected off , connected to off)

    I think the error in hind sight was that in SimpleBLEPeripheral ->SimpleBLEPeripheral_performPeriodicTask(void) will only trigger when connected correct?

    This would mean that if advertising was set to false in setup it would never turn on unless when I use to make a call too something like this

    void SimpleBLEPeripheral_BLE_RADIO(uint8_t states){
    if(states==1)
    {
    en=1;
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, 1, &en ); // 1=on
    }
    if(states==0)
    {
    en=0;
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, 1, &en ); // 0=off
    }

    }

    But this wasn't placed in a clock object as the timeout fxn call it was just a function I called from say.....main.c

    This would work when the device was not connected... But wouldn't ever turn off the advertising even after a disconnection...
  • You don't have to use a clock object for that, there are plenty of different solution to enable advertising.

    For example, if you take a look at KeyFob project, you can see that the advertising is toggled by pressing KEY_RIGHT(change GPIO state).
    And this will solve your problem even after disconnecting from the master.
  • Thank you for another reference I will post here if I have any further questions.
  • So in KeyFob this is handled by events as well... Would directly calling GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, xxxx, xxxx ); True or False matter when it has been called?

    Say that I made a task that just sleeps and wakes up.... and it called GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, xxxx, xxxx ); and toggled the value... Would it matter in the state that it was called in? As I see that events are used in the KeyFob example...
  • Hi,

    No, it does not matter, but if you want to have better control of the state, using a button is always the easiest solution and easy to detect too.
  • So I had something that seemed to work in the stack version 2.1.1 in 2.2.0 I am getting errors in the connection when trying to start up advertising....

    So I wanted to come back into this question here.....

    If I create a clock as in SimpleBLEPeripheral.c wouldnt this clock only trigger if I am connected with a device... thus I would need an object outside of the example to enable the advertising.... when doing this in 2.2.0 it will connect and will now fail to send notification packets when it was working within 2.1.1.... have you heard of anything like this for this update?

    I will make another post later and will provide code I just wanted to reachout quickly....