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.

[参考译文] CC2652R:蓝牙网状网络配置和消息发送

Guru**** 1812430 points
Other Parts Discussed in Thread: ENERGYTRACE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1191582/cc2652r-bluetooth-mesh-provisioning-and-message-sending

器件型号:CC2652R
主题中讨论的其他器件:ENERGYTRACE

您好!

我正在使用简单网状网络节点示例、我想实现一项任务、即在不使用 UART 接口的情况下配置器件并在器件之间实现通信。 回调函数执行、但当我尝试通过按下按钮来打开另一个器件的 LED 时、它会切换其自己的 LED、因此我认为我正在使用的两个器件之间没有通信、并且每个器件位于不同的网络上。 我如何才能继续,以便只有一个网络,以便设备能够进行通信?  

非常感谢、

Alexandra Goloubkove2e.ti.com/.../start_5F00_provisioning-_2800_1_2900_.c

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <math.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/sysbios/knl/Semaphore.h>
#include <ti/sysbios/BIOS.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/mesh.h>
#include <bt_le_porting_layer.h>

#include <start_provisioning.h>


#include <ti/drivers/GPIO.h>
#include "ti_drivers_config.h"

#include <simple_mesh_node.h>
#include "ti_ble_mesh_config.h"
#include "simple_mesh_node_menu.h"
#include <net/buf.h>
#include <include/bluetooth/mesh/access.h>
#include "static_prov.h"

#define START_PROV_TASK_PRIORITY    3
#ifndef START_PROV_STACK_SIZE
#define START_PROV_STACK_SIZE      2248
#endif

#define GROUP_ADDR 0xc000
extern void start_prov_init(void);
uint8_t button_state = 0;
uint16_t addr;
uint8_t led_state;
uint16_t mesh_device_own_addr = DEVICE_OWN_ADDRESS;
//static const uint16_t app_idx;
Task_Struct start_prov_Task;
uint8_t start_prov_Stack[START_PROV_STACK_SIZE];
Semaphore_Struct semstart_prov_Task_Struct;
Semaphore_Handle semstart_prov_Task_Handle;

struct bt_mesh_model *model;
struct bt_mesh_msg_ctx *ctx;
struct net_buf_simple *buf;
void provision_done_cbk()
{

    GPIO_write(CONFIG_GPIO_LED_0,1);

    }

void btn1Fxn_cbk(uint_least8_t index)
{
    Semaphore_post(semstart_prov_Task_Handle);
}

void turnLed(uint8_t on_off)
{
  if (on_off)
  {
      GPIO_write(CONFIG_GPIO_LED_1,1);
  }
  else
  {
    GPIO_write(CONFIG_GPIO_LED_1,0);
  }
}
void button_pressed_cb(struct bt_mesh_model *model,
                      struct bt_mesh_msg_ctx *ctx,
                      struct net_buf_simple *buf)
{
  // check own address
    /*(ctx->addr == mesh_device_own_addr)*/
  if (ctx->addr == mesh_device_own_addr) {


     return;
  }

  led_state = net_buf_simple_pull_u8(buf);

  turnLed(led_state);

}

void start_prov_init(void)
{

    GPIO_init();
    GPIO_setConfig(CONFIG_GPIO_BTN1,
                   GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
    GPIO_setCallback(CONFIG_GPIO_BTN1,btn1Fxn_cbk );
    GPIO_enableInt(CONFIG_GPIO_BTN1);

    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
}

static void start_prov_taskFxn(UArg a0, UArg a1)
{

    start_prov_init();
    bleApp_stackInit();

    MeshApp_init(DEVICE_OWN_ADDRESS, UNPROVISIONED_BEACON);
   /* MeshApp_static_provisioning(DEVICE_OWN_ADDRESS, BT_MESH_KEY_UNUSED);*/

    for (;;)
    {

        Semaphore_pend(semstart_prov_Task_Handle, BIOS_WAIT_FOREVER);
        button_state = 1;
        MeshApp_button_pressed(button_state);

   }
}

void start_prov_CreateTask(void)
{
    bleStack_createTasks();
    k_sys_work_q_init(NULL);
    Semaphore_Params semParams;
    Task_Params taskParams;

    Task_Params_init(&taskParams);
    taskParams.stack = start_prov_Stack;
    taskParams.stackSize = START_PROV_STACK_SIZE;
    taskParams.priority = START_PROV_TASK_PRIORITY;

    Task_construct(&start_prov_Task, start_prov_taskFxn, &taskParams, NULL);
    Semaphore_Params_init(&semParams);
    Semaphore_construct(&semstart_prov_Task_Struct, 0, &semParams);
    semstart_prov_Task_Handle = Semaphore_handle(
            &semstart_prov_Task_Struct);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandra、

    感谢您与我们联系。 我们将研究您的查询并尽快作出响应。 同时、您能否为我们提供您正在使用的 SDK 版本?

    此致、

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jan、

    我正在使用 simplelink_cc13xx_cc26xx_sdk_6_10_01_01 SDK。

    此致、

    亚历山德拉

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandra、

    您能否提供有关已遵循的调试步骤的详细信息?

    您能否解释一下预期行为是什么?

    [引用 userid="551249" URL"~/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1191582/cc2652r-bluetooth-mesh-provisioning-and-message-sending "]当我尝试通过按某个按钮来打开另一个设备的 LED 时,它会切换自己的 LED

    我已经快速查看了您的文件、我看到您执行了一些影响 button_pressed_bb 内 LED 的代码。这是预期行为吗?

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Cl é ment、

    其理念是、当您按下第一个器件上的按钮时、它将打开第二个器件上的绿色 LED (LED1)。 下面是我所遵循的调试步骤的屏幕截图,可以看到配置过程确实会执行:  

    此致、

    亚历山德拉

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandra、

    您能否确认所有设备都已加入网络?

    此外、您能否解释配置是如何完成的? 我看到"meshApp_static_provisioning"被注释掉、但我不确定配置的实际执行位置。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Cl é ment、

    这些设备明显不会加入同一个网络、我认为它们都是自己创建的。 配置通过在 SYSCFG 文件中激活它并调用 MeshApp_init (device_own 地址、未配置的 beacon)来完成、因此调用回调函数

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandra、

    在进行 SimpleLink Academy 实验时、您能否确认是否已设法让所有器件加入同一网络?

    https://dev.ti.com/tirex/content/simplelink_academy_cc13xx_cc26xxsdk_6_40_00_00/modules/blemesh/ble_mesh_provisioning/ble_mesh_provision.html

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Cl é ment、

    现在它不起作用、我将首先尝试使用简单的网状节点基本应用

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    好的、请随时更新我们的信息!

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    使用简单的网状节点应用、当在每个节点上配置了静态配置选项时、两个节点都是相同网络的一部分。 使用 SimpleLink Starter 应用程序时遇到问题:尽管我取消激活了 WiFi,但它无法检测到任何设备

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    请验证设备是否正确广播。 这可以通过使用蓝牙监听器或查看器件的功耗来实现

    EnergyTrace 可用于此目的(请参阅 https://dev.ti.com/tirex/content/simplelink_cc13xx_cc26xx_sdk_6_30_00_84/docs/ble5stack/ble_user_guide/html/energy-trace/energy-trace.htmlhttps://www.ti.com/lit/swra478)

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    这些器件正在进行广播、并可通过 BLE 扫描仪进行检测。 这让我认为我必须回顾消息发送过程、

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    好的、请随时向我们通报您的最新进展。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Cl é ment、  

    我按照 BLE 网状网络基础教程创建自己的模型。 现在我想问题是、这两个器件位于单独的网络上、当我按下按钮时、它会自动点亮自己的 LED。 以下是更新后的文件

    非常感谢、

    亚历山德拉

    /******************************************************************************
     *
     *
    
    @file  simple_mesh_node.c
    
    @brief This file contains the simple_peripheral_and_mesh sample application for use
    with the CC2652 Bluetooth Low Energy Protocol Stack.
    
    Group: WCS, BTS
    Target Device: cc13xx_cc26xx
    
    ******************************************************************************
    
     Copyright (c) 2013-2022, 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>
    
    #include "autoconf.h"
    
    #define ADD_SENSOR_MODELS
    
    #if !(defined __TI_COMPILER_VERSION__) && !(defined __GNUC__)
    #include <intrinsics.h>
    #endif
    
    #include <ti/drivers/utils/List.h>
    
    #include "util.h"
    #include <bcomdef.h>
    #include "ble_stack_api.h"
    
    #include <devinfoservice.h>
    #include <simple_gatt_profile.h>
    
    #ifdef USE_RCOSC
    #include <rcosc_calibration.h>
    #endif //USE_RCOSC
    
    #include <ti_drivers_config.h>
    #include <board_key.h>
    
    #include <menu/two_btn_menu.h>
    #include "simple_mesh_node.h"
    #include "simple_mesh_node_menu.h"
    #include "ti_ble_config.h"
    #include "ti_device_composition.h"
    #if defined(OAD_SUPPORT)
    #include "oad_app_support.h"
    #endif
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <settings/settings.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/mesh.h>
    #include <bt_le_porting_layer.h>
    
    #ifdef USE_STATIC_PROVISIONING
    #include "static_prov.h"
    #endif
    
    #include "generic_models.h"
    #include "sensor_models.h"
    #include "sensor_temperature8.h"
    
    #include "mesh_erpc_wrapper.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
    * CONSTANTS
    */
    // How often to perform periodic event (in ms)
    #define BLEAPP_PERIODIC_EVT_PERIOD               2000
    
    
    // Task configuration
    #define BLEAPP_TASK_PRIORITY                     3
    
    #ifndef BLEAPP_TASK_STACK_SIZE
    #define BLEAPP_TASK_STACK_SIZE                   2248
    #endif
    
    // Application events
    #define BLEAPP_EVT_CHAR_CHANGE         1
    #define BLEAPP_EVT_KEY_CHANGE          2
    #define BLEAPP_EVT_ADV                 3
    #define BLEAPP_EVT_PAIRING_STATE       4
    #define BLEAPP_EVT_PASSCODE_NEEDED     5
    #define BLEAPP_EVT_PERIODIC            6
    #define BLEAPP_EVT_READ_RPA            7
    #define BLEAPP_EVT_SEND_PARAM_UPDATE   8
    #define BLEAPP_EVT_CONN                9
    #define BLEAPP_EVT_INSUFFICIENT_MEM    10
    #define BLEAPP_EVT_ADV_REPORT          11
    #define BLEAPP_EVT_SCAN_ENABLED        12
    #define BLEAPP_EVT_SCAN_DISABLED       13
    #define MESHAPP_EVT_ADV                14
    #define MESHAPP_EVT_GATT_WRT           15
    #define BLEAPP_EVT_STACK_CALLBACK      16
    #define OADAPP_EVT_CALLBACK            17
    #define OADAPP_EVT_RESET               18
    
    // For storing the active connections
    #define SP_RSSI_TRACK_CHNLS        1            // Max possible channels can be GAP_BONDINGS_MAX
    #define SP_MAX_RSSI_STORE_DEPTH    5
    #define SP_INVALID_HANDLE          0xFFFF
    #define RSSI_2M_THRSHLD           -30
    #define RSSI_1M_THRSHLD           -40
    #define RSSI_S2_THRSHLD           -50
    #define RSSI_S8_THRSHLD           -60
    #define SP_PHY_NONE                LL_PHY_NONE  // No PHY set
    #define AUTO_PHY_UPDATE            0xFF
    
    // Spin if the expression is not true
    #define BLEAPP_ASSERT(expr) if (!(expr)) bleApp_spin();
    
    // address string length is an ascii character for each digit +
    #define SMN_ADDR_STR_SIZE     15
    #define APP_QUEUE_EVT         UTIL_QUEUE_EVENT_ID // Event_Id_30
    #define EVENT_PEND_FOREVER    0xfffffffful
    
    /*********************************************************************
    * TYPEDEFS
    */
    
    // App event passed from stack modules. This type is defined by the application
    // since it can queue events to itself however it wants.
    typedef struct
    {
      uint8_t event;                // event type
      void    *pData;               // pointer to message
    } appEvt_t;
    
    // Container to store passcode data when passing from gapbondmgr callback
    // to app event. See the pfnPairStateCB_t documentation from the gapbondmgr.h
    // header file for more information on each parameter.
    typedef struct
    {
      uint8_t state;
      uint16_t connHandle;
      uint8_t status;
    } appPairStateData_t;
    
    // Container to store passcode data when passing from gapbondmgr callback
    // to app event. See the pfnPasscodeCB_t documentation from the gapbondmgr.h
    // header file for more information on each parameter.
    typedef struct
    {
      uint8_t deviceAddr[B_ADDR_LEN];
      uint16_t connHandle;
      uint8_t uiInputs;
      uint8_t uiOutputs;
      uint32_t numComparison;
    } appPasscodeData_t;
    
    // Container to store advertising event data when passing from advertising
    // callback to app event. See the respective event in GapAdvScan_Event_IDs
    // in gap_advertiser.h for the type that pBuf should be cast to.
    typedef struct
    {
      uint32_t event;
      void *pBuf;
    } appGapAdvEventData_t;
    
    // Container to store information from clock expiration using a flexible array
    // since data is not always needed
    typedef struct
    {
      uint8_t event;
      uint8_t data[];
    } appClockEventData_t;
    
    // Scanned device information record
    typedef struct
    {
      uint8_t addrType;         // Peer Device's Address Type
      uint8_t addr[B_ADDR_LEN]; // Peer Device Address
    } scanRec_t;
    
    // Container to store all scan callback params
    typedef struct
    {
      uint32_t evt;
      void* pMsg;
      uintptr_t arg;
    } scanCbData_t;
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    
    // List element for parameter update and PHY command status lists
    typedef struct
    {
      List_Elem elem;
      uint16_t  connHandle;
    } spConnHandleEntry_t;
    
    // Connected device information
    typedef struct
    {
      uint16_t              connHandle;                        // Connection Handle
      appClockEventData_t*   pParamUpdateEventData;
      Clock_Struct*         pUpdateClock;                      // pointer to clock struct
      int8_t                rssiArr[SP_MAX_RSSI_STORE_DEPTH];
      uint8_t               rssiCntr;
      int8_t                rssiAvg;
      bool                  phyCngRq;                          // Set to true if PHY change request is in progress
      uint8_t               currPhy;
      uint8_t               rqPhy;
      uint8_t               phyRqFailCnt;                      // PHY change request count
      bool                  isAutoPHYEnable;                   // Flag to indicate auto phy change
    } spConnRec_t;
    #endif // ADD_SIMPLE_PERIPHERAL
    
    /*********************************************************************
    * GLOBAL VARIABLES
    */
    // Display Interface
    Display_Handle dispHandle = NULL;
    
    // Task configuration
    Task_Struct appTask;
    #if defined __TI_COMPILER_VERSION__
    #pragma DATA_ALIGN(appTaskStack, 8)
    #else
    #pragma data_alignment=8
    #endif
    uint8_t appTaskStack[BLEAPP_TASK_STACK_SIZE];
    
    
    #define BLEAPP_EVT_EVENT_MAX  19
    char *appEventStrings[] = {
      "BLEAPP_ZERO                 ",
      "BLEAPP_EVT_CHAR_CHANGE      ",
      "BLEAPP_EVT_KEY_CHANGE       ",
      "BLEAPP_EVT_ADV              ",
      "BLEAPP_EVT_PAIRING_STATE    ",
      "BLEAPP_EVT_PASSCODE_NEEDED  ",
      "BLEAPP_EVT_PERIODIC         ",
      "BLEAPP_EVT_READ_RPA         ",
      "BLEAPP_EVT_SEND_PARAM_UPDATE",
      "BLEAPP_EVT_CONN             ",
      "BLEAPP_EVT_INSUFFICIENT_MEM ",
      "BLEAPP_EVT_ADV_REPORT       ",
      "BLEAPP_EVT_SCAN_ENABLED     ",
      "BLEAPP_EVT_SCAN_DISABLED    ",
      "MESHAPP_EVT_ADV             ",
      "MESHAPP_EVT_GATT_WRT        ",
      "BLEAPP_EVT_STACK_CALLBACK   ",
      "OADAPP_EVT_CALLBACK         ",
      "OADAPP_EVT_RESET            ",
    };
    
    /*********************************************************************
    * LOCAL VARIABLES
    */
    
    // Entity ID globally used to check for source and/or destination of messages
    bleStack_entityId_t appSelfEntity;
    bleStack_entityId_t meshAppSelfEntity;  //extern in bt.c
    static Event_Handle appSyncEvent;
    
    // Queue object used for app messages
    static Queue_Struct appMsgQueue;
    static Queue_Handle appMsgQueueHandle;
    
    // Clock instance for internal periodic events. Only one is needed since
    // GattServApp will handle notifying all connected GATT clients
    static Clock_Struct clkPeriodic;
    // Clock instance for RPA read events.
    static Clock_Struct clkRpaRead;
    
    // Memory to pass periodic event ID to clock handler
    appClockEventData_t argPeriodic =
    { .event = BLEAPP_EVT_PERIODIC };
    
    // Memory to pass RPA read event ID to clock handler
    appClockEventData_t argRpaRead =
    { .event = BLEAPP_EVT_READ_RPA };
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    // Per-handle connection info
    spConnRec_t connList[MAX_NUM_BLE_CONNS];
    
    // Current connection handle as chosen by menu
    static uint16_t menuConnHandle = LINKDB_CONNHANDLE_INVALID;
    
    // List to store connection handles for set phy command status's
    static List_List setPhyCommStatList;
    
    // List to store connection handles for queued param updates
    static List_List paramUpdateList;
    
    // Auto connect Disabled/Enabled {0 - Disabled, 1- Group A , 2-Group B, ...}
    uint8_t autoConnect = AUTOCONNECT_DISABLE;
    
    // Advertising handles
    static uint8 advHandle1;
    #ifdef SECOND_ADV_SET
    static uint8 advHandle2;
    #endif /* SECOND_ADV_SET */
    #endif // ADD_SIMPLE_PERIPHERAL
    
    // Address mode
    static GAP_Addr_Modes_t addrMode = ADDRMODE_PUBLIC;//DEFAULT_ADDRESS_MODE;
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    // Current Random Private Address
    static uint8 rpa[B_ADDR_LEN] = {0};
    #endif // ADD_SIMPLE_PERIPHERAL
    
    #ifdef USE_STATIC_PROVISIONING
    uint16_t mesh_own_addr = DEVICE_OWN_ADDRESS;
    #else
    uint16_t mesh_own_addr = 1;
    #endif
    int advCb_count = 0;
    int scanCb_count = 0;
    int scanCb_beaconCount = 0;
    int scanCb_msgCount = 0;
    int scanCb_provCount = 0;
    #ifdef CONFIG_BT_MESH_PROXY
    static uint8_t meshScanData[] = "SimpleMeshNode";
    #endif
    
    // Used for save and restore the default device UUID
    uint8_t defaultUUID[UUID_MAX_LEN];
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    
    static void     bleApp_init( void );
    static void     bleApp_taskFxn(UArg a0, UArg a1);
    static void     bleApp_processAppMsg(appEvt_t *pMsg);
    static uint8_t  bleApp_processStackMsg(bleStack_msgHdt_t *pMsg);
    static uint8_t  bleApp_processGATTMsg(gattMsgEvent_t *pMsg);
    static void     bleApp_processGapMessage(gapEventHdr_t *pMsg);
    #ifdef USE_APP_MENU
    static void     bleApp_handleKeys(uint8_t keys);
    #endif
    static void     bleApp_keyChangeHandler(uint8_t keys);
    static status_t bleApp_enqueueMsg(uint8_t event, void *pData);
    static void     bleApp_performPeriodicTask(void);
    static void     bleApp_clockHandler(UArg arg);
    static void     bleApp_passcodeCB(uint8_t *pDeviceAddr, uint16_t connHandle,
                                                uint8_t uiInputs, uint8_t uiOutputs,
                                                uint32_t numComparison);
    static void     bleApp_pairStateCb(uint16_t connHandle, uint8_t state,
                                                 uint8_t status);
    static void     meshApp_processAdvEvent(appGapAdvEventData_t *pEventData);
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    static void bleApp_processAdvEvent(appGapAdvEventData_t *pEventData);
    static void bleApp_charValueChangeCB(uint8_t paramId);
    static void bleApp_processCharValueChangeEvt(uint8_t paramId);
    static void SimplePeripheral_advCallback(uint32_t event, void *pBuf, uintptr_t arg);
    static void SimplePeripheral_updateRPA(void);
    static void bleApp_processPairState(appPairStateData_t *pPairState);
    static void bleApp_processPasscode(appPasscodeData_t *pPasscodeData);
    static void bleApp_processCmdCompleteEvt(hciEvt_CmdComplete_t *pMsg);
    static void SimplePeripheral_initPHYRSSIArray(void);
    static void SimplePeripheral_updatePHYStat(uint16_t eventCode, uint8_t *pMsg);
    static uint8_t SimplePeripheral_addConn(uint16_t connHandle);
    static uint8_t SimplePeripheral_getConnIndex(uint16_t connHandle);
    static uint8_t SimplePeripheral_removeConn(uint16_t connHandle);
    static void bleApp_processParamUpdate(uint16_t connHandle);
    static status_t SimplePeripheral_startAutoPhyChange(uint16_t connHandle);
    static status_t SimplePeripheral_stopAutoPhyChange(uint16_t connHandle);
    static status_t SimplePeripheral_setPhy(uint16_t connHandle, uint8_t allPhys,
                                            uint8_t txPhy, uint8_t rxPhy,
                                            uint16_t phyOpts);
    static uint8_t SimplePeripheral_clearConnListEntry(uint16_t connHandle);
    void SimplePeripheral_connEvtCB(Gap_ConnEventRpt_t *pReport);
    static void bleApp_processConnEvt(Gap_ConnEventRpt_t *pReport);
    static bStatus_t SimplePeripheral_initAdvSet(pfnGapCB_t advCallback,
                                                 uint8_t * const advHandle, GapAdv_params_t * const advParams,
                                                 uint8_t advData[], const int advDataLen,
                                                 uint8_t scanRespData[], const int scanRespDataLen);
    #ifdef PTM_MODE
    void PTM_init(bleStack_entityId_t appSelfEntity);
    void PTM_handle_hci_event(uint8_t *pMsg);
    #endif // PTM_MODE
    #endif // ADD_SIMPLE_PERIPHERAL
    
    uint8_t bleApp_processStackMsgCB(uint8_t event, uint8_t *pMsg);
    
    /* Mesh profile */
    int generic_models_extensions(void);
    int MeshApp_init(uint16_t addr, uint8_t prov_type);
    int MeshApp_unprovisioned_beacon(void);
    
    /* Mesh Callbacks */
    #ifdef USE_APP_MENU
    
    #ifdef CONFIG_BT_MESH_LOW_POWER
    static void meshApp_lpn_friendshipEstablished(uint16_t net_idx, uint16_t friend_addr,
    		    uint8_t queue_size, uint8_t recv_window);
    static void meshApp_lpn_friendshipTerminated(uint16_t net_idx, uint16_t friend_addr);
    static void meshApp_lpnPolled(uint16_t net_idx, uint16_t friend_addr, bool retry);
    #endif /* CONFIG_BT_MESH_LOW_POWER */
    
    static void meshApp_hbRecv(const struct bt_mesh_hb_sub *sub, uint8_t hops,
    	     uint16_t feat);
    static void meshApp_hb_subEnd(const struct bt_mesh_hb_sub *sub);
    
    #ifdef CONFIG_BT_MESH_FRIEND
    static void meshApp_friend_friendshipEstablished(uint16_t net_idx, uint16_t lpn_addr,
    			    uint8_t recv_delay, uint32_t polltimeout);
    static void meshApp_friend_friendshipTerminated(uint16_t net_idx, uint16_t lpn_addr);
    #endif /* CONFIG_BT_MESH_FRIEND */
    
    #endif /* USE_APP_MENU */
    
    
    /*********************************************************************
     * EXTERN FUNCTIONS
    */
    extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);
    extern void mesh_portingLayer_scanCB(uint32_t evt, void* pMsg, uintptr_t arg);
    extern void mesh_portingLayer_advCB(uint32_t event, void *pBuf);
    extern int k_sys_work_q_init(void *dev);
    
    #ifdef CONFIG_BT_MESH_PROXY
    extern Event_Handle workQThreadSyncEvent;
    #endif
    #ifdef MESH_ERPC
    extern void eRpcMesh_createTask();
    // ERPC thread entity ID globally used to check for source and/or
    // destination of messages
    bleStack_entityId_t erpcThreadSelfEntity;    // eRPC thread
    // ERPC thread event globally used to post local events and pend on
    // system and local events
    Event_Handle erpcThreadSyncEvent;    // eRPC thread
    #endif
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t bleApp_bondMgrCBs =
    {
      bleApp_passcodeCB,       // Passcode callback
      bleApp_pairStateCb       // Pairing/Bonding state Callback
    };
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    // Simple GATT Profile Callbacks
    static simpleProfileCBs_t bleApp_simpleProfileCBs =
    {
      bleApp_charValueChangeCB // Simple GATT Characteristic value change callback
    };
    #endif
    
    /*********************************************************************
     * Mesh Callbacks Global Variables
     */
    #ifdef USE_APP_MENU
    
    BT_MESH_HB_CB_DEFINE(meshApp_hb_cb) = {
      .recv    = meshApp_hbRecv,
      .sub_end = meshApp_hb_subEnd,
    };
    
    #ifdef CONFIG_BT_MESH_FRIEND
    BT_MESH_FRIEND_CB_DEFINE(meshApp_friend_cb) = {
      .established = meshApp_friend_friendshipEstablished,
      .terminated  = meshApp_friend_friendshipTerminated,
    };
    #endif /* CONFIG_BT_MESH_FRIEND */
    
    #ifdef CONFIG_BT_MESH_LOW_POWER
    BT_MESH_LPN_CB_DEFINE(meshApp_lpn_cb) = {
      .established = meshApp_lpn_friendshipEstablished,
      .terminated  = meshApp_lpn_friendshipTerminated,
      .polled      = meshApp_lpnPolled,
    };
    #endif /* CONFIG_BT_MESH_LOW_POWER */
    #endif /* USE_APP_MENU */
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      bleApp_spin
     *
     * @brief   Spin forever
     *
     * @param   none
     */
    static void bleApp_spin(void)
    {
      volatile uint8_t x = 0;
    
      while(1)
      {
        x++;
      }
    }
    
    #ifdef MESH_ERPC
    /*********************************************************************
     * @fn      mesh_erpc_register
     *
     * @brief   Register to ble stack from the eRPC context.
     *
     * @return  none
     */
    void mesh_erpc_register(void)
    {
        bleStack_errno_t err;
    
        // When eRPC is enabled, need to register to the ble stack from the eRPC context
        err = bleStack_register(&erpcThreadSelfEntity, 0);
        BLEAPP_ASSERT(BLE_STACK_ERRNO_SUCCESS == err);
    }
    #endif
    
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    /*********************************************************************
     * @fn      SimplePeripheral_initProfiles
     *
     * @brief   Init simple peripheral profiles
     */
    int SimplePeripheral_initProfiles(void)
    {
      DevInfo_AddService();                        // Device Information Service
    
      SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
    #if defined(OAD_SUPPORT_ONCHIP)
      // OAD profile for reset action
      OadApp_addService();
    #endif
      // Setup the SimpleProfile Characteristic Values
      // For more information, see the GATT and GATTServApp sections in the User's Guide:
      // software-dl.ti.com/.../
      {
        uint8_t charValue1 = 1;
        uint8_t charValue2 = 2;
        uint8_t charValue3 = 3;
        uint8_t charValue4 = 4;
        uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
                                   &charValue1);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
                                   &charValue2);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
                                   &charValue3);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &charValue4);
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
                                   charValue5);
      }
    
      // Register callback with SimpleGATTprofile
      SimpleProfile_RegisterAppCBs(&bleApp_simpleProfileCBs);
    
      return 0;
    }
    #endif // ADD_SIMPLE_PERIPHERAL
    
    /*********************************************************************
     * @fn      bleApp_stackInit
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     */
    int bleApp_stackInit(void)
    {
      uint8_t profileRole;
    
      // ******************************************************************
      // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO bleStack_register
      // ******************************************************************
      // Register the stack messages callback - see ble_stack_api.c - #ifdef ICALL_NO_APP_EVENTS
      bleStack_register(&appSelfEntity, bleApp_processStackMsgCB);
      meshAppSelfEntity = appSelfEntity; // used by bt.c
      // Create the application appSyncEvent
      appSyncEvent = Event_create(NULL, NULL);
    
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueueHandle = Util_constructQueue(&appMsgQueue);
    
      // Create one-shot clock for internal periodic events.
      Util_constructClock(&clkPeriodic, bleApp_clockHandler,
                          BLEAPP_PERIODIC_EVT_PERIOD, 0, false, (UArg)&argPeriodic);
    
    #if defined(CONFIG_BT_MESH_PROXY) || defined(ADD_SIMPLE_PERIPHERAL)
      profileRole = GAP_PROFILE_PERIPHERAL | GAP_PROFILE_OBSERVER;
      BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- role PERIPHERAL+OBSERVER", profileRole);
    #else
      profileRole = GAP_PROFILE_BROADCASTER | GAP_PROFILE_OBSERVER;
      BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- role BROADCASTER+OBSERVER", profileRole);
    #endif // CONFIG_BT_MESH_PROXY || ADD_SIMPLE_PERIPHERAL
    
    #ifdef USE_RCOSC
      // Set device's Sleep Clock Accuracy
    #if ( HOST_CONFIG & ( CENTRAL_CFG | PERIPHERAL_CFG ) )
      HCI_EXT_SetSCACmd(500);
    #endif // (CENTRAL_CFG | PERIPHERAL_CFG)
      RCOSC_enableCalibration();
    #endif // USE_RCOSC
    
    #if defined(CONFIG_BT_MESH_PROXY) || defined(ADD_SIMPLE_PERIPHERAL)
      // init GAP
      bleStack_initGap(profileRole, appSelfEntity, DEFAULT_PARAM_UPDATE_REQ_DECISION);
    
      // init GapBond
      bleStack_initGapBond(0, &bleApp_bondMgrCBs);
    
      // init GATT
      bleStack_initGatt(profileRole, appSelfEntity, attDeviceName);
    #else
      // init GAP
      bleStack_initGap(profileRole, appSelfEntity, 0);
    
      // init GapBond
      bleStack_initGapBond(0, &bleApp_bondMgrCBs);
    #endif
    
    #if defined ( GAP_BOND_MGR )
      // Setup the GAP Bond Manager. For more information see the GAP Bond Manager
      // section in the User's Guide
      // ToDo - remove implementation from SysConfig
      // ToDo - set one call _all instaead of many calls to GAPBondMgr_SetParameter
      setBondManagerParameters();
    #endif
    
    #ifdef ADD_SIMPLE_PERIPHERAL
      SimplePeripheral_initProfiles();
    #endif
    
    #ifdef ADD_SIMPLE_PERIPHERAL
      // Initialize Connection List
      SimplePeripheral_clearConnListEntry(LINKDB_CONNHANDLE_ALL);
    
      // Initialize array to store connection handle and RSSI values
      SimplePeripheral_initPHYRSSIArray();
    #endif
    
      BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- call GAP_DeviceInit", profileRole);
      //Initialize GAP layer for Peripheral and Central role and register to receive GAP events
      GAP_DeviceInit(profileRole, appSelfEntity, addrMode, &pRandomAddress);
    
    #ifdef PTM_MODE
      PTM_init(appSelfEntity);
    #endif
    
    #ifdef OAD_SUPPORT
    #ifdef OAD_DEBUG
      tbm_setItemStatus(&spMenuMain, SP_ITEM_SELECT_OAD_DBG, SP_ITEM_SELECT_CONN);
    #endif
      OadApp_init();
    #endif
      // Preempting Advertise over Scan
      BLEAPP_ASSERT(HCI_EXT_SetQOSDefaultParameters(LL_QOS_MEDIUM_PRIORITY,
          LL_QOS_TYPE_PRIORITY, LL_QOS_ADV_TASK_TYPE) == HCI_SUCCESS);
    
      return 0;
    }
    
    /*********************************************************************
     * @fn      bleApp_init
     *
     * @brief   Called during initialization and contains application
     *          specific initialization (ie. hardware initialization/setup,
     *          table initialization, power up notification, etc), and
     *          profile initialization/setup.
     */
    static void bleApp_init(void)
    {
      BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- init ", BLEAPP_TASK_PRIORITY);
    
      /*
       * Init the menu with input keys and display
       */
    
      // Init key debouncer
      Board_initKeys(bleApp_keyChangeHandler);
    
    #ifdef USE_APP_MENU
      // preprocessor definitions
      dispHandle = Display_open(Display_Type_ANY, NULL);
    
      // Create the menu
     // SimpleMeshMenu_init(dispHandle);
    #endif
    
      /*
       * Init the ble stack
       */
      bleApp_stackInit();
    
      if (IS_ENABLED(CONFIG_BT_SETTINGS))
      {
        // Initialize settings submodule
        int err = settings_subsys_init();
        BLEAPP_ASSERT(err == SUCCESS);
        Display_printf(dispHandle, SMN_ROW_MENU_ST, 0, "NVS: settings_subsys_init() ret status: %d", err);
      }
    
      /*
       * Init the mesh stack
       */
    #if defined (USE_APP_MENU) || defined (MESH_ERPC)
        // TBMenu will call MeshApp_init
        // eRpc will call bt_mesh_init + bt_mesh_provision
    #else
        // bt_ready now, zephyr mesh stack can be initialized
        MeshApp_init(mesh_own_addr, UNPROVISIONED_BEACON);
    #endif
    }
    
    /*********************************************************************
     * @fn      simple_mesh_and_peripheral_createTask
     *
     * @brief   Task creation function for simple_mesh_and_peripheral.
     */
    void simple_mesh_and_peripheral_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = appTaskStack;
      taskParams.stackSize = BLEAPP_TASK_STACK_SIZE;
      taskParams.priority = BLEAPP_TASK_PRIORITY;
    
      Task_construct(&appTask, bleApp_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      bleApp_createTasks
     *
     * @brief   Task creation function for this ble application.
     */
    void bleApp_createTasks(void)
    {
      // Init and create ble stack tasks
      bleStack_createTasks();
    
      // init zephyr mesh worker task
      k_sys_work_q_init(NULL);
    
    #ifdef MESH_ERPC
      // create eRpc task
      eRpcMesh_createTask();
    #endif
    
      // Create local app task
      simple_mesh_and_peripheral_createTask();
    }
    
    /*********************************************************************
     * @fn      bleApp_taskFxn
     *
     * @brief   Application task entry point for the Simple Mesh.
     *
     * @param   a0, a1 - not used.
     */
    static void bleApp_taskFxn(UArg a0, UArg a1)
    {
      // Initialize application
      bleApp_init();
    
      // Application main loop
      for (;;)
      {
        uint32_t events;
    
        appEvt_t *pMsg;
    
        // Waits for an event to be posted
        events = Event_pend(appSyncEvent, Event_Id_NONE, APP_QUEUE_EVT,
                              EVENT_PEND_FOREVER);
        if (events)
        {
          // Check if there are any messages in the queue
          while (!Queue_empty(appMsgQueueHandle))
          {
              pMsg = (appEvt_t *)Util_dequeueMsg(appMsgQueueHandle);
    
              if (pMsg)
              {
                if (BLEAPP_EVT_STACK_CALLBACK == pMsg->event)
                {
                  // Process stack messages - changed from events to callback
                  if (bleApp_processStackMsg((bleStack_msgHdt_t*)pMsg->pData))
                  {
                    bleStack_freeMsg((bleStack_msgHdt_t*)pMsg->pData);
                  }
                }
    #ifdef OAD_SUPPORT
                else if (OADAPP_EVT_CALLBACK == pMsg->event)
                {
                    OadApp_processEvents((uint32_t)(*(uint8_t *)(pMsg->pData)));
                    bleStack_free(pMsg->pData);
                }
    #endif
                else
                {
                  // Process application messages (callbacks after switch context)
                  bleApp_processAppMsg(pMsg);
                }
    
                // Free the space from the message.
                bleStack_free(pMsg);
            }
          }
        }
      }
    }
    
    /*********************************************************************
     * @fn      bleApp_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 bleApp_processStackMsg(bleStack_msgHdt_t *pMsg)
    {
      // Always dealloc pMsg unless set otherwise
      uint8_t safeToDealloc = TRUE;
    
      BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : Stack msg status=%d, event=0x%x\n", pMsg->status, pMsg->event);
    
      switch (pMsg->event)
      {
        case GAP_MSG_EVENT:
          bleApp_processGapMessage((gapEventHdr_t*) pMsg);
          break;
    
        case GATT_MSG_EVENT:
          // Process GATT message
          safeToDealloc = bleApp_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 Events here
            {
    #ifdef ADD_SIMPLE_PERIPHERAL
              bleApp_processCmdCompleteEvt((hciEvt_CmdComplete_t *) pMsg);
    #endif
              break;
            }
    
            case HCI_BLE_HARDWARE_ERROR_EVENT_CODE:
              AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0);
              break;
    
    #ifdef ADD_SIMPLE_PERIPHERAL
            // HCI Commands Events
            case HCI_COMMAND_STATUS_EVENT_CODE:
            {
              hciEvt_CommandStatus_t *pMyMsg = (hciEvt_CommandStatus_t *)pMsg;
              switch ( pMyMsg->cmdOpcode )
              {
                case HCI_LE_SET_PHY:
                {
                  if (pMyMsg->cmdStatus == HCI_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE)
                  {
                    Display_printf(dispHandle, SP_ROW_STATUS_1, 0,
                            "PHY Change failure, peer does not support this");
                  }
                  else
                  {
                    Display_printf(dispHandle, SP_ROW_STATUS_1, 0,
                                   "PHY Update Status Event: 0x%x",
                                   pMyMsg->cmdStatus);
                  }
    
                  SimplePeripheral_updatePHYStat(HCI_LE_SET_PHY, (uint8_t *)pMsg);
                  break;
                }
    
                default:
                  break;
              }
              break;
            }
    
            // LE Events
            case HCI_LE_EVENT_CODE:
            {
              hciEvt_BLEPhyUpdateComplete_t *pPUC =
                (hciEvt_BLEPhyUpdateComplete_t*) pMsg;
    
              // A Phy Update Has Completed or Failed
              if (pPUC->BLEEventCode == HCI_BLE_PHY_UPDATE_COMPLETE_EVENT)
              {
                if (pPUC->status != SUCCESS)
                {
                  Display_printf(dispHandle, SP_ROW_STATUS_1, 0,
                                 "PHY Change failure");
                }
                else
                {
                  // Only symmetrical PHY is supported.
                  // rxPhy should be equal to txPhy.
                  Display_printf(dispHandle, SP_ROW_STATUS_2, 0,
                                 "PHY Updated to %s",
                                 (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_1M) ? "1M" :
                                 (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_2M) ? "2M" :
                                 (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_CODED) ? "CODED" : "Unexpected PHY Value");
                }
    
                SimplePeripheral_updatePHYStat(HCI_BLE_PHY_UPDATE_COMPLETE_EVENT, (uint8_t *)pMsg);
              }
              break;
            }
    
    #endif // ADD_SIMPLE_PERIPHERAL
            default:
              break;
          }
    
          break;
        }
    
    #ifdef OAD_SUPPORT
        case L2CAP_SIGNAL_EVENT:
          // Process L2CAP signal
          safeToDealloc = OadApp_processL2CAPMsg((l2capSignalEvent_t *)pMsg);
          break;
    #endif
    
        default:
          // Do nothing
          break;
      }
    
    #ifdef PTM_MODE
      // Check for NPI Messages
      PTM_handle_hci_event(pMsg);
    #endif
    
      return (safeToDealloc);
    }
    
    /*********************************************************************
    * @fn      bleApp_processGATTMsg
    *
    * @brief   Process GATT messages and events.
    *
    * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
    */
    static uint8_t bleApp_processGATTMsg(gattMsgEvent_t *pMsg)
    {
    #ifdef ADD_SIMPLE_PERIPHERAL
      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_printf(dispHandle, SP_ROW_STATUS_1, 0, "FC Violated: %d", pMsg->msg.flowCtrlEvt.opcode);
      }
      else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
      {
        // MTU size updated
    #ifdef OAD_SUPPORT
        OAD_setBlockSize(pMsg->msg.mtuEvt.MTU);
    #endif
        Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "MTU Size: %d", pMsg->msg.mtuEvt.MTU);
      }
    #endif // ADD_SIMPLE_PERIPHERAL
    
    #ifdef CONFIG_BT_MESH_PROXY
      if (pMsg->method == ATT_MTU_UPDATED_EVENT)
      {
        mesh_portingLayer_updateLinkMTU(pMsg->msg.mtuEvt.MTU);
      }
    #endif
      // 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      bleApp_processAppMsg
     *
     * @brief   Process an incoming callback from a profile.
     *
     * @param   pMsg - message to process
     *
     * @return  None.
     */
    static void bleApp_processAppMsg(appEvt_t *pMsg)
    {
      bool dealloc = TRUE;
    
      if (pMsg->event <= BLEAPP_EVT_EVENT_MAX)
      {
        BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=%s\n", 0, appEventStrings[pMsg->event]);
      }
      else
      {
        BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=0x%x\n", 0, pMsg->event);
      }
    
      switch (pMsg->event)
      {
    #ifdef ADD_SIMPLE_PERIPHERAL
        case BLEAPP_EVT_CHAR_CHANGE:
          bleApp_processCharValueChangeEvt(*(uint8_t*)(pMsg->pData));
          break;
    #endif
    
    #ifdef USE_APP_MENU
        case BLEAPP_EVT_KEY_CHANGE:
          bleApp_handleKeys(*(uint8_t *)(pMsg->pData));
          break;
    #endif
    
    #ifdef ADD_SIMPLE_PERIPHERAL
        case BLEAPP_EVT_ADV:
          advCb_count++;
          bleApp_processAdvEvent((appGapAdvEventData_t*)(pMsg->pData));
          break;
    #endif
    
        case MESHAPP_EVT_ADV:
          advCb_count++;
          meshApp_processAdvEvent((appGapAdvEventData_t*)(pMsg->pData));
          break;
    
        case BLEAPP_EVT_PERIODIC:
          bleApp_performPeriodicTask();
          break;
    
    #ifdef ADD_SIMPLE_PERIPHERAL
        case BLEAPP_EVT_PAIRING_STATE:
          bleApp_processPairState((appPairStateData_t*)(pMsg->pData));
          break;
    
        case BLEAPP_EVT_PASSCODE_NEEDED:
          bleApp_processPasscode((appPasscodeData_t*)(pMsg->pData));
          break;
    
        case BLEAPP_EVT_READ_RPA:
          SimplePeripheral_updateRPA();
          break;
    
        case BLEAPP_EVT_SEND_PARAM_UPDATE:
        {
          // Extract connection handle from data
          uint16_t connHandle = *(uint16_t *)(((appClockEventData_t *)pMsg->pData)->data);
    
          bleApp_processParamUpdate(connHandle);
    
          // This data is not dynamically allocated
          dealloc = FALSE;
          break;
        }
    
        case BLEAPP_EVT_CONN:
          bleApp_processConnEvt((Gap_ConnEventRpt_t *)(pMsg->pData));
          break;
    
    #if defined(OAD_SUPPORT_ONCHIP)
        case OADAPP_EVT_RESET:
          OadApp_processOadResetEvt((oadResetWrite_t *)(pMsg->pData));
          break;
    #endif
    #endif // ADD_SIMPLE_PERIPHERAL
    
        case BLEAPP_EVT_ADV_REPORT:
        {
          scanCbData_t *pData = (scanCbData_t *)pMsg->pData;
          GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pData->pMsg);
    
          mesh_portingLayer_scanCB(pData->evt, pData->pMsg, pData->arg);
    #define BT_DATA_MESH_PROV               0x29 /* Mesh Provisioning PDU */
    #define BT_DATA_MESH_MESSAGE            0x2a /* Mesh Networking PDU */
    #define BT_DATA_MESH_BEACON             0x2b /* Mesh Beacon */
    
          scanCb_count++;
          if (pAdvRpt->pData[1] == BT_DATA_MESH_BEACON)
              scanCb_beaconCount++;
          else if (pAdvRpt->pData[1] == BT_DATA_MESH_MESSAGE)
              scanCb_msgCount++;
          else if (pAdvRpt->pData[1] == BT_DATA_MESH_PROV)
              scanCb_provCount++;
    
          // Free scan payload data
          if (pAdvRpt->pData != NULL)
          {
            bleStack_free(pAdvRpt->pData);
          }
          if (pAdvRpt != NULL)
          {
            bleStack_free(pAdvRpt);
          }
          break;
        }
    
        case BLEAPP_EVT_SCAN_ENABLED:
        case BLEAPP_EVT_SCAN_DISABLED:
        {
          scanCbData_t *pData = (scanCbData_t *)pMsg->pData;
    
          mesh_portingLayer_scanCB(pData->evt, pData->pMsg, pData->arg);
    
          break;
        }
    
        case BLEAPP_EVT_INSUFFICIENT_MEM:
        {
          // We are running out of memory.
    #ifdef USE_APP_MENU
    //      Display_printf(dispHandle, SMN_ROW_ANY_CONN, 0, "Insufficient Memory");
    #endif
          BLEAPP_ASSERT(FAILURE);
          break;
        }
    
    #ifdef CONFIG_BT_MESH_PROXY
        case MESHAPP_EVT_GATT_WRT:
        {
          writeCbParams_t *writeParams = (writeCbParams_t *)(pMsg->pData);
          // call real writeCB
          mesh_portingLayer_proxyProvAttWriteCB(writeParams);
          break;
        }
    #endif
    
        default:
          // Do nothing.
          break;
      }
    
      // Free message data if it exists and we are to dealloc
      if ((dealloc == TRUE) && (pMsg->pData != NULL))
      {
        bleStack_free(pMsg->pData);
      }
    }
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    /*********************************************************************
     * @fn      SimplePeripheral_initAdvSet
     *
     * @brief   Initialize and starts advertise set (legacy or extended)
     *
     * @param advCallback Function pointer to a callback for this advertising set
     * @param advHandle Output parameter to return the created advertising handle
     * @param advParams pointer to structure of adversing parameters
     * @param advData pointer to array containing the advertise data
     * @param advDataLen length (in bytes) of @ref advData
     * @param scanRespData pointer to array containing the scan response data
     * @param scanRespDataLen length (in bytes) of @ref scanRespDataLen
     *
     * @return @ref SUCCESS upon successful initialization,
     *         else, relevant error code upon failure
     */
    static bStatus_t SimplePeripheral_initAdvSet(pfnGapCB_t advCallback,
                                                 uint8_t * const advHandle, GapAdv_params_t * const advParams,
                                                 uint8_t advData[], const int advDataLen,
                                                 uint8_t scanRespData[], const int scanRespDataLen)
    {
      bStatus_t status;
    
      BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : ---- call GapAdv_create set=%d,%d\n", 0, 0);
      // Create Advertisement set and assign handle
      status = GapAdv_create(advCallback, advParams,
                             advHandle);
      if (status != SUCCESS)
      {
        return status;
      }
    
    
      // Load advertising data for set that is statically allocated by the app
      status = GapAdv_loadByHandle(*advHandle, GAP_ADV_DATA_TYPE_ADV,
                                   advDataLen, advData);
      if (status != SUCCESS)
      {
        return status;
      }
    
      // Load scan response data for set that is statically allocated by the app
      if (scanRespData != NULL)
      {
        status = GapAdv_loadByHandle(*advHandle, GAP_ADV_DATA_TYPE_SCAN_RSP,
                                     scanRespDataLen, scanRespData);
        if (status != SUCCESS)
        {
          return status;
        }
      }
    
      // Set event mask for set
      status = GapAdv_setEventMask(*advHandle,
                                   GAP_ADV_EVT_MASK_START_AFTER_ENABLE |
                                   GAP_ADV_EVT_MASK_END_AFTER_DISABLE |
                                   GAP_ADV_EVT_MASK_SET_TERMINATED);
    
      if (status != SUCCESS)
      {
        return status;
      }
      // Enable advertising for set
      status = GapAdv_enable(*advHandle, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
    
      return status;
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_startAdvertising
     *
     * @brief   start advertising - legacy and long range
     */
    int SimplePeripheral_startAdvertising(uint8_t *devAddr)
    {
        bStatus_t status;
        Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Initialized");
    
        // Setup and start Advertising
        // For more information, see the GAP section in the User's Guide:
        // software-dl.ti.com/.../
    
        // Initialize advertisement handlers
    
        // In case of extended, initialize advertise set with advertising data,
        // else (Legacy), initialize advertise set with scan response data and advertising data
        // Note: In this example, the default adv set is extended. When changing the set to Legacy,
        // please un-comment the "else" section.
        if ( (advParams1.eventProps & GAP_ADV_PROP_LEGACY) == 0)
        {
          status = SimplePeripheral_initAdvSet(&SimplePeripheral_advCallback, &advHandle1, &advParams1,
                                               advData1, sizeof(advData1) ,NULL, 0);
          BLEAPP_ASSERT(status == SUCCESS);
        }
        // else
        // {
        //   status = SimplePeripheral_initAdvSet(&SimplePeripheral_advCallback, &advHandle1, &advParams1,
        //                                        advData1, sizeof(advData1) ,
        //                                        scanResData1, sizeof(scanResData1));
        //   BLEAPP_ASSERT(status == SUCCESS);
        // }
    
    #ifdef SECOND_ADV_SET
        // In case of extended, initialize advertise set with advertising data,
        // else (Legacy), initialize advertise set with scan response data and advertising data
        // Note: In this example, the default adv set is extended. When changing the set to Legacy,
        // please un-comment the "else" section.
        if (advParams2.eventProps & GAP_ADV_PROP_LEGACY == 0)
        {
          status = SimplePeripheral_initAdvSet(&SimplePeripheral_advCallback, &advHandle2, &advParams2,
                                               advData2, sizeof(advData2) ,NULL, 0);
          BLEAPP_ASSERT(status == SUCCESS);
        }
        // else
        // {
        //   status = SimplePeripheral_initAdvSet(&SimplePeripheral_advCallback, &advHandle2, &advParams2,
        //                                        advData2, sizeof(advData2) ,
        //                                        scanResData2, sizeof(scanResData2));
        //   BLEAPP_ASSERT(status == SUCCESS);
        // }
    #endif /* SECOND_ADV_SET */
    
        // Display device address
        Display_printf(dispHandle, SP_ROW_IDA, 0, "%s Addr: %s",
                       (addrMode <= ADDRMODE_RANDOM) ? "Dev" : "ID",
                       Util_convertBdAddr2Str(devAddr));
    
        if (addrMode > ADDRMODE_RANDOM)
        {
          SimplePeripheral_updateRPA();
    
          // Create one-shot clock for RPA check event.
          Util_constructClock(&clkRpaRead, bleApp_clockHandler,
                              READ_RPA_PERIOD, 0, true,
                              (UArg) &argRpaRead);
        }
        tbm_setItemStatus(&spMenuMain, SP_ITEM_AUTOCONNECT, TBM_ITEM_NONE);
    
        return 0;
    }
    
    /*********************************************************************
     * @fn      SimplePeripheral_connectIndication
     *
     * @brief   conection establish indication
     */
    int SimplePeripheral_connectIndication(uint16_t connectionHandle, uint8 pkt_status)
    {
          // Display the amount of current connections
          uint8_t numActive = linkDB_NumActive();
    #ifdef USE_APP_MENU
          Display_printf(dispHandle, SP_ROW_STATUS_2, 0, "Num Conns: %d",
                         (uint16_t)numActive);
    #endif
    
          if (pkt_status == SUCCESS)
          {
            // Add connection to list and start RSSI
            SimplePeripheral_addConn(connectionHandle);
            // Enable connection selection option
            tbm_setItemStatus(&spMenuMain, SP_ITEM_SELECT_CONN,SP_ITEM_AUTOCONNECT);
    
            // Start Periodic Clock.
            Util_startClock(&clkPeriodic);
          }
    
          if ((numActive < MAX_NUM_BLE_CONNS) && (autoConnect == AUTOCONNECT_DISABLE))
          {
            // Start advertising since there is room for more connections
            GapAdv_enable(advHandle1, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
    #ifdef SECOND_ADV_SET
            GapAdv_enable(advHandle2, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
    #endif /* SECOND_ADV_SET */
          }
          else
          {
            GapAdv_disable(advHandle1);
    #ifdef SECOND_ADV_SET
            GapAdv_disable(advHandle2);
    #endif /* SECOND_ADV_SET */
          }
    
          return 0;
    }
    /*********************************************************************
     * @fn      SimplePeripheral_disableAdvertising
     *
     * @brief   disable advertising - legacy and long range
     */
    int SimplePeripheral_disconnectIndication(uint16_t connectionHandle)
    {
          // Display the amount of current connections
          uint8_t numActive = linkDB_NumActive();
    #ifdef USE_APP_MENU
          Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Device Disconnected!");
          Display_printf(dispHandle, SP_ROW_STATUS_2, 0, "Num Conns: %d",
                         (uint16_t)numActive);
    #endif
    
          // Remove the connection from the list and disable RSSI if needed
          SimplePeripheral_removeConn(connectionHandle);
    
          // If no active connections
          if (numActive == 0)
          {
            // Stop periodic clock
            Util_stopClock(&clkPeriodic);
    
            // Disable Connection Selection option
            tbm_setItemStatus(&spMenuMain, SP_ITEM_AUTOCONNECT, SP_ITEM_SELECT_CONN);
          }
    
          BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : GAP msg: status=%d, opcode=%s\n", 0, "GAP_LINK_TERMINATED_EVENT");
          // Start advertising since there is room for more connections
          GapAdv_enable(advHandle1, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
    #ifdef SECOND_ADV_SET
          GapAdv_enable(advHandle2, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
    #endif /* SECOND_ADV_SET */
    
          // Clear remaining lines
          Display_clearLine(dispHandle, SP_ROW_CONNECTION);
    
    #ifdef OAD_SUPPORT
          // Cancel the OAD if one is going on
          // A disconnect forces the peer to re-identify
          OadApp_cancel();
    #endif
          return 0;
    }
    #endif // ADD_SIMPLE_PERIPHERAL
    /*********************************************************************
     * @fn      bleApp_processGapMessage
     *
     * @brief   Process an incoming GAP event.
     *
     * @param   pMsg - message to process
     */
    static void bleApp_processGapMessage(gapEventHdr_t *pMsg)
    {
      switch (pMsg->opcode)
      {
        case GAP_DEVICE_INIT_DONE_EVENT:
        {
          gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
    
          BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- got GAP_DEVICE_INIT_DONE_EVENT", 0);
          if(pPkt->hdr.status == SUCCESS)
          {
            // Store the system ID
            uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
    
            // use 6 bytes of device address for 8 bytes of system ID value
            systemId[0] = pPkt->devAddr[0];
            systemId[1] = pPkt->devAddr[1];
            systemId[2] = pPkt->devAddr[2];
    
            // set middle bytes to zero
            systemId[4] = 0x00;
            systemId[3] = 0x00;
    
            // shift three bytes up
            systemId[7] = pPkt->devAddr[5];
            systemId[6] = pPkt->devAddr[4];
            systemId[5] = pPkt->devAddr[3];
    
            // Set Device Info Service Parameter
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
    
            // Register callback to process Scanner events
            GapScan_registerCb(MeshApp_scanCB, NULL);
    
    #ifdef CONFIG_BT_MESH_PROXY
            // Set the device's name in the mesh porting layer
            mesh_portingLayer_setDeviceName(meshScanData);
    #endif
    
    #ifdef ADD_SIMPLE_PERIPHERAL
            SimplePeripheral_startAdvertising(pPkt->devAddr);
    #endif
          }
    
          break;
        }
    
        case GAP_LINK_ESTABLISHED_EVENT:
        {
    #if defined(CONFIG_BT_MESH_PROXY) || defined(ADD_SIMPLE_PERIPHERAL)
          gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;
    
          BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- got GAP_LINK_ESTABLISHED_EVENT", 0);
    #endif
    #ifdef CONFIG_BT_MESH_PROXY
            // Call zephyr cb
            mesh_portingLayer_newConnectionCB(pPkt);
    #endif
    
    #ifdef ADD_SIMPLE_PERIPHERAL
            SimplePeripheral_connectIndication(pPkt->connectionHandle, pPkt->hdr.status);
    #endif
          break;
        }
    
        case GAP_LINK_TERMINATED_EVENT:
        {
    #if defined(CONFIG_BT_MESH_PROXY) || defined(ADD_SIMPLE_PERIPHERAL)
          gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;
    #endif
    
    #ifdef CONFIG_BT_MESH_PROXY
          // Call zephyr cb
          mesh_portingLayer_disconnectCB(pPkt);
    #endif
    
    #ifdef ADD_SIMPLE_PERIPHERAL
            SimplePeripheral_disconnectIndication(pPkt->connectionHandle);
    #endif
          break;
        }
    
    #if defined(CONFIG_BT_MESH_PROXY) || defined(ADD_SIMPLE_PERIPHERAL)
        case GAP_UPDATE_LINK_PARAM_REQ_EVENT:
        {
          gapUpdateLinkParamReqReply_t rsp;
    
          gapUpdateLinkParamReqEvent_t *pReq = (gapUpdateLinkParamReqEvent_t *)pMsg;
    
          rsp.connectionHandle = pReq->req.connectionHandle;
          rsp.signalIdentifier = pReq->req.signalIdentifier;
    
          // Only accept connection intervals with slave latency of 0
          // This is just an example of how the application can send a response
          if(pReq->req.connLatency == 0)
          {
            rsp.intervalMin = pReq->req.intervalMin;
            rsp.intervalMax = pReq->req.intervalMax;
            rsp.connLatency = pReq->req.connLatency;
            rsp.connTimeout = pReq->req.connTimeout;
            rsp.accepted = TRUE;
          }
          else
          {
            rsp.accepted = FALSE;
          }
    
          // Send Reply
          VOID GAP_UpdateLinkParamReqReply(&rsp);
    
          break;
        }
    
        case GAP_LINK_PARAM_UPDATE_EVENT:
        {
          gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;
    
          // Get the address from the connection handle
          linkDBInfo_t linkInfo;
          linkDB_GetInfo(pPkt->connectionHandle, &linkInfo);
    
    #ifdef CONFIG_BT_MESH_PROXY
          mesh_portingLayer_updateLinkMTU(linkInfo.MTU);
    #endif
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    #ifdef USE_APP_MENU
          if(pPkt->status == SUCCESS)
          {
            // Display the address of the connection update
            Display_printf(dispHandle, SP_ROW_STATUS_2, 0, "Link Param Updated: %s",
                           Util_convertBdAddr2Str(linkInfo.addr));
          }
          else
          {
            // Display the address of the connection update failure
            Display_printf(dispHandle, SP_ROW_STATUS_2, 0,
                           "Link Param Update Failed 0x%x: %s", pPkt->opcode,
                           Util_convertBdAddr2Str(linkInfo.addr));
          }
    #endif
          // Check if there are any queued parameter updates
          spConnHandleEntry_t *connHandleEntry = (spConnHandleEntry_t *)List_get(&paramUpdateList);
          if (connHandleEntry != NULL)
          {
            // Attempt to send queued update now
            bleApp_processParamUpdate(connHandleEntry->connHandle);
    
            // Free list element
            bleStack_free(connHandleEntry);
          }
    #endif // ADD_SIMPLE_PERIPHERAL
          break;
        }
    
    #if defined ( NOTIFY_PARAM_UPDATE_RJCT )
         case GAP_LINK_PARAM_UPDATE_REJECT_EVENT:
         {
           linkDBInfo_t linkInfo;
           gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;
    
           // Get the address from the connection handle
           linkDB_GetInfo(pPkt->connectionHandle, &linkInfo);
    
           // Display the address of the connection update failure
           Display_printf(dispHandle, SP_ROW_CONNECTION, 0,
                          "Peer Device's Update Request Rejected 0x%h: %s", pPkt->opcode,
                          Util_convertBdAddr2Str(linkInfo.addr));
    
           break;
         }
    #endif
    #endif /* defined(CONFIG_BT_MESH_PROXY) || defined(ADD_SIMPLE_PERIPHERAL) */
    
        default:
    #ifdef ADD_SIMPLE_PERIPHERAL
          Display_clearLines(dispHandle, SP_ROW_STATUS_1, SP_ROW_STATUS_2);
    #endif // ADD_SIMPLE_PERIPHERAL
          break;
      }
    }
    
    /*********************************************************************
    * @fn      bleApp_processStackMsgCB
    *
    * @brief   Callback for application from ble stack
    *
    * @param   pMessage - message from ble stack
    *
    * @return  None.
    */
    uint8_t bleApp_processStackMsgCB(uint8_t event, uint8_t *pMessage)
    {
      // ignore the event
      // Enqueue the msg in order to be excuted in the application context
      bleApp_enqueueMsg(BLEAPP_EVT_STACK_CALLBACK, pMessage);
    
      // not safe to dealloc, the application layer will free the msg
      return (false);
    }
    
    #ifdef OAD_SUPPORT
    /*********************************************************************
    * @fn      bleApp_processOadEventsInAppContext
    *
    * @brief   Callback from OAD to handle OAD events
    *
    * @param   event - event from OAD
    *
    * @return  None.
    */
    uint8_t bleApp_processOadEventsInAppContext(uint8_t *pEventData)
    {
      // Enqueue the msg in order to be excuted in the application context
      bleApp_enqueueMsg(OADAPP_EVT_CALLBACK, pEventData);
    
      // not safe to dealloc, the application layer will free the msg
      return (false);
    }
    #if defined(OAD_SUPPORT_ONCHIP)
    /*********************************************************************
    * @fn      bleApp_processOadResetInAppContext
    *
    * @brief   Callback from OAD to handle OAD reset
    *
    * @param   event - event from OAD
    *
    * @return  None.
    */
    uint8_t bleApp_processOadResetInAppContext(uint8_t *pEventData)
    {
      // Enqueue the msg in order to be excuted in the application context
      bleApp_enqueueMsg(OADAPP_EVT_RESET, pEventData);
    
      // not safe to dealloc, the application layer will free the msg
      return (false);
    }
    #endif // OAD_SUPPORT_ONCHIP
    #endif // OAD_SUPPORT
    
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    /*********************************************************************
    * @fn      bleApp_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 bleApp_charValueChangeCB(uint8_t paramId)
    {
      uint8_t *pValue = bleStack_malloc(sizeof(uint8_t));
    
      if (pValue)
      {
        *pValue = paramId;
    
        if(bleApp_enqueueMsg(BLEAPP_EVT_CHAR_CHANGE, pValue) != SUCCESS)
        {
          bleStack_free(pValue);
        }
      }
    }
    #endif // ADD_SIMPLE_PERIPHERAL
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    /*********************************************************************
     * @fn      bleApp_processCharValueChangeEvt
     *
     * @brief   Process a pending Simple Profile characteristic value change
     *          event.
     *
     * @param   paramID - parameter ID of the value that was changed.
     */
    static void bleApp_processCharValueChangeEvt(uint8_t paramId)
    {
      uint8_t newValue;
    
      switch(paramId)
      {
        case SIMPLEPROFILE_CHAR1:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
    
          Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Char 1: %d", (uint16_t)newValue);
          break;
    
        case SIMPLEPROFILE_CHAR3:
          SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
    
          Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Char 3: %d", (uint16_t)newValue);
          break;
    
        default:
          // should not reach here!
          break;
      }
    }
    #endif // ADD_SIMPLE_PERIPHERAL
    
    /*********************************************************************
     * @fn      bleApp_performPeriodicTask
     *
     * @brief   Perform a periodic application task. This function gets called
     *          every two seconds (BLEAPP_PERIODIC_EVT_PERIOD).
     *
     * @param   None.
     *
     * @return  None.
     */
    static void bleApp_performPeriodicTask(void)
    {
    #if defined(USE_APP_MENU) && defined(DEBUG_MESH_APP)
      Display_printf(dispHandle, SMN_ROW_CBCK_ST, 0, "CBCK: advCb count=%04d, scanCb=%04d, beacon=%04x, msg=%04x, prov=%04x",
                                      advCb_count, scanCb_count, scanCb_beaconCount, scanCb_msgCount, scanCb_provCount);
    #endif
    #ifdef ADD_SIMPLE_PERIPHERAL
      uint8_t valueToCopy;
    
      // Call to retrieve the value of the third characteristic in the profile
      if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &valueToCopy) == SUCCESS)
      {
        // Call to set that value of the fourth characteristic in the profile.
        // Note that if notifications of the fourth characteristic have been
        // enabled by a GATT client device, then a notification will be sent
        // every time this function is called.
        SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
                                   &valueToCopy);
      }
    #endif // ADD_SIMPLE_PERIPHERAL
    }
    
    #ifdef ADD_SIMPLE_PERIPHERAL
    /*********************************************************************
     * @fn      SimplePeripheral_updateRPA
     *
     * @brief   Read the current RPA from the stack and update display
     *          if the RPA has changed.
     *
     * @param   None.
     *
     * @return  None.
     */
    static void SimplePeripheral_updateRPA(void)
    {
      uint8_t* pRpaNew;
    
      // Read the current RPA.
      pRpaNew = GAP_GetDevAddress(FALSE);
    
      if (memcmp(pRpaNew, rpa, B_ADDR_LEN))
      {
        // If the RPA has changed, update the display
        Display_printf(dispHandle, SP_ROW_RPA, 0, "RP Addr: %s",
                       Util_convertBdAddr2Str(pRpaNew));
        memcpy(rpa, pRpaNew, B_ADDR_LEN);
      }
    }
    #endif // ADD_SIMPLE_PERIPHERAL
    
    /*********************************************************************
     * @fn      SimpleMeshNode_advCB
     *
     * @brief   GapAdv module callback, called from MESH stack
     *
     * @param   pMsg - message to process
     */
    void SimpleMeshNode_advCB(uint32_t event, void *pBuf, uintptr_t arg)
    {
      appGapAdvEventData_t *pData = bleStack_malloc(sizeof(appGapAdvEventData_t));
    
      if (pData)
      {
        pData->event = event;
        pData->pBuf = pBuf;
    
        if(bleApp_enqueueMsg(MESHAPP_EVT_ADV, pData) != SUCCESS)
        {
          bleStack_free(pData);
        }
      }
    }
    
    /*
     * start_provisioning.c
     *
     *  Created on: 19 janv. 2023
     *      Author: alexa
     */
    
    
    #include <stdio.h>
    #include <stdint.h>
    #include <stddef.h>
    #include <string.h>
    #include <math.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/sysbios/knl/Semaphore.h>
    #include <ti/sysbios/BIOS.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/mesh.h>
    #include <bt_le_porting_layer.h>
    
    #include <start_provisioning.h>
    
    
    #include <ti/drivers/GPIO.h>
    #include "ti_drivers_config.h"
    
    #include <simple_mesh_node.h>
    #include "ti_ble_mesh_config.h"
    #include <simple_mesh_node_menu.h>
    #include <net/buf.h>
    #include <include/bluetooth/mesh/access.h>
    #include "static_prov.h"
    
    #define START_PROV_TASK_PRIORITY    3
    #ifndef START_PROV_STACK_SIZE
    #define START_PROV_STACK_SIZE      2248
    #endif
    
    #define GROUP_ADDR 0xc000
    extern void start_prov_init(void);
    uint8_t button_state = 0;
    uint8_t led_state = 0;
    uint16_t addr;
    uint16_t mesh_device_own_addr = DEVICE_OWN_ADDRESS;
    extern uint16_t mesh_btn_target_addr;
    //static const uint16_t app_idx;
    Task_Struct start_prov_Task;
    uint8_t start_prov_Stack[START_PROV_STACK_SIZE];
    Semaphore_Struct semstart_prov_Task_Struct;
    Semaphore_Handle semstart_prov_Task_Handle;
    Semaphore_Struct semstart_led_Task_Struct;
    Semaphore_Handle semstart_led_Task_Handle;
    
    
    void provision_done_cbk()
    {
    
      GPIO_write(CONFIG_GPIO_LED_0,1);
    
        }
    
    void btn1fxn_cbk(uint_least8_t index)
    {
        Semaphore_post(semstart_prov_Task_Handle);
    }
    
    void btn2fxn_cbk(uint_least8_t index)
    {
        Semaphore_post(semstart_led_Task_Handle);
    }
    
    void turnLed(uint8_t on_off)
    {
      if (on_off)
      {
          GPIO_write(CONFIG_GPIO_LED_1,1);
      }
      else
      {
        GPIO_write(CONFIG_GPIO_LED_1,0);
      }
    }
    
    void Mesh_doButton(uint8_t index)
    {
    
    
      if (index == 0) // turn LED on
      {
        MeshApp_button_pressed(1);
      }
      else if (index == 1) // turn LED off
      {
        MeshApp_button_pressed(0);
      }
    }
    void button_pressed_cb(struct bt_mesh_model *model,
                          struct bt_mesh_msg_ctx *ctx,
                          struct net_buf_simple *buf)
    {
      // check own address
    
      if (ctx->addr == mesh_device_own_addr )
      {
         return;
      }
    
      uint8_t led_state = net_buf_simple_pull_u8(buf);
      //SimpleMeshMenu_turnLed(led_state);
    
      turnLed(led_state);
    
    }
    
    void start_prov_init(void)
    {
    
        GPIO_init();
        GPIO_setConfig(CONFIG_GPIO_BTN1,
                       GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
        GPIO_setCallback(CONFIG_GPIO_BTN1,btn1fxn_cbk );
        GPIO_enableInt(CONFIG_GPIO_BTN1);
    
        GPIO_init();
        GPIO_setConfig(CONFIG_GPIO_BTN2,
                          GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
        GPIO_setCallback(CONFIG_GPIO_BTN2,btn2fxn_cbk );
        GPIO_enableInt(CONFIG_GPIO_BTN2);
    
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    }
    
    static void start_prov_taskFxn(UArg a0, UArg a1)
    {
    
        start_prov_init();
        bleApp_stackInit();
    
       /* MeshApp_init(DEVICE_OWN_ADDRESS, UNPROVISIONED_BEACON);
        MeshApp_static_provisioning(DEVICE_OWN_ADDRESS, BT_MESH_KEY_UNUSED);*/
    
        for (;;)
        {
    
            Semaphore_pend(semstart_prov_Task_Handle, BIOS_WAIT_FOREVER);
            MeshApp_init(DEVICE_OWN_ADDRESS, UNPROVISIONED_BEACON);
    
    
    
            Semaphore_pend(semstart_led_Task_Handle, BIOS_WAIT_FOREVER);
            mesh_btn_target_addr = GROUP_ADDR;
            button_state = 0;
            Mesh_doButton(button_state);
    
    
       }
    }
    
    void start_prov_CreateTask(void)
    {
        bleStack_createTasks();
        k_sys_work_q_init(NULL);
        Semaphore_Params semParams;
        Task_Params taskParams;
    
        Task_Params_init(&taskParams);
        taskParams.stack = start_prov_Stack;
        taskParams.stackSize = START_PROV_STACK_SIZE;
        taskParams.priority = START_PROV_TASK_PRIORITY;
    
        Task_construct(&start_prov_Task, start_prov_taskFxn, &taskParams, NULL);
        Semaphore_Params_init(&semParams);
        Semaphore_construct(&semstart_prov_Task_Struct, 0, &semParams);
        semstart_prov_Task_Handle = Semaphore_handle(
                &semstart_prov_Task_Struct);
        Semaphore_construct(&semstart_led_Task_Struct, 0, &semParams);
           semstart_led_Task_Handle = Semaphore_handle(
                   &semstart_led_Task_Struct);
    
    }
    
    

     

    /******************************************************************************
    
    @file  static_prov.c
    
    @brief This file contains static provisioning configurations and performance.
    
    Group: WCS, BTS
    Target Device: cc13xx_cc26xx
    
    ******************************************************************************
    
     Copyright (c) 2013-2022, 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.
    
    ******************************************************************************
    
    
    *****************************************************************************/
    
    #ifdef USE_STATIC_PROVISIONING
    /*********************************************************************
    * INCLUDES
    */
    
    #include "static_prov.h"
    #include "mesh_erpc_wrapper.h"
    #include "ti_device_composition.h"
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <settings/settings.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/mesh.h>
    
    /*********************************************************************
     * MACROS
     */
    #define MOD_LF 0x0000
    #define GROUP_ADDR 0xc000
    
    /*********************************************************************
    * CONSTANTS
    */
    
    /*********************************************************************
    * TYPEDEFS
    */
    
    /*********************************************************************
    * GLOBAL VARIABLES
    */
    
    /*********************************************************************
    * LOCAL VARIABLES
    */
    static const uint16_t net_idx;
    static const uint32_t iv_index;
    static uint8_t prov_flags = 0;
    static const uint8_t net_key[16] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
    };
    static const uint8_t dev_key[16] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
    };
    static const uint8_t app_key[16] = {
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void MeshApp_provConfigure(uint16_t addr, uint16_t app_idx);
    
    /*********************************************************************
     * EXTERN FUNCTIONS
    */
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      MeshApp_static_provisioning
     *
     * @brief   Perform Static Provisioning by calling bt_mesh_provision
     *          and MeshApp_provConfigure
     *
     * @param   addr
     * @param   app_idx
     */
    int MeshApp_static_provisioning(uint16_t addr, uint16_t app_idx)
    {
        int status;
        status = bt_mesh_provision(net_key, net_idx, prov_flags, iv_index, addr, dev_key);
        if (status)
        {
            return status;
        }
    
        MeshApp_provConfigure(addr, app_idx);
    
      return status;
    }
    
    /*********************************************************************
     * @fn      MeshApp_provConfigure
     *
     * @brief   Configure the Mesh Node
     *
     * @param   addr
     * @param   app_idx
     */
    static void MeshApp_provConfigure(uint16_t addr, uint16_t app_idx)
    {
      /* Add Application Key */
      bt_mesh_cfg_app_key_add_wrapper(net_idx, addr, net_idx, app_idx, app_key);
    
      /* Bind to vendor model */
      bt_mesh_cfg_mod_app_bind_vnd_wrapper(net_idx, addr, addr, app_idx,
                                   MOD_LF, CONFIG_BT_COMPANY_ID);
    
      /* Bind to Health model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_HEALTH_SRV);
    
      /* Bind to Generic OnOff server model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_ONOFF_SRV);
    
      /* When using static provisioning, the loopback buffer is used
       * when the device sends messages.
       * The amount of the loopback buffers is determined by
       * CONFIG_BT_MESH_LOOPBACK_BUFS which is defined in autoconf.h.
       * Sleep is needed for the loopback buffers to be freed.
       */
      k_sleep(K_MSEC(100));
    
      /* Bind to vendor model
    
         bt_mesh_cfg_mod_app_bind_vnd Input Parameter Deep-dive
    
         net_idx: Pass in the network index
         addr: Address of the node
         elem_addr: Address of the element of the node. Here we refer to the second element, so we add 1.
         mod_app_idx: Application Key Index
         mod_id: Model ID. Here we set 0x1234 to match our Model ID in SysConfig.
         cid: Company ID
         status: Not needed
         */
    
         bt_mesh_cfg_mod_app_bind_vnd(net_idx, addr, addr+1, app_idx,
                                        0x1234, CONFIG_BT_COMPANY_ID, NULL);
    
      /* Bind to Generic OnOff client model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_ONOFF_CLI);
      /* Bind to Generic Level server model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_LEVEL_SRV);
      /* Bind to Generic Level client model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_LEVEL_CLI);
    
      k_sleep(K_MSEC(100));
    
      /* Bind to Generic Transition Time server model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV);
      /* Bind to Generic Transition Time client model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI);
      /* Bind to Generic Power OnOff server model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV);
    
      k_sleep(K_MSEC(100));
    
      /* Bind to Generic Power OnOff client model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI);
      /* Bind to Generic Power OnOff Setup server model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV);
      /* Bind to Generic Battery server model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_BATTERY_SRV);
    
      k_sleep(K_MSEC(100));
    
      /* Bind to Generic Battery client model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_GEN_BATTERY_CLI);
      /* Bind to Sensor server model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_SENSOR_SRV);
      /* Bind to Sensor client model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_SENSOR_CLI);
    
      k_sleep(K_MSEC(100));
    
      /* Bind to Sensor setup server model */
      bt_mesh_cfg_mod_app_bind_wrapper(net_idx, addr, addr, app_idx,
                               BT_MESH_MODEL_ID_SENSOR_SETUP_SRV);
    
      /* Add model subscription */
      bt_mesh_cfg_mod_sub_add_vnd_wrapper(net_idx, addr, addr, GROUP_ADDR,
                                  MOD_LF, CONFIG_BT_COMPANY_ID);
    
      /* Add model subscription */
      bt_mesh_cfg_mod_sub_add_vnd(net_idx, addr, addr+1, GROUP_ADDR,
                                  0x1234, CONFIG_BT_COMPANY_ID, NULL);
    }
    
    #endif // USE_STATIC_PROVISIONING

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandra、

    您能否解释一下您认为这两个器件加入不同网络的原因? 您是否为两台设备提供了相同的凭据?

    您是否考虑过监听器来确定正在发生什么?

    [编辑]关闭此主题、并将其标记为已解析、因为已在此处打开新主题

    此致、