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.

CC2640R2F: Simple peripheral: Stop and start advertisement(only for 120s) according to the data received in the UART

Part Number: CC2640R2F


SDK --> simplelink_cc2640r2_sdk_4_10_00_10

I am working on Simple peripheral project.

***** After starting up the advertisement should not be happening/Start *****

I am able to send data via UART to the application & when the UART receives data it is pushing an event to the queue.

The data received is correct and I want to do below operations in the task function:

Received Data:  { identification byte, control byte, 12byte for the name of the device(BLE), reserved bytes }

1) IF data received in the control byte is '1': Advertisement should start and name should be the one that is received & the advertisement should stop after 120s( BLE's name should not be visible to any device ).

2) IF data received in the control byte is '2':

  • The advertisement should start and name should be the one that is received & the advertisement should stop after 120s( BLE's name should not be visible to any device ).
  • But the BLE device should be able to connect to the phone which is already bonded with the device/already previously connected with the device.
  • And if before the 120s time period the control byte with '3' received the advertisement should stop immediately.

3) IF data received in the control byte is '3': Advertisement should stop immediately ( BLE's name should not be visible to any device ).

4) IF data received in the control byte is '4': The connection should be terminated immediately and after that advertisement should not start till '1' or '2' in the control byte received.

Please suggest an implementation.

below are my current implementation files:

/******************************************************************************

 @file  simple_peripheral.c

 @brief This file contains the Simple Peripheral sample application for use
        with the CC2650 Bluetooth Low Energy Protocol Stack.

 Group: WCS, BTS
 Target Device: cc2640r2

 ******************************************************************************

 Copyright (c) 2013-2020, Texas Instruments Incorporated
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 *  Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 *  Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

 *  Neither the name of Texas Instruments Incorporated nor the names of
    its contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 ******************************************************************************


 *****************************************************************************/

/*********************************************************************
 * INCLUDES
 */
#include <string.h>

#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/display/Display.h>

#if defined( USE_FPGA ) || defined( DEBUG_SW_TRACE )
#include <driverlib/ioc.h>
#endif // USE_FPGA | DEBUG_SW_TRACE

#include <icall.h>
#include "util.h"
#include "att_rsp.h"

/* This Header file contains all BLE API and icall structure definition */
#include "icall_ble_api.h"

#include "devinfoservice.h"
#include "simple_gatt_profile.h"
#include "ll_common.h"

#include "peripheral.h"

#ifdef USE_RCOSC
#include "rcosc_calibration.h"
#endif //USE_RCOSC

#include "board_key.h"

#include "board.h"

#include "simple_peripheral.h"
#include "uart_manager.h"
/*********************************************************************
 * CONSTANTS
 */
uint8_t arr[28];

//typedef struct
//{
//  appEvtHdr_t hdr;  // event header.
//  uint8_t *pData;  // event data
//} sbpEvt_t;

static uint8_t Autoconnection_flag = 0;
static uint8_t timer = 0;

#define DATA_PAYLOAD_SIZE                   0x1A // 26 in decimal

// Advertising interval when device is discoverable (units of 625us, 160=100ms)
#define DEFAULT_ADVERTISING_INTERVAL          160

// General discoverable mode: advertise indefinitely
#define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL

// Minimum connection interval (units of 1.25ms, 80=100ms) for automatic
// parameter update request
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80

// Maximum connection interval (units of 1.25ms, 800=1000ms) for automatic
// parameter update request
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800

// Slave latency to use for automatic parameter update request
#define DEFAULT_DESIRED_SLAVE_LATENCY         0

// Supervision timeout value (units of 10ms, 1000=10s) for automatic parameter
// update request
#define DEFAULT_DESIRED_CONN_TIMEOUT          1000

// After the connection is formed, the peripheral waits until the central
// device asks for its preferred connection parameters
#define DEFAULT_ENABLE_UPDATE_REQUEST         GAPROLE_LINK_PARAM_UPDATE_WAIT_REMOTE_PARAMS

// 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

// Application specific event ID for HCI Connection Event End Events
#define SBP_HCI_CONN_EVT_END_EVT              0x0001

// Type of Display to open
#if !defined(Display_DISABLE_ALL)
  #if defined(BOARD_DISPLAY_USE_LCD) && (BOARD_DISPLAY_USE_LCD!=0)
    #define SBP_DISPLAY_TYPE Display_Type_LCD
  #elif defined (BOARD_DISPLAY_USE_UART) && (BOARD_DISPLAY_USE_UART!=0)
    #define SBP_DISPLAY_TYPE Display_Type_UART
  #else // !BOARD_DISPLAY_USE_LCD && !BOARD_DISPLAY_USE_UART
    #define SBP_DISPLAY_TYPE 0 // Option not supported
  #endif // BOARD_DISPLAY_USE_LCD && BOARD_DISPLAY_USE_UART
#else // BOARD_DISPLAY_USE_LCD && BOARD_DISPLAY_USE_UART
  #define SBP_DISPLAY_TYPE 0 // No Display
#endif // !Display_DISABLE_ALL

// Task configuration
#define SBP_TASK_PRIORITY                     1

#ifndef SBP_TASK_STACK_SIZE
#define SBP_TASK_STACK_SIZE                   644
#endif

// Application events
#define SBP_STATE_CHANGE_EVT                  0x0001
#define SBP_CHAR_CHANGE_EVT                   0x0002
#define SBP_PAIRING_STATE_EVT                 0x0004
#define SBP_PASSCODE_NEEDED_EVT               0x0008
#define SBP_CONN_EVT                          0x0010
#define SBP_TEST_EVT1                         0x0020
#define SBP_TEST_EVT2                         0x0021

// Internal Events for RTOS application
#define SBP_ICALL_EVT                         ICALL_MSG_EVENT_ID // Event_Id_31
#define SBP_QUEUE_EVT                         UTIL_QUEUE_EVENT_ID // Event_Id_30
#define SBP_PERIODIC_EVT                      Event_Id_00

#define ADV_PERIODIC_EVT                      Event_Id_01 //Timer_120s
#define ADV_PERIODIC_EVT_PERIOD               1000*1 //1000 = 1sec //Timer_120s

// Bitwise OR of all events to pend on
#define SBP_ALL_EVENTS                        (SBP_ICALL_EVT        | \
                                               SBP_QUEUE_EVT        | \
                                               ADV_PERIODIC_EVT     | \
                                               SBP_PERIODIC_EVT)

static Clock_Struct periodicClockAdv;  //Timer_120s

// Set the register cause to the registration bit-mask
#define CONNECTION_EVENT_REGISTER_BIT_SET(RegisterCause) (connectionEventRegisterCauseBitMap |= RegisterCause )
// Remove the register cause from the registration bit-mask
#define CONNECTION_EVENT_REGISTER_BIT_REMOVE(RegisterCause) (connectionEventRegisterCauseBitMap &= (~RegisterCause) )
// Gets whether the current App is registered to the receive connection events
#define CONNECTION_EVENT_IS_REGISTERED (connectionEventRegisterCauseBitMap > 0)
// Gets whether the RegisterCause was registered to recieve connection event
#define CONNECTION_EVENT_REGISTRATION_CAUSE(RegisterCause) (connectionEventRegisterCauseBitMap & RegisterCause )

/*********************************************************************
 * TYPEDEFS
 */

/*********************************************************************
 * GLOBAL VARIABLES
 */

// Display Interface
Display_Handle dispHandle = NULL;

// Event globally used to post local events and pend on system and
// local events.
ICall_SyncHandle syncEvent;

Queue_Handle appMsgQueue;

/*********************************************************************
 * LOCAL VARIABLES
 */

// Entity ID globally used to check for source and/or destination of messages
static ICall_EntityID selfEntity;

// Clock instances for internal periodic events.
static Clock_Struct periodicClock;

// Queue object used for app messages
static Queue_Struct appMsg;

// Task configuration
Task_Struct sbpTask;
Char sbpTaskStack[SBP_TASK_STACK_SIZE];

// Scan response data (max size = 31 bytes)
static uint8_t scanRspData[] =
{
  // complete name
  13,//0x14,   // length of this data
  GAP_ADTYPE_LOCAL_NAME_COMPLETE,
  'S',
  'A',
  'S',
  ' ',
  ' ',
  ' ',
  ' ',
  ' ',
  ' ',
  ' ',
  ' ',
  ' ',
//  ' ',
//  ' ',
//  ' ',
//  ' ',
//  ' ',

  // 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
};

// Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertising)
static uint8_t advertData[] =
{
  // Flags: this field sets the device to use general discoverable
  // mode (advertises indefinitely) instead of general
  // discoverable mode (advertise for 30 seconds at a time)
  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
  LO_UINT16(SIMPLEPROFILE_SERV_UUID),
  HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};

// GAP GATT Attributes
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple Peripheral";


/*********************************************************************
 * LOCAL FUNCTIONS
 */

static void SimplePeripheral_init( void );
static void SimplePeripheral_taskFxn(UArg a0, UArg a1);

static uint8_t SimplePeripheral_processStackMsg(ICall_Hdr *pMsg);
static uint8_t SimplePeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
static void SimplePeripheral_processAppMsg(sbpEvt_t *pMsg);
static void SimplePeripheral_processStateChangeEvt(gaprole_States_t newState);
static void SimplePeripheral_processCharValueChangeEvt(uint8_t paramID);
static void SimplePeripheral_performPeriodicTask(void);
static void SimplePeripheral_clockHandler(UArg arg);

static void SimplePeripheral_passcodeCB(uint8_t *deviceAddr,
                                        uint16_t connHandle,
                                        uint8_t uiInputs, uint8_t uiOutputs,
                                        uint32_t numComparison);
static void SimplePeripheral_pairStateCB(uint16_t connHandle, uint8_t state,
                                         uint8_t status);
static void SimplePeripheral_processPairState(uint8_t state, uint8_t status);
static void SimplePeripheral_processPasscode(uint8_t uiOutputs);

static void SimplePeripheral_stateChangeCB(gaprole_States_t newState);
static void SimplePeripheral_charValueChangeCB(uint8_t paramID);
static uint8_t SimplePeripheral_enqueueMsg(uint8_t event, uint8_t state,
                                              uint8_t *pData);

static void SimplePeripheral_connEvtCB(Gap_ConnEventRpt_t *pReport);
static void SimplePeripheral_processConnEvt(Gap_ConnEventRpt_t *pReport);
static void SimplePeripheral_TestEvent(uint8_t state, uint8_t* status);
static void SimplePeripheral_TestEvent1(uint8_t state, uint8_t* status);


/*********************************************************************
 * EXTERN FUNCTIONS
 */
extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);

/*********************************************************************
 * PROFILE CALLBACKS
 */

// Peripheral GAPRole Callbacks
static gapRolesCBs_t SimplePeripheral_gapRoleCBs =
{
  SimplePeripheral_stateChangeCB     // GAPRole State Change Callbacks
};

// GAP Bond Manager Callbacks
// These are set to NULL since they are not needed. The application
// is set up to only perform justworks pairing.
static gapBondCBs_t simplePeripheral_BondMgrCBs =
{
  SimplePeripheral_passcodeCB,  // Passcode callback
  SimplePeripheral_pairStateCB  // Pairing / Bonding state Callback
};

// Simple GATT Profile Callbacks
static simpleProfileCBs_t SimplePeripheral_simpleProfileCBs =
{
  SimplePeripheral_charValueChangeCB // Simple GATT Characteristic value change callback
};

/*********************************************************************
 * PUBLIC FUNCTIONS
 */

/*********************************************************************
 * The following typedef and global handle the registration to connection event
 */
typedef enum
{
   NOT_REGISTER       = 0,
   FOR_AOA_SCAN       = 1,
   FOR_ATT_RSP        = 2,
   FOR_AOA_SEND       = 4,
   FOR_TOF_SEND       = 8
}connectionEventRegisterCause_u;

// Handle the registration and un-registration for the connection event, since only one can be registered.
uint32_t       connectionEventRegisterCauseBitMap = NOT_REGISTER; //see connectionEventRegisterCause_u

/*********************************************************************
 * @fn      SimplePeripheral_RegistertToAllConnectionEvent()
 *
 * @brief   register to receive connection events for all the connection
 *
 * @param connectionEventRegisterCause represents the reason for registration
 *
 * @return @ref SUCCESS
 *
 */
bStatus_t SimplePeripheral_RegistertToAllConnectionEvent (connectionEventRegisterCause_u connectionEventRegisterCause)
{
  bStatus_t status = SUCCESS;

  // in case  there is no registration for the connection event, make the registration
  if (!CONNECTION_EVENT_IS_REGISTERED)
  {
    status = GAP_RegisterConnEventCb(SimplePeripheral_connEvtCB, GAP_CB_REGISTER, LINKDB_CONNHANDLE_ALL);
  }
  if(status == SUCCESS)
  {
    //add the reason bit to the bitamap.
    CONNECTION_EVENT_REGISTER_BIT_SET(connectionEventRegisterCause);
  }

  return(status);
}

/*********************************************************************
 * @fn      SimplePeripheral_UnRegistertToAllConnectionEvent()
 *
 * @brief   Unregister connection events
 *
 * @param connectionEventRegisterCause represents the reason for registration
 *
 * @return @ref SUCCESS
 *
 */
bStatus_t SimplePeripheral_UnRegistertToAllConnectionEvent (connectionEventRegisterCause_u connectionEventRegisterCause)
{
  bStatus_t status = SUCCESS;

  CONNECTION_EVENT_REGISTER_BIT_REMOVE(connectionEventRegisterCause);
  // in case  there is no more registration for the connection event than unregister
  if (!CONNECTION_EVENT_IS_REGISTERED)
  {
    GAP_RegisterConnEventCb(SimplePeripheral_connEvtCB, GAP_CB_UNREGISTER, LINKDB_CONNHANDLE_ALL);
  }

  return(status);
}

 /*********************************************************************
 * @fn      SimplePeripheral_createTask
 *
 * @brief   Task creation function for the Simple Peripheral.
 *
 * @param   None.
 *
 * @return  None.
 */
void SimplePeripheral_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, SimplePeripheral_taskFxn, &taskParams, NULL);
}

/*********************************************************************
 * @fn      SimplePeripheral_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 SimplePeripheral_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, &syncEvent);

#ifdef USE_RCOSC
  RCOSC_enableCalibration();
#endif // USE_RCOSC

#if defined( USE_FPGA )
  // configure RF Core SMI Data Link
  IOCPortConfigureSet(IOID_12, IOC_PORT_RFC_GPO0, IOC_STD_OUTPUT);
  IOCPortConfigureSet(IOID_11, IOC_PORT_RFC_GPI0, IOC_STD_INPUT);

  // configure RF Core SMI Command Link
  IOCPortConfigureSet(IOID_10, IOC_IOCFG0_PORT_ID_RFC_SMI_CL_OUT, IOC_STD_OUTPUT);
  IOCPortConfigureSet(IOID_9, IOC_IOCFG0_PORT_ID_RFC_SMI_CL_IN, IOC_STD_INPUT);

  // configure RF Core tracer IO
  IOCPortConfigureSet(IOID_8, IOC_PORT_RFC_TRC, IOC_STD_OUTPUT);
#else // !USE_FPGA
  #if defined( DEBUG_SW_TRACE )
    // configure RF Core tracer IO
    IOCPortConfigureSet(IOID_8, IOC_PORT_RFC_TRC, IOC_STD_OUTPUT | IOC_CURRENT_4MA | IOC_SLEW_ENABLE);
  #endif // DEBUG_SW_TRACE
#endif // USE_FPGA

    /************/
    Util_constructClock(&periodicClockAdv, SimplePeripheral_clockHandler,
                        ADV_PERIODIC_EVT_PERIOD, 0, false, ADV_PERIODIC_EVT);
    //Util_startClock(&periodicClockAdv);
    /************/

  // 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, SimplePeripheral_clockHandler,
                      SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);

  dispHandle = Display_open(SBP_DISPLAY_TYPE, NULL);

  // Set GAP Parameters: After a connection was established, delay in seconds
  // before sending when GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE,...)
  // uses GAPROLE_LINK_PARAM_UPDATE_INITIATE_BOTH_PARAMS or
  // GAPROLE_LINK_PARAM_UPDATE_INITIATE_APP_PARAMS
  // For current defaults, this has no effect.
  GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);

  // Start the Device:
  // Please Notice that in case of wanting to use the GAPRole_SetParameter
  // function with GAPROLE_IRK or GAPROLE_SRK parameter - Perform
  // these function calls before the GAPRole_StartDevice use.
  // (because Both cases are updating the gapRole_IRK & gapRole_SRK variables).
  //VOID GAPRole_StartDevice(&SimplePeripheral_gapRoleCBs);

  // Setup the Peripheral GAPRole Profile. For more information see the User's
  // Guide:
  // http://software-dl.ti.com/lprf/sdg-latest/html/
  {
    // 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 re-enabled by the application
    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;

    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 Device Name characteristic in the GAP GATT Service
  // For more information, see the section in the User's Guide:
  // http://software-dl.ti.com/lprf/sdg-latest/html
  GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);

  // Set GAP Parameters to set the advertising interval
  // For more information, see the GAP section of the User's Guide:
  // http://software-dl.ti.com/lprf/sdg-latest/html
  {
    // Use the same interval for general and limited advertising.
    // Note that only general advertising will occur based on the above configuration
    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. For more information see the section in the
  // User's Guide:
  // http://software-dl.ti.com/lprf/sdg-latest/html/
  {
    // Don't send a pairing request after connecting; the peer device must
    // initiate pairing
    uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE;
    // Use authenticated pairing: require passcode.
    uint8_t mitm = FALSE;
    // This device only has display capabilities. Therefore, it will display the
    // passcode during pairing. However, since the default passcode is being
    // used, there is no need to display anything.
    uint8_t ioCap = GAPBOND_IO_CAP_NO_INPUT_NO_OUTPUT;
    // Request bonding (storing long-term keys for re-encryption upon subsequent
    // connections without repairing)
    uint8_t bonding = TRUE;
    // Whether to replace the least recently used entry when bond list is full,
    // and a new device is bonded.
    // Alternative is pairing succeeds but bonding fails, unless application has
    // manually erased at least one bond.
    uint8_t replaceBonds = FALSE;

    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);
    GAPBondMgr_SetParameter(GAPBOND_LRU_BOND_REPLACEMENT, sizeof(uint8_t), &replaceBonds);
  }

  // Initialize GATT attributes
  GGS_AddService(GATT_ALL_SERVICES);           // GAP GATT Service
  GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT Service
  DevInfo_AddService();                        // Device Information Service
  SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile

  // Setup the SimpleProfile Characteristic Values
  // For more information, see the sections in the User's Guide:
  // http://software-dl.ti.com/lprf/sdg-latest/html/
  {
    uint8_t charValue1[SIMPLEPROFILE_CHAR1_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    uint8_t charValue2[SIMPLEPROFILE_CHAR2_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1,SIMPLEPROFILE_CHAR1_LEN,
                               charValue1);

    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2,SIMPLEPROFILE_CHAR2_LEN,
                               charValue2);
  }

  // Register callback with SimpleGATTprofile
  SimpleProfile_RegisterAppCBs(&SimplePeripheral_simpleProfileCBs);

  // Start Bond Manager and register callback
  VOID GAPBondMgr_Register(&simplePeripheral_BondMgrCBs);

  // Register with GAP for HCI/Host messages. This is needed to receive HCI
  // events. For more information, see the section in the User's Guide:
  // http://software-dl.ti.com/lprf/sdg-latest/html
  GAP_RegisterForMsgs(selfEntity);

  // Register for GATT local events and ATT Responses pending for transmission
  GATT_RegisterForMsgs(selfEntity);

  //Set default values for Data Length Extension
  {
    //Set initial values to maximum, RX is set to max. by default(251 octets, 2120us)
    #define APP_SUGGESTED_PDU_SIZE 251 //default is 27 octets(TX)
    #define APP_SUGGESTED_TX_TIME 2120 //default is 328us(TX)

    //This API is documented in hci.h
    //See the LE Data Length Extension section in the BLE-Stack User's Guide for information on using this command:
    //http://software-dl.ti.com/lprf/sdg-latest/html/cc2640/index.html
    //HCI_LE_WriteSuggestedDefaultDataLenCmd(APP_SUGGESTED_PDU_SIZE, APP_SUGGESTED_TX_TIME);
  }

#if !defined (USE_LL_CONN_PARAM_UPDATE)
  // Get the currently set local supported LE features
  // The HCI will generate an HCI event that will get received in the main
  // loop
  HCI_LE_ReadLocalSupportedFeaturesCmd();
#endif // !defined (USE_LL_CONN_PARAM_UPDATE)

  Display_print0(dispHandle, 0, 0, "BLE Peripheral");
}

/*********************************************************************
 * @fn      SimplePeripheral_taskFxn
 *
 * @brief   Application task entry point for the Simple Peripheral.
 *
 * @param   a0, a1 - not used.
 *
 * @return  None.
 */
uint8_t * t_arr;
static void SimplePeripheral_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  SimplePeripheral_init();
  //GATT_UpdateMTU( (uint16) connHandle, (uint16) 40 );

  // Application main loop
  for (;;)
  {
    uint32_t events;

    // Waits for an event to be posted associated with the calling thread.
    // Note that an event associated with a thread is posted when a
    // message is queued to the message receive queue of the thread
    events = Event_pend(syncEvent, Event_Id_NONE, SBP_ALL_EVENTS,
                        ICALL_TIMEOUT_FOREVER);

    if (events)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;

      // Fetch any available messages that might have been sent from the stack
      if (ICall_fetchServiceMsg(&src, &dest,
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        uint8 safeToDealloc = TRUE;

        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;

          if (pEvt->signature != 0xffff)
          {
            // Process inter-task message
            safeToDealloc = SimplePeripheral_processStackMsg((ICall_Hdr *)pMsg);
          }
        }

        if (pMsg && safeToDealloc)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      if (events & SBP_QUEUE_EVT)
      {
        while (!Queue_empty(appMsgQueue))
        {
          sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
          if (pMsg)
          {
            // Process message.
            SimplePeripheral_processAppMsg(pMsg);

            // Free the space from the message.
            ICall_free(pMsg);
          }
        }
      }

      if (events & SBP_PERIODIC_EVT)
      {
        Util_startClock(&periodicClock);

        // Perform periodic application task
        SimplePeripheral_performPeriodicTask();
      }

      if (events & ADV_PERIODIC_EVT)
      {
        if(Autoconnection_flag == 1)
        {
            //Util_stopClock(&periodicClockAdv);  //Timer_120s
            if(timer < 20) //20s
            {
                timer++;
                //Util_startClock(&periodicClockAdv);  //Timer_120s
                Util_restartClock(&periodicClockAdv,1000);
            }
            else
            {
                timer=0;
                *t_arr=3;
                SimplePeripheral_TestEvent(1,(uint8_t *)t_arr);
            }
        }
      }
    }
  }
}

/*********************************************************************
 * @fn      SimplePeripheral_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 SimplePeripheral_processStackMsg(ICall_Hdr *pMsg)
{
  uint8_t safeToDealloc = TRUE;

  switch (pMsg->event)
  {
    case GATT_MSG_EVENT:
      // Process GATT message
      safeToDealloc = SimplePeripheral_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
            {

#if !defined (USE_LL_CONN_PARAM_UPDATE)
              // This code will disable the use of the LL_CONNECTION_PARAM_REQ
              // control procedure (for connection parameter updates, the
              // L2CAP Connection Parameter Update procedure will be used
              // instead). To re-enable the LL_CONNECTION_PARAM_REQ control
              // procedures, define the symbol USE_LL_CONN_PARAM_UPDATE
              // The L2CAP Connection Parameter Update procedure is used to
              // support a delta between the minimum and maximum connection
              // intervals required by some iOS devices.

              // Parse Command Complete Event for opcode and status
              hciEvt_CmdComplete_t* command_complete = (hciEvt_CmdComplete_t*) pMsg;
              uint8_t   pktStatus = command_complete->pReturnParam[0];

              //find which command this command complete is for
              switch (command_complete->cmdOpcode)
              {
                case HCI_LE_READ_LOCAL_SUPPORTED_FEATURES:
                  {
                    if (pktStatus == SUCCESS)
                    {
                      uint8_t featSet[8];

                      // Get current feature set from received event (bits 1-9
                      // of the returned data
                      memcpy( featSet, &command_complete->pReturnParam[1], 8 );

                      // Clear bit 1 of byte 0 of feature set to disable LL
                      // Connection Parameter Updates
                      CLR_FEATURE_FLAG( featSet[0], LL_FEATURE_CONN_PARAMS_REQ );

                      // Update controller with modified features
                      HCI_EXT_SetLocalSupportedFeaturesCmd( featSet );
                    }
                  }
                  break;

                default:
                  //do nothing
                  break;
              }
#endif // !defined (USE_LL_CONN_PARAM_UPDATE)

            }
            break;

          case HCI_BLE_HARDWARE_ERROR_EVENT_CODE:
            AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0);
            break;

          default:
            break;
        }
      }
      break;

      default:
        // do nothing
        break;

    }

  return (safeToDealloc);
}

/*********************************************************************
 * @fn      SimplePeripheral_processGATTMsg
 *
 * @brief   Process GATT messages and events.
 *
 * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
 */
static uint8_t SimplePeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
{
  // See if GATT server was unable to transmit an ATT response
  if (attRsp_isAttRsp(pMsg))
  {
    // No HCI buffer was available. Let's try to retransmit the response
    // on the next connection event.
    if( SimplePeripheral_RegistertToAllConnectionEvent(FOR_ATT_RSP) == SUCCESS)
    {
      // 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.
    Display_print1(dispHandle, 5, 0, "FC Violated: %d", pMsg->msg.flowCtrlEvt.opcode);
  }
  else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
  {
    // MTU size updated
    Display_print1(dispHandle, 5, 0, "MTU Size: %d", pMsg->msg.mtuEvt.MTU);
  }

  // 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      SimplePeripheral_processConnEvt
 *
 * @brief   Process connection event.
 *
 * @param pReport pointer to connection event report
 */
static void SimplePeripheral_processConnEvt(Gap_ConnEventRpt_t *pReport)
{

  if( CONNECTION_EVENT_REGISTRATION_CAUSE(FOR_ATT_RSP))
  {
    // The GATT server might have returned a blePending as it was trying
    // to process an ATT Response. Now that we finished with this
    // connection event, let's try sending any remaining ATT Responses
    // on the next connection event.
    // Try to retransmit pending ATT Response (if any)
    if (attRsp_sendAttRsp() == SUCCESS)
    {
        // Disable connection event end notice
        SimplePeripheral_UnRegistertToAllConnectionEvent (FOR_ATT_RSP);
    }
  }

}

/*********************************************************************
 * @fn      SimplePeripheral_processAppMsg
 *
 * @brief   Process an incoming callback from a profile.
 *
 * @param   pMsg - message to process
 *
 * @return  None.
 */
static void SimplePeripheral_processAppMsg(sbpEvt_t *pMsg)
{
  switch (pMsg->hdr.event)
  {
    case SBP_STATE_CHANGE_EVT:
      {
        SimplePeripheral_processStateChangeEvt((gaprole_States_t)pMsg->
                                                hdr.state);
      }
      break;

    case SBP_CHAR_CHANGE_EVT:
      {
        SimplePeripheral_processCharValueChangeEvt(pMsg->hdr.state);
      }
      break;

    // Pairing event
    case SBP_PAIRING_STATE_EVT:
      {
        SimplePeripheral_processPairState(pMsg->hdr.state, *pMsg->pData);

        ICall_free(pMsg->pData);
        break;
      }

    // Passcode event
    case SBP_PASSCODE_NEEDED_EVT:
      {
        SimplePeripheral_processPasscode(*pMsg->pData);

        ICall_free(pMsg->pData);
        break;
      }

    case SBP_CONN_EVT:
      {
        SimplePeripheral_processConnEvt((Gap_ConnEventRpt_t *)(pMsg->pData));

        ICall_free(pMsg->pData);
        break;
      }

    case SBP_TEST_EVT1:
      {
        /* 0x30 :: Process Connection request from UART (Manual pairing/ auto connection) */
        SimplePeripheral_TestEvent(pMsg->hdr.state,(uint8_t *)pMsg->pData);

        ICall_free(pMsg->pData);
        break;
      }

    case SBP_TEST_EVT2:
      {
        /* 0x37 :: SUZUKI_CLUSTER_STATUS_PKT */
        SimplePeripheral_TestEvent1(pMsg->hdr.state, (uint8_t*)pMsg->pData);

        ICall_free(pMsg->pData);
        break;
      }

    default:
      // Do nothing.
      break;
  }
}

/*********************************************************************
 * @fn      SimplePeripheral_stateChangeCB
 *
 * @brief   Callback from GAP Role indicating a role state change.
 *
 * @param   newState - new state
 *
 * @return  None.
 */
static void SimplePeripheral_stateChangeCB(gaprole_States_t newState)
{
  SimplePeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState, NULL);
}

/*********************************************************************
 * @fn      SimplePeripheral_processStateChangeEvt
 *
 * @brief   Process a pending GAP Role state change event.
 *
 * @param   newState - new state
 *
 * @return  None.
 */
static void SimplePeripheral_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); //-saurav

        // use 6 bytes of device address for 8 bytes of system ID value
        systemId[0] = 1;//ownAddress[0];
        systemId[1] = 1;//ownAddress[1];
        systemId[2] = 1;//ownAddress[2];

        // set middle bytes to zero
        systemId[4] = 1;//0x00;
        systemId[3] = 1;//0x00;

        // shift three bytes up
        systemId[7] = 2;//ownAddress[5];
        systemId[6] = 2;//ownAddress[4];
        systemId[5] = 2;//ownAddress[3];

        /* The SystemID is updated as default as of now - saurav */
        DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);

        // Display device address
        Display_print0(dispHandle, 1, 0, Util_convertBdAddr2Str(ownAddress));
        Display_print0(dispHandle, 2, 0, "Initialized");

        // Device starts advertising upon initialization of GAP
        uint8_t initialAdvertEnable = TRUE;
        // Set the Peripheral GAPRole Parameters
        GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                         &initialAdvertEnable);
      }
      break;

    case GAPROLE_ADVERTISING:
      Display_print0(dispHandle, 2, 0, "Advertising");
      break;

#ifdef PLUS_BROADCASTER
    // After a connection is dropped, a device in PLUS_BROADCASTER will continue
    // sending non-connectable advertisements and shall send 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;

        attRsp_freeAttRsp(bleNotConnected);
      }
      break;
#endif //PLUS_BROADCASTER

    case GAPROLE_CONNECTED:
      {
        linkDBInfo_t linkInfo;
        uint8_t numActive = 0;

        Util_startClock(&periodicClock);

        numActive = linkDB_NumActive();

        // Use numActive to determine the connection handle of the last
        // connection
        if ( linkDB_GetInfo( numActive - 1, &linkInfo ) == SUCCESS )
        {
          Display_print1(dispHandle, 2, 0, "Num Conns: %d", (uint16_t)numActive);
          Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(linkInfo.addr));
        }
        else
        {
          uint8_t peerAddress[B_ADDR_LEN];

          GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);

          Display_print0(dispHandle, 2, 0, "Connected");
          Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(peerAddress));
        }

        #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-connectable 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:
      Display_print0(dispHandle, 2, 0, "Connected Advertising");
      break;

    case GAPROLE_WAITING:
      {
        //uint8_t advertReEnable = FALSE;//TRUE;

        Util_stopClock(&periodicClock);
        attRsp_freeAttRsp(bleNotConnected);

        // Clear remaining lines
        Display_clearLines(dispHandle, 3, 5);

        //GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertReEnable);
        Display_print0(dispHandle, 2, 0, "Advertising");
      }
      break;

    case GAPROLE_WAITING_AFTER_TIMEOUT:
      attRsp_freeAttRsp(bleNotConnected);

      Display_print0(dispHandle, 2, 0, "Timed Out");

      // Clear remaining lines
      Display_clearLines(dispHandle, 3, 5);

      #ifdef PLUS_BROADCASTER
        // Reset flag for next connection.
        firstConnFlag = false;
      #endif // PLUS_BROADCASTER
      break;

    case GAPROLE_ERROR:
      Display_print0(dispHandle, 2, 0, "Error");
      break;

    default:
      Display_clearLine(dispHandle, 2);
      break;
  }
}

/*********************************************************************
 * @fn      SimplePeripheral_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 SimplePeripheral_charValueChangeCB(uint8_t paramID)
{
  SimplePeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID, 0);
}

/*********************************************************************
 * @fn      SimplePeripheral_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 SimplePeripheral_processCharValueChangeEvt(uint8_t paramID)
{
  uint8_t newValue;

  switch(paramID)
  {
    case SIMPLEPROFILE_CHAR1:
      SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);

      Display_print1(dispHandle, 4, 0, "Char 1: %d", (uint16_t)newValue);
      break;

    default:
      // should not reach here!
      break;
  }
}

/*********************************************************************
 * @fn      SimplePeripheral_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 SimplePeripheral_performPeriodicTask(void)
{
  uint8_t valueToCopy[SIMPLEPROFILE_CHAR1_LEN];
  uint8_t payload[] = {'0','0','0','0','0','0','0','0','0','0',
                       '0','0','0','0','0','0','0','0','0','0',
                       '0','0','0','0','0','0'};

  memset(valueToCopy, 0, SIMPLEPROFILE_CHAR1_LEN);
  //memset(payload, 0, DATA_PAYLOAD_SIZE);

  // Call to retrieve the value of the First characteristic in the profile
  // 0x31 - 0x36 :: APP to BLE
  if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, valueToCopy) == SUCCESS)
  {
    for ( uint8_t i=2 ; i<DATA_PAYLOAD_SIZE+2 ; i++ )
    {
        payload[i-2] = valueToCopy[i];
    }

    UartManager_SetStatus(valueToCopy[1], payload); /* send to uart */
  }
}

/*********************************************************************
 * @fn      SimplePeripheral_pairStateCB
 *
 * @brief   Pairing state callback.
 *
 * @return  none
 */
static void SimplePeripheral_pairStateCB(uint16_t connHandle, uint8_t state,
                                            uint8_t status)
{
  uint8_t *pData;

  // Allocate space for the event data.
  if ((pData = ICall_malloc(sizeof(uint8_t))))
  {
    *pData = status;

    // Queue the event.
    SimplePeripheral_enqueueMsg(SBP_PAIRING_STATE_EVT, state, pData);
  }
}

/*********************************************************************
 * @fn      SimplePeripheral_processPairState
 *
 * @brief   Process the new paring state.
 *
 * @return  none
 */
static void SimplePeripheral_processPairState(uint8_t state, uint8_t status)
{
  if (state == GAPBOND_PAIRING_STATE_STARTED)
  {
    Display_print0(dispHandle, 2, 0, "Pairing started");
  }
  else if (state == GAPBOND_PAIRING_STATE_COMPLETE)
  {
    if (status == SUCCESS)
    {
      Display_print0(dispHandle, 2, 0, "Pairing success");
    }
    else
    {
      Display_print1(dispHandle, 2, 0, "Pairing fail: %d", status);
    }
  }
  else if (state == GAPBOND_PAIRING_STATE_BONDED)
  {
    if (status == SUCCESS)
    {
      Display_print0(dispHandle, 2, 0, "Bonding success");
    }
  }
  else if (state == GAPBOND_PAIRING_STATE_BOND_SAVED)
  {
    if (status == SUCCESS)
    {
      Display_print0(dispHandle, 2, 0, "Bond save success");
    }
    else
    {
      Display_print1(dispHandle, 2, 0, "Bond save failed: %d", status);
    }
  }
}

/*********************************************************************
 * @fn      SimplePeripheral_passcodeCB
 *
 * @brief   Passcode callback.
 *
 * @return  none
 */
static void SimplePeripheral_passcodeCB(uint8_t *deviceAddr,
                                        uint16_t connHandle,
                                        uint8_t uiInputs,
                                        uint8_t uiOutputs,
                                        uint32_t numComparison)
{
  uint8_t *pData;

  // Allocate space for the passcode event.
  if ((pData = ICall_malloc(sizeof(uint8_t))))
  {
    *pData = uiOutputs;

    // Enqueue the event.
    SimplePeripheral_enqueueMsg(SBP_PASSCODE_NEEDED_EVT, 0, pData);
  }
}

/*********************************************************************
 * @fn      SimplePeripheral_processPasscode
 *
 * @brief   Process the Passcode request.
 *
 * @return  none
 */
static void SimplePeripheral_processPasscode(uint8_t uiOutputs)
{
  // This app uses a default passcode. A real-life scenario would handle all
  // pairing scenarios and likely generate this randomly.
  uint32_t passcode = B_APP_DEFAULT_PASSCODE;

  // Display passcode to user
  if (uiOutputs != 0)
  {
    Display_print1(dispHandle, 4, 0, "Passcode: %d", passcode);
  }

  uint16_t connectionHandle;
  GAPRole_GetParameter(GAPROLE_CONNHANDLE, &connectionHandle);

  // Send passcode response
  GAPBondMgr_PasscodeRsp(connectionHandle, SUCCESS, passcode);
}

/*********************************************************************
 * @fn      SimplePeripheral_clockHandler
 *
 * @brief   Handler function for clock timeouts.
 *
 * @param   arg - event type
 *
 * @return  None.
 */
static void SimplePeripheral_clockHandler(UArg arg)
{
  // Wake up the application.
  Event_post(syncEvent, arg);
}

/*********************************************************************
 * @fn      SimplePeripheral_connEvtCB
 *
 * @brief   Connection event callback.
 *
 * @param pReport pointer to connection event report
 */
static void SimplePeripheral_connEvtCB(Gap_ConnEventRpt_t *pReport)
{
  // Enqueue the event for processing in the app context.
  if( SimplePeripheral_enqueueMsg(SBP_CONN_EVT, 0 ,(uint8_t *) pReport) == FALSE)
  {
    ICall_free(pReport);
  }

}

/*********************************************************************
 * @fn      SimplePeripheral_processPairState
 *
 * @brief   Process the new paring state.
 *
 * @return  none
 */
uint8_t advertEnabled1 = FALSE;
uint8_t Control_Data = 0;
static void SimplePeripheral_TestEvent(uint8_t state, uint8_t* status)
{
    //gaprole_States_t newState;

//    0x30 :: Process Connection request from UART (Manual pairing/ auto connection)
//    CONTROL DATA --> status[0]
//    0x01 : Start Manual Pairing
//    0x02 : Start Auto Connection
//    0x03 : Stop Auto Connection
//    0x04 : Disconnect

    Control_Data = (uint8_t)status[0];

    switch (Control_Data)
    {
        case 1:
            VOID GAPRole_StartDevice(&SimplePeripheral_gapRoleCBs);

            scanRspData[2] = (uint8_t)status[1];
            scanRspData[3] = (uint8_t)status[2];
            scanRspData[4] = (uint8_t)status[3];
            scanRspData[5] = (uint8_t)status[4];
            scanRspData[6] = (uint8_t)status[5];
            scanRspData[7] = (uint8_t)status[6];
            scanRspData[8] = (uint8_t)status[7];
            scanRspData[9] = (uint8_t)status[8];
            scanRspData[10] = (uint8_t)status[9];
            scanRspData[11] = (uint8_t)status[10];
            scanRspData[12] = (uint8_t)status[11];
            //scanRspData[13] = (uint8_t)status[12];

            GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                                 scanRspData);

            advertEnabled1 = TRUE;
            // Enabled advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabled1);
            break;

        case 2: /* Start Auto Connection */
            Util_startClock(&periodicClockAdv);  //Timer_120s

            Autoconnection_flag = 1;

            VOID GAPRole_StartDevice(&SimplePeripheral_gapRoleCBs);

            scanRspData[2] = (uint8_t)status[1];
            scanRspData[3] = (uint8_t)status[2];
            scanRspData[4] = (uint8_t)status[3];
            scanRspData[5] = (uint8_t)status[4];
            scanRspData[6] = (uint8_t)status[5];
            scanRspData[7] = (uint8_t)status[6];
            scanRspData[8] = (uint8_t)status[7];
            scanRspData[9] = (uint8_t)status[8];
            scanRspData[10] = (uint8_t)status[9];
            scanRspData[11] = (uint8_t)status[10];
            scanRspData[12] = (uint8_t)status[11];
            //scanRspData[13] = (uint8_t)status[12];

            GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                                 scanRspData);

            advertEnabled1 = TRUE;
            // Enabled advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                   &advertEnabled1);
            break;

        case 3: /* Stop Auto Connection */
            //Util_stopClock(&periodicClockAdv);  //Timer_120s

            Autoconnection_flag = 0;

            advertEnabled1 = FALSE;
            //Disabled advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabled1);

            //newState = GAPROLE_WAITING;//4
            SimplePeripheral_stateChangeCB((gaprole_States_t)4/*newState*/);
            break;

        case 4:
            GAPRole_TerminateConnection();

            advertEnabled1 = FALSE;
            //Disabled advertising.
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnabled1);

            //newState = GAPROLE_WAITING;//4
            SimplePeripheral_stateChangeCB((gaprole_States_t)4/*newState*/);
            break;

        default :
            break;
    }
    Control_Data = 0;
}


static void SimplePeripheral_TestEvent1(uint8_t state, uint8_t *status)
{
    /* 0x37 :: SUZUKI_CLUSTER_STATUS_PKT */

    uint8_t Temp[SIMPLEPROFILE_CHAR2_LEN] = { 0xA5, 0x37, 0, 0, 0, 0, 0, 0, 0, 0,
                                              0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                              0, 0, 0, 0, 0, 0, 0, 0, 0xEE, 0x7F};
    /* Data copying to Temp array */
    for ( uint8_t i=2 ; i< 28/*18*//*DATA_PAYLOAD_SIZE+2*/ ; i++ )
        Temp[i] = status[i-2];

    /* directly transferring the data to mobile via char2 */
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN,
                               Temp);
}

/*********************************************************************
 *
 * @brief   Creates a message and puts the message in RTOS queue.
 *
 * @param   event - message event.
 * @param   state - message state.
 * @param   pData - message data pointer.
 *
 * @return  TRUE or FALSE
 */
static uint8_t SimplePeripheral_enqueueMsg(uint8_t event, uint8_t state,
                                           uint8_t *pData)
{
  sbpEvt_t *pMsg = ICall_malloc(sizeof(sbpEvt_t));

  // Create dynamic pointer to message.
  if (pMsg)
  {
    pMsg->hdr.event = event;
    pMsg->hdr.state = state;
    pMsg->pData = pData;

    // Enqueue the message.
    return Util_enqueueMsg(appMsgQueue, syncEvent, (uint8_t *)pMsg);
  }

  return FALSE;
}
/*********************************************************************
*********************************************************************/
/******************************************************************************

 @file  uart_manager.c

 @brief This file contains the uart sample application for use
        with the CC2650 Bluetooth Low Energy Protocol Stack.

 Group: WCS, BTS
 Target Device: cc2640r2

 ******************************************************************************

 Copyright (c) 2013-2020, Texas Instruments Incorporated
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 *  Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 *  Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

 *  Neither the name of Texas Instruments Incorporated nor the names of
    its contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 ******************************************************************************


 *****************************************************************************/

/*********************************************************************
 * INCLUDES
 */
#include <string.h>

#include <xdc/std.h>
#include <icall.h>

#include <board.h>
#include <ti/drivers/UART.h>

#include "simple_peripheral.h"

/*********************************************************************
 * MACROS
 */

/*********************************************************************
 * CONSTANTS
 */

#define ACK                                     0x06
#define NACK                                    0x15

#define START_BYTE                              0xA5
#define END_BYTE                                0x7F

#define INFO_DATA_ID                            0x30
#define INFO_DATA_PAYLOAD_SIZE                  0x1A // 26 in decimal

#define NAV_DATA_ID                             0x31
#define NAV_DATA_PAYLOAD_SIZE                   0x1A // 26 in decimal

#define CALL_DATA_ID                            0x32
#define CALL_DATA_PAYLOAD_SIZE                  0x1A // 26 in decimal

#define SPSTATUS_DATA_ID                        0x33
#define SPSTATUS_DATA_PAYLOAD_SIZE              0x1A // 26 in decimal

#define MISSEDCALL_DATA_ID                      0x34
#define MISSEDCALL_DATA_PAYLOAD_SIZE            0x1A // 26 in decimal

#define SMS_DATA_ID                             0x35
#define SMS_DATA_PAYLOAD_SIZE                   0x1A // 26 in decimal

#define USERINFO_DATA_ID                        0x36
#define USERINFO_DATA_PAYLOAD_SIZE              0x1A // 26 in decimal

#define VECHILE_DATA_ID                         0x37
#define VECHILE_DATA_PAYLOAD_SIZE               0x1A // 26 in decimal

//#define ADVERTISEMENT_DATA_ID                0x38
//#define ADVERTISEMENT_DATA_PAYLOAD_SIZE      0x1A // 26 in decimal
//
//#define CONTROL_DATA_ID                      0x40
//#define CONTROL_DATA_PAYLOAD_SIZE            0x01
//
//#define BLE_STATUS_PAYLOAD_ID                0x39
//#define BLE_STATUS_PAYLOAD_SIZE              0x01

/*********************************************************************
 * TYPEDEFS
 */

typedef struct
{
  uint8_t Start_Byte;
  uint8_t Identification_Byte;
  uint8_t Payload_Data[INFO_DATA_PAYLOAD_SIZE];
  uint8_t Checksum;
  uint8_t End_Byte;
} InfoDataPacket_t;

typedef struct
{
  uint8_t Start_Byte;
  uint8_t Identification_Byte;
  uint8_t Payload_Data[NAV_DATA_PAYLOAD_SIZE];
  uint8_t Checksum;
  uint8_t End_Byte;
} NavDataPacket_t;

typedef struct
{
  uint8_t Start_Byte;
  uint8_t Identification_Byte;
  uint8_t Payload_Data[CALL_DATA_PAYLOAD_SIZE];
  uint8_t Checksum;
  uint8_t End_Byte;
} CallDataPacket_t;

typedef struct
{
  uint8_t Start_Byte;
  uint8_t Identification_Byte;
  uint8_t Payload_Data[SPSTATUS_DATA_PAYLOAD_SIZE];
  uint8_t Checksum;
  uint8_t End_Byte;
} SpStatusDataPacket_t;

typedef struct
{
  uint8_t Start_Byte;
  uint8_t Identification_Byte;
  uint8_t Payload_Data[MISSEDCALL_DATA_PAYLOAD_SIZE];
  uint8_t Checksum;
  uint8_t End_Byte;
} MissedCallDataPacket_t;

typedef struct
{
  uint8_t Start_Byte;
  uint8_t Identification_Byte;
  uint8_t Payload_Data[SMS_DATA_PAYLOAD_SIZE];
  uint8_t Checksum;
  uint8_t End_Byte;
} SmsDataPacket_t;

typedef struct
{
  uint8_t Start_Byte;
  uint8_t Identification_Byte;
  uint8_t Payload_Data[USERINFO_DATA_PAYLOAD_SIZE];
  uint8_t Checksum;
  uint8_t End_Byte;
} UserInfoDataPacket_t;

typedef struct
{
  uint8_t Start_Byte;
  uint8_t Identification_Byte;
  uint8_t Payload_Data[VECHILE_DATA_PAYLOAD_SIZE];
  uint8_t Checksum;
  uint8_t End_Byte;
} VechileDataPacket_t;

//typedef struct
//{
//  uint8_t Start_Byte;
//  uint8_t Identification_Byte;
//  uint8_t Payload_Data[ADVERTISEMENT_DATA_PAYLOAD_SIZE];
//  uint8_t Checksum;
//  uint8_t End_Byte;
//} AdvertisementDataPacket_t;
//
//typedef struct
//{
//  uint8_t Start_Byte;
//  uint8_t Identification_Byte;
//  uint8_t Payload_Data[BLE_STATUS_PAYLOAD_SIZE];
//  uint8_t Checksum;
//  uint8_t End_Byte;
//} BleStatusPacket_t;
//
//typedef struct
//{
//  uint8_t Start_Byte;
//  uint8_t Identification_Byte;
//  uint8_t Payload_Data[CONTROL_DATA_PAYLOAD_SIZE];
//  uint8_t Checksum;
//  uint8_t End_Byte;
//} ControlDataPacket_t;

/*********************************************************************
 * GLOBAL VARIABLES
 */

extern ICall_SyncHandle syncEvent;

extern Queue_Handle appMsgQueue;

/*********************************************************************
 * LOCAL VARIABLES
 */

static UART_Handle uart;
static UART_Params uartParams;

static uint8_t Req;

static bool Read_Req_status = TRUE;

InfoDataPacket_t stInfoData;

NavDataPacket_t stNavData =
{
 .Start_Byte = START_BYTE,
 .Identification_Byte = NAV_DATA_ID,
 .End_Byte = END_BYTE
};

CallDataPacket_t stCallData =
{
 .Start_Byte = START_BYTE,
 .Identification_Byte = CALL_DATA_ID,
 .End_Byte = END_BYTE
};

SpStatusDataPacket_t stSpStatus =
{
 .Start_Byte = START_BYTE,
 .Identification_Byte = SPSTATUS_DATA_ID,
 .End_Byte = END_BYTE
};

MissedCallDataPacket_t MissedCall =
{
 .Start_Byte = START_BYTE,
 .Identification_Byte = MISSEDCALL_DATA_ID,
 .End_Byte = END_BYTE
};

SmsDataPacket_t stSmsData =
{
 .Start_Byte = START_BYTE,
 .Identification_Byte = SMS_DATA_ID,
 .End_Byte = END_BYTE
};

UserInfoDataPacket_t stUserInfo =
{
 .Start_Byte = START_BYTE,
 .Identification_Byte = USERINFO_DATA_ID,
 .End_Byte = END_BYTE
};

VechileDataPacket_t stVechileData;

//BleStatusPacket_t stBleStatus =
//{
// .Start_Byte = START_BYTE,
// .Identification_Byte = BLE_STATUS_PAYLOAD_ID,
// .End_Byte = END_BYTE
//};

//AdvertisementDataPacket_t stAdvertisementData;
//
//ControlDataPacket_t stControlData;

/*********************************************************************
 * LOCAL FUNCTIONS
 */
static void UartManager_readCallBack(UART_Handle handle, void *ptr, size_t size);
static void UartManager_writeCallBack(UART_Handle handle, void *ptr, size_t size);
static uint8_t UartManager_enqueueMsg(uint8_t event, uint8_t state, uint8_t *pData);

/*********************************************************************
 * PUBLIC FUNCTIONS
 */

void UartManager_SetStatus(uint8_t ID, void* payload)
{
    switch (ID)
    {
        case NAV_DATA_ID:
            (void) memcpy( &stNavData.Payload_Data, payload, NAV_DATA_PAYLOAD_SIZE );
            break;

        case CALL_DATA_ID:
            (void) memcpy( &stCallData.Payload_Data, payload, CALL_DATA_PAYLOAD_SIZE );
            break;

        case SPSTATUS_DATA_ID:
            (void) memcpy( &stSpStatus.Payload_Data, payload, SPSTATUS_DATA_PAYLOAD_SIZE );
            break;

        case MISSEDCALL_DATA_ID:
            (void) memcpy( &MissedCall.Payload_Data, payload, MISSEDCALL_DATA_PAYLOAD_SIZE );
            break;

        case SMS_DATA_ID:
            (void) memcpy( &stSmsData.Payload_Data, payload, SMS_DATA_PAYLOAD_SIZE );
            break;

        case USERINFO_DATA_ID:
            (void) memcpy( &stUserInfo.Payload_Data, payload, USERINFO_DATA_PAYLOAD_SIZE );
            break;

        case VECHILE_DATA_ID:
            (void) memcpy( &stVechileData.Payload_Data, payload, VECHILE_DATA_PAYLOAD_SIZE );
            break;

        default:
            break;
    }
}

/*********************************************************************
 * @fn      UartManager_init
 *
 * @brief   Called during initialization and contains application
 *          specific initialization (ie. hardware initialization/setup,
 *          table initialization, power up notification, etc), and
 *          profile initialization/setup.
 */
void UartManager_init(void)
{
    UART_init();

    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.readCallback = UartManager_readCallBack;
    uartParams.writeMode = UART_MODE_CALLBACK;
    uartParams.writeCallback = UartManager_writeCallBack;
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;

    uart = UART_open(Board_UART0, &uartParams);

    if (uart == NULL) {
        /* UART_open() failed */
        while (1);
    }

    UART_read(uart, &Req, sizeof(Req));
}

static void UartManager_readCallBack(UART_Handle handle, void *ptr, size_t size)
{
    uint8_t ack = 0x06;
    uint8_t arr[28];

    switch (Req)
    {
        case INFO_DATA_ID:
            if (Read_Req_status == 1)
            {
                UART_write(uart, &ack, 1);
            }
            else
            {
                UART_read(uart, &Req, sizeof(Req));

                memcpy(arr,&stInfoData.Payload_Data, 28);
                (void)UartManager_enqueueMsg(0x0020, (uint8_t)stInfoData.Checksum, &arr);
                Read_Req_status = 1;
                Req = 0;
            }
            break;

        case NAV_DATA_ID:
            UART_write(uart, &ack, 1);
            break;

        case CALL_DATA_ID:
            UART_write(uart, &ack, 1);
            break;

        case SPSTATUS_DATA_ID:
            UART_write(uart, &ack, 1);
            break;

        case MISSEDCALL_DATA_ID:
            UART_write(uart, &ack, 1);
            break;

        case SMS_DATA_ID:
            UART_write(uart, &ack, 1);
            break;

        case USERINFO_DATA_ID:
            UART_write(uart, &ack, 1);
            break;

        case VECHILE_DATA_ID:
            if (Read_Req_status == 1)
            {
                UART_write(uart, &ack, 1);
            }
            else
            {
                UART_read(uart, &Req, sizeof(Req));

                memcpy(arr,&stVechileData.Payload_Data, 28);
                (void)UartManager_enqueueMsg(0x0021, (uint8_t)stVechileData.Checksum, &arr);
                Read_Req_status = 1;
                Req = 0;
            }
            break;

//        case ADVERTISEMENT_DATA_ID:
//            if (Read_Req_status == 1)
//            {
//                UART_write(uart, &ack, 1);
//            }
//            else
//            {
//                UART_read(uart, &Req, sizeof(Req));
//                (void)UartManager_enqueueMsg(0x0021, (uint8_t)stAdvertisementData.Checksum,
//                                             (uint8_t *)stAdvertisementData.Payload_Data);
//                Read_Req_status = 1;
//                Req = 0;
//            }
//            break;
//
//        case BLE_STATUS_PAYLOAD_ID:
//            UART_write(uart, &ack, 1);
//            break;
//
//        case CONTROL_DATA_ID:
//            if (Read_Req_status == 1)
//            {
//                UART_write(uart, &ack, 1);
//            }
//            else
//            {
//                UART_read(uart, &Req, sizeof(Req));
//                (void)UartManager_enqueueMsg(0x0022, (uint8_t)stControlData.Checksum,
//                                             (uint8_t *)stControlData.Payload_Data);
//                Read_Req_status = 1;
//                Req = 0;
//            }
//            break;

        default:
            Req = 0;
            UART_read(uart, &Req, sizeof(Req));
            break;
    }
}

static void UartManager_writeCallBack(UART_Handle handle, void *ptr, size_t size)
{
    switch (Req)
    {
        case INFO_DATA_ID:
            UART_read(uart, &stInfoData, sizeof(stInfoData));
            Read_Req_status = 0;
            break;

        case NAV_DATA_ID:
            stNavData.Checksum = 0xEE;
            UART_write(uart, &stNavData, sizeof(stNavData));
            UART_read(uart, &Req, sizeof(Req));
            Req = 0;
            break;

        case CALL_DATA_ID:
            UART_write(uart, &stCallData, sizeof(stCallData));
            UART_read(uart, &Req, sizeof(Req));
            Req = 0;
            break;

        case SPSTATUS_DATA_ID:
            UART_write(uart, &stSpStatus, sizeof(stSpStatus));
            UART_read(uart, &Req, sizeof(Req));
            Req = 0;
            break;

        case MISSEDCALL_DATA_ID:
            UART_write(uart, &MissedCall, sizeof(MissedCall));
            UART_read(uart, &Req, sizeof(Req));
            Req = 0;
            break;

        case SMS_DATA_ID:
            UART_write(uart, &stSmsData, sizeof(stSmsData));
            UART_read(uart, &Req, sizeof(Req));
            Req = 0;
            break;

        case USERINFO_DATA_ID:
            UART_write(uart, &stUserInfo, sizeof(stUserInfo));
            UART_read(uart, &Req, sizeof(Req));
            Req = 0;
            break;

        case VECHILE_DATA_ID:
            UART_read(uart, &stVechileData, sizeof(stVechileData));
            Read_Req_status = 0;
            break;

//        case ADVERTISEMENT_DATA_ID:
//            UART_read(uart, &stAdvertisementData, sizeof(stControlData));
//            Read_Req_status = 0;
//            break;
//
//        case BLE_STATUS_PAYLOAD_ID:
//            UART_write(uart, &stBleStatus, sizeof(stBleStatus));
//            UART_read(uart, &Req, sizeof(Req));
//            Req = 0;
//            break;
//
//        case CONTROL_DATA_ID:
//            UART_read(uart, &stControlData, sizeof(stControlData));
//            Read_Req_status = 0;
//            break;

        default:
            break;
    }
}

static uint8_t UartManager_enqueueMsg(uint8_t event, uint8_t state,
                                           uint8_t *pData)
{
  sbpEvt_t *pMsg = ICall_malloc(sizeof(sbpEvt_t));

  // Create dynamic pointer to message.
  if (pMsg)
  {
    pMsg->hdr.event = event;
    pMsg->hdr.state = state;
    pMsg->pData = pData;

    // Enqueue the message.
    return Util_enqueueMsg(appMsgQueue, syncEvent, (uint8_t *)pMsg);
  }

  return FALSE;
}

/*********************************************************************
*********************************************************************/
/******************************************************************************

 @file  simple_gatt_profile.c

 @brief This file contains the Simple GATT profile sample GATT service profile
        for use with the BLE sample application.

 Group: WCS, BTS
 Target Device: cc2640r2

 ******************************************************************************

 Copyright (c) 2010-2020, Texas Instruments Incorporated
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 *  Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

 *  Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

 *  Neither the name of Texas Instruments Incorporated nor the names of
    its contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 ******************************************************************************


 *****************************************************************************/

/*********************************************************************
 * INCLUDES
 */
#include <string.h>
#include <icall.h>
#include "util.h"
/* This Header file contains all BLE API and icall structure definition */
#include "icall_ble_api.h"

#include "simple_gatt_profile.h"

/*********************************************************************
 * MACROS
 */

/*********************************************************************
 * CONSTANTS
 */

#define SERVAPP_NUM_ATTR_SUPPORTED        8

/*********************************************************************
 * TYPEDEFS
 */

/*********************************************************************
 * GLOBAL VARIABLES
 */
// Simple GATT Profile Service UUID: 0xFFF0
CONST uint8 simpleProfileServUUID[ATT_BT_UUID_SIZE] =
{
  LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};

// Characteristic 1 UUID: 0xFFF1
CONST uint8 simpleProfilechar1UUID[ATT_BT_UUID_SIZE] =
{
  LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)
};

// Characteristic 2 UUID: 0xFFF2
CONST uint8 simpleProfilechar2UUID[ATT_BT_UUID_SIZE] =
{
  LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)
};

/*********************************************************************
 * EXTERNAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL FUNCTIONS
 */

/*********************************************************************
 * LOCAL VARIABLES
 */

static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;

/*********************************************************************
 * Profile Attributes - variables
 */

// Simple Profile Service attribute
static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };


// Simple Profile Characteristic 1 Properties
static uint8 simpleProfileChar1Props = GATT_PROP_WRITE;

// Characteristic 1 Value
static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

// Simple Profile Characteristic 1 User Description
static uint8 simpleProfileChar1UserDesp[17] = "Mobile Data";


// Simple Profile Characteristic 2 Properties
static uint8 simpleProfileChar2Props = GATT_PROP_NOTIFY;

// Characteristic 2 Value
static uint8 simpleProfileChar2[SIMPLEPROFILE_CHAR2_LEN] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

// Simple Profile Characteristic 4 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
// that client and writes only affect the configuration of that client.
static gattCharCfg_t *simpleProfileChar2Config;

// Simple Profile Characteristic 2 User Description
static uint8 simpleProfileChar2UserDesp[17] = "Vehicle Data";


/*********************************************************************
 * Profile Attributes - Table
 */

static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
{
      // Simple Profile Service
      {
        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
        GATT_PERMIT_READ,                         /* permissions */
        0,                                        /* handle */
        (uint8 *)&simpleProfileService            /* pValue */
      },

      // Characteristic 1 Declaration
      {
        { ATT_BT_UUID_SIZE, characterUUID },
        GATT_PERMIT_READ,
        0,
        &simpleProfileChar1Props
      },

      // Characteristic Value 1
      {
        { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },
        GATT_PERMIT_WRITE,
        0,
        simpleProfileChar1
      },

      // Characteristic 1 User Description
      {
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ,
        0,
        simpleProfileChar1UserDesp
      },

      // Characteristic 2 Declaration
      {
        { ATT_BT_UUID_SIZE, characterUUID },
        GATT_PERMIT_READ,
        0,
        &simpleProfileChar2Props
      },

      // Characteristic Value 2
      {
        { ATT_BT_UUID_SIZE, simpleProfilechar2UUID },
        0,
        0,
        simpleProfileChar2
      },

      // Characteristic 2 configuration
      {
        { ATT_BT_UUID_SIZE, clientCharCfgUUID },
        GATT_PERMIT_READ | GATT_PERMIT_WRITE,
        0,
        (uint8 *)&simpleProfileChar2Config
      },

      // Characteristic 2 User Description
      {
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ,
        0,
        simpleProfileChar2UserDesp
      },
};

/*********************************************************************
 * LOCAL FUNCTIONS
 */
static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
                                          gattAttribute_t *pAttr,
                                          uint8_t *pValue, uint16_t *pLen,
                                          uint16_t offset, uint16_t maxLen,
                                          uint8_t method);
static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
                                           gattAttribute_t *pAttr,
                                           uint8_t *pValue, uint16_t len,
                                           uint16_t offset, uint8_t method);

/*********************************************************************
 * PROFILE CALLBACKS
 */

// Simple Profile Service Callbacks
// Note: When an operation on a characteristic requires authorization and
// pfnAuthorizeAttrCB is not defined for that characteristic's service, the
// Stack will report a status of ATT_ERR_UNLIKELY to the client.  When an
// operation on a characteristic requires authorization the Stack will call
// pfnAuthorizeAttrCB to check a client's authorization prior to calling
// pfnReadAttrCB or pfnWriteAttrCB, so no checks for authorization need to be
// made within these functions.
CONST gattServiceCBs_t simpleProfileCBs =
{
  simpleProfile_ReadAttrCB,  // Read callback function pointer
  simpleProfile_WriteAttrCB, // Write callback function pointer
  NULL                       // Authorization callback function pointer
};

/*********************************************************************
 * PUBLIC FUNCTIONS
 */

/*********************************************************************
 * @fn      SimpleProfile_AddService
 *
 * @brief   Initializes the Simple Profile service by registering
 *          GATT attributes with the GATT server.
 *
 * @param   services - services to add. This is a bit map and can
 *                     contain more than one service.
 *
 * @return  Success or Failure
 */
bStatus_t SimpleProfile_AddService( uint32 services )
{
  uint8 status;

  // Allocate Client Characteristic Configuration table
  simpleProfileChar2Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
                                                              linkDBNumConns );
  if ( simpleProfileChar2Config == NULL )
  {
    return ( bleMemAllocError );
  }

  // Initialize Client Characteristic Configuration attributes
  GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar2Config );

  if ( services & SIMPLEPROFILE_SERVICE )
  {
    // Register GATT attribute list and CBs with GATT Server App
    status = GATTServApp_RegisterService( simpleProfileAttrTbl,
                                          GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                          GATT_MAX_ENCRYPT_KEY_SIZE,
                                          &simpleProfileCBs );
  }
  else
  {
    status = SUCCESS;
  }

  return ( status );
}

/*********************************************************************
 * @fn      SimpleProfile_RegisterAppCBs
 *
 * @brief   Registers the application callback function. Only call
 *          this function once.
 *
 * @param   callbacks - pointer to application callbacks.
 *
 * @return  SUCCESS or bleAlreadyInRequestedMode
 */
bStatus_t SimpleProfile_RegisterAppCBs( simpleProfileCBs_t *appCallbacks )
{
  if ( appCallbacks )
  {
    simpleProfile_AppCBs = appCallbacks;

    return ( SUCCESS );
  }
  else
  {
    return ( bleAlreadyInRequestedMode );
  }
}

/*********************************************************************
 * @fn      SimpleProfile_SetParameter
 *
 * @brief   Set a Simple Profile parameter.
 *
 * @param   param - Profile parameter ID
 * @param   len - length of data to write
 * @param   value - pointer to data to write.  This is dependent on
 *          the parameter ID and WILL be cast to the appropriate
 *          data type (example: data type of uint16 will be cast to
 *          uint16 pointer).
 *
 * @return  bStatus_t
 */
bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
{
  bStatus_t ret = SUCCESS;
  switch ( param )
  {

    case SIMPLEPROFILE_CHAR1:
      if ( len == SIMPLEPROFILE_CHAR1_LEN )
      {
        VOID memcpy( simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case SIMPLEPROFILE_CHAR2:
      if ( len == SIMPLEPROFILE_CHAR2_LEN )
      {
        VOID memcpy( simpleProfileChar2, value, SIMPLEPROFILE_CHAR2_LEN );

        // See if Notification has been enabled
        GATTServApp_ProcessCharCfg( simpleProfileChar2Config, simpleProfileChar2, FALSE,
                                      simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                      INVALID_TASK_ID, simpleProfile_ReadAttrCB );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    default:
      ret = INVALIDPARAMETER;
      break;
  }

  return ( ret );
}

/*********************************************************************
 * @fn      SimpleProfile_GetParameter
 *
 * @brief   Get a Simple Profile parameter.
 *
 * @param   param - Profile parameter ID
 * @param   value - pointer to data to put.  This is dependent on
 *          the parameter ID and WILL be cast to the appropriate
 *          data type (example: data type of uint16 will be cast to
 *          uint16 pointer).
 *
 * @return  bStatus_t
 */
bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
{
  bStatus_t ret = SUCCESS;
  switch ( param )
  {
    case SIMPLEPROFILE_CHAR1:
      VOID memcpy( value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN );
      break;

    case SIMPLEPROFILE_CHAR2:
      VOID memcpy( value, simpleProfileChar2, SIMPLEPROFILE_CHAR2_LEN );
      break;

    default:
      ret = INVALIDPARAMETER;
      break;
  }

  return ( ret );
}

/*********************************************************************
 * @fn          simpleProfile_ReadAttrCB
 *
 * @brief       Read an attribute.
 *
 * @param       connHandle - connection message was received on
 * @param       pAttr - pointer to attribute
 * @param       pValue - pointer to data to be read
 * @param       pLen - length of data to be read
 * @param       offset - offset of the first octet to be read
 * @param       maxLen - maximum length of data to be read
 * @param       method - type of read message
 *
 * @return      SUCCESS, blePending or Failure
 */
static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
                                          gattAttribute_t *pAttr,
                                          uint8_t *pValue, uint16_t *pLen,
                                          uint16_t offset, uint16_t maxLen,
                                          uint8_t method)
{
  bStatus_t status = SUCCESS;

  // Make sure it's not a blob operation (no attributes in the profile are long)
  if ( offset > 0 )
  {
    return ( ATT_ERR_ATTR_NOT_LONG );
  }

  if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  {
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    switch ( uuid )
    {
      // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
      // gattserverapp handles those reads

      // characteristics 1 and 2 have read permissions
      // characteritisc 3 does not have read permissions; therefore it is not
      //   included here
      // characteristic 4 does not have read permissions, but because it
      //   can be sent as a notification, it is included here
      case SIMPLEPROFILE_CHAR1_UUID:
          *pLen = SIMPLEPROFILE_CHAR1_LEN;
          VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
          break;

      case SIMPLEPROFILE_CHAR2_UUID:
          *pLen = SIMPLEPROFILE_CHAR2_LEN;
          VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR2_LEN );
          break;

      default:
        // Should never get here! (characteristics 3 and 4 do not have read permissions)
        *pLen = 0;
        status = ATT_ERR_ATTR_NOT_FOUND;
        break;
    }
  }
  else
  {
    // 128-bit UUID
    *pLen = 0;
    status = ATT_ERR_INVALID_HANDLE;
  }

  return ( status );
}

/*********************************************************************
 * @fn      simpleProfile_WriteAttrCB
 *
 * @brief   Validate attribute data prior to a write operation
 *
 * @param   connHandle - connection message was received on
 * @param   pAttr - pointer to attribute
 * @param   pValue - pointer to data to be written
 * @param   len - length of data
 * @param   offset - offset of the first octet to be written
 * @param   method - type of write message
 *
 * @return  SUCCESS, blePending or Failure
 */
static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
                                           gattAttribute_t *pAttr,
                                           uint8_t *pValue, uint16_t len,
                                           uint16_t offset, uint8_t method)
{
  bStatus_t status = SUCCESS;
  uint8 notifyApp = 0xFF;

  if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  {
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    switch ( uuid )
    {
      case SIMPLEPROFILE_CHAR1_UUID:

          //Validate the value
          // Make sure it's not a blob oper
          if ( offset == 0 )
          {
            if ( len != SIMPLEPROFILE_CHAR1_LEN )
            {
              status = ATT_ERR_INVALID_VALUE_SIZE;
            }
          }
          else
          {
            status = ATT_ERR_ATTR_NOT_LONG;
          }

          //Write the value
          if ( status == SUCCESS )
          {
            uint8 *pCurValue = (uint8 *)pAttr->pValue;
            //*pCurValue = pValue[0];
            VOID memcpy( pCurValue, pValue, SIMPLEPROFILE_CHAR1_LEN );

            if( pAttr->pValue == simpleProfileChar1 )
            {
              notifyApp = SIMPLEPROFILE_CHAR1;
            }
          }
          break;

      case GATT_CLIENT_CHAR_CFG_UUID:
        status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                 offset, GATT_CLIENT_CFG_NOTIFY );
        break;

      default:
        // Should never get here! (characteristics 2 and 4 do not have write permissions)
        status = ATT_ERR_ATTR_NOT_FOUND;
        break;
    }
  }
  else
  {
    // 128-bit UUID
    status = ATT_ERR_INVALID_HANDLE;
  }

  // If a characteristic value changed then callback function to notify application of change
  if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
  {
    simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );
  }

  return ( status );
}

/*********************************************************************
*********************************************************************/

  • Try to refer to which shows you how to toggle BLE advertising.

  • Hi ,

    I have used some part of your implementation as an inspiration for my code.

    But your logic was not working as it is, I have made some additional changes and now it is working fine.

    Please take a look into the implementation and do suggest a possible better way of doing all the things that I have mentioned in my original post.

    Below are my latest code files:

    /******************************************************************************
    
     @file  simple_peripheral.c
    
     @brief This file contains the Simple Peripheral sample application for use
            with the CC2650 Bluetooth Low Energy Protocol Stack.
    
     Group: WCS, BTS
     Target Device: cc2640r2
    
     ******************************************************************************
    
     Copyright (c) 2013-2020, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
    
    
     *****************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Queue.h>
    #include <ti/display/Display.h>
    
    #if defined( USE_FPGA ) || defined( DEBUG_SW_TRACE )
    #include <driverlib/ioc.h>
    #endif // USE_FPGA | DEBUG_SW_TRACE
    
    #include <icall.h>
    #include "util.h"
    #include "att_rsp.h"
    
    /* This Header file contains all BLE API and icall structure definition */
    #include "icall_ble_api.h"
    
    #include "devinfoservice.h"
    #include "simple_gatt_profile.h"
    #include "ll_common.h"
    
    #include "peripheral.h"
    
    #ifdef USE_RCOSC
    #include "rcosc_calibration.h"
    #endif //USE_RCOSC
    
    #include "board_key.h"
    
    #include "board.h"
    
    #include "simple_peripheral.h"
    #include "uart_manager.h"
    /*********************************************************************
     * CONSTANTS
     */
    //uint8_t arr[28];
    
    //typedef struct
    //{
    //  appEvtHdr_t hdr;  // event header.
    //  uint8_t *pData;  // event data
    //} sbpEvt_t;
    
    static uint8_t Autoconnection_flag = 0;
    uint8_t advertEnabled1 = FALSE;
    uint8_t Control_Data = 0;
    
    #define DATA_PAYLOAD_SIZE                   0x1A // 26 in decimal
    
    // Advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // General discoverable mode: advertise indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    // Minimum connection interval (units of 1.25ms, 80=100ms) for automatic
    // parameter update request
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) for automatic
    // parameter update request
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    
    // Slave latency to use for automatic parameter update request
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) for automatic parameter
    // update request
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // After the connection is formed, the peripheral waits until the central
    // device asks for its preferred connection parameters
    #define DEFAULT_ENABLE_UPDATE_REQUEST         GAPROLE_LINK_PARAM_UPDATE_WAIT_REMOTE_PARAMS
    
    // 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
    
    // Application specific event ID for HCI Connection Event End Events
    #define SBP_HCI_CONN_EVT_END_EVT              0x0001
    
    // Type of Display to open
    #if !defined(Display_DISABLE_ALL)
      #if defined(BOARD_DISPLAY_USE_LCD) && (BOARD_DISPLAY_USE_LCD!=0)
        #define SBP_DISPLAY_TYPE Display_Type_LCD
      #elif defined (BOARD_DISPLAY_USE_UART) && (BOARD_DISPLAY_USE_UART!=0)
        #define SBP_DISPLAY_TYPE Display_Type_UART
      #else // !BOARD_DISPLAY_USE_LCD && !BOARD_DISPLAY_USE_UART
        #define SBP_DISPLAY_TYPE 0 // Option not supported
      #endif // BOARD_DISPLAY_USE_LCD && BOARD_DISPLAY_USE_UART
    #else // BOARD_DISPLAY_USE_LCD && BOARD_DISPLAY_USE_UART
      #define SBP_DISPLAY_TYPE 0 // No Display
    #endif // !Display_DISABLE_ALL
    
    // Task configuration
    #define SBP_TASK_PRIORITY                     1
    
    #ifndef SBP_TASK_STACK_SIZE
    #define SBP_TASK_STACK_SIZE                   644
    #endif
    
    // Application events
    #define SBP_STATE_CHANGE_EVT                  0x0001
    #define SBP_CHAR_CHANGE_EVT                   0x0002
    #define SBP_PAIRING_STATE_EVT                 0x0004
    #define SBP_PASSCODE_NEEDED_EVT               0x0008
    #define SBP_CONN_EVT                          0x0010
    #define SBP_TEST_EVT1                         0x0020
    #define SBP_TEST_EVT2                         0x0021
    
    // Internal Events for RTOS application
    #define SBP_ICALL_EVT                         ICALL_MSG_EVENT_ID // Event_Id_31
    #define SBP_QUEUE_EVT                         UTIL_QUEUE_EVENT_ID // Event_Id_30
    #define SBP_PERIODIC_EVT                      Event_Id_00
    
    #define ADV_PERIODIC_EVT                      Event_Id_01 //Timer_120s
    #define ADV_PERIODIC_EVT_PERIOD               1000*120 //1000 = 1sec //Timer_120s
    
    // Bitwise OR of all events to pend on
    #define SBP_ALL_EVENTS                        (SBP_ICALL_EVT        | \
                                                   SBP_QUEUE_EVT        | \
                                                   ADV_PERIODIC_EVT     | \
                                                   SBP_PERIODIC_EVT)
    
    static Clock_Struct periodicClockAdv;  //Timer_120s
    
    // Set the register cause to the registration bit-mask
    #define CONNECTION_EVENT_REGISTER_BIT_SET(RegisterCause) (connectionEventRegisterCauseBitMap |= RegisterCause )
    // Remove the register cause from the registration bit-mask
    #define CONNECTION_EVENT_REGISTER_BIT_REMOVE(RegisterCause) (connectionEventRegisterCauseBitMap &= (~RegisterCause) )
    // Gets whether the current App is registered to the receive connection events
    #define CONNECTION_EVENT_IS_REGISTERED (connectionEventRegisterCauseBitMap > 0)
    // Gets whether the RegisterCause was registered to recieve connection event
    #define CONNECTION_EVENT_REGISTRATION_CAUSE(RegisterCause) (connectionEventRegisterCauseBitMap & RegisterCause )
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    
    // Display Interface
    Display_Handle dispHandle = NULL;
    
    // Event globally used to post local events and pend on system and
    // local events.
    ICall_SyncHandle syncEvent;
    
    Queue_Handle appMsgQueue;
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Clock instances for internal periodic events.
    static Clock_Struct periodicClock;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    
    // Task configuration
    Task_Struct sbpTask;
    Char sbpTaskStack[SBP_TASK_STACK_SIZE];
    
    // Scan response data (max size = 31 bytes)
    static uint8_t scanRspData[] =
    {
      // complete name
      13,//0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      'S',
      'A',
      'S',
      '0',
      '1',
      '0',
      '0',
      '0',
      '0',
      '0',
      '0',
      '1',
    
      // 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
    };
    
    // Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertising)
    static uint8_t advertData[] =
    {
      // Flags: this field sets the device to use general discoverable
      // mode (advertises indefinitely) instead of general
      // discoverable mode (advertise for 30 seconds at a time)
      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
      LO_UINT16(SIMPLEPROFILE_SERV_UUID),
      HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    };
    
    // GAP GATT Attributes
    static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple Peripheral";
    
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void SimplePeripheral_init( void );
    static void SimplePeripheral_taskFxn(UArg a0, UArg a1);
    
    static uint8_t SimplePeripheral_processStackMsg(ICall_Hdr *pMsg);
    static uint8_t SimplePeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
    static void SimplePeripheral_processAppMsg(sbpEvt_t *pMsg);
    static void SimplePeripheral_processStateChangeEvt(gaprole_States_t newState);
    static void SimplePeripheral_processCharValueChangeEvt(uint8_t paramID);
    static void SimplePeripheral_performPeriodicTask(void);
    static void SimplePeripheral_clockHandler(UArg arg);
    
    static void SimplePeripheral_passcodeCB(uint8_t *deviceAddr,
                                            uint16_t connHandle,
                                            uint8_t uiInputs, uint8_t uiOutputs,
                                            uint32_t numComparison);
    static void SimplePeripheral_pairStateCB(uint16_t connHandle, uint8_t state,
                                             uint8_t status);
    static void SimplePeripheral_processPairState(uint8_t state, uint8_t status);
    static void SimplePeripheral_processPasscode(uint8_t uiOutputs);
    
    static void SimplePeripheral_stateChangeCB(gaprole_States_t newState);
    static void SimplePeripheral_charValueChangeCB(uint8_t paramID);
    static uint8_t SimplePeripheral_enqueueMsg(uint8_t event, uint8_t state,
                                                  uint8_t *pData);
    
    static void SimplePeripheral_connEvtCB(Gap_ConnEventRpt_t *pReport);
    static void SimplePeripheral_processConnEvt(Gap_ConnEventRpt_t *pReport);
    static void SimplePeripheral_TestEvent(uint8_t state, uint8_t* status);
    static void SimplePeripheral_TestEvent1(uint8_t state, uint8_t* status);
    
    
    /*********************************************************************
     * EXTERN FUNCTIONS
     */
    extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // Peripheral GAPRole Callbacks
    static gapRolesCBs_t SimplePeripheral_gapRoleCBs =
    {
      SimplePeripheral_stateChangeCB     // GAPRole State Change Callbacks
    };
    
    // GAP Bond Manager Callbacks
    // These are set to NULL since they are not needed. The application
    // is set up to only perform justworks pairing.
    static gapBondCBs_t simplePeripheral_BondMgrCBs =
    {
      SimplePeripheral_passcodeCB,  // Passcode callback
      SimplePeripheral_pairStateCB  // Pairing / Bonding state Callback
    };
    
    // Simple GATT Profile Callbacks
    static simpleProfileCBs_t SimplePeripheral_simpleProfileCBs =
    {
      SimplePeripheral_charValueChangeCB // Simple GATT Characteristic value change callback
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * The following typedef and global handle the registration to connection event
     */
    typedef enum
    {
       NOT_REGISTER       = 0,
       FOR_AOA_SCAN       = 1,
       FOR_ATT_RSP        = 2,
       FOR_AOA_SEND       = 4,
       FOR_TOF_SEND       = 8
    }connectionEventRegisterCause_u;
    
    // Handle the registration and un-registration for the connection event, since only one can be registered.
    uint32_t       connectionEventRegisterCauseBitMap = NOT_REGISTER; //see connectionEventRegisterCause_u
    
    /*********************************************************************
     * @fn      SimplePeripheral_RegistertToAllConnectionEvent()
     *
     * @brief   register to receive connection events for all the connection
     *
     * @param connectionEventRegisterCause represents the reason for registration
     *
     * @return @ref SUCCESS
     *
     */
    bStatus_t SimplePeripheral_RegistertToAllConnectionEvent (connectionEventRegisterCause_u connectionEventRegisterCause)
    {
      bStatus_t status = SUCCESS;
    
      // in case  there is no registration for the connection event, make the registration
      if (!CONNECTION_EVENT_IS_REGISTERED)
      {
        status = GAP_RegisterConnEventCb(SimplePeripheral_connEvtCB, GAP_CB_REGISTER, LINKDB_CONNHANDLE_ALL);
      }
      if(status == SUCCESS)
      {
        //add the reason bit to the bitamap.
        CONNECTION_EVENT_REGISTER_BIT_SET(connectionEventRegisterCause);
      }
    
      return(status);
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_UnRegistertToAllConnectionEvent()
     *
     * @brief   Unregister connection events
     *
     * @param connectionEventRegisterCause represents the reason for registration
     *
     * @return @ref SUCCESS
     *
     */
    bStatus_t SimplePeripheral_UnRegistertToAllConnectionEvent (connectionEventRegisterCause_u connectionEventRegisterCause)
    {
      bStatus_t status = SUCCESS;
    
      CONNECTION_EVENT_REGISTER_BIT_REMOVE(connectionEventRegisterCause);
      // in case  there is no more registration for the connection event than unregister
      if (!CONNECTION_EVENT_IS_REGISTERED)
      {
        GAP_RegisterConnEventCb(SimplePeripheral_connEvtCB, GAP_CB_UNREGISTER, LINKDB_CONNHANDLE_ALL);
      }
    
      return(status);
    }
    
     /*********************************************************************
     * @fn      SimplePeripheral_createTask
     *
     * @brief   Task creation function for the Simple Peripheral.
     *
     * @param   None.
     *
     * @return  None.
     */
    void SimplePeripheral_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, SimplePeripheral_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_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 SimplePeripheral_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, &syncEvent);
    
    #ifdef USE_RCOSC
      RCOSC_enableCalibration();
    #endif // USE_RCOSC
    
    #if defined( USE_FPGA )
      // configure RF Core SMI Data Link
      IOCPortConfigureSet(IOID_12, IOC_PORT_RFC_GPO0, IOC_STD_OUTPUT);
      IOCPortConfigureSet(IOID_11, IOC_PORT_RFC_GPI0, IOC_STD_INPUT);
    
      // configure RF Core SMI Command Link
      IOCPortConfigureSet(IOID_10, IOC_IOCFG0_PORT_ID_RFC_SMI_CL_OUT, IOC_STD_OUTPUT);
      IOCPortConfigureSet(IOID_9, IOC_IOCFG0_PORT_ID_RFC_SMI_CL_IN, IOC_STD_INPUT);
    
      // configure RF Core tracer IO
      IOCPortConfigureSet(IOID_8, IOC_PORT_RFC_TRC, IOC_STD_OUTPUT);
    #else // !USE_FPGA
      #if defined( DEBUG_SW_TRACE )
        // configure RF Core tracer IO
        IOCPortConfigureSet(IOID_8, IOC_PORT_RFC_TRC, IOC_STD_OUTPUT | IOC_CURRENT_4MA | IOC_SLEW_ENABLE);
      #endif // DEBUG_SW_TRACE
    #endif // USE_FPGA
    
        /******************************120s Timer********************************/
        Util_constructClock(&periodicClockAdv, SimplePeripheral_clockHandler,
                            ADV_PERIODIC_EVT_PERIOD, 0, false, ADV_PERIODIC_EVT);
        /**********************************X*************************************/
    
      // 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, SimplePeripheral_clockHandler,
                          SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
    
      dispHandle = Display_open(SBP_DISPLAY_TYPE, NULL);
    
      // Set GAP Parameters: After a connection was established, delay in seconds
      // before sending when GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE,...)
      // uses GAPROLE_LINK_PARAM_UPDATE_INITIATE_BOTH_PARAMS or
      // GAPROLE_LINK_PARAM_UPDATE_INITIATE_APP_PARAMS
      // For current defaults, this has no effect.
      GAP_SetParamValue(TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL);
    
      // Start the Device:
      // Please Notice that in case of wanting to use the GAPRole_SetParameter
      // function with GAPROLE_IRK or GAPROLE_SRK parameter - Perform
      // these function calls before the GAPRole_StartDevice use.
      // (because Both cases are updating the gapRole_IRK & gapRole_SRK variables).
      //VOID GAPRole_StartDevice(&SimplePeripheral_gapRoleCBs);
    
      // Setup the Peripheral GAPRole Profile. For more information see the User's
      // Guide:
      // http://software-dl.ti.com/lprf/sdg-latest/html/
      {
        // 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 re-enabled by the application
        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;
    
        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 Device Name characteristic in the GAP GATT Service
      // For more information, see the section in the User's Guide:
      // http://software-dl.ti.com/lprf/sdg-latest/html
      GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
    
      // Set GAP Parameters to set the advertising interval
      // For more information, see the GAP section of the User's Guide:
      // http://software-dl.ti.com/lprf/sdg-latest/html
      {
        // Use the same interval for general and limited advertising.
        // Note that only general advertising will occur based on the above configuration
        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. For more information see the section in the
      // User's Guide:
      // http://software-dl.ti.com/lprf/sdg-latest/html/
      {
        // Don't send a pairing request after connecting; the peer device must
        // initiate pairing
        uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE;
        // Use authenticated pairing: require passcode.
        uint8_t mitm = FALSE;
        // This device only has display capabilities. Therefore, it will display the
        // passcode during pairing. However, since the default passcode is being
        // used, there is no need to display anything.
        uint8_t ioCap = GAPBOND_IO_CAP_NO_INPUT_NO_OUTPUT;
        // Request bonding (storing long-term keys for re-encryption upon subsequent
        // connections without repairing)
        uint8_t bonding = TRUE;
        // Whether to replace the least recently used entry when bond list is full,
        // and a new device is bonded.
        // Alternative is pairing succeeds but bonding fails, unless application has
        // manually erased at least one bond.
        uint8_t replaceBonds = FALSE;
    
        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);
        GAPBondMgr_SetParameter(GAPBOND_LRU_BOND_REPLACEMENT, sizeof(uint8_t), &replaceBonds);
      }
    
      // Initialize GATT attributes
      GGS_AddService(GATT_ALL_SERVICES);           // GAP GATT Service
      GATTServApp_AddService(GATT_ALL_SERVICES);   // GATT Service
      DevInfo_AddService();                        // Device Information Service
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    
      // Setup the SimpleProfile Characteristic Values
      // For more information, see the sections in the User's Guide:
      // http://software-dl.ti.com/lprf/sdg-latest/html/
      {
        uint8_t charValue1[SIMPLEPROFILE_CHAR1_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
        uint8_t charValue2[SIMPLEPROFILE_CHAR2_LEN] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1,SIMPLEPROFILE_CHAR1_LEN,
                                   charValue1);
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2,SIMPLEPROFILE_CHAR2_LEN,
                                   charValue2);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&SimplePeripheral_simpleProfileCBs);
    
      // Start Bond Manager and register callback
      VOID GAPBondMgr_Register(&simplePeripheral_BondMgrCBs);
    
      // Register with GAP for HCI/Host messages. This is needed to receive HCI
      // events. For more information, see the section in the User's Guide:
      // http://software-dl.ti.com/lprf/sdg-latest/html
      GAP_RegisterForMsgs(selfEntity);
    
      // Register for GATT local events and ATT Responses pending for transmission
      GATT_RegisterForMsgs(selfEntity);
    
      //Set default values for Data Length Extension
      {
        //Set initial values to maximum, RX is set to max. by default(251 octets, 2120us)
        #define APP_SUGGESTED_PDU_SIZE 251 //default is 27 octets(TX)
        #define APP_SUGGESTED_TX_TIME 2120 //default is 328us(TX)
    
        //This API is documented in hci.h
        //See the LE Data Length Extension section in the BLE-Stack User's Guide for information on using this command:
        //http://software-dl.ti.com/lprf/sdg-latest/html/cc2640/index.html
        //HCI_LE_WriteSuggestedDefaultDataLenCmd(APP_SUGGESTED_PDU_SIZE, APP_SUGGESTED_TX_TIME);
      }
    
    #if !defined (USE_LL_CONN_PARAM_UPDATE)
      // Get the currently set local supported LE features
      // The HCI will generate an HCI event that will get received in the main
      // loop
      HCI_LE_ReadLocalSupportedFeaturesCmd();
    #endif // !defined (USE_LL_CONN_PARAM_UPDATE)
    
      Display_print0(dispHandle, 0, 0, "BLE Peripheral");
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_taskFxn
     *
     * @brief   Application task entry point for the Simple Peripheral.
     *
     * @param   a0, a1 - not used.
     *
     * @return  None.
     */
    static void SimplePeripheral_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      SimplePeripheral_init();
    
      // Application main loop
      for (;;)
      {
        uint32_t events;
    
        // Waits for an event to be posted associated with the calling thread.
        // Note that an event associated with a thread is posted when a
        // message is queued to the message receive queue of the thread
        events = Event_pend(syncEvent, Event_Id_NONE, SBP_ALL_EVENTS,
                            ICALL_TIMEOUT_FOREVER);
    
        if (events)
        {
          ICall_EntityID dest;
          ICall_ServiceEnum src;
          ICall_HciExtEvt *pMsg = NULL;
    
          // Fetch any available messages that might have been sent from the stack
          if (ICall_fetchServiceMsg(&src, &dest,
                                    (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
          {
            uint8 safeToDealloc = TRUE;
    
            if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
            {
              ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;
    
              if (pEvt->signature != 0xffff)
              {
                // Process inter-task message
                safeToDealloc = SimplePeripheral_processStackMsg((ICall_Hdr *)pMsg);
              }
            }
    
            if (pMsg && safeToDealloc)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message.
          if (events & SBP_QUEUE_EVT)
          {
            while (!Queue_empty(appMsgQueue))
            {
              sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
              if (pMsg)
              {
                // Process message.
                SimplePeripheral_processAppMsg(pMsg);
    
                // Free the space from the message.
                ICall_free(pMsg);
              }
            }
          }
    
          if (events & SBP_PERIODIC_EVT)
          {
            Util_startClock(&periodicClock);
    
            // Perform periodic application task
            SimplePeripheral_performPeriodicTask();
          }
    
          if (events & ADV_PERIODIC_EVT)  /* Event get triggered when 120s gets elapsed */
          {
            if(Autoconnection_flag == 1)
            {
               /* Stop Auto Connection */
               Autoconnection_flag = 0;
    
               advertEnabled1 = FALSE;
               //Disabled advertising.
               GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                    &advertEnabled1);
    
               //newState = GAPROLE_WAITING;//4
               SimplePeripheral_stateChangeCB((gaprole_States_t)4/*newState*/);
            }
          }
        }
      }
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_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 SimplePeripheral_processStackMsg(ICall_Hdr *pMsg)
    {
      uint8_t safeToDealloc = TRUE;
    
      switch (pMsg->event)
      {
        case GATT_MSG_EVENT:
          // Process GATT message
          safeToDealloc = SimplePeripheral_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
                {
    
    #if !defined (USE_LL_CONN_PARAM_UPDATE)
                  // This code will disable the use of the LL_CONNECTION_PARAM_REQ
                  // control procedure (for connection parameter updates, the
                  // L2CAP Connection Parameter Update procedure will be used
                  // instead). To re-enable the LL_CONNECTION_PARAM_REQ control
                  // procedures, define the symbol USE_LL_CONN_PARAM_UPDATE
                  // The L2CAP Connection Parameter Update procedure is used to
                  // support a delta between the minimum and maximum connection
                  // intervals required by some iOS devices.
    
                  // Parse Command Complete Event for opcode and status
                  hciEvt_CmdComplete_t* command_complete = (hciEvt_CmdComplete_t*) pMsg;
                  uint8_t   pktStatus = command_complete->pReturnParam[0];
    
                  //find which command this command complete is for
                  switch (command_complete->cmdOpcode)
                  {
                    case HCI_LE_READ_LOCAL_SUPPORTED_FEATURES:
                      {
                        if (pktStatus == SUCCESS)
                        {
                          uint8_t featSet[8];
    
                          // Get current feature set from received event (bits 1-9
                          // of the returned data
                          memcpy( featSet, &command_complete->pReturnParam[1], 8 );
    
                          // Clear bit 1 of byte 0 of feature set to disable LL
                          // Connection Parameter Updates
                          CLR_FEATURE_FLAG( featSet[0], LL_FEATURE_CONN_PARAMS_REQ );
    
                          // Update controller with modified features
                          HCI_EXT_SetLocalSupportedFeaturesCmd( featSet );
                        }
                      }
                      break;
    
                    default:
                      //do nothing
                      break;
                  }
    #endif // !defined (USE_LL_CONN_PARAM_UPDATE)
    
                }
                break;
    
              case HCI_BLE_HARDWARE_ERROR_EVENT_CODE:
                AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0);
                break;
    
              default:
                break;
            }
          }
          break;
    
          default:
            // do nothing
            break;
    
        }
    
      return (safeToDealloc);
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_processGATTMsg
     *
     * @brief   Process GATT messages and events.
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t SimplePeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
    {
      // See if GATT server was unable to transmit an ATT response
      if (attRsp_isAttRsp(pMsg))
      {
        // No HCI buffer was available. Let's try to retransmit the response
        // on the next connection event.
        if( SimplePeripheral_RegistertToAllConnectionEvent(FOR_ATT_RSP) == SUCCESS)
        {
          // 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.
        Display_print1(dispHandle, 5, 0, "FC Violated: %d", pMsg->msg.flowCtrlEvt.opcode);
      }
      else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
      {
        // MTU size updated
        Display_print1(dispHandle, 5, 0, "MTU Size: %d", pMsg->msg.mtuEvt.MTU);
      }
    
      // 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      SimplePeripheral_processConnEvt
     *
     * @brief   Process connection event.
     *
     * @param pReport pointer to connection event report
     */
    static void SimplePeripheral_processConnEvt(Gap_ConnEventRpt_t *pReport)
    {
    
      if( CONNECTION_EVENT_REGISTRATION_CAUSE(FOR_ATT_RSP))
      {
        // The GATT server might have returned a blePending as it was trying
        // to process an ATT Response. Now that we finished with this
        // connection event, let's try sending any remaining ATT Responses
        // on the next connection event.
        // Try to retransmit pending ATT Response (if any)
        if (attRsp_sendAttRsp() == SUCCESS)
        {
            // Disable connection event end notice
            SimplePeripheral_UnRegistertToAllConnectionEvent (FOR_ATT_RSP);
        }
      }
    
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void SimplePeripheral_processAppMsg(sbpEvt_t *pMsg)
    {
      switch (pMsg->hdr.event)
      {
        case SBP_STATE_CHANGE_EVT:
          {
            SimplePeripheral_processStateChangeEvt((gaprole_States_t)pMsg->
                                                    hdr.state);
          }
          break;
    
        case SBP_CHAR_CHANGE_EVT:
          {
            SimplePeripheral_processCharValueChangeEvt(pMsg->hdr.state);
          }
          break;
    
        // Pairing event
        case SBP_PAIRING_STATE_EVT:
          {
            SimplePeripheral_processPairState(pMsg->hdr.state, *pMsg->pData);
    
            ICall_free(pMsg->pData);
            break;
          }
    
        // Passcode event
        case SBP_PASSCODE_NEEDED_EVT:
          {
            SimplePeripheral_processPasscode(*pMsg->pData);
    
            ICall_free(pMsg->pData);
            break;
          }
    
        case SBP_CONN_EVT:
          {
            SimplePeripheral_processConnEvt((Gap_ConnEventRpt_t *)(pMsg->pData));
    
            ICall_free(pMsg->pData);
            break;
          }
    
        case SBP_TEST_EVT1:
          {
            /* 0x30 :: Process Connection request from UART (Manual pairing/ auto connection) */
            SimplePeripheral_TestEvent(pMsg->hdr.state,(uint8_t *)pMsg->pData);
    
            ICall_free(pMsg->pData);
            break;
          }
    
        case SBP_TEST_EVT2:
          {
            /* 0x37 :: SUZUKI_CLUSTER_STATUS_PKT */
            SimplePeripheral_TestEvent1(pMsg->hdr.state, (uint8_t*)pMsg->pData);
    
            ICall_free(pMsg->pData);
            break;
          }
    
        default:
          // Do nothing.
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_stateChangeCB
     *
     * @brief   Callback from GAP Role indicating a role state change.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimplePeripheral_stateChangeCB(gaprole_States_t newState)
    {
      SimplePeripheral_enqueueMsg(SBP_STATE_CHANGE_EVT, newState, NULL);
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_processStateChangeEvt
     *
     * @brief   Process a pending GAP Role state change event.
     *
     * @param   newState - new state
     *
     * @return  None.
     */
    static void SimplePeripheral_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); //-saurav
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = 1;//ownAddress[0];
            systemId[1] = 1;//ownAddress[1];
            systemId[2] = 1;//ownAddress[2];
    
            // set middle bytes to zero
            systemId[4] = 1;//0x00;
            systemId[3] = 1;//0x00;
    
            // shift three bytes up
            systemId[7] = 2;//ownAddress[5];
            systemId[6] = 2;//ownAddress[4];
            systemId[5] = 2;//ownAddress[3];
    
            /* The SystemID is updated as default as of now - saurav */
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
    
            // Display device address
            Display_print0(dispHandle, 1, 0, Util_convertBdAddr2Str(ownAddress));
            Display_print0(dispHandle, 2, 0, "Initialized");
    
            // Device starts advertising upon initialization of GAP
            uint8_t initialAdvertEnable = TRUE;
            // Set the Peripheral GAPRole Parameters
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                             &initialAdvertEnable);
          }
          break;
    
        case GAPROLE_ADVERTISING:
          Display_print0(dispHandle, 2, 0, "Advertising");
          break;
    
    #ifdef PLUS_BROADCASTER
        // After a connection is dropped, a device in PLUS_BROADCASTER will continue
        // sending non-connectable advertisements and shall send 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;
    
            attRsp_freeAttRsp(bleNotConnected);
          }
          break;
    #endif //PLUS_BROADCASTER
    
        case GAPROLE_CONNECTED:
          {
            Autoconnection_flag = 0;
    
            linkDBInfo_t linkInfo;
            uint8_t numActive = 0;
    
            Util_startClock(&periodicClock);
    
            numActive = linkDB_NumActive();
    
            // Use numActive to determine the connection handle of the last
            // connection
            if ( linkDB_GetInfo( numActive - 1, &linkInfo ) == SUCCESS )
            {
              Display_print1(dispHandle, 2, 0, "Num Conns: %d", (uint16_t)numActive);
              Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(linkInfo.addr));
            }
            else
            {
              uint8_t peerAddress[B_ADDR_LEN];
    
              GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
    
              Display_print0(dispHandle, 2, 0, "Connected");
              Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(peerAddress));
            }
    
            #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-connectable 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:
          Display_print0(dispHandle, 2, 0, "Connected Advertising");
          break;
    
        case GAPROLE_WAITING:
          {
            //uint8_t advertReEnable = FALSE;
    
            Util_stopClock(&periodicClock);
            attRsp_freeAttRsp(bleNotConnected);
    
            // Clear remaining lines
            Display_clearLines(dispHandle, 3, 5);
    
            //GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertReEnable);
            Display_print0(dispHandle, 2, 0, "Advertising");
          }
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          attRsp_freeAttRsp(bleNotConnected);
    
          Display_print0(dispHandle, 2, 0, "Timed Out");
    
          // Clear remaining lines
          Display_clearLines(dispHandle, 3, 5);
    
          #ifdef PLUS_BROADCASTER
            // Reset flag for next connection.
            firstConnFlag = false;
          #endif // PLUS_BROADCASTER
          break;
    
        case GAPROLE_ERROR:
          Display_print0(dispHandle, 2, 0, "Error");
          break;
    
        default:
          Display_clearLine(dispHandle, 2);
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_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 SimplePeripheral_charValueChangeCB(uint8_t paramID)
    {
      SimplePeripheral_enqueueMsg(SBP_CHAR_CHANGE_EVT, paramID, 0);
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_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 SimplePeripheral_processCharValueChangeEvt(uint8_t paramID)
    {
      uint8_t newValue;
    
      switch(paramID)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          Display_print1(dispHandle, 4, 0, "Char 1: %d", (uint16_t)newValue);
          break;
    
        default:
          // should not reach here!
          break;
      }
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_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 SimplePeripheral_performPeriodicTask(void)
    {
      uint8_t valueToCopy[SIMPLEPROFILE_CHAR1_LEN];
      uint8_t payload[] = {'0','0','0','0','0','0','0','0','0','0',
                           '0','0','0','0','0','0','0','0','0','0',
                           '0','0','0','0','0','0'};
    
      memset(valueToCopy, 0, SIMPLEPROFILE_CHAR1_LEN);
      //memset(payload, 0, DATA_PAYLOAD_SIZE);
    
      // Call to retrieve the value of the First characteristic in the profile
      // 0x31 - 0x36 :: APP to BLE
      if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, valueToCopy) == SUCCESS)
      {
        for ( uint8_t i=2 ; i<DATA_PAYLOAD_SIZE+2 ; i++ )
        {
            payload[i-2] = valueToCopy[i];
        }
    
        UartManager_SetStatus(valueToCopy[1], payload); /* send to uart */
      }
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_pairStateCB
     *
     * @brief   Pairing state callback.
     *
     * @return  none
     */
    static void SimplePeripheral_pairStateCB(uint16_t connHandle, uint8_t state,
                                                uint8_t status)
    {
      uint8_t *pData;
    
      // Allocate space for the event data.
      if ((pData = ICall_malloc(sizeof(uint8_t))))
      {
        *pData = status;
    
        // Queue the event.
        SimplePeripheral_enqueueMsg(SBP_PAIRING_STATE_EVT, state, pData);
      }
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_processPairState
     *
     * @brief   Process the new paring state.
     *
     * @return  none
     */
    static void SimplePeripheral_processPairState(uint8_t state, uint8_t status)
    {
      if (state == GAPBOND_PAIRING_STATE_STARTED)
      {
        Display_print0(dispHandle, 2, 0, "Pairing started");
      }
      else if (state == GAPBOND_PAIRING_STATE_COMPLETE)
      {
        if (status == SUCCESS)
        {
          Display_print0(dispHandle, 2, 0, "Pairing success");
        }
        else
        {
          Display_print1(dispHandle, 2, 0, "Pairing fail: %d", status);
        }
      }
      else if (state == GAPBOND_PAIRING_STATE_BONDED)
      {
        if (status == SUCCESS)
        {
          Display_print0(dispHandle, 2, 0, "Bonding success");
        }
      }
      else if (state == GAPBOND_PAIRING_STATE_BOND_SAVED)
      {
        if (status == SUCCESS)
        {
          Display_print0(dispHandle, 2, 0, "Bond save success");
        }
        else
        {
          Display_print1(dispHandle, 2, 0, "Bond save failed: %d", status);
        }
      }
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_passcodeCB
     *
     * @brief   Passcode callback.
     *
     * @return  none
     */
    static void SimplePeripheral_passcodeCB(uint8_t *deviceAddr,
                                            uint16_t connHandle,
                                            uint8_t uiInputs,
                                            uint8_t uiOutputs,
                                            uint32_t numComparison)
    {
      uint8_t *pData;
    
      // Allocate space for the passcode event.
      if ((pData = ICall_malloc(sizeof(uint8_t))))
      {
        *pData = uiOutputs;
    
        // Enqueue the event.
        SimplePeripheral_enqueueMsg(SBP_PASSCODE_NEEDED_EVT, 0, pData);
      }
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_processPasscode
     *
     * @brief   Process the Passcode request.
     *
     * @return  none
     */
    static void SimplePeripheral_processPasscode(uint8_t uiOutputs)
    {
      // This app uses a default passcode. A real-life scenario would handle all
      // pairing scenarios and likely generate this randomly.
      uint32_t passcode = B_APP_DEFAULT_PASSCODE;
    
      // Display passcode to user
      if (uiOutputs != 0)
      {
        Display_print1(dispHandle, 4, 0, "Passcode: %d", passcode);
      }
    
      uint16_t connectionHandle;
      GAPRole_GetParameter(GAPROLE_CONNHANDLE, &connectionHandle);
    
      // Send passcode response
      GAPBondMgr_PasscodeRsp(connectionHandle, SUCCESS, passcode);
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_clockHandler
     *
     * @brief   Handler function for clock timeouts.
     *
     * @param   arg - event type
     *
     * @return  None.
     */
    static void SimplePeripheral_clockHandler(UArg arg)
    {
      // Wake up the application.
      Event_post(syncEvent, arg);
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_connEvtCB
     *
     * @brief   Connection event callback.
     *
     * @param pReport pointer to connection event report
     */
    static void SimplePeripheral_connEvtCB(Gap_ConnEventRpt_t *pReport)
    {
      // Enqueue the event for processing in the app context.
      if( SimplePeripheral_enqueueMsg(SBP_CONN_EVT, 0 ,(uint8_t *) pReport) == FALSE)
      {
        ICall_free(pReport);
      }
    
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_processPairState
     *
     * @brief   Process the new paring state.
     *
     * @return  none
     */
    
    static void SimplePeripheral_TestEvent(uint8_t state, uint8_t* status)
    {
        //gaprole_States_t newState;
    
        //0x30 :: Process Connection request from UART (Manual pairing/ auto connection)
        //CONTROL DATA --> status[0]
        //0x01 : Start Manual Pairing
        //0x02 : Start Auto Connection
        //0x03 : Stop Auto Connection
        //0x04 : Disconnect
    
        Control_Data = (uint8_t)status[0];
    
        switch (Control_Data)
        {
            case 1:  /* Start Manual Pairing */
                Autoconnection_flag = 0;
    
                Util_startClock(&periodicClockAdv);  //Timer_120s
    
                VOID GAPRole_StartDevice(&SimplePeripheral_gapRoleCBs);
    
                /* 12byte containing name of the device */
                for(uint8_t i = 2 ; i<14 ; i++){
                    scanRspData[i] = (uint8_t)status[i-1];
                }
    //            scanRspData[2] = (uint8_t)status[1];
    //            scanRspData[3] = (uint8_t)status[2];
    //            scanRspData[4] = (uint8_t)status[3];
    //            scanRspData[5] = (uint8_t)status[4];
    //            scanRspData[6] = (uint8_t)status[5];
    //            scanRspData[7] = (uint8_t)status[6];
    //            scanRspData[8] = (uint8_t)status[7];
    //            scanRspData[9] = (uint8_t)status[8];
    //            scanRspData[10] = (uint8_t)status[9];
    //            scanRspData[11] = (uint8_t)status[10];
    //            scanRspData[12] = (uint8_t)status[11];
    //            scanRspData[13] = (uint8_t)status[12];
    
                GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                                     scanRspData);
    
                advertEnabled1 = TRUE;
                // Enabled advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled1);
                break;
    
            case 2: /* Start Auto Connection */
                Autoconnection_flag = 1;
    
                Util_startClock(&periodicClockAdv);  //Timer_120s
    
                VOID GAPRole_StartDevice(&SimplePeripheral_gapRoleCBs);
    
                /* 12byte containing name of the device */
                for(uint8_t i = 2 ; i<14 ; i++){
                    scanRspData[i] = (uint8_t)status[i-1];
                }
    //            scanRspData[2] = (uint8_t)status[1];
    //            scanRspData[3] = (uint8_t)status[2];
    //            scanRspData[4] = (uint8_t)status[3];
    //            scanRspData[5] = (uint8_t)status[4];
    //            scanRspData[6] = (uint8_t)status[5];
    //            scanRspData[7] = (uint8_t)status[6];
    //            scanRspData[8] = (uint8_t)status[7];
    //            scanRspData[9] = (uint8_t)status[8];
    //            scanRspData[10] = (uint8_t)status[9];
    //            scanRspData[11] = (uint8_t)status[10];
    //            scanRspData[12] = (uint8_t)status[11];
    //            scanRspData[13] = (uint8_t)status[12];
    
                GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
                                     scanRspData);
    
                advertEnabled1 = TRUE;
                // Enabled advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled1);
                break;
    
            case 3: /* Stop Auto Connection */
                Autoconnection_flag = 0;
    
                advertEnabled1 = FALSE;
                //Disabled advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled1);
    
                //newState = GAPROLE_WAITING;//4
                SimplePeripheral_stateChangeCB((gaprole_States_t)4/*newState*/);
                break;
    
            case 4:  /* Disconnect  */
                Autoconnection_flag = 0;
    
                GAPRole_TerminateConnection();
    
                advertEnabled1 = FALSE;
                //Disabled advertising.
                GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                     &advertEnabled1);
    
                //newState = GAPROLE_WAITING;//4
                SimplePeripheral_stateChangeCB((gaprole_States_t)4/*newState*/);
                break;
    
            default :
                break;
        }
        Control_Data = 0;
    }
    
    
    static void SimplePeripheral_TestEvent1(uint8_t state, uint8_t *status)
    {
        /* 0x37 :: SUZUKI_CLUSTER_STATUS_PKT */
    
        uint8_t Temp[SIMPLEPROFILE_CHAR2_LEN] = { 0xA5, 0x37, 0, 0, 0, 0, 0, 0, 0, 0,
                                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                  0, 0, 0, 0, 0, 0, 0, 0, 0xEE, 0x7F};
        /* Data copying to Temp array */
        for ( uint8_t i=2 ; i< DATA_PAYLOAD_SIZE+2 ; i++ )
            Temp[i] = status[i-2];
    
        /* directly transferring the data to mobile via char2 */
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN,
                                   Temp);
    }
    
    /*********************************************************************
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event - message event.
     * @param   state - message state.
     * @param   pData - message data pointer.
     *
     * @return  TRUE or FALSE
     */
    static uint8_t SimplePeripheral_enqueueMsg(uint8_t event, uint8_t state,
                                               uint8_t *pData)
    {
      sbpEvt_t *pMsg = ICall_malloc(sizeof(sbpEvt_t));
    
      // Create dynamic pointer to message.
      if (pMsg)
      {
        pMsg->hdr.event = event;
        pMsg->hdr.state = state;
        pMsg->pData = pData;
    
        // Enqueue the message.
        return Util_enqueueMsg(appMsgQueue, syncEvent, (uint8_t *)pMsg);
      }
    
      return FALSE;
    }
    /*********************************************************************
    *********************************************************************/
    
    /******************************************************************************
    
     @file  simple_gatt_profile.c
    
     @brief This file contains the Simple GATT profile sample GATT service profile
            for use with the BLE sample application.
    
     Group: WCS, BTS
     Target Device: cc2640r2
    
     ******************************************************************************
    
     Copyright (c) 2010-2020, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
    
    
     *****************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    #include <icall.h>
    #include "util.h"
    /* This Header file contains all BLE API and icall structure definition */
    #include "icall_ble_api.h"
    
    #include "simple_gatt_profile.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    #define SERVAPP_NUM_ATTR_SUPPORTED        8
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    // Simple GATT Profile Service UUID: 0xFFF0
    CONST uint8 simpleProfileServUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_SERV_UUID), HI_UINT16(SIMPLEPROFILE_SERV_UUID)
    };
    
    // Characteristic 1 UUID: 0xFFF1
    CONST uint8 simpleProfilechar1UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR1_UUID), HI_UINT16(SIMPLEPROFILE_CHAR1_UUID)
    };
    
    // Characteristic 2 UUID: 0xFFF2
    CONST uint8 simpleProfilechar2UUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(SIMPLEPROFILE_CHAR2_UUID), HI_UINT16(SIMPLEPROFILE_CHAR2_UUID)
    };
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
    
    /*********************************************************************
     * Profile Attributes - variables
     */
    
    // Simple Profile Service attribute
    static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };
    
    
    // Simple Profile Characteristic 1 Properties
    static uint8 simpleProfileChar1Props = GATT_PROP_WRITE;
    
    // Characteristic 1 Value
    static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    // Simple Profile Characteristic 1 User Description
    static uint8 simpleProfileChar1UserDesp[17] = "Mobile Data";
    
    
    // Simple Profile Characteristic 2 Properties
    static uint8 simpleProfileChar2Props = GATT_PROP_NOTIFY;
    
    // Characteristic 2 Value
    static uint8 simpleProfileChar2[SIMPLEPROFILE_CHAR2_LEN] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    // Simple Profile Characteristic 4 Configuration Each client has its own
    // instantiation of the Client Characteristic Configuration. Reads of the
    // Client Characteristic Configuration only shows the configuration for
    // that client and writes only affect the configuration of that client.
    static gattCharCfg_t *simpleProfileChar2Config;
    
    // Simple Profile Characteristic 2 User Description
    static uint8 simpleProfileChar2UserDesp[17] = "Vehicle Data";
    
    
    /*********************************************************************
     * Profile Attributes - Table
     */
    
    static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
    {
          // Simple Profile Service
          {
            { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
            GATT_PERMIT_READ,                         /* permissions */
            0,                                        /* handle */
            (uint8 *)&simpleProfileService            /* pValue */
          },
    
          // Characteristic 1 Declaration
          {
            { ATT_BT_UUID_SIZE, characterUUID },
            GATT_PERMIT_READ,
            0,
            &simpleProfileChar1Props
          },
    
          // Characteristic Value 1
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },
            GATT_PERMIT_WRITE,
            0,
            simpleProfileChar1
          },
    
          // Characteristic 1 User Description
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar1UserDesp
          },
    
          // Characteristic 2 Declaration
          {
            { ATT_BT_UUID_SIZE, characterUUID },
            GATT_PERMIT_READ,
            0,
            &simpleProfileChar2Props
          },
    
          // Characteristic Value 2
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar2UUID },
            0,
            0,
            simpleProfileChar2
          },
    
          // Characteristic 2 configuration
          {
            { ATT_BT_UUID_SIZE, clientCharCfgUUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE,
            0,
            (uint8 *)&simpleProfileChar2Config
          },
    
          // Characteristic 2 User Description
          {
            { ATT_BT_UUID_SIZE, charUserDescUUID },
            GATT_PERMIT_READ,
            0,
            simpleProfileChar2UserDesp
          },
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
                                              gattAttribute_t *pAttr,
                                              uint8_t *pValue, uint16_t *pLen,
                                              uint16_t offset, uint16_t maxLen,
                                              uint8_t method);
    static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
                                               gattAttribute_t *pAttr,
                                               uint8_t *pValue, uint16_t len,
                                               uint16_t offset, uint8_t method);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // Simple Profile Service Callbacks
    // Note: When an operation on a characteristic requires authorization and
    // pfnAuthorizeAttrCB is not defined for that characteristic's service, the
    // Stack will report a status of ATT_ERR_UNLIKELY to the client.  When an
    // operation on a characteristic requires authorization the Stack will call
    // pfnAuthorizeAttrCB to check a client's authorization prior to calling
    // pfnReadAttrCB or pfnWriteAttrCB, so no checks for authorization need to be
    // made within these functions.
    CONST gattServiceCBs_t simpleProfileCBs =
    {
      simpleProfile_ReadAttrCB,  // Read callback function pointer
      simpleProfile_WriteAttrCB, // Write callback function pointer
      NULL                       // Authorization callback function pointer
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleProfile_AddService
     *
     * @brief   Initializes the Simple Profile service by registering
     *          GATT attributes with the GATT server.
     *
     * @param   services - services to add. This is a bit map and can
     *                     contain more than one service.
     *
     * @return  Success or Failure
     */
    bStatus_t SimpleProfile_AddService( uint32 services )
    {
      uint8 status;
    
      // Allocate Client Characteristic Configuration table
      simpleProfileChar2Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
                                                                  linkDBNumConns );
      if ( simpleProfileChar2Config == NULL )
      {
        return ( bleMemAllocError );
      }
    
      // Initialize Client Characteristic Configuration attributes
      GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar2Config );
    
      if ( services & SIMPLEPROFILE_SERVICE )
      {
        // Register GATT attribute list and CBs with GATT Server App
        status = GATTServApp_RegisterService( simpleProfileAttrTbl,
                                              GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                              GATT_MAX_ENCRYPT_KEY_SIZE,
                                              &simpleProfileCBs );
      }
      else
      {
        status = SUCCESS;
      }
    
      return ( status );
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_RegisterAppCBs
     *
     * @brief   Registers the application callback function. Only call
     *          this function once.
     *
     * @param   callbacks - pointer to application callbacks.
     *
     * @return  SUCCESS or bleAlreadyInRequestedMode
     */
    bStatus_t SimpleProfile_RegisterAppCBs( simpleProfileCBs_t *appCallbacks )
    {
      if ( appCallbacks )
      {
        simpleProfile_AppCBs = appCallbacks;
    
        return ( SUCCESS );
      }
      else
      {
        return ( bleAlreadyInRequestedMode );
      }
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_SetParameter
     *
     * @brief   Set a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   len - length of data to write
     * @param   value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
    
        case SIMPLEPROFILE_CHAR1:
          if ( len == SIMPLEPROFILE_CHAR1_LEN )
          {
            VOID memcpy( simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN );
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        case SIMPLEPROFILE_CHAR2:
          if ( len == SIMPLEPROFILE_CHAR2_LEN )
          {
            VOID memcpy( simpleProfileChar2, value, SIMPLEPROFILE_CHAR2_LEN );
    
            // See if Notification has been enabled
            GATTServApp_ProcessCharCfg( simpleProfileChar2Config, simpleProfileChar2, FALSE,
                                          simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                          INVALID_TASK_ID, simpleProfile_ReadAttrCB );
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
    
      return ( ret );
    }
    
    /*********************************************************************
     * @fn      SimpleProfile_GetParameter
     *
     * @brief   Get a Simple Profile parameter.
     *
     * @param   param - Profile parameter ID
     * @param   value - pointer to data to put.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     *
     * @return  bStatus_t
     */
    bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case SIMPLEPROFILE_CHAR1:
          VOID memcpy( value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN );
          break;
    
        case SIMPLEPROFILE_CHAR2:
          VOID memcpy( value, simpleProfileChar2, SIMPLEPROFILE_CHAR2_LEN );
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
    
      return ( ret );
    }
    
    /*********************************************************************
     * @fn          simpleProfile_ReadAttrCB
     *
     * @brief       Read an attribute.
     *
     * @param       connHandle - connection message was received on
     * @param       pAttr - pointer to attribute
     * @param       pValue - pointer to data to be read
     * @param       pLen - length of data to be read
     * @param       offset - offset of the first octet to be read
     * @param       maxLen - maximum length of data to be read
     * @param       method - type of read message
     *
     * @return      SUCCESS, blePending or Failure
     */
    static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
                                              gattAttribute_t *pAttr,
                                              uint8_t *pValue, uint16_t *pLen,
                                              uint16_t offset, uint16_t maxLen,
                                              uint8_t method)
    {
      bStatus_t status = SUCCESS;
    
      // Make sure it's not a blob operation (no attributes in the profile are long)
      if ( offset > 0 )
      {
        return ( ATT_ERR_ATTR_NOT_LONG );
      }
    
      if ( pAttr->type.len == ATT_BT_UUID_SIZE )
      {
        // 16-bit UUID
        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
        switch ( uuid )
        {
          // No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
          // gattserverapp handles those reads
    
          // characteristics 1 and 2 have read permissions
          // characteritisc 3 does not have read permissions; therefore it is not
          //   included here
          // characteristic 4 does not have read permissions, but because it
          //   can be sent as a notification, it is included here
          case SIMPLEPROFILE_CHAR1_UUID:
              *pLen = SIMPLEPROFILE_CHAR1_LEN;
              VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
              break;
    
          case SIMPLEPROFILE_CHAR2_UUID:
              *pLen = SIMPLEPROFILE_CHAR2_LEN;
              VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR2_LEN );
              break;
    
          default:
            // Should never get here! (characteristics 3 and 4 do not have read permissions)
            *pLen = 0;
            status = ATT_ERR_ATTR_NOT_FOUND;
            break;
        }
      }
      else
      {
        // 128-bit UUID
        *pLen = 0;
        status = ATT_ERR_INVALID_HANDLE;
      }
    
      return ( status );
    }
    
    /*********************************************************************
     * @fn      simpleProfile_WriteAttrCB
     *
     * @brief   Validate attribute data prior to a write operation
     *
     * @param   connHandle - connection message was received on
     * @param   pAttr - pointer to attribute
     * @param   pValue - pointer to data to be written
     * @param   len - length of data
     * @param   offset - offset of the first octet to be written
     * @param   method - type of write message
     *
     * @return  SUCCESS, blePending or Failure
     */
    static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
                                               gattAttribute_t *pAttr,
                                               uint8_t *pValue, uint16_t len,
                                               uint16_t offset, uint8_t method)
    {
      bStatus_t status = SUCCESS;
      uint8 notifyApp = 0xFF;
    
      if ( pAttr->type.len == ATT_BT_UUID_SIZE )
      {
        // 16-bit UUID
        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
        switch ( uuid )
        {
          case SIMPLEPROFILE_CHAR1_UUID:
    
              //Validate the value
              // Make sure it's not a blob oper
              if ( offset == 0 )
              {
                if ( len != SIMPLEPROFILE_CHAR1_LEN )
                {
                  status = ATT_ERR_INVALID_VALUE_SIZE;
                }
              }
              else
              {
                status = ATT_ERR_ATTR_NOT_LONG;
              }
    
              //Write the value
              if ( status == SUCCESS )
              {
                uint8 *pCurValue = (uint8 *)pAttr->pValue;
                //*pCurValue = pValue[0];
                VOID memcpy( pCurValue, pValue, SIMPLEPROFILE_CHAR1_LEN );
    
                if( pAttr->pValue == simpleProfileChar1 )
                {
                  notifyApp = SIMPLEPROFILE_CHAR1;
                }
              }
              break;
    
          case GATT_CLIENT_CHAR_CFG_UUID:
            status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                     offset, GATT_CLIENT_CFG_NOTIFY );
            break;
    
          default:
            // Should never get here! (characteristics 2 and 4 do not have write permissions)
            status = ATT_ERR_ATTR_NOT_FOUND;
            break;
        }
      }
      else
      {
        // 128-bit UUID
        status = ATT_ERR_INVALID_HANDLE;
      }
    
      // If a characteristic value changed then callback function to notify application of change
      if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
      {
        simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );
      }
    
      return ( status );
    }
    
    /*********************************************************************
    *********************************************************************/
    
    /******************************************************************************
    
     @file  uart_manager.c
    
     @brief This file contains the uart sample application for use
            with the CC2650 Bluetooth Low Energy Protocol Stack.
    
     Group: WCS, BTS
     Target Device: cc2640r2
    
     ******************************************************************************
    
     Copyright (c) 2013-2020, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
    
    
     *****************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <xdc/std.h>
    #include <icall.h>
    
    #include <board.h>
    #include <ti/drivers/UART.h>
    
    #include "simple_peripheral.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    #define ACK                                     0x06
    #define NACK                                    0x15
    
    #define START_BYTE                              0xA5
    #define END_BYTE                                0x7F
    
    #define INFO_DATA_ID                            0x30
    #define INFO_DATA_PAYLOAD_SIZE                  0x1A // 26 in decimal
    
    #define NAV_DATA_ID                             0x31
    #define NAV_DATA_PAYLOAD_SIZE                   0x1A // 26 in decimal
    
    #define CALL_DATA_ID                            0x32
    #define CALL_DATA_PAYLOAD_SIZE                  0x1A // 26 in decimal
    
    #define SPSTATUS_DATA_ID                        0x33
    #define SPSTATUS_DATA_PAYLOAD_SIZE              0x1A // 26 in decimal
    
    #define MISSEDCALL_DATA_ID                      0x34
    #define MISSEDCALL_DATA_PAYLOAD_SIZE            0x1A // 26 in decimal
    
    #define SMS_DATA_ID                             0x35
    #define SMS_DATA_PAYLOAD_SIZE                   0x1A // 26 in decimal
    
    #define USERINFO_DATA_ID                        0x36
    #define USERINFO_DATA_PAYLOAD_SIZE              0x1A // 26 in decimal
    
    #define VECHILE_DATA_ID                         0x37
    #define VECHILE_DATA_PAYLOAD_SIZE               0x1A // 26 in decimal
    
    //#define ADVERTISEMENT_DATA_ID                0x38
    //#define ADVERTISEMENT_DATA_PAYLOAD_SIZE      0x1A // 26 in decimal
    //
    //#define CONTROL_DATA_ID                      0x40
    //#define CONTROL_DATA_PAYLOAD_SIZE            0x01
    //
    //#define BLE_STATUS_PAYLOAD_ID                0x39
    //#define BLE_STATUS_PAYLOAD_SIZE              0x01
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    typedef struct
    {
      uint8_t Start_Byte;
      uint8_t Identification_Byte;
      uint8_t Payload_Data[INFO_DATA_PAYLOAD_SIZE];
      uint8_t Checksum;
      uint8_t End_Byte;
    } InfoDataPacket_t;
    
    typedef struct
    {
      uint8_t Start_Byte;
      uint8_t Identification_Byte;
      uint8_t Payload_Data[NAV_DATA_PAYLOAD_SIZE];
      uint8_t Checksum;
      uint8_t End_Byte;
    } NavDataPacket_t;
    
    typedef struct
    {
      uint8_t Start_Byte;
      uint8_t Identification_Byte;
      uint8_t Payload_Data[CALL_DATA_PAYLOAD_SIZE];
      uint8_t Checksum;
      uint8_t End_Byte;
    } CallDataPacket_t;
    
    typedef struct
    {
      uint8_t Start_Byte;
      uint8_t Identification_Byte;
      uint8_t Payload_Data[SPSTATUS_DATA_PAYLOAD_SIZE];
      uint8_t Checksum;
      uint8_t End_Byte;
    } SpStatusDataPacket_t;
    
    typedef struct
    {
      uint8_t Start_Byte;
      uint8_t Identification_Byte;
      uint8_t Payload_Data[MISSEDCALL_DATA_PAYLOAD_SIZE];
      uint8_t Checksum;
      uint8_t End_Byte;
    } MissedCallDataPacket_t;
    
    typedef struct
    {
      uint8_t Start_Byte;
      uint8_t Identification_Byte;
      uint8_t Payload_Data[SMS_DATA_PAYLOAD_SIZE];
      uint8_t Checksum;
      uint8_t End_Byte;
    } SmsDataPacket_t;
    
    typedef struct
    {
      uint8_t Start_Byte;
      uint8_t Identification_Byte;
      uint8_t Payload_Data[USERINFO_DATA_PAYLOAD_SIZE];
      uint8_t Checksum;
      uint8_t End_Byte;
    } UserInfoDataPacket_t;
    
    typedef struct
    {
      uint8_t Start_Byte;
      uint8_t Identification_Byte;
      uint8_t Payload_Data[VECHILE_DATA_PAYLOAD_SIZE];
      uint8_t Checksum;
      uint8_t End_Byte;
    } VechileDataPacket_t;
    
    //typedef struct
    //{
    //  uint8_t Start_Byte;
    //  uint8_t Identification_Byte;
    //  uint8_t Payload_Data[ADVERTISEMENT_DATA_PAYLOAD_SIZE];
    //  uint8_t Checksum;
    //  uint8_t End_Byte;
    //} AdvertisementDataPacket_t;
    //
    //typedef struct
    //{
    //  uint8_t Start_Byte;
    //  uint8_t Identification_Byte;
    //  uint8_t Payload_Data[BLE_STATUS_PAYLOAD_SIZE];
    //  uint8_t Checksum;
    //  uint8_t End_Byte;
    //} BleStatusPacket_t;
    //
    //typedef struct
    //{
    //  uint8_t Start_Byte;
    //  uint8_t Identification_Byte;
    //  uint8_t Payload_Data[CONTROL_DATA_PAYLOAD_SIZE];
    //  uint8_t Checksum;
    //  uint8_t End_Byte;
    //} ControlDataPacket_t;
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    
    extern ICall_SyncHandle syncEvent;
    
    extern Queue_Handle appMsgQueue;
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static UART_Handle uart;
    static UART_Params uartParams;
    
    static uint8_t Req;
    
    static bool Read_Req_status = TRUE;
    
    InfoDataPacket_t stInfoData;
    
    NavDataPacket_t stNavData =
    {
     .Start_Byte = START_BYTE,
     .Identification_Byte = NAV_DATA_ID,
     .End_Byte = END_BYTE
    };
    
    CallDataPacket_t stCallData =
    {
     .Start_Byte = START_BYTE,
     .Identification_Byte = CALL_DATA_ID,
     .End_Byte = END_BYTE
    };
    
    SpStatusDataPacket_t stSpStatus =
    {
     .Start_Byte = START_BYTE,
     .Identification_Byte = SPSTATUS_DATA_ID,
     .End_Byte = END_BYTE
    };
    
    MissedCallDataPacket_t MissedCall =
    {
     .Start_Byte = START_BYTE,
     .Identification_Byte = MISSEDCALL_DATA_ID,
     .End_Byte = END_BYTE
    };
    
    SmsDataPacket_t stSmsData =
    {
     .Start_Byte = START_BYTE,
     .Identification_Byte = SMS_DATA_ID,
     .End_Byte = END_BYTE
    };
    
    UserInfoDataPacket_t stUserInfo =
    {
     .Start_Byte = START_BYTE,
     .Identification_Byte = USERINFO_DATA_ID,
     .End_Byte = END_BYTE
    };
    
    VechileDataPacket_t stVechileData;
    
    //BleStatusPacket_t stBleStatus =
    //{
    // .Start_Byte = START_BYTE,
    // .Identification_Byte = BLE_STATUS_PAYLOAD_ID,
    // .End_Byte = END_BYTE
    //};
    
    //AdvertisementDataPacket_t stAdvertisementData;
    //
    //ControlDataPacket_t stControlData;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void UartManager_readCallBack(UART_Handle handle, void *ptr, size_t size);
    static void UartManager_writeCallBack(UART_Handle handle, void *ptr, size_t size);
    static uint8_t UartManager_enqueueMsg(uint8_t event, uint8_t state, uint8_t *pData);
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    void UartManager_SetStatus(uint8_t ID, void* payload)
    {
        switch (ID)
        {
            case NAV_DATA_ID:
                (void) memcpy( &stNavData.Payload_Data, payload, NAV_DATA_PAYLOAD_SIZE );
                break;
    
            case CALL_DATA_ID:
                (void) memcpy( &stCallData.Payload_Data, payload, CALL_DATA_PAYLOAD_SIZE );
                break;
    
            case SPSTATUS_DATA_ID:
                (void) memcpy( &stSpStatus.Payload_Data, payload, SPSTATUS_DATA_PAYLOAD_SIZE );
                break;
    
            case MISSEDCALL_DATA_ID:
                (void) memcpy( &MissedCall.Payload_Data, payload, MISSEDCALL_DATA_PAYLOAD_SIZE );
                break;
    
            case SMS_DATA_ID:
                (void) memcpy( &stSmsData.Payload_Data, payload, SMS_DATA_PAYLOAD_SIZE );
                break;
    
            case USERINFO_DATA_ID:
                (void) memcpy( &stUserInfo.Payload_Data, payload, USERINFO_DATA_PAYLOAD_SIZE );
                break;
    
            case VECHILE_DATA_ID:
                (void) memcpy( &stVechileData.Payload_Data, payload, VECHILE_DATA_PAYLOAD_SIZE );
                break;
    
            default:
                break;
        }
    }
    
    /*********************************************************************
     * @fn      UartManager_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     */
    void UartManager_init(void)
    {
        UART_init();
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.readMode = UART_MODE_CALLBACK;
        uartParams.readCallback = UartManager_readCallBack;
        uartParams.writeMode = UART_MODE_CALLBACK;
        uartParams.writeCallback = UartManager_writeCallBack;
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
    
        uart = UART_open(Board_UART0, &uartParams);
    
        if (uart == NULL) {
            /* UART_open() failed */
            while (1);
        }
    
        UART_read(uart, &Req, sizeof(Req));
    }
    
    static void UartManager_readCallBack(UART_Handle handle, void *ptr, size_t size)
    {
        uint8_t ack = 0x06;
        uint8_t arr[28];
    
        switch (Req)
        {
            case INFO_DATA_ID:
                if (Read_Req_status == 1)
                {
                    UART_write(uart, &ack, 1);
                }
                else
                {
                    UART_read(uart, &Req, sizeof(Req));
    
                    memcpy(arr,&stInfoData.Payload_Data, 28);
                    (void)UartManager_enqueueMsg(0x0020, (uint8_t)stInfoData.Checksum, &arr);
                    Read_Req_status = 1;
                    Req = 0;
                }
                break;
    
            case NAV_DATA_ID:
                UART_write(uart, &ack, 1);
                break;
    
            case CALL_DATA_ID:
                UART_write(uart, &ack, 1);
                break;
    
            case SPSTATUS_DATA_ID:
                UART_write(uart, &ack, 1);
                break;
    
            case MISSEDCALL_DATA_ID:
                UART_write(uart, &ack, 1);
                break;
    
            case SMS_DATA_ID:
                UART_write(uart, &ack, 1);
                break;
    
            case USERINFO_DATA_ID:
                UART_write(uart, &ack, 1);
                break;
    
            case VECHILE_DATA_ID:
                if (Read_Req_status == 1)
                {
                    UART_write(uart, &ack, 1);
                }
                else
                {
                    UART_read(uart, &Req, sizeof(Req));
    
                    memcpy(arr,&stVechileData.Payload_Data, 28);
                    (void)UartManager_enqueueMsg(0x0021, (uint8_t)stVechileData.Checksum, &arr);
                    Read_Req_status = 1;
                    Req = 0;
                }
                break;
    
    //        case ADVERTISEMENT_DATA_ID:
    //            if (Read_Req_status == 1)
    //            {
    //                UART_write(uart, &ack, 1);
    //            }
    //            else
    //            {
    //                UART_read(uart, &Req, sizeof(Req));
    //                (void)UartManager_enqueueMsg(0x0021, (uint8_t)stAdvertisementData.Checksum,
    //                                             (uint8_t *)stAdvertisementData.Payload_Data);
    //                Read_Req_status = 1;
    //                Req = 0;
    //            }
    //            break;
    //
    //        case BLE_STATUS_PAYLOAD_ID:
    //            UART_write(uart, &ack, 1);
    //            break;
    //
    //        case CONTROL_DATA_ID:
    //            if (Read_Req_status == 1)
    //            {
    //                UART_write(uart, &ack, 1);
    //            }
    //            else
    //            {
    //                UART_read(uart, &Req, sizeof(Req));
    //                (void)UartManager_enqueueMsg(0x0022, (uint8_t)stControlData.Checksum,
    //                                             (uint8_t *)stControlData.Payload_Data);
    //                Read_Req_status = 1;
    //                Req = 0;
    //            }
    //            break;
    
            default:
                Req = 0;
                UART_read(uart, &Req, sizeof(Req));
                break;
        }
    }
    
    static void UartManager_writeCallBack(UART_Handle handle, void *ptr, size_t size)
    {
        switch (Req)
        {
            case INFO_DATA_ID:
                UART_read(uart, &stInfoData, sizeof(stInfoData));
                Read_Req_status = 0;
                break;
    
            case NAV_DATA_ID:
                stNavData.Checksum = 0xEE;
                UART_write(uart, &stNavData, sizeof(stNavData));
                UART_read(uart, &Req, sizeof(Req));
                Req = 0;
                break;
    
            case CALL_DATA_ID:
                UART_write(uart, &stCallData, sizeof(stCallData));
                UART_read(uart, &Req, sizeof(Req));
                Req = 0;
                break;
    
            case SPSTATUS_DATA_ID:
                UART_write(uart, &stSpStatus, sizeof(stSpStatus));
                UART_read(uart, &Req, sizeof(Req));
                Req = 0;
                break;
    
            case MISSEDCALL_DATA_ID:
                UART_write(uart, &MissedCall, sizeof(MissedCall));
                UART_read(uart, &Req, sizeof(Req));
                Req = 0;
                break;
    
            case SMS_DATA_ID:
                UART_write(uart, &stSmsData, sizeof(stSmsData));
                UART_read(uart, &Req, sizeof(Req));
                Req = 0;
                break;
    
            case USERINFO_DATA_ID:
                UART_write(uart, &stUserInfo, sizeof(stUserInfo));
                UART_read(uart, &Req, sizeof(Req));
                Req = 0;
                break;
    
            case VECHILE_DATA_ID:
                UART_read(uart, &stVechileData, sizeof(stVechileData));
                Read_Req_status = 0;
                break;
    
    //        case ADVERTISEMENT_DATA_ID:
    //            UART_read(uart, &stAdvertisementData, sizeof(stControlData));
    //            Read_Req_status = 0;
    //            break;
    //
    //        case BLE_STATUS_PAYLOAD_ID:
    //            UART_write(uart, &stBleStatus, sizeof(stBleStatus));
    //            UART_read(uart, &Req, sizeof(Req));
    //            Req = 0;
    //            break;
    //
    //        case CONTROL_DATA_ID:
    //            UART_read(uart, &stControlData, sizeof(stControlData));
    //            Read_Req_status = 0;
    //            break;
    
            default:
                break;
        }
    }
    
    static uint8_t UartManager_enqueueMsg(uint8_t event, uint8_t state,
                                               uint8_t *pData)
    {
      sbpEvt_t *pMsg = ICall_malloc(sizeof(sbpEvt_t));
    
      // Create dynamic pointer to message.
      if (pMsg)
      {
        pMsg->hdr.event = event;
        pMsg->hdr.state = state;
        pMsg->pData = pData;
    
        // Enqueue the message.
        return Util_enqueueMsg(appMsgQueue, syncEvent, (uint8_t *)pMsg);
      }
    
      return FALSE;
    }
    
    /*********************************************************************
    *********************************************************************/
    

  • Hi ,

    One additional thing I have to implement in the case2/Autoconnection:

    Received Data:  { identification byte, control byte, 12byte for the name of the device(BLE), reserved bytes }

    2) IF data received in the control byte is '2':

    • The advertisement should start and name should be the one that is received & the advertisement should stop after 120s( BLE's name should not be visible to any device ).
    • But the BLE device should be able to connect to the phone which is already bonded with the device/already previously connected with the device.
    • And if before the 120s time period the control byte with '3' received the advertisement should stop immediately.
    • In this 120s(Auto connection) period, the BLE device should be able to connect with only previously bonded devices. No new device can be connected to the BLE at any cost!!!

     

    Please suggest how to go about this particular highlighted requirement.

     

    Regards,

    Saurav

  • You can check bonding info in "case GAPROLE_CONNECTED: ..." of SimplePeripheral_processStateChangeEvt to do disconnect if other BLE central try to do connect.

  • When the  "case GAPROLE_CONNECTED: ..." event will come after the bonding will be completed I guess.

    So, will I be able to know the connected device is previously bonded or not??

    And let me know the implementation also if possible.

    Thanks in advance!

  • "case GAPROLE_CONNECTED: ..." event should be triggered before bonding.

  • "case GAPROLE_CONNECTED: ..." event should be triggered before bonding.

    Okay, But can you plz let me know how I will get to know the Bonding data of this new device?

    And, how should I compare the value of new device from that in the list of bonded devices?

    Thanks in advance!

  •   uint8_t bondAddr[B_ADDR_LEN];
      uint8_t connectingAddress[B_ADDR_LEN];

    1. Use "GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, connectingAddress);" to get connectingAddress.

    2. Use "GAPBondMgr_ResolveAddr(ADDRTYPE_RANDOM_ID, connectingAddress, bondAddr);" to resolve bonding address.

    If no resolve bonding address, you can disconnect the link.

  • The logic is working fine, thanks a lot for the help .

  • Hi ,

    There is an issue I am facing with the same thing.

    The first time when I am trying to connect with the BLE with a  non bonded phone then the logic is restricting the phone.

    But after bonding the phone with it, and then I am deleting the bond using the nrf connect app --> after this when I am again trying to connect with the BLE then the BLE is somehow allowing this device.

    Why is the bond info not deleted by the BLE ??

     

  • As I know, it only delete the bonding info on APP side when you do delete from APP and the device side won't know it's unbonded. You might need to use "GAPBondMgr_SetParameter(GAPBOND_ERASE_ALLBONDS, 0, NULL);" to unbond on device side by yourself.