diff --git a/README.md b/README.md index 87a57f7..dea0e88 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ For examples for other SDK versions and platforms, see table below.
  • Full Duplex Bidirectional Audio Demo (Central/Peripheral)
  • I2S Echo
  • Bluetooth 5 Throughput Demo
  • +
  • Tree Structure Network
  • @@ -275,6 +276,19 @@ with the Simplelink Starter app. * [CCS Project Files](examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/throughput_central/tirtos/ccs) * [Source](examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/throughput_central/src) +### Tree Structure Network + +Set up a tree structure network using tiers of star network. This network format +can be used to set up a network with up to 47 devices. The same example is used +for the founding node (grandpa node), the middle nodes (father nodes) and the +children nodes. + +* tree_structure_network + * [Documentation](examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/readme.md) + * [CCS Project Files](examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs) + * [IAR Project Files](examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar) + * [Source](examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src) + ## References The following reference pages may be helpful during general Bluetooth Low diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/readme.md b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/readme.md new file mode 100644 index 0000000..3437030 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/readme.md @@ -0,0 +1,205 @@ +Introduction +============ + +The tree_structure_network project demonstrates the capabilities of the Texas +Instruments BLE stack to function in Bluetooth® Low energy Tree Structure +network. Technical aspects of this example are described in the accompanied app +note. Please see: [Bluetooth® Low Energy Tree Structure Network](www.ti.com/lit/swra648) + +This example project is capable of functioning as a grandfather +node, a father node and a child node in any combination, while +maintaining several connections (up to the amount of connections defined by +MAX_NUM_BLE_CONNS). The project is capable of connecting to any role in tree +structure network. The role will be defined according to the connection sequence +(e.g. the first nod to connect as a master will become the grandpa node). The +project supports multiple simultaneous GATT discoveries. This project has the +following app build configurations available: + +| Build Configuration | Description | +|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| FlashROM_Release (default) | All TI-RTOS debug features disabled but application-logging to UART remains enabled. The application uses the config file ble_release.cfg and the defines are in \_FlashROM\_Release.opt. | +| FlashROM_Debug | All TI-RTOS debug features enabled. The application uses the config file ble_debug.cfg and the defines are in \_FlashROM\_Debug.opt. | + +All application configurations use the stack library configuration, +FlashROM_Library. This build configuration will yield additional flash footprint +optimizations by the linker since the application and stack can share contiguous +flash pages. This configuration is further discussed in the Stack Library +Configuration section of the BLE5-Stack User’s Guide provided in the SDK. + +Hardware Prerequisites +====================== + +The default Tree Structure Network board configuration uses the CC26x2R1 +LaunchPad development kit. This hardware configuration is shown in the below +image: + +![Hardware Configuration](resources/hardware_config.png) + +For custom hardware, see the Running the SDK on Custom Boards section of the +BLE5-Stack User’s Guide. + +Software Prerequisites +====================== + +For information on what versions of Code Composer Studio and IAR Embedded +Workbench to use, see the Release Notes file provided in the SDK. For +information on how to import this project into your IDE workspace and build/run +it, please refer to the device’s Platform section in the BLE5-Stack User’s Guide. + +Assumptions/Considerations +========================== + +Once the connection limit (set with the MAX_NUM_BLE_CONNS preprocessor define) +is reached, the grandfather device and father device won’t be allowed to scan +until there is a disconnection. + +By default, the tree_structure_network application is configured to filter and +connect to peripheral devices with the TI Tree Structure Service UUID. + +If the project is configured for a large number of connections (via the +MAX_NUM_BLE_CONNS preprocessor define) and also security (pairing/bonding), it +is possible for heap allocation failures to occur which will break the stack. +Therefore, the project should be stress-tested for its intended use case to verify +that there are no heap issues by including the HEAPMGR_METRICS preprocessor +define. See the Debugging section of the BLE5-Stack User’s Guide for more +information on how to do this. + +When at least one connection is already formed, in order to allow enough +processing time to scan for a new connection, the minimum possible connection +interval (in milliseconds) that can be used is: + +12.5 + 5\*n + +where n is the amount of current connections. For example, if there are currently +four connections, all four connections must use a minimum connection interval of +12\*5 + 5\*4 = 32.5 ms in order to allow scanning to occur to establish a new +connection. + +Usage +===== + +The tree_structure_network project uses the two buttons on the LaunchPad to +accept user input and outputs information through the UART. The UART is only +used for display messages. This document will use a terminal program (Tera Term, +PuTTY, etc.) to serve as the display for the output of the LaunchPad. Note that +any other serial terminal can be used. The following default parameters are used +for the UART peripheral for display: + +| UART Param | Default Values | +|--------------|----------------| +| Baud Rate | 115200 | +| Data length | 8 bits | +| Parity | None | +| Stop bits | 1 bit | +| Flow Control | None | + +Upon powering on or resetting the device, the user will see the default board +message. (RP address refers to resolvable private address.) + +![Power Up](resources/power-up.png) + +In certain cases, the user may want to switch from a "menu view" to a "log view" +(i.e. each new message is printed on the next line). In order to achieve this, +open the compiler predefined symbols list (`.opt` file) and set the following +define to zero: + +`-DBOARD_DISPLAY_USE_UART_ANSI=0` + +Establish the First Connection +============================== + +Program all devices that will be a part of the the network with the tree network +structure example project. + +Click the right button on the intended grandpa node. The device will discover +other devices. If other devices are discovered, it will connect this device, then +enable the connected device’s notification function, and send the command to turn +on the green LED automatically. (In the image, the grandfather device display is +shown on the left and the father1 device display on the right.) + +![Connection Established](resources/connection.png) + +Establish the Tree Structure Network +==================================== + +Now the grandfather board is connected to the the father1 board. Then turn on +the power of father2, click the right button on grandfather board to connect the +father2 board. Then follow the same way to use father1 board to connect the +child1 board, and father2 board to connect the child2 board. + +![Network Topology](resources/topology.png) + +GAP Role Information +==================== + +For grandpa node, it is always central role. For children nodes, they are always +peripheral role. For father node, when it is connected by grandpa node, it will +be central role first. And after it connects to children node, it will be +peripheral node. So father node GAP role changes when the connection and is thus +defined as multi-role. + +![GAPRoles Topology](resources/gaproles.png) + +Grandfather Node Writing +======================== + +After establishing the tree structure network, the option to write and notify +will now become available. In this option, pressing the left button on the +grandfather board once will enable grandfather node to write data to all father +nodes and children nodes defined in chalVals array. (If the data is intended to +a child node, the father node will forward it automatically.) Note that when the +message is received in each father and child node, their red led will be set or +reset in order according to the message. When this happens the green led will +automatically turn off. + +![Message propagation](resources/order1.png) + +![Message propagation](resources/order2.png) + +![Message propagation](resources/order3.png) + +Grandfather node’s operation in tree type network is defined in the charVals +table. See details below. + +``` +//Char value table length +#define string_index_max 8 + +//Send char value table +uint8_t charVals[string_index_max][TREENETWORKSERVICE_CHAR1_LEN] = { + {'0', '1', '0', '0', '\0'}, //Father 1 led off + {'0', '1', '1', '0', '\0'}, //Father 1's child 1 led off + {'0', '2', '0', '0', '\0'}, //Father 2 led off + {'0', '2', '1', '0', '\0'}, //Father 2's child 1 led off + {'0', '1', '0', '1', '\0'}, //Father 1 led on + {'0', '1', '1', '1', '\0'}, //Father 1's child 1 led on + {'0', '2', '0', '1', '\0'}, //Father 2 led on + {'0', '2', '1', '1', '\0'} //Father 2's child 1 led on + // Reserved + // Father index + // Father branch elements (child index) + // Led ON/OFF + }; // Should be consistent with those in GattWrite +``` + +Child Node Notification +======================= + +After the network has been established, pressing the left button on a father +board or a child board once will enable the node to send a message that this +happened to the grandpa node (by GATT notification). The following shows the +successful message on the grandpa node of the key pressing message. + +![Child node identification](resources/child_node.png) + +Data Transmission Flow and Data Format +============================================================= + +![Transmission flow](resources/flow.png) + +Data packets are sent as GATT write or GATT notification packets. The data format +is given below: + +| Array index | 0 | 1 | 2 | 3 | +|-------------|:--------:|:-------------------:|:---------------------:|:----------:| +| Meaning | Reserved | Father branch index | Children branch index | Led status | \ No newline at end of file diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/child_node.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/child_node.png new file mode 100644 index 0000000..14ccada Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/child_node.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/connection.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/connection.png new file mode 100644 index 0000000..6e62267 Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/connection.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/flow.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/flow.png new file mode 100644 index 0000000..60139eb Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/flow.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/gaproles.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/gaproles.png new file mode 100644 index 0000000..5e5820b Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/gaproles.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/hardware_config.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/hardware_config.png new file mode 100644 index 0000000..df2c55d Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/hardware_config.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order1.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order1.png new file mode 100644 index 0000000..0c5b0d1 Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order1.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order2.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order2.png new file mode 100644 index 0000000..79a1508 Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order2.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order3.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order3.png new file mode 100644 index 0000000..ae965bc Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/order3.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/power-up.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/power-up.png new file mode 100644 index 0000000..fd080af Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/power-up.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/topology.png b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/topology.png new file mode 100644 index 0000000..c956d21 Binary files /dev/null and b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/resources/topology.png differ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/main.c b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/main.c new file mode 100644 index 0000000..37426b8 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/main.c @@ -0,0 +1,298 @@ +/****************************************************************************** + + @file main.c + + @brief main entry of the BLE stack sample application. + + Group: CMCU, LPRF + Target Device: CC2652 + + ****************************************************************************** + + Copyright (c) 2013-2018, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + Release Name: simplelink_cc26x2_sdk_2_30_00_34 + Release Date: 2018-10-04 14:27:27 + *****************************************************************************/ + +/******************************************************************************* + * INCLUDES + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include "hal_assert.h" +#include "bcomdef.h" +#include "tree_structure_network.h" + +/* Header files required to enable instruction fetch cache */ +#include +#include + +#ifndef USE_DEFAULT_USER_CFG + +#include "ble_user_config.h" + +// BLE user defined configuration +#ifdef ICALL_JT +icall_userCfg_t user0Cfg = BLE_USER_CFG; +#else /* ! ICALL_JT */ +bleUserCfg_t user0Cfg = BLE_USER_CFG; +#endif /* ICALL_JT */ + +#endif // USE_DEFAULT_USER_CFG + +#ifdef USE_FPGA +#include +#endif // USE_FPGA + +/******************************************************************************* + * MACROS + */ + +/******************************************************************************* + * CONSTANTS + */ + +#if defined( USE_FPGA ) + #define RFC_MODE_BLE PRCM_RFCMODESEL_CURR_MODE1 + #define RFC_MODE_ANT PRCM_RFCMODESEL_CURR_MODE4 + #define RFC_MODE_EVERYTHING_BUT_ANT PRCM_RFCMODESEL_CURR_MODE5 + #define RFC_MODE_EVERYTHING PRCM_RFCMODESEL_CURR_MODE6 + // + #define SET_RFC_BLE_MODE(mode) HWREG( PRCM_BASE + PRCM_O_RFCMODESEL ) = (mode) +#endif // USE_FPGA + +/******************************************************************************* + * TYPEDEFS + */ + +/******************************************************************************* + * LOCAL VARIABLES + */ + +/******************************************************************************* + * GLOBAL VARIABLES + */ + +/******************************************************************************* + * EXTERNS + */ +extern assertCback_t halAssertCback; + +extern void AssertHandler(uint8 assertCause, uint8 assertSubcause); + +extern Display_Handle dispHandle; + +/******************************************************************************* + * @fn Main + * + * @brief Application Main + * + * input parameters + * + * @param None. + * + * output parameters + * + * @param None. + * + * @return None. + */ +int main() +{ + /* Register Application callback to trap asserts raised in the Stack */ + halAssertCback = AssertHandler; + + Board_initGeneral(); + + // Enable iCache prefetching + VIMSConfigure(VIMS_BASE, TRUE, TRUE); + // Enable cache + VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED); + + /* Register Application callback to trap asserts raised in the Stack */ + RegisterAssertCback(AssertHandler); + +#if !defined( POWER_SAVING ) || defined( USE_FPGA ) + /* Set constraints for Standby, powerdown and idle mode */ + // PowerCC26XX_SB_DISALLOW may be redundant + Power_setConstraint(PowerCC26XX_SB_DISALLOW); + Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW); +#endif // POWER_SAVING | USE_FPGA + + /* Update User Configuration of the stack */ + user0Cfg.appServiceInfo->timerTickPeriod = Clock_tickPeriod; + user0Cfg.appServiceInfo->timerMaxMillisecond = ICall_getMaxMSecs(); + + /* Initialize ICall module */ + ICall_init(); + + /* Start tasks of external images - Priority 5 */ + ICall_createRemoteTasks(); + + /* Kick off application - Priority 1 */ + tree_structure_network_createTask(); + + /* enable interrupts and start SYS/BIOS */ + BIOS_start(); + + return 0; +} + + +/******************************************************************************* + * @fn AssertHandler + * + * @brief This is the Application's callback handler for asserts raised + * in the stack. When EXT_HAL_ASSERT is defined in the Stack + * project this function will be called when an assert is raised, + * and can be used to observe or trap a violation from expected + * behavior. + * + * As an example, for Heap allocation failures the Stack will raise + * HAL_ASSERT_CAUSE_OUT_OF_MEMORY as the assertCause and + * HAL_ASSERT_SUBCAUSE_NONE as the assertSubcause. An application + * developer could trap any malloc failure on the stack by calling + * HAL_ASSERT_SPINLOCK under the matching case. + * + * An application developer is encouraged to extend this function + * for use by their own application. To do this, add hal_assert.c + * to your project workspace, the path to hal_assert.h (this can + * be found on the stack side). Asserts are raised by including + * hal_assert.h and using macro HAL_ASSERT(cause) to raise an + * assert with argument assertCause. the assertSubcause may be + * optionally set by macro HAL_ASSERT_SET_SUBCAUSE(subCause) prior + * to asserting the cause it describes. More information is + * available in hal_assert.h. + * + * input parameters + * + * @param assertCause - Assert cause as defined in hal_assert.h. + * @param assertSubcause - Optional assert subcause (see hal_assert.h). + * + * output parameters + * + * @param None. + * + * @return None. + */ +void AssertHandler(uint8 assertCause, uint8 assertSubcause) +{ + // Open the display if the app has not already done so + if ( !dispHandle ) + { + dispHandle = Display_open(Display_Type_ANY, NULL); + } + + Display_print0(dispHandle, 0, 0, ">>>STACK ASSERT"); + + // check the assert cause + switch (assertCause) + { + case HAL_ASSERT_CAUSE_OUT_OF_MEMORY: + Display_print0(dispHandle, 0, 0, "***ERROR***"); + Display_print0(dispHandle, 2, 0, ">> OUT OF MEMORY!"); + break; + + case HAL_ASSERT_CAUSE_INTERNAL_ERROR: + // check the subcause + if (assertSubcause == HAL_ASSERT_SUBCAUSE_FW_INERNAL_ERROR) + { + Display_print0(dispHandle, 0, 0, "***ERROR***"); + Display_print0(dispHandle, 2, 0, ">> INTERNAL FW ERROR!"); + } + else + { + Display_print0(dispHandle, 0, 0, "***ERROR***"); + Display_print0(dispHandle, 2, 0, ">> INTERNAL ERROR!"); + } + break; + + case HAL_ASSERT_CAUSE_ICALL_ABORT: + Display_print0(dispHandle, 0, 0, "***ERROR***"); + Display_print0(dispHandle, 2, 0, ">> ICALL ABORT!"); + HAL_ASSERT_SPINLOCK; + break; + + case HAL_ASSERT_CAUSE_ICALL_TIMEOUT: + Display_print0(dispHandle, 0, 0, "***ERROR***"); + Display_print0(dispHandle, 2, 0, ">> ICALL TIMEOUT!"); + HAL_ASSERT_SPINLOCK; + break; + + case HAL_ASSERT_CAUSE_WRONG_API_CALL: + Display_print0(dispHandle, 0, 0, "***ERROR***"); + Display_print0(dispHandle, 2, 0, ">> WRONG API CALL!"); + HAL_ASSERT_SPINLOCK; + break; + + default: + Display_print0(dispHandle, 0, 0, "***ERROR***"); + Display_print0(dispHandle, 2, 0, ">> DEFAULT SPINLOCK!"); + HAL_ASSERT_SPINLOCK; + } + + return; +} + + +/******************************************************************************* + * @fn smallErrorHook + * + * @brief Error handler to be hooked into TI-RTOS. + * + * input parameters + * + * @param eb - Pointer to Error Block. + * + * output parameters + * + * @param None. + * + * @return None. + */ +void smallErrorHook(Error_Block *eb) +{ + for (;;); +} + + +/******************************************************************************* + */ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/tree_structure_network.c b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/tree_structure_network.c new file mode 100644 index 0000000..cb12ec7 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/tree_structure_network.c @@ -0,0 +1,3088 @@ +/****************************************************************************** + +@file tree_structure_network.c + +@brief This file contains the tree_structure_network sample application for use +with the TI Bluetooth Low Energy Protocol Stack. + +Group: CMCU, LPRF +Target Device: CC2652 + +****************************************************************************** + + Copyright (c) 2013-2019, 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 + +#include +#include +#include +#include +#include + +#if !(defined __TI_COMPILER_VERSION__) +#include +#endif + +#include + +#include +#include "util.h" +#include +/* This Header file contains all BLE API and icall structure definition */ +#include + +#include +#include + +#include +#include + +#include "tree_structure_network.h" + +/********************************************************************* +* CONSTANTS +*/ + +//Char value table length +#define string_index_max 8 + +//Send char value table +uint8_t charVals[string_index_max][TREENETWORKSERVICE_CHAR1_LEN] = { + {'0', '1', '0', '0', '\0'}, //Father 1 led off + {'0', '1', '1', '0', '\0'}, //Father 1's child 1 led off + {'0', '2', '0', '0', '\0'}, //Father 2 led off + {'0', '2', '1', '0', '\0'}, //Father 2's child 1 led off + {'0', '1', '0', '1', '\0'}, //Father 1 led on + {'0', '1', '1', '1', '\0'}, //Father 1's child 1 led on + {'0', '2', '0', '1', '\0'}, //Father 2 led on + {'0', '2', '1', '1', '\0'} //Father 2's child 1 led on + // Reserved + // Father index + // Father branch elements (child index) + // Led ON/OFF + }; // Should be consistent with those in GattWrite + +// defgroup GAP_Profile_Roles GAP Profile Roles +#define GAP_PROFILE_MULTIROLE 0x10 + +// Address mode of the local device +// Note: When using the DEFAULT_ADDRESS_MODE as ADDRMODE_RANDOM or +// ADDRMODE_RP_WITH_RANDOM_ID, GAP_DeviceInit() should be called with +// it's last parameter set to a static random address +#define DEFAULT_ADDRESS_MODE ADDRMODE_RP_WITH_PUBLIC_ID + +// Application events +#define TSN_EVT_CHAR_CHANGE 1 +#define TSN_EVT_KEY_CHANGE 2 +#define TSN_EVT_ADV_REPORT 3 +#define TSN_EVT_SCAN_ENABLED 4 +#define TSN_EVT_SCAN_DISABLED 5 +#define TSN_EVT_SVC_DISC 6 +#define TSN_EVT_ADV 7 +#define TSN_EVT_PAIRING_STATE 8 +#define TSN_EVT_PASSCODE_NEEDED 9 +#define TSN_EVT_SEND_PARAM_UPDATE 10 +#define TSN_EVT_PERIODIC 11 +#define TSN_EVT_READ_RPA 12 +#define TSN_EVT_INSUFFICIENT_MEM 13 +#define TSN_EVT_EN_NOTI 14 +#define TSN_EVT_WRITE_CHAR 15 +#define TSN_EVT_CHAR1_NOTI 16 + +// Internal Events for RTOS application +#define TSN_ICALL_EVT ICALL_MSG_EVENT_ID // Event_Id_31 +#define TSN_QUEUE_EVT UTIL_QUEUE_EVENT_ID // Event_Id_30 + +#define TSN_ALL_EVENTS (TSN_ICALL_EVT | \ + TSN_QUEUE_EVT) + +// Default PHY for scanning +#define DEFAULT_SCAN_PHY SCAN_PRIM_PHY_1M + +// Limited discoverable mode advertises for 30.72s, and then stops +// General discoverable mode advertises indefinitely +#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL + +// Default scan duration in 10 ms +#define DEFAULT_SCAN_DURATION 200 // 2 sec + +// TRUE to filter discovery results on desired service UUID +#define DEFAULT_DEV_DISC_BY_SVC_UUID TRUE + +// Minimum connection interval (units of 1.25ms) if automatic parameter update +// request is enabled +#define DEFAULT_UPDATE_MIN_CONN_INTERVAL 400 + +// Maximum connection interval (units of 1.25ms) if automatic parameter update +// request is enabled +#define DEFAULT_UPDATE_MAX_CONN_INTERVAL 800 + +// Slave latency to use if automatic parameter update request is enabled +#define DEFAULT_UPDATE_SLAVE_LATENCY 0 + +// Supervision timeout value (units of 10ms) if automatic parameter update +// request is enabled +#define DEFAULT_UPDATE_CONN_TIMEOUT 600 + +// Minimum connection interval (units of 1.25ms, 80=100ms) for parameter update request +#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 80 + +// Maximum connection interval (units of 1.25ms, 104=130ms) for parameter update request +#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 104 + +// Slave latency to use for parameter update request +#define DEFAULT_DESIRED_SLAVE_LATENCY 0 + +// Supervision timeout value (units of 10ms, 300=3s) for parameter update request +#define DEFAULT_DESIRED_CONN_TIMEOUT 300 + +// Supervision timeout conversion rate to miliseconds +#define CONN_TIMEOUT_MS_CONVERSION 10 + +// Pass parameter updates to the app for it to decide. +#define DEFAULT_PARAM_UPDATE_REQ_DECISION GAP_UPDATE_REQ_PASS_TO_APP + +// Task configuration +#define TSN_TASK_PRIORITY 1 +#ifndef TSN_TASK_STACK_SIZE +#define TSN_TASK_STACK_SIZE 1024 +#endif + +// Advertising report fields to keep in the list +// Interested in only peer address type and peer address +#define TSN_ADV_RPT_FIELDS (SCAN_ADVRPT_FLD_ADDRTYPE | SCAN_ADVRPT_FLD_ADDRESS) + +// Discovery states +typedef enum { + BLE_DISC_STATE_IDLE, // Idle + BLE_DISC_STATE_MTU, // Exchange ATT MTU size + BLE_DISC_STATE_SVC, // Service discovery + BLE_DISC_STATE_CHAR, // Characteristic discovery + BLE_DISC_STATE_ENABLE_CHAR_NOTIFICATION, + BLE_DISC_STATE_WRITE_CHAR +} discState_t; + +// Row numbers for two-button menu +#define TBM_ROW_APP 0 +#define TSN_ROW_NON_CONN (TBM_ROW_APP + 0) +#define TSN_ROW_MYADDRSS (TBM_ROW_APP + 1) +#define TSN_ROW_RPA (TBM_ROW_APP + 2) +#define TSN_ROW_ADVERTIS (TBM_ROW_APP + 3) +#define TSN_ROW_NUM_CONN (TBM_ROW_APP + 4) +#define TSN_ROW_CUR_CONN (TBM_ROW_APP + 5) +#define TSN_ROW_SECURITY (TBM_ROW_APP + 6) +#define TSN_ROW_CHARSTAT (TBM_ROW_APP + 7) +#define TSN_ROW_SEL_CONN (TBM_ROW_APP + 8) +#define TSN_ROW_MYROLE (TBM_ROW_APP + 9) +#define TSN_ROW_MYMSG (TBM_ROW_APP + 10) +#define TSN_ROW_NOTI (TBM_ROW_APP + 11) + +// address string length is an ascii character for each digit + +#define TSN_ADDR_STR_SIZE 15 + +// How often to perform periodic event (in msec) +#define TSN_PERIODIC_EVT_PERIOD 1000 + +// How often to read current current RPA (in ms) +#define TSN_EVT_READ_RPA_PERIOD 3000 + +// Delay (in ms) after connection establishment before sending a parameter update requst +#define TSN_SEND_PARAM_UPDATE_DELAY 6000 + +#define CONNINDEX_INVALID 0xFF + +// Spin if the expression is not true +#define TREESTRUCTURENETWORK_ASSERT(expr) if (!(expr)) tree_structure_network_spin(); + +/********************************************************************* +* TYPEDEFS +*/ + +// App event passed from profiles. +typedef struct +{ + uint8_t event; // event type + void *pData; // event data pointer +} tsnEvt_t; + +// Container to store paring state info 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; +} tsnPairStateData_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; +} tsnPasscodeData_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 information from clock expiration using a flexible array +// since data is not always needed +typedef struct +{ + uint8_t event; + uint8_t data[]; +} tsnClockEventData_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; +} tsnGapAdvEventData_t; + +// List element for parameter update and PHY command status lists +typedef struct +{ + List_Elem elem; + uint16_t connHandle; +} tsnConnHandleEntry_t; + +// Connected device information +typedef struct +{ + uint16_t connHandle; // Connection Handle + uint8_t addr[B_ADDR_LEN]; // Peer Device Address + uint8_t charHandle; // Characteristic Handle + Clock_Struct* pUpdateClock; // pointer to clock struct + uint8_t discState; // Per connection discovery state +} tsnConnRec_t; + +// Container to store notify event data when passing from GATTMsg event. +typedef struct +{ + uint16_t connHandle; + uint8_t data[TREENETWORKSERVICE_CHAR1_LEN]; +} tsnNotiEventData_t; + +/********************************************************************* +* GLOBAL VARIABLES +*/ + +// Display Interface +Display_Handle dispHandle = NULL; + +/* Pin driver handles */ +static PIN_Handle ledPinHandle; + +/* Global memory storage for a PIN_Config table */ +static PIN_State ledPinState; + +/* + * Initial LED pin configuration table + * - LEDs Board_PIN_LED0 & Board_PIN_LED1 are off. + */ +PIN_Config ledPinTable[] = { + Board_PIN_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | + PIN_DRVSTR_MAX, + Board_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | + PIN_DRVSTR_MAX, + PIN_TERMINATE +}; + +/********************************************************************* +* LOCAL VARIABLES +*/ + +// Entity ID globally used to check for source and/or destination of messages +static ICall_EntityID selfEntity; + +// Event globally used to post local events and pend on system and +// local events. +static ICall_SyncHandle syncEvent; + +// Clock instances for internal periodic events. +static Clock_Struct clkPeriodic; + +// Clock instance for RPA read events. +static Clock_Struct clkRpaRead; + +// Memory to pass periodic event to clock handler +tsnClockEventData_t periodicUpdateData = +{ + .event = TSN_EVT_PERIODIC +}; + +// Memory to pass RPA read event ID to clock handler +tsnClockEventData_t argRpaRead = +{ + .event = TSN_EVT_READ_RPA +}; + +// Queue object used for app messages +static Queue_Struct appMsg; +static Queue_Handle appMsgQueue; + +// Task configuration +Task_Struct tsnTask; +#if defined __TI_COMPILER_VERSION__ +#pragma DATA_ALIGN(tsnTaskStack, 8) +#else +#pragma data_alignment=8 +#endif +uint8_t tsnTaskStack[TSN_TASK_STACK_SIZE]; + +static uint8_t scanRspData[] = +{ + // complete name + 18, // length of this data + GAP_ADTYPE_LOCAL_NAME_COMPLETE, + 'T', 'r', 'e', 'e', ' ', 'N', 'e', 't', 'w', 'o', 'r', 'k', ' ', 'N', 'o', 'd', 'e', + + // Tx power level + 2, // length of this data + GAP_ADTYPE_POWER_LEVEL, + 0 // 0dBm +}; + +// GAP - Advertisement data (max size = 31 bytes, though this is +// best kept short to conserve power while advertisting) +static uint8_t advertData[] = +{ + // Flags; this sets the device to use limited discoverable + // mode (advertises for 30 seconds at a time) instead of general + // discoverable mode (advertises indefinitely) + 0x02, // length of this data + GAP_ADTYPE_FLAGS, + DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, + + // service UUID, to notify central devices what services are included + // in this peripheral + 0x03, // length of this data + GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all + LO_UINT16(TREENETWORKSERVICE_SERV_UUID), + HI_UINT16(TREENETWORKSERVICE_SERV_UUID) +}; + +// GAP GATT Attributes +static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Tree Network Device"; + +// Maximim PDU size (default = 27 octets) +static uint16 tsnMaxPduSize; + +#if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) +// Number of scan results filtered by Service UUID +static uint8_t numScanRes = 0; + +// Scan results filtered by Service UUID +static scanRec_t scanList[DEFAULT_MAX_SCAN_RES]; +#endif // DEFAULT_DEV_DISC_BY_SVC_UUID + +// Discovered service start and end handle +static uint16_t svcStartHdl = 0; +static uint16_t svcEndHdl = 0; + +// Number of connected devices +static uint8_t numConn = 0; + +// Connection handle of current connection +static uint16_t tsnConnHandle = LINKDB_CONNHANDLE_INVALID; + +// List to store connection handles for queued param updates +static List_List paramUpdateList; + +// Per-handle connection info +static tsnConnRec_t connList[MAX_NUM_BLE_CONNS]; + +// Advertising handles +static uint8 advHandle; + +static bool tsnIsAdvertising = false; +// Address mode +static GAP_Addr_Modes_t addrMode = DEFAULT_ADDRESS_MODE; + +// Current Random Private Address +static uint8 rpa[B_ADDR_LEN] = {0}; + +// Initiating PHY +static uint8_t tsnInitPhy = INIT_PHY_1M; + +// Periodic task enable flag +static uint8_t en_period_task = 0; +static volatile uint32_t bytesRecvd = 0; + +// Tree structure role defination +volatile uint8_t my_role = 0; + +// Grandfather index +volatile uint8_t grandfather_index = 0; + +/********************************************************************* +* LOCAL FUNCTIONS +*/ +static void tree_structure_network_init(void); +static void tree_structure_network_scanInit(void); +static void tree_structure_network_advertInit(void); +static void tree_structure_network_taskFxn(UArg a0, UArg a1); +static uint8_t tree_structure_network_processStackMsg(ICall_Hdr *pMsg); +static uint8_t tree_structure_network_processGATTMsg(gattMsgEvent_t *pMsg); +static void tree_structure_network_processAppMsg(tsnEvt_t *pMsg); +static void tree_structure_network_processCharValueChangeEvt(uint8_t paramID); +static void tree_structure_network_processGATTDiscEvent(gattMsgEvent_t *pMsg); +static void tree_structure_network_processPasscode(tsnPasscodeData_t *pData); +static void tree_structure_network_processPairState(tsnPairStateData_t* pairingEvent); +static void tree_structure_network_processGapMsg(gapEventHdr_t *pMsg); +static void tree_structure_network_processParamUpdate(uint16_t connHandle); +static void tree_structure_network_processAdvEvent(tsnGapAdvEventData_t *pEventData); +static void tree_structure_network_charValueChangeCB(uint8_t paramID); +static status_t tree_structure_network_enqueueMsg(uint8_t event, void *pData); +static void tree_structure_network_handleKeys(uint8_t keys); +static uint16_t tree_structure_network_getConnIndex(uint16_t connHandle); +static void tree_structure_network_keyChangeHandler(uint8_t keys); +static uint8_t tree_structure_network_addConnInfo(uint16_t connHandle, uint8_t *pAddr, uint8_t role); +static void tree_structure_network_performPeriodicTask(void); +static void tree_structure_network_clockHandler(UArg arg); +static uint8_t tree_structure_network_clearConnListEntry(uint16_t connHandle); +#if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) +static void tree_structure_network_addScanInfo(uint8_t *pAddr, uint8_t addrType); +static bool tree_structure_network_findSvcUuid(uint16_t uuid, uint8_t *pData, uint16_t dataLen); +#endif // DEFAULT_DEV_DISC_BY_SVC_UUID +static uint8_t tree_structure_network_removeConnInfo(uint16_t connHandle); +static void tree_structure_network_startSvcDiscovery(void); +#ifndef Display_DISABLE_ALL +static char* tree_structure_network_getConnAddrStr(uint16_t connHandle); +#endif +static void tree_structure_network_advCB(uint32_t event, void *pBuf, uintptr_t arg); +static void tree_structure_network_scanCB(uint32_t evt, void* msg, uintptr_t arg); +static void tree_structure_network_passcodeCB(uint8_t *deviceAddr, uint16_t connHandle, + uint8_t uiInputs, uint8_t uiOutputs, uint32_t numComparison); +static void tree_structure_network_pairStateCB(uint16_t connHandle, uint8_t state, + uint8_t status); +static void tree_structure_network_updateRPA(void); +bool tree_structure_network_doGattWriteString(uint8_t internal_tsnConnHandle, uint8_t *pAddr); +bool tree_structure_network_doGattWriteEnableNotification(); +static void tree_structure_network_processChar1ValueNotiEvt(tsnNotiEventData_t *pMsg); + +/********************************************************************* + * EXTERN FUNCTIONS +*/ +extern void AssertHandler(uint8 assertCause, uint8 assertSubcause); + +/********************************************************************* +* PROFILE CALLBACKS +*/ + +// Simple GATT Profile Callbacks +static treeNetworkServiceCBs_t tree_structure_network_treeNetworkServiceCBs = +{ + tree_structure_network_charValueChangeCB // Characteristic value change callback +}; + +// GAP Bond Manager Callbacks +static gapBondCBs_t tree_structure_network_BondMgrCBs = +{ + tree_structure_network_passcodeCB, // Passcode callback + tree_structure_network_pairStateCB // Pairing state callback +}; + +/********************************************************************* +* PUBLIC FUNCTIONS +*/ + +/********************************************************************* + * @fn tree_structure_network_spin + * + * @brief Spin forever + * + * @param none + */ +static void tree_structure_network_spin(void) +{ + volatile uint8_t x = 0; + + while(1) + { + x++; + } +} + +/********************************************************************* +* @fn tree_structure_network_createTask +* +* @brief Task creation function for tree_structure_network. +* +* @param None. +* +* @return None. +*/ +void tree_structure_network_createTask(void) +{ + Task_Params taskParams; + + // Configure task + Task_Params_init(&taskParams); + taskParams.stack = tsnTaskStack; + taskParams.stackSize = TSN_TASK_STACK_SIZE; + taskParams.priority = TSN_TASK_PRIORITY; + + Task_construct(&tsnTask, tree_structure_network_taskFxn, &taskParams, NULL); +} + +/********************************************************************* +* @fn tree_structure_network_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 tree_structure_network_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); + + // Open Display. + //dispHandle = Display_open(Display_Type_ANY, NULL); + dispHandle = Display_open(Display_Type_UART, NULL); + + // Create an RTOS queue for message from profile to be sent to app. + appMsgQueue = Util_constructQueue(&appMsg); + + // Create one-shot clock for internal periodic events. + Util_constructClock(&clkPeriodic, tree_structure_network_clockHandler, + TSN_PERIODIC_EVT_PERIOD, 0, false, + (UArg)&periodicUpdateData); + + // Open LED pins + ledPinHandle = PIN_open(&ledPinState, ledPinTable); + if(!ledPinHandle) + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Error initializing board LED pins"); + Task_exit(); + } + + // Init key debouncer + Board_initKeys(tree_structure_network_keyChangeHandler); + + // Initialize Connection List + tree_structure_network_clearConnListEntry(LINKDB_CONNHANDLE_ALL); + + // 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/ble5stack-latest/ + GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, (void *)attDeviceName); + + // Configure GAP + { + uint16_t paramUpdateDecision = DEFAULT_PARAM_UPDATE_REQ_DECISION; + + // Pass all parameter update requests to the app for it to decide + GAP_SetParamValue(GAP_PARAM_LINK_UPDATE_DECISION, paramUpdateDecision); + } + + // Set default values for Data Length Extension + // Extended Data Length Feature is already enabled by default + { + // Set initial values to maximum, RX is set to max. by default(251 octets, 2120us) + // Some brand smartphone is essentially needing 251/2120, so we set them here. + #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 BLE5-Stack User's Guide for information on using this command: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + HCI_LE_WriteSuggestedDefaultDataLenCmd(APP_SUGGESTED_PDU_SIZE, APP_SUGGESTED_TX_TIME); + } + + // Initialize GATT Client, used by GAPBondMgr to look for RPAO characteristic for network privacy + GATT_InitClient(); + + // Register to receive incoming ATT Indications/Notifications + GATT_RegisterForInd(selfEntity); + + // Setup the GAP Bond Manager + { + // Send a pairing request after connecting. + uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE; + // Use authenticated pairing: require passcode. + uint8_t mitm = TRUE; + // 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_DISPLAY_ONLY; + // Request bonding (storing long-term keys for re-encryption upon subsequent + // connections without repairing) + uint8_t bonding = TRUE; + + GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode); + GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm); + GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap); + GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding); + } + + // Initialize GATT attributes + GGS_AddService(GATT_ALL_SERVICES); // GAP + GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes + DevInfo_AddService(); // Device Information Service + TreeNetworkService_AddService(GATT_ALL_SERVICES); // Simple GATT Profile + + // Setup the TreeNetworkService Characteristic Values + // For more information, see the GATT and GATTServApp sections in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + { + uint8_t charValue1[TREENETWORKSERVICE_CHAR1_LEN] = { 1, 2, 3, 4}; + + TreeNetworkService_SetParameter(TREENETWORKSERVICE_CHAR1, TREENETWORKSERVICE_CHAR1_LEN, + charValue1); + } + + // Register callback with SimpleGATTprofile + TreeNetworkService_RegisterAppCBs(&tree_structure_network_treeNetworkServiceCBs); + + // Start Bond Manager and register callback + VOID GAPBondMgr_Register(&tree_structure_network_BondMgrCBs); + + // Register with GAP for HCI/Host messages. This is needed to receive HCI + // events. For more information, see the HCI section in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + GAP_RegisterForMsgs(selfEntity); + + // Register for GATT local events and ATT Responses pending for transmission + GATT_RegisterForMsgs(selfEntity); + + //Initialize GAP layer for Peripheral and Central role and register to receive GAP events + GAP_DeviceInit(GAP_PROFILE_PERIPHERAL | GAP_PROFILE_CENTRAL, selfEntity, + addrMode, NULL); +} + +/********************************************************************* +* @fn tree_structure_network_taskFxn +* +* @brief Application task entry point for the tree_structure_network. +* +* @param a0, a1 - not used. +* +* @return None. +*/ +static void tree_structure_network_taskFxn(UArg a0, UArg a1) +{ + // Initialize application + tree_structure_network_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, TSN_ALL_EVENTS, + ICALL_TIMEOUT_FOREVER); + + if (events) + { + ICall_EntityID dest; + ICall_ServiceEnum src; + ICall_HciExtEvt *pMsg = NULL; + + if (ICall_fetchServiceMsg(&src, &dest, + (void **)&pMsg) == ICALL_ERRNO_SUCCESS) + { + uint8_t safeToDealloc = TRUE; + + if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) + { + ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg; + + // Check for BLE stack events first + if (pEvt->signature != 0xffff) + { + // Process inter-task message + safeToDealloc = tree_structure_network_processStackMsg((ICall_Hdr *)pMsg); + } + } + + if (pMsg && safeToDealloc) + { + ICall_freeMsg(pMsg); + } + } + + // If RTOS queue is not empty, process app message. + if (events & TSN_QUEUE_EVT) + { + while (!Queue_empty(appMsgQueue)) + { + tsnEvt_t *pMsg = (tsnEvt_t *)Util_dequeueMsg(appMsgQueue); + if (pMsg) + { + // Process message. + tree_structure_network_processAppMsg(pMsg); + + // Free the space from the message. + ICall_free(pMsg); + } + } + } + } + } +} + +/********************************************************************* +* @fn tree_structure_network_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 tree_structure_network_processStackMsg(ICall_Hdr *pMsg) +{ + uint8_t safeToDealloc = TRUE; + + switch (pMsg->event) + { + case GAP_MSG_EVENT: + tree_structure_network_processGapMsg((gapEventHdr_t*) pMsg); + break; + + case GATT_MSG_EVENT: + // Process GATT message + safeToDealloc = tree_structure_network_processGATTMsg((gattMsgEvent_t *)pMsg); + break; + + case HCI_GAP_EVENT_EVENT: + { + // Process HCI message + switch (pMsg->status) + { + case HCI_COMMAND_COMPLETE_EVENT_CODE: + break; + + case HCI_BLE_HARDWARE_ERROR_EVENT_CODE: + AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0); + break; + + // 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, TSN_ROW_CUR_CONN, 0, + "PHY Change failure, peer does not support this"); + } + else + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, + "PHY Update Status: 0x%02x", + pMyMsg->cmdStatus); + } + } + break; + case HCI_DISCONNECT: + break; + + default: + { + Display_printf(dispHandle, TSN_ROW_NON_CONN, 0, + "Unknown Cmd Status: 0x%04x::0x%02x", + pMyMsg->cmdOpcode, pMyMsg->cmdStatus); + } + break; + } + } + break; + + // LE Events + case HCI_LE_EVENT_CODE: + { + hciEvt_BLEPhyUpdateComplete_t *pPUC + = (hciEvt_BLEPhyUpdateComplete_t*) pMsg; + + if (pPUC->BLEEventCode == HCI_BLE_PHY_UPDATE_COMPLETE_EVENT) + { + if (pPUC->status != SUCCESS) + { + + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, + "%s: PHY change failure", + tree_structure_network_getConnAddrStr(pPUC->connHandle)); + } + else + { + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, + "%s: PHY updated to %s", + tree_structure_network_getConnAddrStr(pPUC->connHandle), + // Only symmetrical PHY is supported. + // rxPhy should be equal to txPhy. + (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_1M) ? "1 Mbps" : + (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_2M) ? "2 Mbps" : + (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_CODED) ? "Coded" : "Unexpected PHY Value"); + } + } + + break; + } + + default: + break; + } + + break; + } + + case L2CAP_SIGNAL_EVENT: + // place holder for L2CAP Connection Parameter Reply + break; + + default: + // Do nothing + break; + } + + return (safeToDealloc); +} + +/********************************************************************* + * @fn tree_structure_network_processGapMsg + * + * @brief GAP message processing function. + * + * @param pMsg - pointer to event message structure + * + * @return none + */ +static void tree_structure_network_processGapMsg(gapEventHdr_t *pMsg) +{ + switch (pMsg->opcode) + { + case GAP_DEVICE_INIT_DONE_EVENT: + { + gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg; + + 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); + + //Setup and start advertising + tree_structure_network_advertInit(); + + // Set device info characteristic + DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, pPkt->devAddr); + } + + //Setup scanning + tree_structure_network_scanInit(); + + tsnMaxPduSize = pPkt->dataPktLen; + + //Display initialized state status + Display_printf(dispHandle, TSN_ROW_NUM_CONN, 0, "Num Conns: %d", numConn); + Display_printf(dispHandle, TSN_ROW_NON_CONN, 0, "Initialized"); + Display_printf(dispHandle, TSN_ROW_MYADDRSS, 0, "Tree Device Address: %s",(char *)Util_convertBdAddr2Str(pPkt->devAddr)); + + break; + } + + case GAP_CONNECTING_CANCELLED_EVENT: + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, + "Conneting attempt cancelled"); + break; + } + + case GAP_LINK_ESTABLISHED_EVENT: + { + uint16_t connHandle = ((gapEstLinkReqEvent_t*) pMsg)->connectionHandle; + // Update the role type when the lnk established + uint8_t role = ((gapEstLinkReqEvent_t*) pMsg)->connRole; + static uint8_t last_role; + + // Judge the role change + if ( ( (role == GAP_PROFILE_CENTRAL) && (last_role == GAP_PROFILE_PERIPHERAL) ) + || ( (role == GAP_PROFILE_PERIPHERAL) && (last_role == GAP_PROFILE_CENTRAL) ) ) + { + // New father node + my_role = GAP_PROFILE_MULTIROLE; + } + else + { + // Child or grandpa node + my_role = role; + } + + // Save the last role state + last_role = role; + + uint8_t* pAddr = ((gapEstLinkReqEvent_t*) pMsg)->devAddr; + uint8_t connIndex; + uint8_t* pStrAddr; + + // Add this connection info to the list + connIndex = tree_structure_network_addConnInfo(connHandle, pAddr, role); + // connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNS + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + connList[connIndex].charHandle = 0; + + pStrAddr = (uint8_t*) Util_convertBdAddr2Str(connList[connIndex].addr); + + Display_printf(dispHandle, TSN_ROW_NON_CONN, 0, "Connected to %s", pStrAddr); + Display_printf(dispHandle, TSN_ROW_NUM_CONN, 0, "Num Conns: %d", numConn); + + tsnConnHandle = connHandle; + + // Only central do the connection + if (my_role == GAP_PROFILE_CENTRAL) + { + tree_structure_network_doSelectConn(connIndex); + } + else if (my_role == GAP_PROFILE_MULTIROLE) + { + tree_structure_network_doSelectConn(connIndex); + } + break; + } + + case GAP_LINK_TERMINATED_EVENT: + { + uint16_t connHandle = ((gapTerminateLinkEvent_t*) pMsg)->connectionHandle; + uint8_t connIndex; + uint8_t* pStrAddr; + + // Mark this connection deleted in the connected device list. + connIndex = tree_structure_network_removeConnInfo(connHandle); + + // connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNS + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + pStrAddr = (uint8_t*) Util_convertBdAddr2Str(connList[connIndex].addr); + + Display_printf(dispHandle, TSN_ROW_NON_CONN, 0, "%s is disconnected", + pStrAddr); + Display_printf(dispHandle, TSN_ROW_NUM_CONN, 0, "Num Conns: %d", numConn); + Display_clearLines(dispHandle, TSN_ROW_CUR_CONN, TSN_ROW_NOTI); + + PIN_setOutputValue(ledPinHandle, Board_PIN_RLED, 0x00); + PIN_setOutputValue(ledPinHandle, Board_PIN_GLED, 0x00); + + // Start advertising since there is room for more connections + GapAdv_enable(advHandle, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + + // If no active connections + if (numConn == 0) + { + // Stop periodic clock + Util_stopClock(&clkPeriodic); + } + + break; + } + + 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; + if (linkDB_GetInfo(pPkt->connectionHandle, &linkInfo) == SUCCESS) + { + + if(pPkt->status == SUCCESS) + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, + "Link Param Updated: %s", + Util_convertBdAddr2Str(linkInfo.addr)); + } + else + { + // Display the address of the connection update failure + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, + "Link Param Update Failed 0x%h: %s", pPkt->opcode, + Util_convertBdAddr2Str(linkInfo.addr)); + } + } + // Check if there are any queued parameter updates + tsnConnHandleEntry_t *connHandleEntry = (tsnConnHandleEntry_t *)List_get(¶mUpdateList); + if (connHandleEntry != NULL) + { + // Attempt to send queued update now + tree_structure_network_processParamUpdate(connHandleEntry->connHandle); + + // Free list element + ICall_free(connHandleEntry); + } + break; + } + + + default: + break; + } +} + +/********************************************************************* +* @fn tree_structure_network_scanInit +* +* @brief Setup initial device scan settings. +* +* @return None. +*/ +static void tree_structure_network_scanInit(void) +{ + uint8_t temp8; + uint16_t temp16; + + // Setup scanning + // For more information, see the GAP section in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + + // Register callback to process Scanner events + GapScan_registerCb(tree_structure_network_scanCB, NULL); + + // Set Scanner Event Mask + GapScan_setEventMask(GAP_EVT_SCAN_ENABLED | GAP_EVT_SCAN_DISABLED | + GAP_EVT_ADV_REPORT); + + // Set Scan PHY parameters + GapScan_setPhyParams(DEFAULT_SCAN_PHY, SCAN_TYPE_ACTIVE, + SCAN_PARAM_DFLT_INTERVAL, SCAN_PARAM_DFLT_INTERVAL); + + // Set Advertising report fields to keep + temp16 = TSN_ADV_RPT_FIELDS; + GapScan_setParam(SCAN_PARAM_RPT_FIELDS, &temp16); + // Set Scanning Primary PHY + temp8 = DEFAULT_SCAN_PHY; + GapScan_setParam(SCAN_PARAM_PRIM_PHYS, &temp8); + // Set LL Duplicate Filter + temp8 = SCAN_FLT_DUP_ENABLE; + GapScan_setParam(SCAN_PARAM_FLT_DUP, &temp8); + + // Set PDU type filter - + // Only 'Connectable' and 'Complete' packets are desired. + // It doesn't matter if received packets are + // whether Scannable or Non-Scannable, whether Directed or Undirected, + // whether Scan_Rsp's or Advertisements, and whether Legacy or Extended. + temp16 = SCAN_FLT_PDU_CONNECTABLE_ONLY | SCAN_FLT_PDU_COMPLETE_ONLY; + GapScan_setParam(SCAN_PARAM_FLT_PDU_TYPE, &temp16); +} + +/********************************************************************* +* @fn tree_structure_network_scanInit +* +* @brief Setup initial advertisment and start advertising from device init. +* +* @return None. +*/ +static void tree_structure_network_advertInit(void) +{ + uint8_t status = FAILURE; + // Setup and start Advertising + // For more information, see the GAP section in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + + // Temporary memory for advertising parameters for set #1. These will be copied + // by the GapAdv module + GapAdv_params_t advParam = GAPADV_PARAMS_LEGACY_SCANN_CONN; + + // Create Advertisement set #1 and assign handle + GapAdv_create(&tree_structure_network_advCB, &advParam, + &advHandle); + + // Load advertising data for set #1 that is statically allocated by the app + GapAdv_loadByHandle(advHandle, GAP_ADV_DATA_TYPE_ADV, + sizeof(advertData), advertData); + + // Load scan response data for set #1 that is statically allocated by the app + GapAdv_loadByHandle(advHandle, GAP_ADV_DATA_TYPE_SCAN_RSP, + sizeof(scanRspData), scanRspData); + + // Set event mask for set #1 + GapAdv_setEventMask(advHandle, + GAP_ADV_EVT_MASK_START_AFTER_ENABLE | + GAP_ADV_EVT_MASK_END_AFTER_DISABLE | + GAP_ADV_EVT_MASK_SET_TERMINATED); + + // Enable legacy advertising for set #1 + status = GapAdv_enable(advHandle, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + + if(status != SUCCESS) + { + tsnIsAdvertising = false; + Display_printf(dispHandle, TSN_ROW_ADVERTIS, 0, "Error: Failed to Start Advertising!"); + } + + if (addrMode > ADDRMODE_RANDOM) + { + tree_structure_network_updateRPA(); + + // Create one-shot clock for RPA check event. + Util_constructClock(&clkRpaRead, tree_structure_network_clockHandler, + TSN_EVT_READ_RPA_PERIOD, 0, true, + (UArg) &argRpaRead); + } +} + +/********************************************************************* + * @fn tree_structure_network_advCB + * + * @brief GapAdv module callback + * + * @param pMsg - message to process + */ +static void tree_structure_network_advCB(uint32_t event, void *pBuf, uintptr_t arg) +{ + tsnGapAdvEventData_t *pData = ICall_malloc(sizeof(tsnGapAdvEventData_t)); + + if (pData) + { + pData->event = event; + pData->pBuf = pBuf; + + if(tree_structure_network_enqueueMsg(TSN_EVT_ADV, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + + +/********************************************************************* +* @fn tree_structure_network_processGATTMsg +* +* @brief Process GATT messages and events. +* +* @return TRUE if safe to deallocate incoming message, FALSE otherwise. +*/ +static uint8_t tree_structure_network_processGATTMsg(gattMsgEvent_t *pMsg) +{ + // Get connection index from handle + uint8_t connIndex = tree_structure_network_getConnIndex(pMsg->connHandle); + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + 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, TSN_ROW_CUR_CONN, 0, "FC Violated: %d", pMsg->msg.flowCtrlEvt.opcode); + } + else if (pMsg->method == ATT_MTU_UPDATED_EVENT) + { + // MTU size updated + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "MTU Size: %d", pMsg->msg.mtuEvt.MTU); + } + + + // Messages from GATT server + if (linkDB_Up(pMsg->connHandle)) + { + if ((pMsg->method == ATT_READ_RSP) || + ((pMsg->method == ATT_ERROR_RSP) && + (pMsg->msg.errorRsp.reqOpcode == ATT_READ_REQ))) + { + if (pMsg->method == ATT_ERROR_RSP) + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Read Error %d", pMsg->msg.errorRsp.errCode); + } + else + { + // After a successful read, display the read value + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Read rsp: %d", pMsg->msg.readRsp.pValue[0]); + } + + } + else if ((pMsg->method == ATT_WRITE_RSP) || + ((pMsg->method == ATT_ERROR_RSP) && + (pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ))) + { + + if (pMsg->method == ATT_ERROR_RSP == ATT_ERROR_RSP) + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Write Error %d", pMsg->msg.errorRsp.errCode); + } + else + { + // After a succesful write, display the value that was written and + // increment value + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "write success\n\n", connIndex + 1); + } + } + else if (pMsg->method == ATT_HANDLE_VALUE_NOTI) + { + { + //Post the notification transmit task + tsnNotiEventData_t *paramUpdateNotiData; + paramUpdateNotiData = ICall_malloc( sizeof(tsnNotiEventData_t) ); + paramUpdateNotiData->connHandle = connIndex; + memcpy(paramUpdateNotiData->data, pMsg->msg.handleValueNoti.pValue, TREENETWORKSERVICE_CHAR1_LEN); + tree_structure_network_enqueueMsg(TSN_EVT_CHAR1_NOTI, paramUpdateNotiData); + } + } + if (connList[connIndex].discState != BLE_DISC_STATE_IDLE) + { + tree_structure_network_processGATTDiscEvent(pMsg); + } + } // Else - in case a GATT message came after a connection has dropped, ignore it. + + // 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 tree_structure_network_processParamUpdate + * + * @brief Remove a device from the connected device list + * + * @return index of the connected device list entry where the new connection + * info is removed from. + * if connHandle is not found, MAX_NUM_BLE_CONNS will be returned. + */ +static void tree_structure_network_processParamUpdate(uint16_t connHandle) +{ + gapUpdateLinkParamReq_t req; + uint8_t connIndex; + + req.connectionHandle = connHandle; + req.connLatency = DEFAULT_DESIRED_SLAVE_LATENCY; + req.connTimeout = DEFAULT_DESIRED_CONN_TIMEOUT; + req.intervalMin = DEFAULT_DESIRED_MIN_CONN_INTERVAL; + req.intervalMax = DEFAULT_DESIRED_MAX_CONN_INTERVAL; + + connIndex = tree_structure_network_getConnIndex(connHandle); + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + // Deconstruct the clock object + Clock_destruct(connList[connIndex].pUpdateClock); + // Free clock struct + ICall_free(connList[connIndex].pUpdateClock); + connList[connIndex].pUpdateClock = NULL; + + // Send parameter update + bStatus_t status = GAP_UpdateLinkParamReq(&req); + + // If there is an ongoing update, queue this for when the udpate completes + if (status == bleAlreadyInRequestedMode) + { + tsnConnHandleEntry_t *connHandleEntry = ICall_malloc(sizeof(tsnConnHandleEntry_t)); + if (connHandleEntry) + { + connHandleEntry->connHandle = connHandle; + + List_put(¶mUpdateList, (List_Elem *)&connHandleEntry); + } + } +} + +/********************************************************************* +* @fn tree_structure_network_processAppMsg +* +* @brief Process an incoming callback from a profile. +* +* @param pMsg - message to process +* +* @return None. +*/ +static void tree_structure_network_processAppMsg(tsnEvt_t *pMsg) +{ + bool safeToDealloc = TRUE; + + switch (pMsg->event) + { + case TSN_EVT_CHAR_CHANGE: + { + tree_structure_network_processCharValueChangeEvt(*(uint8_t*)(pMsg->pData)); + break; + } + + case TSN_EVT_KEY_CHANGE: + { + tree_structure_network_handleKeys(*(uint8_t *)(pMsg->pData)); + break; + } + + case TSN_EVT_ADV_REPORT: + { + GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData); + +#if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) + if (tree_structure_network_findSvcUuid(TREENETWORKSERVICE_SERV_UUID, + pAdvRpt->pData, pAdvRpt->dataLen)) + { + tree_structure_network_addScanInfo(pAdvRpt->addr, pAdvRpt->addrType); + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Discovered: %s", + Util_convertBdAddr2Str(pAdvRpt->addr)); + } +#else // !DEFAULT_DEV_DISC_BY_SVC_UUID + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Discovered: %s", + Util_convertBdAddr2Str(pAdvRpt->addr)); +#endif // DEFAULT_DEV_DISC_BY_SVC_UUID + + // Free scan payload data + if (pAdvRpt->pData != NULL) + { + ICall_free(pAdvRpt->pData); + } + break; + } + + case TSN_EVT_SCAN_ENABLED: + { + Display_printf(dispHandle, TSN_ROW_NUM_CONN, 0, "Discovering..."); + break; + } + + case TSN_EVT_SCAN_DISABLED: + { + uint8_t numReport; + uint8_t i; + static uint8_t* pAddrs = NULL; + uint8_t* pAddrTemp; + +#if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) + numReport = numScanRes; +#else // !DEFAULT_DEV_DISC_BY_SVC_UUID + GapScan_Evt_AdvRpt_t advRpt; + + numReport = ((GapScan_Evt_End_t*) (pMsg->pData))->numReport; +#endif // DEFAULT_DEV_DISC_BY_SVC_UUID + + Display_printf(dispHandle, TSN_ROW_ADVERTIS, 0, + "%d devices discovered", numReport); + + if (numReport > 0) + { + // Also enable "Connect to" + tree_structure_network_doConnect(0); + } + + // Allocate buffer to display addresses + pAddrs = ICall_malloc(numReport * TSN_ADDR_STR_SIZE); + if (pAddrs == NULL) + { + numReport = 0; + } + + if (pAddrs != NULL) + { + pAddrTemp = pAddrs; + for (i = 0; i < numReport; i++, pAddrTemp += TSN_ADDR_STR_SIZE) + { + #if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) + // Get the address from the list, convert it to string, and + // copy the string to the address buffer + memcpy(pAddrTemp, Util_convertBdAddr2Str(scanList[i].addr), + TSN_ADDR_STR_SIZE); + #else // !DEFAULT_DEV_DISC_BY_SVC_UUID + // Get the address from the report, convert it to string, and + // copy the string to the address buffer + GapScan_getAdvReport(i, &advRpt); + memcpy(pAddrTemp, Util_convertBdAddr2Str(advRpt.addr), + TSN_ADDR_STR_SIZE); + #endif // DEFAULT_DEV_DISC_BY_SVC_UUID + } + } + break; + } + + case TSN_EVT_SVC_DISC: + { + tree_structure_network_startSvcDiscovery(); + break; + } + + case TSN_EVT_ADV: + { + tree_structure_network_processAdvEvent((tsnGapAdvEventData_t*)(pMsg->pData)); + break; + } + + case TSN_EVT_PAIRING_STATE: + { + tree_structure_network_processPairState((tsnPairStateData_t*)(pMsg->pData)); + break; + } + + case TSN_EVT_PASSCODE_NEEDED: + { + tree_structure_network_processPasscode((tsnPasscodeData_t*)(pMsg->pData)); + break; + } + + case TSN_EVT_SEND_PARAM_UPDATE: + { + // Extract connection handle from data + uint16_t locConnHandle = *(uint16_t *)(((tsnClockEventData_t *)pMsg->pData)->data); + tree_structure_network_processParamUpdate(locConnHandle); + safeToDealloc = FALSE; + break; + } + + case TSN_EVT_PERIODIC: + { + // If the current role is grandpa node: + if(my_role == GAP_PROFILE_CENTRAL) + tree_structure_network_performPeriodicTask(); + break; + } + + case TSN_EVT_READ_RPA: + { + tree_structure_network_updateRPA(); + break; + } + + case TSN_EVT_INSUFFICIENT_MEM: + { + // We are running out of memory. + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Insufficient Memory"); + + // We might be in the middle of scanning, try stopping it. + GapScan_disable(); + break; + } + + case TSN_EVT_EN_NOTI: + { + tree_structure_network_doGattWriteEnableNotification(); + break; + } + + case TSN_EVT_WRITE_CHAR: + { + tree_structure_network_doGattWriteString(tsnConnHandle, "LED2"); + break; + } + + //Add notification event + case TSN_EVT_CHAR1_NOTI: + { + tree_structure_network_processChar1ValueNotiEvt((tsnNotiEventData_t*)(pMsg->pData)); + break; + } + + default: + // Do nothing. + break; + } + + if ((safeToDealloc == TRUE) && (pMsg->pData != NULL)) + { + ICall_free(pMsg->pData); + } +} + +/********************************************************************* + * @fn tree_structure_network_processAdvEvent + * + * @brief Process advertising event in app context + * + * @param pEventData + */ +static void tree_structure_network_processAdvEvent(tsnGapAdvEventData_t *pEventData) +{ + switch (pEventData->event) + { + case GAP_EVT_ADV_START_AFTER_ENABLE: + tsnIsAdvertising = true; + Display_printf(dispHandle, TSN_ROW_ADVERTIS, 0, "Advertising Enabled"); + break; + + case GAP_EVT_ADV_END_AFTER_DISABLE: + tsnIsAdvertising = false; + Display_printf(dispHandle, TSN_ROW_ADVERTIS, 0, "Advertising Disabled"); + break; + + case GAP_EVT_ADV_START: + Display_printf(dispHandle, TSN_ROW_ADVERTIS, 0, "Adv Started %d Enabled", + *(uint8_t *)(pEventData->pBuf)); + break; + + case GAP_EVT_ADV_END: + Display_printf(dispHandle, TSN_ROW_ADVERTIS, 0, "Adv Ended %d Disabled", + *(uint8_t *)(pEventData->pBuf)); + break; + + case GAP_EVT_ADV_SET_TERMINATED: + { + tsnIsAdvertising = false; +#ifndef Display_DISABLE_ALL + GapAdv_setTerm_t *advSetTerm = (GapAdv_setTerm_t *)(pEventData->pBuf); +#endif + Display_printf(dispHandle, TSN_ROW_ADVERTIS, 0, "Advertising disabled after conn %d", + advSetTerm->handle, advSetTerm->connHandle ); + } + break; + + case GAP_EVT_SCAN_REQ_RECEIVED: + break; + + case GAP_EVT_INSUFFICIENT_MEMORY: + break; + + default: + break; + } + + // All events have associated memory to free except the insufficient memory + // event + if (pEventData->event != GAP_EVT_INSUFFICIENT_MEMORY) + { + ICall_free(pEventData->pBuf); + } +} + +#if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) +/********************************************************************* + * @fn tree_structure_network_findSvcUuid + * + * @brief Find a given UUID in an advertiser's service UUID list. + * + * @return TRUE if service UUID found + */ +static bool tree_structure_network_findSvcUuid(uint16_t uuid, uint8_t *pData, + uint16_t dataLen) +{ + uint8_t adLen; + uint8_t adType; + uint8_t *pEnd; + + if (dataLen > 0) + { + pEnd = pData + dataLen - 1; + + // While end of data not reached + while (pData < pEnd) + { + // Get length of next AD item + adLen = *pData++; + if (adLen > 0) + { + adType = *pData; + + // If AD type is for 16-bit service UUID + if ((adType == GAP_ADTYPE_16BIT_MORE) || + (adType == GAP_ADTYPE_16BIT_COMPLETE)) + { + pData++; + adLen--; + + // For each UUID in list + while (adLen >= 2 && pData < pEnd) + { + // Check for match + if ((pData[0] == LO_UINT16(uuid)) && (pData[1] == HI_UINT16(uuid))) + { + // Match found + return TRUE; + } + + // Go to next + pData += 2; + adLen -= 2; + } + + // Handle possible erroneous extra byte in UUID list + if (adLen == 1) + { + pData++; + } + } + else + { + // Go to next item + pData += adLen; + } + } + } + } + + // Match not found + return FALSE; +} + +/********************************************************************* + * @fn tree_structure_network_addScanInfo + * + * @brief Add a device to the scanned device list + * + * @return none + */ +static void tree_structure_network_addScanInfo(uint8_t *pAddr, uint8_t addrType) +{ + uint8_t i; + + // If result count not at max + if (numScanRes < DEFAULT_MAX_SCAN_RES) + { + // Check if device is already in scan results + for (i = 0; i < numScanRes; i++) + { + if (memcmp(pAddr, scanList[i].addr , B_ADDR_LEN) == 0) + { + return; + } + } + + // Add addr to scan result list + memcpy(scanList[numScanRes].addr, pAddr, B_ADDR_LEN); + scanList[numScanRes].addrType = addrType; + + // Increment scan result count + numScanRes++; + } +} +#endif // DEFAULT_DEV_DISC_BY_SVC_UUID + +/********************************************************************* + * @fn tree_structure_network_scanCB + * + * @brief Callback called by GapScan module + * + * @param evt - event + * @param msg - message coming with the event + * @param arg - user argument + * + * @return none + */ +void tree_structure_network_scanCB(uint32_t evt, void* pMsg, uintptr_t arg) +{ + uint8_t event; + + if (evt & GAP_EVT_ADV_REPORT) + { + event = TSN_EVT_ADV_REPORT; + } + else if (evt & GAP_EVT_SCAN_ENABLED) + { + event = TSN_EVT_SCAN_ENABLED; + } + else if (evt & GAP_EVT_SCAN_DISABLED) + { + event = TSN_EVT_SCAN_DISABLED; + } + else if (evt & GAP_EVT_INSUFFICIENT_MEMORY) + { + event = TSN_EVT_INSUFFICIENT_MEM; + } + else + { + return; + } + + if(tree_structure_network_enqueueMsg(event, pMsg) != SUCCESS) + { + ICall_free(pMsg); + } + +} + +/********************************************************************* +* @fn tree_structure_network_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 tree_structure_network_charValueChangeCB(uint8_t paramID) +{ + uint8_t *pData; + + // Allocate space for the event data. + if ((pData = ICall_malloc(sizeof(uint8_t)))) + { + *pData = paramID; + + // Queue the event. + if(tree_structure_network_enqueueMsg(TSN_EVT_CHAR_CHANGE, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/********************************************************************* + * @fn tree_structure_network_enqueueMsg + * + * @brief Creates a message and puts the message in RTOS queue. + * + * @param event - message event. + * @param state - message state. + * @param pData - message data pointer. + * + * @return TRUE or FALSE + */ +static status_t tree_structure_network_enqueueMsg(uint8_t event, void *pData) +{ + uint8_t success; + tsnEvt_t *pMsg = ICall_malloc(sizeof(tsnEvt_t)); + + // Create dynamic pointer to message. + if (pMsg) + { + pMsg->event = event; + pMsg->pData = pData; + + // Enqueue the message. + success = Util_enqueueMsg(appMsgQueue, syncEvent, (uint8_t *)pMsg); + return (success) ? SUCCESS : FAILURE; + } + + return(bleMemAllocError); +} + +/********************************************************************* + * @fn tree_structure_network_processCharValueChangeEvt + * + * @brief Process a pending Tree Network Service characteristic value change + * event. + * + * @param paramID - parameter ID of the value that was changed. + */ +static void tree_structure_network_processCharValueChangeEvt(uint8_t paramId) +{ + uint8_t newValue[TREENETWORKSERVICE_CHAR1_LEN]={0}; + uint8_t valueToCompare[TREENETWORKSERVICE_CHAR1_LEN] = {'0', '0', '0', '0', '\0'}; + switch(paramId) + { + case TREENETWORKSERVICE_CHAR1: + TreeNetworkService_GetParameter(TREENETWORKSERVICE_CHAR1, &newValue); + PIN_setOutputValue(ledPinHandle, Board_PIN_GLED, newValue[3] & 0x02); + + Display_printf(dispHandle, TSN_ROW_CHARSTAT, 0, "Char 1: %s", (uintptr_t)newValue); + { + uint8_t i = 0; + uint8_t state; + uint8_t child_index = 0; + uint8_t valid_table[MAX_NUM_BLE_CONNS] ={0}; + uint8_t valid_table_sum = 0; + + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle != LINKDB_CONNHANDLE_INVALID) + valid_table[i] = 1; + else + valid_table[i] = 0; + } + + //get sum + for(i = 0; i < MAX_NUM_BLE_CONNS; i++) + valid_table_sum = valid_table_sum + valid_table[i]; + + //Father node or Children node to do action + if( (my_role == GAP_PROFILE_PERIPHERAL) || (my_role == GAP_PROFILE_MULTIROLE) ) + { + if ( strncmp((char const*)newValue, (char const*)valueToCompare, TREENETWORKSERVICE_CHAR1_LEN) ) + { + //Father type peripheral + if (valid_table_sum > 1) + { + Display_printf(dispHandle, TSN_ROW_MYROLE, 0, "Father %c", newValue[1]); + + //Is the message to father? (Check newValue[2]). If yes, no transmit required + if (newValue[2] == '0') + { + Display_printf(dispHandle, TSN_ROW_MYMSG, 0, "Received message %s", newValue); + // set/reset LED + PIN_setOutputValue(ledPinHandle, Board_PIN_RLED, newValue[3] & 0x01); + } + // Message to child, transmit to the appointed child + else if ( (newValue[2] - 48) <= (valid_table_sum - 1) ) + { + // Transpose ASCII value to decimal value (48 = ASCII 0) + child_index = newValue[2] - 48; + state = tree_structure_network_doSelectConn(child_index); + if (state == false) + Display_printf(dispHandle, TSN_ROW_SEL_CONN, 0, "doSelectConn fail: %d", child_index); + else + { + // Transmit the data + tree_structure_network_doGattWriteString(connList[child_index].connHandle, newValue); + } + } + else + { + Display_printf(dispHandle, TSN_ROW_SEL_CONN, 0, "doSelectConn fail: %c isn't in connected list", (newValue[2] - 1)); + } + } + //child type peripheral + else if (valid_table_sum == 1) + { + if (newValue[0] == 'L') + { + // Connected child, no action. + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Connected, GLED ON"); + } + else + { + Display_printf(dispHandle, TSN_ROW_MYROLE, 0, "Father %c's child %c", newValue[1], newValue[2]); + Display_printf(dispHandle, TSN_ROW_MYMSG, 0, "Get message %s", newValue); + } + // set/reset the led + PIN_setOutputValue(ledPinHandle, Board_PIN_RLED, newValue[3] & 0x01); + } + }//End of newValue != {'0000'} + }//End of peripheral + } + break; + + default: + // should not reach here! + break; + } +} + +/********************************************************************* + * @fn tree_structure_network_processChar1ValueNotiEvt + * + * @brief Process a pending Simple Profile characteristic value notification + * event. + * + * @param paramID - parameter ID of the value that was notified. + */ +static void tree_structure_network_processChar1ValueNotiEvt(tsnNotiEventData_t *pMsg) +{ + uint8_t i = 0; + uint8_t valid_table[MAX_NUM_BLE_CONNS] ={0}; + uint8_t valid_table_sum = 0; + + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle != LINKDB_CONNHANDLE_INVALID) + valid_table[i] = 1; + else + valid_table[i] = 0; + } + + //get sum + for(i = 0; i < MAX_NUM_BLE_CONNS; i++) + valid_table_sum = valid_table_sum + valid_table[i]; + + //Father type node + if (my_role == GAP_PROFILE_MULTIROLE) + { + //Father type peripheral, send the notification up to grandfather + if (valid_table_sum > 1) + { + attHandleValueNoti_t noti; + status_t status; + + noti.pValue = (uint8 *)GATT_bm_alloc( grandfather_index, ATT_HANDLE_VALUE_NOTI, TREENETWORKSERVICE_CHAR1_LEN, NULL ); + if ( noti.pValue != NULL ) + { + uint8_t connIndex = tree_structure_network_getConnIndex(grandfather_index); + + noti.handle = connList[connIndex].charHandle; + noti.len = TREENETWORKSERVICE_CHAR1_LEN; + pMsg->data[2] = '0' + pMsg->connHandle; // order number in tree = connHandle + memcpy(noti.pValue, pMsg->data, TREENETWORKSERVICE_CHAR1_LEN); + // Transmit the notification + status = GATT_Notification( grandfather_index, ¬i, FALSE ); + Display_printf(dispHandle, TSN_ROW_CHARSTAT, 0, "Sent key press noti."); + } + if ( status != SUCCESS ) + { + GATT_bm_free( (gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI ); + } + } + } + //Grandfather type, display the key value + else if (my_role == GAP_PROFILE_CENTRAL) + { + // father index starts from 0, so add 1 here + pMsg->data[1] = '0' + pMsg->connHandle + 1; + if (pMsg->data[2] == '0') + Display_printf(dispHandle, TSN_ROW_CHARSTAT, 0, "Key 1: from Father %c", pMsg->data[1]); + else + Display_printf(dispHandle, TSN_ROW_CHARSTAT, 0, "Key 1: from Father %c 's child %c", pMsg->data[1], pMsg->data[2]); + } +} + +/********************************************************************* + * @fn tree_structure_network_performPeriodicTask + * + * @brief Perform a periodic application task. This function gets called + * every five seconds (TSN_PERIODIC_EVT_PERIOD). In this example, + * the value of the first characteristic in the Tree Network + * Service is retrieved from the profile, and then copied into the + * value of the the fourth characteristic. + * + * @param None. + * + * @return None. + */ +static void tree_structure_network_performPeriodicTask(void) +{ + uint8_t state; + uint8_t i = 0; + uint8_t father_index = 0; + static uint8_t string_index = 0; + uint8_t valid_table[MAX_NUM_BLE_CONNS] ={0}; + uint8_t valid_table_sum = 0; + + // Loop all connected device + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle != LINKDB_CONNHANDLE_INVALID) + valid_table[i] = 1; + else + valid_table[i] = 0; + } + + // Get the total number + for(i = 0; i < MAX_NUM_BLE_CONNS; i++) + valid_table_sum = valid_table_sum + valid_table[i]; + + // Loop the charValue table, which includes the tree structure network instruction + if (string_index >= string_index_max - 1) + string_index = 0; + else + string_index ++; + + // Grandfather type node + // According the charVals table to loop the defined sub-node + if(my_role == GAP_PROFILE_CENTRAL) + { + if (valid_table_sum != 0) //Connected number should > 0 + { + // Change the ASCII to the number, get the fatehr index + father_index = charVals[string_index][1] - '0' - 1; + if (father_index <= valid_table_sum - 1) + { + state = tree_structure_network_doSelectConn(father_index); + if (state == false) + Display_printf(dispHandle, TSN_ROW_SEL_CONN, 0, "doSelectConn fail: %d", father_index); + else + { + // Send the data to the father + state = tree_structure_network_doGattWriteString(connList[father_index].connHandle, charVals[string_index]); + } + } + else + { + Display_printf(dispHandle, TSN_ROW_SEL_CONN, 0, "doSelectConn fail: %d is out of list", father_index); + } + } + } +} + +/********************************************************************* + * @fn tree_structure_network_updateRPA + * + * @brief Read the current RPA from the stack and update display + * if the RPA has changed. + * + * @param None. + * + * @return None. + */ +static void tree_structure_network_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, TSN_ROW_RPA, 0, "RP Addr: %s", + Util_convertBdAddr2Str(pRpaNew)); + memcpy(rpa, pRpaNew, B_ADDR_LEN); + } +} + +/********************************************************************* + * @fn tree_structure_network_clockHandler + * + * @brief Handler function for clock timeouts. + * + * @param arg - event type + * + * @return None. + */ +static void tree_structure_network_clockHandler(UArg arg) +{ + tsnClockEventData_t *pData = (tsnClockEventData_t *)arg; + + if (pData->event == TSN_EVT_PERIODIC) + { + // Start the next period + Util_startClock(&clkPeriodic); + + // Send message to perform periodic task + tree_structure_network_enqueueMsg(TSN_EVT_PERIODIC, NULL); + } + else if (pData->event == TSN_EVT_READ_RPA) + { + // Start the next period + Util_startClock(&clkRpaRead); + + // Send message to read the current RPA + tree_structure_network_enqueueMsg(TSN_EVT_READ_RPA, NULL); + } + else if (pData->event == TSN_EVT_SEND_PARAM_UPDATE) + { + // Send message to app + tree_structure_network_enqueueMsg(TSN_EVT_SEND_PARAM_UPDATE, pData); + } +} + +/********************************************************************* +* @fn tree_structure_network_keyChangeHandler +* +* @brief Key event handler function +* +* @param a0 - ignored +* +* @return none +*/ +static void tree_structure_network_keyChangeHandler(uint8_t keys) +{ + uint8_t *pValue = ICall_malloc(sizeof(uint8_t)); + + if (pValue) + { + *pValue = keys; + + tree_structure_network_enqueueMsg(TSN_EVT_KEY_CHANGE, pValue); + } +} + +/********************************************************************* +* @fn tree_structure_network_handleKeys +* +* @brief Handles all key events for this device. +* +* @param keys - bit field for key events. Valid entries: +* KEY_LEFT +* KEY_RIGHT +* +* @return none +*/ +static void tree_structure_network_handleKeys(uint8_t keys) +{ + uint32_t rtnVal = 0; + if (keys & KEY_LEFT) + { + // Check if the key is still pressed + if (PIN_getInputValue(Board_PIN_BUTTON0) == 0) + { + if (my_role == GAP_PROFILE_CENTRAL) + { + if (en_period_task == 0) + { + // Grandfather type node enable the period task to loop the sub-nodes + en_period_task = 1; + Util_startClock(&clkPeriodic); + } + else + { + en_period_task = 0; + Util_stopClock(&clkPeriodic); + } + } + else + { + // Father/child node: send the key value + uint8_t valueToCopy[TREENETWORKSERVICE_CHAR1_LEN] = {'0', '0', '0', 'A', '\0'}; + TreeNetworkService_SetParameter(TREENETWORKSERVICE_CHAR1, TREENETWORKSERVICE_CHAR1_LEN, &valueToCopy); + } + } + } + else if (keys & KEY_RIGHT) + { + // Check if the key is still pressed + rtnVal = PIN_getInputValue(Board_PIN_BUTTON1); + if (rtnVal == 0) + { + tree_structure_network_doDiscoverDevices(0); + } + } +} + +/********************************************************************* +* @fn tree_structure_network_processGATTDiscEvent +* +* @brief Process GATT discovery event +* +* @param pMsg - pointer to discovery event stack message +* +* @return none +*/ +static void tree_structure_network_processGATTDiscEvent(gattMsgEvent_t *pMsg) +{ + uint8_t connIndex = tree_structure_network_getConnIndex(pMsg->connHandle); + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + uint8_t event; + + if (connList[connIndex].discState == BLE_DISC_STATE_MTU) + { + // MTU size response received, discover simple service + if (pMsg->method == ATT_EXCHANGE_MTU_RSP) + { + uint8_t uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(TREENETWORKSERVICE_SERV_UUID), + HI_UINT16(TREENETWORKSERVICE_SERV_UUID) }; + + connList[connIndex].discState = BLE_DISC_STATE_SVC; + + // Discovery simple service + VOID GATT_DiscPrimaryServiceByUUID(pMsg->connHandle, uuid, + ATT_BT_UUID_SIZE, selfEntity); + } + } + else if (connList[connIndex].discState == BLE_DISC_STATE_SVC) + { + // Service found, store handles + if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && + pMsg->msg.findByTypeValueRsp.numInfo > 0) + { + svcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0); + svcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0); + } + + // If procedure complete + if (((pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP) && + (pMsg->hdr.status == bleProcedureComplete)) || + (pMsg->method == ATT_ERROR_RSP)) + { + if (svcStartHdl != 0) + { + attReadByTypeReq_t req; + + // Discover characteristic + connList[connIndex].discState = BLE_DISC_STATE_CHAR; + + req.startHandle = svcStartHdl; + req.endHandle = svcEndHdl; + req.type.len = ATT_BT_UUID_SIZE; + req.type.uuid[0] = LO_UINT16(TREENETWORKSERVICE_CHAR1_UUID); + req.type.uuid[1] = HI_UINT16(TREENETWORKSERVICE_CHAR1_UUID); + + VOID GATT_DiscCharsByUUID(pMsg->connHandle, &req, selfEntity); + } + } + } + else if (connList[connIndex].discState == BLE_DISC_STATE_CHAR) + { + // Characteristic found, store handle + if ((pMsg->method == ATT_READ_BY_TYPE_RSP) && + (pMsg->msg.readByTypeRsp.numPairs > 0)) + { + uint8_t connIndex = tree_structure_network_getConnIndex(tsnConnHandle); + + // connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNS + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + // Store the handle of the simpleprofile characteristic 1 value + connList[connIndex].charHandle + = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[3], + pMsg->msg.readByTypeRsp.pDataList[4]); + + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Simple Svc Found"); + } + + // Next procedure to enable char1 notification + connList[connIndex].discState = BLE_DISC_STATE_ENABLE_CHAR_NOTIFICATION; + } + else if (connList[connIndex].discState == BLE_DISC_STATE_ENABLE_CHAR_NOTIFICATION) + { + event = TSN_EVT_EN_NOTI; + if(tree_structure_network_enqueueMsg(event, 0) != SUCCESS) + { + ICall_free(pMsg); + } + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Enable notification"); + + // Next procedure to write char1 + connList[connIndex].discState = BLE_DISC_STATE_WRITE_CHAR; + } + else if (connList[connIndex].discState == BLE_DISC_STATE_WRITE_CHAR) + { + event = TSN_EVT_WRITE_CHAR; + if(tree_structure_network_enqueueMsg(event, 0) != SUCCESS) + { + ICall_free(pMsg); + } + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Send data"); + connList[connIndex].discState = BLE_DISC_STATE_IDLE; + } + +} + +/********************************************************************* +* @fn tree_structure_network_getConnIndex +* +* @brief Translates connection handle to index +* +* @param connHandle - the connection handle +* + * @return the index of the entry that has the given connection handle. + * if there is no match, MAX_NUM_BLE_CONNS will be returned. +*/ +static uint16_t tree_structure_network_getConnIndex(uint16_t connHandle) +{ + uint8_t i; + // Loop through connection + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + // If matching connection handle found + if (connList[i].connHandle == connHandle) + { + return i; + } + } + + // Not found if we got here + return(MAX_NUM_BLE_CONNS); +} + +#ifndef Display_DISABLE_ALL +/********************************************************************* + * @fn tree_structure_network_getConnAddrStr + * + * @brief Return, in string form, the address of the peer associated with + * the connHandle. + * + * @return A null-terminated string of the address. + * if there is no match, NULL will be returned. + */ +static char* tree_structure_network_getConnAddrStr(uint16_t connHandle) +{ + uint8_t i; + + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle == connHandle) + { + return Util_convertBdAddr2Str(connList[i].addr); + } + } + + return NULL; +} +#endif + +/********************************************************************* + * @fn tree_structure_network_clearConnListEntry + * + * @brief clear device list by connHandle + * + * @return SUCCESS if connHandle found valid index or bleInvalidRange + * if index wasn't found. LINKDB_CONNHANDLE_ALL will always succeed. + */ +static uint8_t tree_structure_network_clearConnListEntry(uint16_t connHandle) +{ + uint8_t i; + // Set to invalid connection index initially + uint8_t connIndex = MAX_NUM_BLE_CONNS; + + if(connHandle != LINKDB_CONNHANDLE_ALL) + { + connIndex = tree_structure_network_getConnIndex(connHandle); + // Get connection index from handle + if(connIndex >= MAX_NUM_BLE_CONNS) + { + return bleInvalidRange; + } + } + + // Clear specific handle or all handles + for(i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if((connIndex == i) || (connHandle == LINKDB_CONNHANDLE_ALL)) + { + connList[i].connHandle = LINKDB_CONNHANDLE_INVALID; + connList[i].charHandle = 0; + connList[i].discState = 0; + } + } + + return SUCCESS; +} + + +/************************************************************************ +* @fn tree_structure_network_pairStateCB +* +* @param connHandle - the connection handle +* +* @param state - pairing state +* +* @param status - status of pairing state +* +* @return none +*/ +static void tree_structure_network_pairStateCB(uint16_t connHandle, uint8_t state, + uint8_t status) +{ + tsnPairStateData_t *pData = ICall_malloc(sizeof(tsnPairStateData_t)); + + // Allocate space for the event data. + if (pData) + { + pData->state = state; + pData->connHandle = connHandle; + pData->status = status; + + // Queue the event. + if (tree_structure_network_enqueueMsg(TSN_EVT_PAIRING_STATE, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/********************************************************************* +* @fn tree_structure_network_passcodeCB +* +* @brief Passcode callback. +* +* @param deviceAddr - pointer to device address +* +* @param connHandle - the connection handle +* +* @param uiInputs - pairing User Interface Inputs +* +* @param uiOutputs - pairing User Interface Outputs +* +* @param numComparison - numeric Comparison 20 bits +* +* @return none +*/ +static void tree_structure_network_passcodeCB(uint8_t *deviceAddr, uint16_t connHandle, + uint8_t uiInputs, uint8_t uiOutputs, + uint32_t numComparison) +{ + tsnPasscodeData_t *pData = ICall_malloc(sizeof(tsnPasscodeData_t)); + + // Allocate space for the passcode event. + if (pData) + { + pData->connHandle = connHandle; + memcpy(pData->deviceAddr, deviceAddr, B_ADDR_LEN); + pData->uiInputs = uiInputs; + pData->uiOutputs = uiOutputs; + pData->numComparison = numComparison; + + // Enqueue the event. + if (tree_structure_network_enqueueMsg(TSN_EVT_PASSCODE_NEEDED, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/********************************************************************* +* @fn tree_structure_network_processPairState +* +* @brief Process the new paring state. +* +* @param pairingEvent - pairing event received from the stack +* +* @return none +*/ +static void tree_structure_network_processPairState(tsnPairStateData_t *pPairData) +{ + uint8_t state = pPairData->state; + uint8_t status = pPairData->status; + + switch (state) + { + case GAPBOND_PAIRING_STATE_STARTED: + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Pairing started"); + break; + + case GAPBOND_PAIRING_STATE_COMPLETE: + if (status == SUCCESS) + { + linkDBInfo_t linkInfo; + + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Pairing success"); + + if (linkDB_GetInfo(pPairData->connHandle, &linkInfo) == SUCCESS) + { + // If the peer was using private address, update with ID address + if ((linkInfo.addrType == ADDRTYPE_PUBLIC_ID || + linkInfo.addrType == ADDRTYPE_RANDOM_ID) && + !Util_isBufSet(linkInfo.addrPriv, 0, B_ADDR_LEN)) + + { + // Update the address of the peer to the ID address + Display_printf(dispHandle, TSN_ROW_NON_CONN, 0, "Addr updated: %s", + Util_convertBdAddr2Str(linkInfo.addr)); + + // Update the connection list with the ID address + uint8_t i = tree_structure_network_getConnIndex(pPairData->connHandle); + + TREESTRUCTURENETWORK_ASSERT(i < MAX_NUM_BLE_CONNS); + memcpy(connList[i].addr, linkInfo.addr, B_ADDR_LEN); + } + } + } + else + { + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Pairing fail: %d", status); + } + break; + + case GAPBOND_PAIRING_STATE_ENCRYPTED: + if (status == SUCCESS) + { + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Encryption success"); + } + else + { + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Encryption failed: %d", status); + } + break; + + case GAPBOND_PAIRING_STATE_BOND_SAVED: + if (status == SUCCESS) + { + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Bond save success"); + } + else + { + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Bond save failed: %d", status); + } + + break; + + default: + break; + } +} + +/********************************************************************* +* @fn tree_structure_network_processPasscode +* +* @brief Process the Passcode request. +* +* @return none +*/ +static void tree_structure_network_processPasscode(tsnPasscodeData_t *pData) +{ + // Display passcode to user + if (pData->uiOutputs != 0) + { + Display_printf(dispHandle, TSN_ROW_SECURITY, 0, "Passcode: %d", + B_APP_DEFAULT_PASSCODE); + } + + // Send passcode response + GAPBondMgr_PasscodeRsp(pData->connHandle, SUCCESS, + B_APP_DEFAULT_PASSCODE); +} + +/********************************************************************* + * @fn tree_structure_network_startSvcDiscovery + * + * @brief Start service discovery. + * + * @return none + */ +static void tree_structure_network_startSvcDiscovery() +{ + uint8_t connIndex = tree_structure_network_getConnIndex(tsnConnHandle); + + // connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNS + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + attExchangeMTUReq_t req; + + // Initialize cached handles + svcStartHdl = svcEndHdl = 0; + + connList[connIndex].discState = BLE_DISC_STATE_MTU; + + // Discover GATT Server's Rx MTU size + req.clientRxMTU = tsnMaxPduSize - L2CAP_HDR_SIZE; + + // ATT MTU size should be set to the minimum of the Client Rx MTU + // and Server Rx MTU values + VOID GATT_ExchangeMTU(tsnConnHandle, &req, selfEntity); +} + +/********************************************************************* +* @fn tree_structure_network_addConnInfo +* +* @brief add a new connection to the index-to-connHandle map +* +* @param connHandle - the connection handle +* +* @param addr - pointer to device address +* +* @return index of connection handle +*/ +static uint8_t tree_structure_network_addConnInfo(uint16_t connHandle, uint8_t *pAddr, + uint8_t role) +{ + uint8_t i; + tsnClockEventData_t *paramUpdateEventData; + + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle == LINKDB_CONNHANDLE_INVALID) + { + // Found available entry to put a new connection info in + connList[i].connHandle = connHandle; + memcpy(connList[i].addr, pAddr, B_ADDR_LEN); + numConn++; + + // If a peripheral, start the clock to send a connection parameter update + if(role == GAP_PROFILE_PERIPHERAL) + { + // Allocate data to send through clock handler + paramUpdateEventData = ICall_malloc(sizeof(tsnClockEventData_t) + + sizeof(uint16_t)); + if(paramUpdateEventData) + { + // Set clock data + paramUpdateEventData->event = TSN_EVT_SEND_PARAM_UPDATE; + *((uint16_t *)paramUpdateEventData->data) = connHandle; + + // Create a clock object and start + connList[i].pUpdateClock + = (Clock_Struct*) ICall_malloc(sizeof(Clock_Struct)); + + if (connList[i].pUpdateClock) + { + Util_constructClock(connList[i].pUpdateClock, + tree_structure_network_clockHandler, + TSN_SEND_PARAM_UPDATE_DELAY, 0, true, + (UArg) paramUpdateEventData); + } + } + else + { + // Memory allocation failed + TREESTRUCTURENETWORK_ASSERT(false); + } + } + + break; + } + } + + return i; +} + +/********************************************************************* + * @fn tree_structure_network_removeConnInfo + * + * @brief Remove a device from the connected device list + * + * @return index of the connected device list entry where the new connection + * info is removed from. + * if connHandle is not found, MAX_NUM_BLE_CONNS will be returned. + */ +static uint8_t tree_structure_network_removeConnInfo(uint16_t connHandle) +{ + uint8_t connIndex = tree_structure_network_getConnIndex(connHandle); + + if(connIndex < MAX_NUM_BLE_CONNS) + { + Clock_Struct* pUpdateClock = connList[connIndex].pUpdateClock; + + if (pUpdateClock != NULL) + { + // Stop and destruct the RTOS clock if it's still alive + if (Util_isActive(pUpdateClock)) + { + Util_stopClock(pUpdateClock); + } + + // Destruct the clock object + Clock_destruct(pUpdateClock); + // Free clock struct + ICall_free(pUpdateClock); + } + // Clear Connection List Entry + tree_structure_network_clearConnListEntry(connHandle); + numConn--; + } + + return connIndex; +} + +/********************************************************************* +* @fn tree_structure_network_doDiscoverDevices +* +* @brief Respond to user input to start scanning +* +* @param index - not used +* +* @return TRUE since there is no callback to use this value +*/ +bool tree_structure_network_doDiscoverDevices(uint8_t index) +{ + (void) index; + +#if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) + // Scanning for DEFAULT_SCAN_DURATION x 10 ms. + // The stack does not need to record advertising reports + // since the application will filter them by Service UUID and save. + + // Reset number of scan results to 0 before starting scan + numScanRes = 0; + GapScan_enable(0, DEFAULT_SCAN_DURATION, 0); +#else // !DEFAULT_DEV_DISC_BY_SVC_UUID + // Scanning for DEFAULT_SCAN_DURATION x 10 ms. + // Let the stack record the advertising reports as many as up to DEFAULT_MAX_SCAN_RES. + GapScan_enable(0, DEFAULT_SCAN_DURATION, DEFAULT_MAX_SCAN_RES); +#endif // DEFAULT_DEV_DISC_BY_SVC_UUID + + + return (true); +} + +/********************************************************************* + * @fn tree_structure_network_doStopDiscovering + * + * @brief Stop on-going scanning + * + * @param index - item index from the menu + * + * @return always true + */ +bool tree_structure_network_doStopDiscovering(uint8_t index) +{ + (void) index; + + GapScan_disable(); + + return (true); +} + +/********************************************************************* + * @fn tree_structure_network_doCancelConnecting + * + * @brief Cancel on-going connection attempt + * + * @param index - item index from the menu + * + * @return always true + */ +bool tree_structure_network_doCancelConnecting(uint8_t index) +{ + (void) index; + + GapInit_cancelConnect(); + + return (true); +} + +/********************************************************************* +* @fn tree_structure_network_doConnect +* +* @brief Respond to user input to form a connection +* +* @param index - index as selected from the tsnMenuConnect +* +* @return TRUE since there is no callback to use this value +*/ +bool tree_structure_network_doConnect(uint8_t index) +{ + // Set the phy parameters + GapInit_setPhyParam(INIT_PHY_1M, INIT_PHYPARAM_CONN_INT_MIN, 160); + GapInit_setPhyParam(INIT_PHY_1M, INIT_PHYPARAM_CONN_INT_MAX, 160); + GapInit_setPhyParam(INIT_PHY_1M, INIT_PHYPARAM_CONN_LATENCY, 5); + GapInit_setPhyParam(INIT_PHY_1M, INIT_PHYPARAM_SUP_TIMEOUT, 1000); + + // Temporarily disable advertising + GapAdv_disable(advHandle); + +#if (DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE) + GapInit_connect(scanList[index].addrType & MASK_ADDRTYPE_ID, + scanList[index].addr, tsnInitPhy, 0); +#else // !DEFAULT_DEV_DISC_BY_SVC_UUID + GapScan_Evt_AdvRpt_t advRpt; + + GapScan_getAdvReport(index, &advRpt); + + GapInit_connect(advRpt.addrType & MASK_ADDRTYPE_ID, + advRpt.addr, tsnInitPhy, 0); +#endif // DEFAULT_DEV_DISC_BY_SVC_UUID + + Display_printf(dispHandle, TSN_ROW_NON_CONN, 0, "Connecting..."); + + return (true); +} + +/********************************************************************* + * @fn tree_structure_network_doSelectConn + * + * @brief Select a connection to communicate with + * + * @param index - item index from the menu + * + * @return always true + */ +bool tree_structure_network_doSelectConn(uint8_t index) +{ + // index cannot be equal to or greater than MAX_NUM_BLE_CONNS + TREESTRUCTURENETWORK_ASSERT(index < MAX_NUM_BLE_CONNS); + + tsnConnHandle = connList[index].connHandle; + + if (connList[index].charHandle == 0) + { + // Initiate service discovery + tree_structure_network_enqueueMsg(TSN_EVT_SVC_DISC, NULL); + } + + // Clear non-connection-related message + Display_clearLine(dispHandle, TSN_ROW_NON_CONN); + + return (true); +} + +/********************************************************************* + * @fn tree_structure_network_doGattRead + * + * @brief GATT Read + * + * @param index - item index from the menu + * + * @return always true + */ +bool tree_structure_network_doGattRead(uint8_t index) +{ + attReadReq_t req; + uint8_t connIndex = tree_structure_network_getConnIndex(tsnConnHandle); + + // connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNS + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + req.handle = connList[connIndex].charHandle; + GATT_ReadCharValue(tsnConnHandle, &req, selfEntity); + + return (true); +} + +/********************************************************************* + * @fn tree_structure_network_doGattWriteString + * + * @brief GATT Write + * + * @param internal_tsnConnHandle - Connection Handle to Write + * pAddr - GATT Writing String address + * + * @return always true + */ +bool tree_structure_network_doGattWriteString(uint8_t internal_tsnConnHandle, uint8_t *pAddr) +{ + status_t status; + + attWriteReq_t req; + + req.pValue = GATT_bm_alloc(internal_tsnConnHandle, ATT_WRITE_REQ, TREENETWORKSERVICE_CHAR1_LEN, NULL); + + if ( req.pValue != NULL ) + { + uint8_t connIndex = tree_structure_network_getConnIndex(internal_tsnConnHandle); + + // connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNS + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + req.handle = connList[connIndex].charHandle; + req.len = TREENETWORKSERVICE_CHAR1_LEN; + memcpy(req.pValue, pAddr, TREENETWORKSERVICE_CHAR1_LEN); + req.sig = 0; + req.cmd = 0; + + if (pAddr[0] == 'L'); // LED Command for link establishment (no action) + else if (pAddr[2] == '0') + { + // LED command for father + if (pAddr[3] == '0') + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Father %c 's RLED off", pAddr[1], pAddr[3]); + } + else + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Father %c 's RLED on", pAddr[1], pAddr[3]); + } + } + else + { + // LED command for child + if (pAddr[3] == '0') + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Father %c 's child %c 's RLED off", pAddr[1], pAddr[2], pAddr[3]); + else + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Father %c 's child %c 's RLED on", pAddr[1], pAddr[2], pAddr[3]); + } + + status = GATT_WriteCharValue(internal_tsnConnHandle, &req, selfEntity); + if ( status != SUCCESS ) + { + GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ); + } + } + + return (true); +} + +/********************************************************************* + * @fn tree_structure_network_doGattWriteEnableNotification + * + * @brief GATT Writing to enable notification + * + * @param Null + * + * @return always true + */ +bool tree_structure_network_doGattWriteEnableNotification() +{ + status_t status; + + attWriteReq_t req; + + req.pValue = GATT_bm_alloc(tsnConnHandle, ATT_WRITE_REQ, 2, NULL); + + if ( req.pValue != NULL ) + { + uint8_t connIndex = tree_structure_network_getConnIndex(tsnConnHandle); + + // connIndex cannot be equal to or greater than MAX_NUM_BLE_CONNS + TREESTRUCTURENETWORK_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + req.handle = connList[connIndex].charHandle + 1; + req.len = 2; + req.pValue[0] = 0x01; + req.pValue[1] = 0x00; + req.sig = 0; + req.cmd = 0; + + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Enable notification\n"); + + // Enable the notification function + status = GATT_WriteCharValue(tsnConnHandle, &req, selfEntity); + if ( status != SUCCESS ) + { + GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ); + } + } + + return (true); +} + +/********************************************************************* +* @fn tree_structure_network_doConnUpdate +* +* @brief Respond to user input to do a connection update +* +* @param index - index as selected from the tsnMenuConnUpdate +* +* @return TRUE since there is no callback to use this value +*/ +bool tree_structure_network_doConnUpdate(uint8_t index) +{ + gapUpdateLinkParamReq_t params; + + (void) index; //may need to get the real connHandle? + + params.connectionHandle = tsnConnHandle; + params.intervalMin = DEFAULT_UPDATE_MIN_CONN_INTERVAL; + params.intervalMax = DEFAULT_UPDATE_MAX_CONN_INTERVAL; + params.connLatency = DEFAULT_UPDATE_SLAVE_LATENCY; + + linkDBInfo_t linkInfo; + if (linkDB_GetInfo(tsnConnHandle, &linkInfo) == SUCCESS) + { + if (linkInfo.connTimeout == DEFAULT_UPDATE_CONN_TIMEOUT) + { + params.connTimeout = DEFAULT_UPDATE_CONN_TIMEOUT + 200; + } + else + { + params.connTimeout = DEFAULT_UPDATE_CONN_TIMEOUT; + } + } + else + { + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, + "update :%s, Unable to find link information", + Util_convertBdAddr2Str(linkInfo.addr)); + } + GAP_UpdateLinkParamReq(¶ms); + + Display_printf(dispHandle, TSN_ROW_CUR_CONN, 0, "Param update Request:connTimeout =%d", + params.connTimeout*CONN_TIMEOUT_MS_CONVERSION); + + return (true); +} + +/********************************************************************* +* @fn multi_role_doDisconnect +* +* @brief Respond to user input to terminate a connection +* +* @param index - index as selected from the tsnMenuConnUpdate +* +* @return always true +*/ +bool tree_structure_network_doDisconnect(uint8_t index) +{ + (void) index; + + // Disconnect + GAP_TerminateLinkReq(tsnConnHandle, HCI_DISCONNECT_REMOTE_USER_TERM); + + return (true); +} + +/********************************************************************* +* @fn tree_structure_network_doAdvertise +* +* @brief Respond to user input to terminate a connection +* +* @param index - index as selected from the tsnMenuConnUpdate +* +* @return always true +*/ +bool tree_structure_network_doAdvertise(uint8_t index) +{ + (void) index; + + // If we're currently advertising + if (tsnIsAdvertising) + { + // Turn off advertising + GapAdv_disable(advHandle); + } + // If we're not currently advertising + else + { + if (numConn < MAX_NUM_BLE_CONNS) + { + // Start advertising since there is room for more connections + GapAdv_enable(advHandle, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + } + else + { + Display_printf(dispHandle, TSN_ROW_ADVERTIS, 0, + "At Maximum Connection Limit, Cannot Enable Advertisment"); + } + } + + return (true); +} + +/********************************************************************* +*********************************************************************/ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/tree_structure_network.h b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/tree_structure_network.h new file mode 100644 index 0000000..81a78d3 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/app/tree_structure_network.h @@ -0,0 +1,134 @@ +/****************************************************************************** + * @file tree_structure_network.h + * + * @description Definitions and prototypes for the tree_structure_network example + * + * + Copyright (c) 2013-2019, 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. + * + *****************************************************************************/ + +#ifndef TREENETWORK_H +#define TREENETWORK_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + * INCLUDES + */ + +/********************************************************************* +* EXTERNAL VARIABLES +*/ + +/********************************************************************* + * CONSTANTS + */ + +// Maximum number of scan responses. +// Note: this value cannot be greater than the number of items reserved in +// tsnMenuConnect (See tree_structure_network_menu.c) +// This cannot exceed 27 (two-button menu's constraint) +#define DEFAULT_MAX_SCAN_RES 15 + +// advertising PHY menu items +#define TSN_ADV_LEGACY_PHY_1_MBPS 0 +#define TSN_ADV_EXT_PHY_1_MBPS 1 +#define TSN_ADV_EXT_PHY_CODED 2 + +/********************************************************************* + * MACROS + */ + +/********************************************************************* + * FUNCTIONS + */ +/* + * Task creation function for the Simple Peripheral. + */ +extern void tree_structure_network_createTask(void); + +/* Action for Menu: Enable Scanning */ +bool tree_structure_network_doDiscoverDevices(uint8_t index); + +/* Action for Menu: Disable Scanning */ +bool tree_structure_network_doStopDiscovering(uint8_t index); + +/* Actions for Menu: Init - Connect */ +bool tree_structure_network_doConnect(uint8 index); + +/* Action for Menu: Cancel Connecting */ +bool tree_structure_network_doCancelConnecting(uint8_t index); + +/* Action for Menu: Select Connection */ +bool tree_structure_network_doSelectConn(uint8_t index); + +bool tree_structure_network_doAdvertise(uint8_t index); + +/* Action for Menu: GATT Read */ +bool tree_structure_network_doGattRead(uint8_t index); + +/* Action for Menu: GATT Write */ +bool tree_structure_network_doGattWrite(uint8_t index); + +/* Actions for Menu: Init - Conn Update */ +bool tree_structure_network_doConnUpdate(uint8_t index); + +/* Actions for Menu: Init - Disconnect */ +bool tree_structure_network_doDisconnect(uint8 index); + +/* Actions for Menu: Init - Advertise */ +bool tsn_doAdvertise(uint8 index); + +/* Action for Menu: Set Scanning PHY */ +bool tree_structure_network_doSetScanPhy(uint8_t index); + +/* Action for Menu: Set Advertising PHY */ +bool tree_structure_network_doSetAdvPhy(uint8_t index); + +/* Action for Menu: Set Initialize PHY */ +bool tree_structure_network_doSetInitPhy(uint8_t index); + +/* Action for Menu: Set Connection PHY */ +bool tree_structure_network_doConnPhy(uint8_t index); + + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* TREENETWORK_H */ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/ccfg_app_ble.c b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/ccfg_app_ble.c new file mode 100644 index 0000000..cc3d144 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/ccfg_app_ble.c @@ -0,0 +1,74 @@ +/****************************************************************************** + + @file ccfg_app_ble.c + + @brief Customer Configuration CC26xx PG2 device family. + + Group: CMCU, LPRF + Target Device: CC2652 + + ****************************************************************************** + + Copyright (c) 2014-2018, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + Release Name: simplelink_cc26x2_sdk_2_30_00_34 + Release Date: 2018-10-04 14:27:27 + *****************************************************************************/ + +// +// ===> READ THIS BEFORE MODIFYING THIS FILE +// +// +// ===> READ THIS BEFORE MODIFYING THIS FILE +// +// +// ===> READ THIS BEFORE MODIFYING THIS FILE +// + +// The customer configuration area (ccfg section) is located at the end of the +// flash and reflect the hw configuration of the device. it is very important +// that it remains align with the version of driverlib you are using. +// all BLE project except sensor tag use the same configuration. +// Keeping the "#include " guarantee that your project using +// driverlib and the ccfg area will be align. + +// you can modify it if you want, the recommend way will be to remove the +// bellow include, copy the content of the file in this +// file and rebuild. + +// ==> KEEP IN MIND that if you do so, be sure that any further update of the +// driverlib must be align with your modified version of ccfg area. +#ifdef CACHE_AS_RAM +#define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM 0x0 /* Enable GPRAM */ +#endif //CACHE_AS_RAM +#include + diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/stack/osal_icall_ble.c b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/stack/osal_icall_ble.c new file mode 100644 index 0000000..ab00686 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/src/stack/osal_icall_ble.c @@ -0,0 +1,269 @@ +/****************************************************************************** + + @file osal_icall_ble.c + + @brief This file contains function that allows user setup tasks + + Group: CMCU, LPRF + Target Device: CC2652 + + ****************************************************************************** + + Copyright (c) 2013-2018, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + Release Name: simplelink_cc26x2_sdk_2_30_00_34 + Release Date: 2018-10-04 14:27:27 + *****************************************************************************/ + +/************************************************************************************************** + * INCLUDES + **************************************************************************************************/ +#include +#include "hal_types.h" +#include "hal_mcu.h" +#include "osal.h" +#include "osal_tasks.h" +#include "osal_snv.h" + + +/* LL */ +#include "ll.h" + +#if defined ( OSAL_CBTIMER_NUM_TASKS ) + #include "osal_cbtimer.h" +#endif + +/* L2CAP */ +#include "l2cap.h" + +/* gap */ +#include "gap.h" + +#if defined ( GAP_BOND_MGR ) + #include "gapbondmgr_internal.h" +#endif + +/* GATT */ +#include "gatt.h" + +/* Application */ +#include "hci_tl.h" + +#include "gattservapp.h" + +#include "gapbondmgr.h" + +#include "ble_user_config.h" +#include "ble_dispatch.h" + + +#ifdef USE_ICALL + +#ifdef ICALL_JT +#include "icall_jt.h" +#endif /* ICALL_JT */ + +#ifdef ICALL_LITE +#include "icall_lite_translation.h" +#include "ble_dispatch_lite.h" +#endif /* ICALL_LITE */ + +#endif /* USE_ICALL */ + +/********************************************************************* + * GLOBAL VARIABLES + */ + +// The order in this table must be identical to the task initialization calls below in osalInitTask. +const pTaskEventHandlerFn tasksArr[] = +{ + LL_ProcessEvent, // task 0 + HCI_ProcessEvent, // task 1 +#if defined ( OSAL_CBTIMER_NUM_TASKS ) + OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), // task 2 +#endif + L2CAP_ProcessEvent, // task 3 + GAP_ProcessEvent, // task 4 + SM_ProcessEvent, // task 5 + GATT_ProcessEvent, // task 6 + GATTServApp_ProcessEvent, // task 7 +#if defined ( GAP_BOND_MGR ) + GAPBondMgr_ProcessEvent, // task 8 +#endif +#ifdef ICALL_LITE + ble_dispatch_liteProcess, // task 9 +#else + bleDispatch_ProcessEvent // task 9 +#endif /* ICALL_LITE */ +}; + +const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] ); +uint16 *tasksEvents; + +/********************************************************************* + * FUNCTIONS + *********************************************************************/ + +/********************************************************************* + * @fn osalInitTasks + * + * @brief This function invokes the initialization function for each task. + * + * @param void + * + * @return none + */ +void osalInitTasks( void ) +{ + ICall_EntityID entity; + ICall_SyncHandle syncHandle; + uint8 taskID = 0; + uint8 i; + + tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); + osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt)); + + /* LL Task */ + LL_Init( taskID++ ); + + /* HCI Task */ + HCI_Init( taskID++ ); + +#if defined ( OSAL_CBTIMER_NUM_TASKS ) + /* Callback Timer Tasks */ + osal_CbTimerInit( taskID ); + taskID += OSAL_CBTIMER_NUM_TASKS; +#endif + + /* L2CAP Task */ + L2CAP_Init( taskID++ ); + + /* GAP Task */ + GAP_Init( taskID++ ); + + /* SM Task */ + SM_Init( taskID++ ); + + /* GATT Task */ + GATT_Init( taskID++ ); + + /* GATT Server App Task */ + GATTServApp_Init( taskID++ ); + +#if defined ( GAP_BOND_MGR ) + /* Bond Manager Task */ + GAPBondMgr_Init( taskID++ ); +#endif + +#ifdef ICALL_LITE + ble_dispatch_liteInit(taskID++); +#else + /* ICall BLE Dispatcher Task */ + bleDispatch_Init( taskID ); +#endif /* ICALL_LITE */ + + // ICall enrollment + /* Enroll the service that this stack represents */ + ICall_enrollService(ICALL_SERVICE_CLASS_BLE, NULL, &entity, &syncHandle); + +#ifndef ICALL_LITE + /* Enroll the obtained dispatcher entity and OSAL task ID of HCI Ext App + * to OSAL so that OSAL can route the dispatcher message into + * the appropriate OSAL task. + */ + osal_enroll_dispatchid(taskID, entity); +#endif /* ICALL_LITE */ + /* Register all other OSAL tasks to use the registered dispatcher entity + * ID as the source of dispatcher messages, even though the other OSAL + * tasks didn't register themselves to receive messages from application. + */ + for (i = 0; i < taskID; i++) + { + osal_enroll_senderid(i, entity); + } +} + +/** + * Main entry function for the stack image + */ +int stack_main( void *arg ) +{ + /* User reconfiguration of BLE Controller and Host variables */ +#ifdef ICALL_JT + setBleUserConfig( (icall_userCfg_t *)arg ); +#else /* !(ICALL_JT) */ + setBleUserConfig( (bleUserCfg_t *)arg ); +#endif /* ICALL_JT */ + + /* Establish OSAL for a stack service that requires accompanying + * messaging service */ + if (ICall_enrollService(ICALL_SERVICE_CLASS_BLE_MSG, + (ICall_ServiceFunc) osal_service_entry, + &osal_entity, + &osal_syncHandle) != ICALL_ERRNO_SUCCESS) + { + /* abort */ + ICall_abort(); + } + + // Disable interrupts + halIntState_t state; + HAL_ENTER_CRITICAL_SECTION(state); + +#if defined(ICALL_LITE) && (!defined(STACK_LIBRARY)) + { + icall_liteTranslationInit((uint32_t*)bleAPItable); + } +#endif /* ICALL_LITE */ + +#ifdef ICALL_LITE + { + osal_set_icall_hook(icall_liteMsgParser); + } +#endif /* ICALL_LITE */ + + // Initialize NV System + osal_snv_init( ); + + // Initialize the operating system + osal_init_system(); + + // Allow interrupts + HAL_EXIT_CRITICAL_SECTION(state); + + osal_start_system(); // No Return from here + + return 0; // Shouldn't get here. +} + +/********************************************************************* +*********************************************************************/ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ble_debug.cfg b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ble_debug.cfg new file mode 100644 index 0000000..865dab7 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ble_debug.cfg @@ -0,0 +1,754 @@ +/****************************************************************************** + + @file ble_debug.cfg + + @brief TI RTOS (in Flash debug) Configuration file for BLE5-Stack + + Group: CMCU, LPRF + Target Device: CC2652 + + ****************************************************************************** + + Copyright (c) 2017-2018, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + Release Name: simplelink_cc26x2_sdk_2_30_00_34 + Release Date: 2018-10-04 14:27:27 + *****************************************************************************/ + + + +/* ================ Boot configuration ================ */ +/* + * This module contains family specific Boot APIs and configuration settings. + * See the SYS/BIOS API guide for more information. + */ +var Boot = xdc.useModule('ti.sysbios.family.arm.cc26xx.Boot'); + + + +/* ================ Clock configuration ================ */ +var Clock = xdc.useModule('ti.sysbios.knl.Clock'); +/* + * When using Power and calibrateRCOSC is set to true, this should be set to 10. + * The timer used by the Clock module supports TickMode_DYNAMIC. This enables us + * to set the tick period to 10 us without generating the overhead of additional + * interrupts. + * + * Note: The calibrateRCOSC parameter is set within the Power configuration + * structure in the "Board.c" file. + */ +Clock.tickPeriod = 10; +Clock.swiPriority = 5; + + +/* ================ Types configuration ================ */ +var Types = xdc.useModule('xdc.runtime.Types'); +/* + * This module defines basic constants and types used throughout the + * xdc.runtime package. + */ + + + +/* ================ Defaults (module) configuration ================ */ +var Defaults = xdc.useModule('xdc.runtime.Defaults'); +/* + * A flag to allow module names to be loaded on the target. Module name + * strings are placed in the .const section for debugging purposes. + * + * Pick one: + * - true (default) + * Setting this parameter to true will include name strings in the .const + * section so that Errors and Asserts are easier to debug. + * - false + * Setting this parameter to false will reduce footprint in the .const + * section. As a result, Error and Assert messages will contain an + * "unknown module" prefix instead of the actual module name. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +Defaults.common$.namedModule = true; +//Defaults.common$.namedModule = false; + +/* Compile out all Assert's */ +//Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF; + +/* Allow Mod_create() and Mod_construct() but not delete() or destruct() */ +Defaults.common$.memoryPolicy = Types.DELETE_POLICY; + + + +/* ================ Error configuration ================ */ +var Error = xdc.useModule('xdc.runtime.Error'); +/* + * This function is called to handle all raised errors, but unlike + * Error.raiseHook, this function is responsible for completely handling the + * error with an appropriately initialized Error_Block. + * + * Pick one: + * - Error.policyDefault (default) + * Calls Error.raiseHook with an initialized Error_Block structure and logs + * the error using the module's logger. + * - Error.policySpin + * Simple alternative that traps on a while(1) loop for minimized target + * footprint. + * Using Error.policySpin, the Error.raiseHook will NOT called. + */ +Error.policyFxn = Error.policyDefault; +//Error.policyFxn = Error.policySpin; + +/* + * If Error.policyFxn is set to Error.policyDefault, this function is called + * whenever an error is raised by the Error module. + * + * Pick one: + * - Error.print (default) + * Errors are formatted and output via System_printf() for easier + * debugging. + * - null + * Errors are trapped with a while(1) stub function. This option reduces + * code footprint. + * - non-null function + * Errors invoke custom user function. See the Error module documentation + * for more details. + */ +Error.raiseHook = Error.print; +//Error.raiseHook = null; +//Error.raiseHook = "&myErrorFxn"; + +/* + * If Error.policyFxn is set to Error.policyDefault, this option applies to the + * maximum number of times the Error.raiseHook function can be recursively + * invoked. This option limits the possibility of an infinite recursion that + * could lead to a stack overflow. + * The default value is 16. + */ +Error.maxDepth = 2; + + + +/* ================ Hwi configuration ================ */ +var halHwi = xdc.useModule('ti.sysbios.hal.Hwi'); +var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi'); +/* + * Checks for Hwi (system) stack overruns while in the Idle loop. + * + * Pick one: + * - true (default) + * Checks the top word for system stack overflows during the idle loop and + * raises an Error if one is detected. + * - false + * Disabling the runtime check improves runtime performance and yields a + * reduced flash footprint. + */ +halHwi.checkStackFlag = true; +//halHwi.checkStackFlag = false; + +/* + * The following options alter the system's behavior when a hardware exception + * is detected. + * + * Pick one: + * - Hwi.enableException = true + * This option causes the default m3Hwi.excHandlerFunc function to fully + * decode an exception and dump the registers to the system console. + * This option raises errors in the Error module and displays the + * exception in ROV. + * - Hwi.enableException = false + * This option reduces code footprint by not decoding or printing the + * exception to the system console. + * It however still raises errors in the Error module and displays the + * exception in ROV. + * - Hwi.excHandlerFunc = null + * This is the most aggressive option for code footprint savings; but it + * can difficult to debug exceptions. It reduces flash footprint by + * plugging in a default while(1) trap when exception occur. This option + * does not raise an error with the Error module. + */ +m3Hwi.enableException = true; +//m3Hwi.enableException = false; +//m3Hwi.excHandlerFunc = null; + +/* + * Enable hardware exception generation when dividing by zero. + * + * Pick one: + * - 0 (default) + * Disables hardware exceptions when dividing by zero + * - 1 + * Enables hardware exceptions when dividing by zero + */ +m3Hwi.nvicCCR.DIV_0_TRP = 0; +//m3Hwi.nvicCCR.DIV_0_TRP = 1; + +/* + * Enable hardware exception generation for invalid data alignment. + * + * Pick one: + * - 0 (default) + * Disables hardware exceptions for data alignment + * - 1 + * Enables hardware exceptions for data alignment + */ +m3Hwi.nvicCCR.UNALIGN_TRP = 0; +//m3Hwi.nvicCCR.UNALIGN_TRP = 1; + +/* Put reset vector at start of Flash */ +m3Hwi.resetVectorAddress = 0x0; + +/* Put interrupt vector at start of RAM so interrupts can be configured at runtime */ +m3Hwi.vectorTableAddress = 0x20000000; + + + +/* ================ Idle configuration ================ */ +var Idle = xdc.useModule('ti.sysbios.knl.Idle'); +/* + * The Idle module is used to specify a list of functions to be called when no + * other tasks are running in the system. + * + * Functions added here will be run continuously within the idle task. + * + * Function signature: + * Void func(Void); + */ +//Idle.addFunc("&myIdleFunc"); +/* Allow power management */ +Idle.addFunc('&Power_idleFunc'); + + + +/* ================ Kernel (SYS/BIOS) configuration ================ */ +var BIOS = xdc.useModule('ti.sysbios.BIOS'); +/* + * Enable asserts in the BIOS library. + * + * Pick one: + * - true (default) + * Enables asserts for debugging purposes. + * - false + * Disables asserts for a reduced code footprint and better performance. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +BIOS.assertsEnabled = true; +//BIOS.assertsEnabled = false; + +/* + * A flag to determine if xdc.runtime sources are to be included in a custom + * built BIOS library. + * + * Pick one: + * - false (default) + * The pre-built xdc.runtime library is provided by the respective target + * used to build the application. + * - true + * xdc.runtime library sources are to be included in the custom BIOS + * library. This option yields the most efficient library in both code + * footprint and runtime performance. + */ +//BIOS.includeXdcRuntime = false; +BIOS.includeXdcRuntime = true; + +/* + * The SYS/BIOS runtime is provided in the form of a library that is linked + * with the application. Several forms of this library are provided with the + * SYS/BIOS product. + * + * Pick one: + * - BIOS.LibType_Custom + * Custom built library that is highly optimized for code footprint and + * runtime performance. + * - BIOS.LibType_Debug + * Custom built library that is non-optimized that can be used to + * single-step through APIs with a debugger. + * + */ +BIOS.libType = BIOS.LibType_Custom; +//BIOS.libType = BIOS.LibType_Debug; + +/* + * Runtime instance creation enable flag. + * + * Pick one: + * - true (default) + * Allows Mod_create() and Mod_delete() to be called at runtime which + * requires a default heap for dynamic memory allocation. + * - false + * Reduces code footprint by disallowing Mod_create() and Mod_delete() to + * be called at runtime. Object instances are constructed via + * Mod_construct() and destructed via Mod_destruct(). + * + * When using BIOS in ROM: + * This option must be set to true. + */ +BIOS.runtimeCreatesEnabled = true; +//BIOS.runtimeCreatesEnabled = false; + +/* + * Enable logs in the BIOS library. + * + * Pick one: + * - true (default) + * Enables logs for debugging purposes. + * - false + * Disables logging for reduced code footprint and improved runtime + * performance. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +BIOS.logsEnabled = true; +//BIOS.logsEnabled = false; + +BIOS.swiEnabled = true; + + + +/* ================ Program configuration ================ */ +/* + * Program.stack is ignored with IAR. Use the project options in + * IAR Embedded Workbench to alter the system stack size. + */ +Program.stack = 1024; +Program.argSize = 0; + + + +/* ================ Semaphore configuration ================ */ +var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore'); +/* + * Enables global support for Task priority pend queuing. + * + * Pick one: + * - true (default) + * This allows pending tasks to be serviced based on their task priority. + * - false + * Pending tasks are services based on first in, first out basis. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +//Semaphore.supportsPriority = true; +Semaphore.supportsPriority = false; + +/* + * Allows for the implicit posting of events through the semaphore, + * disable for additional code saving. + * + * Pick one: + * - true + * This allows the Semaphore module to post semaphores and events + * simultaneously. + * - false (default) + * Events must be explicitly posted to unblock tasks. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +//Semaphore.supportsEvents = true; +Semaphore.supportsEvents = false; + + + + +/* ================ Events configuration ================ */ +var Events = xdc.useModule('ti.sysbios.knl.Event'); + + + +/* ================ Swi configuration ================ */ +var Swi = xdc.useModule('ti.sysbios.knl.Swi'); +/* + * A software interrupt is an object that encapsulates a function to be + * executed and a priority. Software interrupts are prioritized, preempt tasks + * and are preempted by hardware interrupt service routines. + * + * This module is included to allow Swi's in a users' application. + */ +Swi.numPriorities = 6; + + + +/* ================ System configuration ================ */ +var System = xdc.useModule('xdc.runtime.System'); +/* + * The Abort handler is called when the system exits abnormally. + * + * Pick one: + * - System.abortStd (default) + * Call the ANSI C Standard 'abort()' to terminate the application. + * - System.abortSpin + * A lightweight abort function that loops indefinitely in a while(1) trap + * function. + * - A custom abort handler + * A user-defined function. See the System module documentation for + * details. + */ +System.abortFxn = System.abortStd; +//System.abortFxn = System.abortSpin; +//System.abortFxn = "&myAbortSystem"; + +/* + * The Exit handler is called when the system exits normally. + * + * Pick one: + * - System.exitStd (default) + * Call the ANSI C Standard 'exit()' to terminate the application. + * - System.exitSpin + * A lightweight exit function that loops indefinitely in a while(1) trap + * function. + * - A custom exit function + * A user-defined function. See the System module documentation for + * details. + */ +System.exitFxn = System.exitStd; +//System.exitFxn = System.exitSpin; +//System.exitFxn = "&myExitSystem"; + +/* + * Minimize exit handler array in the System module. The System module includes + * an array of functions that are registered with System_atexit() which is + * called by System_exit(). The default value is 8. + */ +System.maxAtexitHandlers = 0; + +/* + * The System.SupportProxy defines a low-level implementation of System + * functions such as System_printf(), System_flush(), etc. + * + * Pick one pair: + * - SysMin + * This module maintains an internal configurable circular buffer that + * stores the output until System_flush() is called. + * The size of the circular buffer is set via SysMin.bufSize. + * - SysCallback + * SysCallback allows for user-defined implementations for System APIs. + * The SysCallback support proxy has a smaller code footprint and can be + * used to supply custom System_printf services. + * The default SysCallback functions point to stub functions. See the + * SysCallback module's documentation. + */ +var SysMin = xdc.useModule('xdc.runtime.SysMin'); +SysMin.bufSize = 768; +System.SupportProxy = SysMin; +//var SysCallback = xdc.useModule('xdc.runtime.SysCallback'); +//System.SupportProxy = SysCallback; +//SysCallback.abortFxn = "&myUserAbort"; +//SysCallback.exitFxn = "&myUserExit"; +//SysCallback.flushFxn = "&myUserFlush"; +//SysCallback.putchFxn = "&myUserPutch"; +//SysCallback.readyFxn = "&myUserReady"; + + + +/* ================ Task configuration ================ */ +var Task = xdc.useModule('ti.sysbios.knl.Task'); +/* + * Check task stacks for overflow conditions. + * + * Pick one: + * - true (default) + * Enables runtime checks for task stack overflow conditions during + * context switching ("from" and "to") + * - false + * Disables runtime checks for task stack overflow conditions. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +Task.checkStackFlag = true; +//Task.checkStackFlag = false; + +/* + * Set the default task stack size when creating tasks. + * + * The default is dependent on the device being used. Reducing the default stack + * size yields greater memory savings. + */ +Task.defaultStackSize = 512; + +/* + * Enables the idle task. + * + * Pick one: + * - true (default) + * Creates a task with priority of 0 which calls idle hook functions. This + * option must be set to true to gain power savings provided by the Power + * module. + * - false + * No idle task is created. This option consumes less memory as no + * additional default task stack is needed. + * To gain power savings by the Power module without having the idle task, + * add Idle.run as the Task.allBlockedFunc. + */ +Task.enableIdleTask = true; +//Task.enableIdleTask = false; +//Task.allBlockedFunc = Idle.run; + +/* + * If Task.enableIdleTask is set to true, this option sets the idle task's + * stack size. + * + * Reducing the idle stack size yields greater memory savings. + */ +Task.idleTaskStackSize = 768; + +/* + * Reduce the number of task priorities. + * The default is 16. + * Decreasing the number of task priorities yield memory savings. + */ +Task.numPriorities = 6; + + + +/* ================ Text configuration ================ */ +var Text = xdc.useModule('xdc.runtime.Text'); +/* + * These strings are placed in the .const section. Setting this parameter to + * false will save space in the .const section. Error, Assert and Log messages + * will print raw ids and args instead of a formatted message. + * + * Pick one: + * - true (default) + * This option loads test string into the .const for easier debugging. + * - false + * This option reduces the .const footprint. + */ +Text.isLoaded = true; +//Text.isLoaded = false; + + + + +/* ================ Diagnostics configuration ================ */ +var Diags = xdc.useModule('xdc.runtime.Diags'); +/* + * You use the Diags module to set and clear bits in a module's diagnostics + * mask for the purpose of controlling diagnostics within that module. A + * module diagnostics mask controls both Assert and Log statements + * within that module, disabling these statements yields + * code savings. + */ + + + +/* ================ Logging configuration ================ */ +var Log = xdc.useModule('xdc.runtime.Log'); +/* + * Modules and the application code generate Log_Event events by calling + * the Log module's functions. + * Disabling all Log statements here will allow the optimizer to completely + * remove all Log code from the application. + * + * Note: In order to generate Log events in your application both the Diags + * and the Log mask must be set. See the SYS/BIOS API guide for + * more information. + */ + + +/* + * LoggingSetup configures TI-RTOS modules to capture user-specified information + * such as CPU Load, Task Load and Task Execution so that it can be + * displayed by System Analyzer. + * + * loadLogging: (default = true) If true, LoggingSetup will add the kernel's + * load module, which measure the CPU load. See the BIOS API + * documentation for usage details + */ +var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup'); +LoggingSetup.loadLogging = false; +//LoggingSetup.loadLoggerSize = 256; +LoggingSetup.mainLoggerSize = 512; +LoggingSetup.sysbiosLoggerSize = 2048; +LoggingSetup.sysbiosSwiLogging = false; +LoggingSetup.sysbiosHwiLogging = false; +LoggingSetup.sysbiosSemaphoreLogging = true; + + + +/* ================ Main configuration ================ */ +var Main = xdc.useModule('xdc.runtime.Main'); +/* Configuration of this Main module is used for all code not in a module */ + +var Reset = xdc.useModule('xdc.runtime.Reset'); + + + +/* + * Heap Configuration defines the type of Heap you want to use for the system (application + Stack) + * Only one Heap buffer will be allocated. This heap will be shared by the system and the stack through + * one manager (HeapMem, HeapMem+HeapTrack or OSAL) + * You can still decide to create several heaps if you want, but at least one heap needs to be created. + * The stack must have a Heap to run. + * The different Heap manager available are : + * OSAL HEAP: legacy Heap manager provided with all BLE sdk. By default, this Heap manager is used. + * HeapMem:  heap manager provided by TI-RTOS (see TI-RTOS user guide for properties) + * HeapTrack: module on top of HeapMem allowing an easy debugging of memory allocated through HeapMem. + * + * The heap manager to use is selected by setting HEAPMGR_CONFIG to the corresponding value (see below) + * 0 = osal Heap manager, size is static. + * 0x80 = osal Heap manager, with auto-size: The remainning RAM (not used by the system) will be fully assign to the Heap. + * 1 = HeapMem with Static size + * 0x81 = HeapMem with auto-size. The remainning RAM (not used by the system) will be fully assign to the Heap. + * 2 = HeapTrack (with HeapMem) with fixe size + * 0x82 = HeapTrack (with HeapMem) with auto-size: The remainning RAM (not used by the system) will be fully assign to the Heap. + * + * If HEAPMGR_CONFIG is not defined, but the configuration file ble_stack_heap.cfg is used, then the value + * HEAPMGR_CONFIG = 0x80 is assumed. + * If HEAPMGR_CONFIG is not defined, and the file ble_stack_heap.cfg is not used, then the value + * HEAPMGR_CONFIG = 0x80 is assumed and the default Heap size will be 3072 + * unless you define HEAPMGR_SIZE to a different value in the project option (0 meaning auto-size). + * + * From the configuration below, two #define will be created that will be used by the application to setup the Heap: + * #define HEAPMGR_SIZE + * #define HEAPMGR_CONFIG + * In order to use those define, this include line needs to be added: #include + * + * In order for the auto-size Heap to work, the following symbol needs to be created by the linker: + * heapStart + * heapEnd + */ + +/* + * DISCLAIMER: The HeapMem module in ROM can only use a GateMutex module. This means the malloc() + * function cannot be used in a Hwi/Swi. + * This means also that other access to the heap, with Icall_alloc for example, can potentially break the Heap... + * Therefore this solution is most effective when TI-RTOS is located in FLASH, so that a GateHwi can be used. + * If you try to use it in ROM, a workaround using HeapCallback is used, which will degrade performance. + */ +var Memory = xdc.useModule('xdc.runtime.Memory'); +var HEAPMGR_CONFIG = 0x02; +var HEAPMGR_SIZE = 30000; //only valid if static size is used. This is the size of the buffer allocated for Heap. + +if (typeof HEAPMGR_CONFIG === 'undefined' ) +{ + var HEAPMGR_CONFIG = 0x80; +} + +// The following will create the #define HEAPMGR_CONFIG. It can then be used by include +Program.global.HEAPMGR_CONFIG = HEAPMGR_CONFIG; + +if (HEAPMGR_CONFIG === 1 || HEAPMGR_CONFIG === 0x81) +{ + var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem'); + var heapMemParams = new HeapMem.Params(); + + if (HEAPMGR_CONFIG === 0x1) + { + heapMemParams.size = HEAPMGR_SIZE; + Program.global.HEAPMGR_SIZE = HEAPMGR_SIZE; + } + else + { + // if you get an undefined error for the symbol bellow it means that AUTOHEAPSIZE has been defined in the application. + Program.global.HEAPMGR_SIZE = 0; + heapMemParams.usePrimaryHeap = true; + HeapMem.primaryHeapBaseAddr = "&heapStart"; + HeapMem.primaryHeapEndAddr = "&heapEnd"; + } + + Program.global.stackHeap = HeapMem.create(heapMemParams); + + var GateHwi = xdc.useModule('ti.sysbios.gates.GateHwi'); + HeapMem.common$.gate = GateHwi.create(); + Memory.defaultHeapInstance = Program.global.stackHeap; +} +else if (HEAPMGR_CONFIG === 2 || HEAPMGR_CONFIG === 0x82) +{ + var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem'); + var heapMemParams = new HeapMem.Params(); + if (HEAPMGR_CONFIG === 2) + { + heapMemParams.size = HEAPMGR_SIZE; + Program.global.HEAPMGR_SIZE = HEAPMGR_SIZE; + } + else + { + // if you get an undefined error for the symbol bellow it means that AUTOHEAPSIZE has been defined in the application. + // + heapMemParams.usePrimaryHeap = true; + HeapMem.primaryHeapBaseAddr = "&heapStart"; + HeapMem.primaryHeapEndAddr = "&heapEnd"; + Program.global.HEAPMGR_SIZE = 0; + } + + var tempHeap = HeapMem.create(heapMemParams); + + var GateHwi = xdc.useModule('ti.sysbios.gates.GateHwi'); + HeapMem.common$.gate = GateHwi.create(); + + var HeapTrack = xdc.useModule('ti.sysbios.heaps.HeapTrack'); + var heapTrackParams = new HeapTrack.Params(); + heapTrackParams.heap = tempHeap; + Program.global.stackHeap = HeapTrack.create(heapTrackParams) + Memory.defaultHeapInstance = Program.global.stackHeap; +} +else if (HEAPMGR_CONFIG === 0 || HEAPMGR_CONFIG === 0x80) +{ + + var HeapCallback = xdc.useModule('ti.sysbios.heaps.HeapCallback'); + var params = new HeapCallback.Params(); + params.arg = 1; + Program.global.heap0 = HeapCallback.create(params); + HeapCallback.initInstFxn = '&osalHeapInitFxn'; // Call First When BIOS boot. Initialize the Heap Manager. + HeapCallback.allocInstFxn = '&osalHeapAllocFxn'; // Call for allocating a buffer + HeapCallback.freeInstFxn = '&osalHeapFreeFxn'; // Call for Freeing a buffer + HeapCallback.getStatsInstFxn = '&osalHeapGetStatsFxn'; // Return Statistic on the Heap. + HeapCallback.isBlockingInstFxn = '&osalHeapIsBlockingFxn'; // Return TRUE: This heap is always blocking ('Hwi Gate' like ) + //HeapCallback.createInstFxn = '&osalHeapCreateFxn'; // Not Supported + //HeapCallback.deleteInstFxn = '&osalHeapDeleteFxn'; // Not supported + Memory.defaultHeapInstance = Program.global.heap0; + + if (HEAPMGR_CONFIG === 0) + { + // the following definition will create the #define HEAPMGR_SIZE , + // which is used by thestack to have information about the heap manager size. + // if set to 0, this imply auto-size heap + Program.global.HEAPMGR_SIZE = HEAPMGR_SIZE; + } + else + { + // the following definition will create the #define HEAPMGR_SIZE , + // which is used by the stack to have information about the heap manager size. + // if set to 0, this imply auto-size heap + // The heap buffer will be created automaticaly by using all the remaiing RAM available at the end of the build/link. + // For this, 2 symbole needs to be created by teh linker file: heapStart and heapEnd + Program.global.HEAPMGR_SIZE = 0; + } +} + +/* ================ GateMutexPri configuration ================ */ +var GateMutexPri = xdc.useModule('ti.sysbios.gates.GateMutexPri'); \ No newline at end of file diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ble_release.cfg b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ble_release.cfg new file mode 100644 index 0000000..0225db9 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ble_release.cfg @@ -0,0 +1,750 @@ +/****************************************************************************** + + @file ble_release.cfg + + @brief TI RTOS (in ROM release) Configuration file for BLE5-Stack + + Group: CMCU, LPRF + Target Device: CC2652 + + ****************************************************************************** + + Copyright (c) 2017-2018, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + Release Name: simplelink_cc26x2_sdk_2_30_00_34 + Release Date: 2018-10-04 14:27:27 + *****************************************************************************/ + + + +/* ================ ROM configuration ================ */ +/* + * To use BIOS in flash, comment out the code block below. + */ +var ROM = xdc.useModule('ti.sysbios.rom.ROM'); +if (Program.cpu.deviceName.match(/CC26/)) { + ROM.romName = ROM.CC26X2; +} +else if (Program.cpu.deviceName.match(/CC13/)) { + ROM.romName = ROM.CC13X2; +} + + + + +/* ================ Boot configuration ================ */ +/* + * This module contains family specific Boot APIs and configuration settings. + * See the SYS/BIOS API guide for more information. + */ +var Boot = xdc.useModule('ti.sysbios.family.arm.cc26xx.Boot'); + + + +/* ================ Clock configuration ================ */ +var Clock = xdc.useModule('ti.sysbios.knl.Clock'); +/* + * When using Power and calibrateRCOSC is set to true, this should be set to 10. + * The timer used by the Clock module supports TickMode_DYNAMIC. This enables us + * to set the tick period to 10 us without generating the overhead of additional + * interrupts. + * + * Note: The calibrateRCOSC parameter is set within the Power configuration + * structure in the "Board.c" file. + */ +Clock.tickPeriod = 10; +Clock.swiPriority = 5; + + +/* ================ Types configuration ================ */ +var Types = xdc.useModule('xdc.runtime.Types'); +/* + * This module defines basic constants and types used throughout the + * xdc.runtime package. + */ + + + +/* ================ Defaults (module) configuration ================ */ +var Defaults = xdc.useModule('xdc.runtime.Defaults'); +/* + * A flag to allow module names to be loaded on the target. Module name + * strings are placed in the .const section for debugging purposes. + * + * Pick one: + * - true (default) + * Setting this parameter to true will include name strings in the .const + * section so that Errors and Asserts are easier to debug. + * - false + * Setting this parameter to false will reduce footprint in the .const + * section. As a result, Error and Assert messages will contain an + * "unknown module" prefix instead of the actual module name. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +//Defaults.common$.namedModule = true; +Defaults.common$.namedModule = false; + +/* Compile out all Assert's */ +//Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF; + +/* Allow Mod_create() and Mod_construct() but not delete() or destruct() */ +Defaults.common$.memoryPolicy = Types.DELETE_POLICY; + + + +/* ================ Error configuration ================ */ +var Error = xdc.useModule('xdc.runtime.Error'); +/* + * This function is called to handle all raised errors, but unlike + * Error.raiseHook, this function is responsible for completely handling the + * error with an appropriately initialized Error_Block. + * + * Pick one: + * - Error.policyDefault (default) + * Calls Error.raiseHook with an initialized Error_Block structure and logs + * the error using the module's logger. + * - Error.policySpin + * Simple alternative that traps on a while(1) loop for minimized target + * footprint. + * Using Error.policySpin, the Error.raiseHook will NOT called. + */ +//Error.policyFxn = Error.policyDefault; +Error.policyFxn = Error.policySpin; + +/* + * If Error.policyFxn is set to Error.policyDefault, this function is called + * whenever an error is raised by the Error module. + * + * Pick one: + * - Error.print (default) + * Errors are formatted and output via System_printf() for easier + * debugging. + * - null + * Errors are trapped with a while(1) stub function. This option reduces + * code footprint. + * - non-null function + * Errors invoke custom user function. See the Error module documentation + * for more details. + */ +//Error.raiseHook = Error.print; +Error.raiseHook = null; +//Error.raiseHook = "&myErrorFxn"; + +/* + * If Error.policyFxn is set to Error.policyDefault, this option applies to the + * maximum number of times the Error.raiseHook function can be recursively + * invoked. This option limits the possibility of an infinite recursion that + * could lead to a stack overflow. + * The default value is 16. + */ +Error.maxDepth = 2; + + + +/* ================ Hwi configuration ================ */ +var halHwi = xdc.useModule('ti.sysbios.hal.Hwi'); +var m3Hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi'); +/* + * Checks for Hwi (system) stack overruns while in the Idle loop. + * + * Pick one: + * - true (default) + * Checks the top word for system stack overflows during the idle loop and + * raises an Error if one is detected. + * - false + * Disabling the runtime check improves runtime performance and yields a + * reduced flash footprint. + */ +//halHwi.checkStackFlag = true; +halHwi.checkStackFlag = false; + +/* + * The following options alter the system's behavior when a hardware exception + * is detected. + * + * Pick one: + * - Hwi.enableException = true + * This option causes the default m3Hwi.excHandlerFunc function to fully + * decode an exception and dump the registers to the system console. + * This option raises errors in the Error module and displays the + * exception in ROV. + * - Hwi.enableException = false + * This option reduces code footprint by not decoding or printing the + * exception to the system console. + * It however still raises errors in the Error module and displays the + * exception in ROV. + * - Hwi.excHandlerFunc = null + * This is the most aggressive option for code footprint savings; but it + * can difficult to debug exceptions. It reduces flash footprint by + * plugging in a default while(1) trap when exception occur. This option + * does not raise an error with the Error module. + */ +//m3Hwi.enableException = true; +//m3Hwi.enableException = false; +m3Hwi.excHandlerFunc = null; + +/* + * Enable hardware exception generation when dividing by zero. + * + * Pick one: + * - 0 (default) + * Disables hardware exceptions when dividing by zero + * - 1 + * Enables hardware exceptions when dividing by zero + */ +m3Hwi.nvicCCR.DIV_0_TRP = 0; +//m3Hwi.nvicCCR.DIV_0_TRP = 1; + +/* + * Enable hardware exception generation for invalid data alignment. + * + * Pick one: + * - 0 (default) + * Disables hardware exceptions for data alignment + * - 1 + * Enables hardware exceptions for data alignment + */ +m3Hwi.nvicCCR.UNALIGN_TRP = 0; +//m3Hwi.nvicCCR.UNALIGN_TRP = 1; + +/* Put reset vector at start of Flash */ +m3Hwi.resetVectorAddress = 0x0; + +/* Put interrupt vector at start of RAM so interrupts can be configured at runtime */ +m3Hwi.vectorTableAddress = 0x20000000; + + + +/* ================ Idle configuration ================ */ +var Idle = xdc.useModule('ti.sysbios.knl.Idle'); +/* + * The Idle module is used to specify a list of functions to be called when no + * other tasks are running in the system. + * + * Functions added here will be run continuously within the idle task. + * + * Function signature: + * Void func(Void); + */ +//Idle.addFunc("&myIdleFunc"); +/* Allow power management */ +Idle.addFunc('&Power_idleFunc'); + + + +/* ================ Kernel (SYS/BIOS) configuration ================ */ +var BIOS = xdc.useModule('ti.sysbios.BIOS'); +/* + * Enable asserts in the BIOS library. + * + * Pick one: + * - true (default) + * Enables asserts for debugging purposes. + * - false + * Disables asserts for a reduced code footprint and better performance. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +//BIOS.assertsEnabled = true; +BIOS.assertsEnabled = false; + +/* + * A flag to determine if xdc.runtime sources are to be included in a custom + * built BIOS library. + * + * Pick one: + * - false (default) + * The pre-built xdc.runtime library is provided by the respective target + * used to build the application. + * - true + * xdc.runtime library sources are to be included in the custom BIOS + * library. This option yields the most efficient library in both code + * footprint and runtime performance. + */ +//BIOS.includeXdcRuntime = false; +BIOS.includeXdcRuntime = true; + +/* + * The SYS/BIOS runtime is provided in the form of a library that is linked + * with the application. Several forms of this library are provided with the + * SYS/BIOS product. + * + * Pick one: + * - BIOS.LibType_Custom + * Custom built library that is highly optimized for code footprint and + * runtime performance. + * - BIOS.LibType_Debug + * Custom built library that is non-optimized that can be used to + * single-step through APIs with a debugger. + * + */ +BIOS.libType = BIOS.LibType_Custom; +//BIOS.libType = BIOS.LibType_Debug; + +/* + * Runtime instance creation enable flag. + * + * Pick one: + * - true (default) + * Allows Mod_create() and Mod_delete() to be called at runtime which + * requires a default heap for dynamic memory allocation. + * - false + * Reduces code footprint by disallowing Mod_create() and Mod_delete() to + * be called at runtime. Object instances are constructed via + * Mod_construct() and destructed via Mod_destruct(). + * + * When using BIOS in ROM: + * This option must be set to true. + */ +BIOS.runtimeCreatesEnabled = true; +//BIOS.runtimeCreatesEnabled = false; + +/* + * Enable logs in the BIOS library. + * + * Pick one: + * - true (default) + * Enables logs for debugging purposes. + * - false + * Disables logging for reduced code footprint and improved runtime + * performance. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +//BIOS.logsEnabled = true; +BIOS.logsEnabled = false; + +BIOS.swiEnabled = true; + + + +/* ================ Program configuration ================ */ +/* + * Program.stack is ignored with IAR. Use the project options in + * IAR Embedded Workbench to alter the system stack size. + */ +Program.stack = 1024; +Program.argSize = 0; + + + +/* ================ Semaphore configuration ================ */ +var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore'); +/* + * Enables global support for Task priority pend queuing. + * + * Pick one: + * - true (default) + * This allows pending tasks to be serviced based on their task priority. + * - false + * Pending tasks are services based on first in, first out basis. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +//Semaphore.supportsPriority = true; +Semaphore.supportsPriority = false; + +/* + * Allows for the implicit posting of events through the semaphore, + * disable for additional code saving. + * + * Pick one: + * - true + * This allows the Semaphore module to post semaphores and events + * simultaneously. + * - false (default) + * Events must be explicitly posted to unblock tasks. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +//Semaphore.supportsEvents = true; +Semaphore.supportsEvents = false; + + + + +/* ================ Events configuration ================ */ +var Events = xdc.useModule('ti.sysbios.knl.Event'); + + + +/* ================ Swi configuration ================ */ +var Swi = xdc.useModule('ti.sysbios.knl.Swi'); +/* + * A software interrupt is an object that encapsulates a function to be + * executed and a priority. Software interrupts are prioritized, preempt tasks + * and are preempted by hardware interrupt service routines. + * + * This module is included to allow Swi's in a users' application. + */ +Swi.numPriorities = 6; + + + +/* ================ System configuration ================ */ +var System = xdc.useModule('xdc.runtime.System'); +/* + * The Abort handler is called when the system exits abnormally. + * + * Pick one: + * - System.abortStd (default) + * Call the ANSI C Standard 'abort()' to terminate the application. + * - System.abortSpin + * A lightweight abort function that loops indefinitely in a while(1) trap + * function. + * - A custom abort handler + * A user-defined function. See the System module documentation for + * details. + */ +//System.abortFxn = System.abortStd; +System.abortFxn = System.abortSpin; +//System.abortFxn = "&myAbortSystem"; + +/* + * The Exit handler is called when the system exits normally. + * + * Pick one: + * - System.exitStd (default) + * Call the ANSI C Standard 'exit()' to terminate the application. + * - System.exitSpin + * A lightweight exit function that loops indefinitely in a while(1) trap + * function. + * - A custom exit function + * A user-defined function. See the System module documentation for + * details. + */ +//System.exitFxn = System.exitStd; +System.exitFxn = System.exitSpin; +//System.exitFxn = "&myExitSystem"; + +/* + * Minimize exit handler array in the System module. The System module includes + * an array of functions that are registered with System_atexit() which is + * called by System_exit(). The default value is 8. + */ +System.maxAtexitHandlers = 0; + +/* + * The System.SupportProxy defines a low-level implementation of System + * functions such as System_printf(), System_flush(), etc. + * + * Pick one pair: + * - SysMin + * This module maintains an internal configurable circular buffer that + * stores the output until System_flush() is called. + * The size of the circular buffer is set via SysMin.bufSize. + * - SysCallback + * SysCallback allows for user-defined implementations for System APIs. + * The SysCallback support proxy has a smaller code footprint and can be + * used to supply custom System_printf services. + * The default SysCallback functions point to stub functions. See the + * SysCallback module's documentation. + */ +//var SysMin = xdc.useModule('xdc.runtime.SysMin'); +//SysMin.bufSize = 768; +//System.SupportProxy = SysMin; +var SysCallback = xdc.useModule('xdc.runtime.SysCallback'); +System.SupportProxy = SysCallback; +//SysCallback.abortFxn = "&myUserAbort"; +//SysCallback.exitFxn = "&myUserExit"; +//SysCallback.flushFxn = "&myUserFlush"; +//SysCallback.putchFxn = "&myUserPutch"; +//SysCallback.readyFxn = "&myUserReady"; + + + +/* ================ Task configuration ================ */ +var Task = xdc.useModule('ti.sysbios.knl.Task'); +/* + * Check task stacks for overflow conditions. + * + * Pick one: + * - true (default) + * Enables runtime checks for task stack overflow conditions during + * context switching ("from" and "to") + * - false + * Disables runtime checks for task stack overflow conditions. + * + * When using BIOS in ROM: + * This option must be set to false. + */ +//Task.checkStackFlag = true; +Task.checkStackFlag = false; + +/* + * Set the default task stack size when creating tasks. + * + * The default is dependent on the device being used. Reducing the default stack + * size yields greater memory savings. + */ +Task.defaultStackSize = 512; + +/* + * Enables the idle task. + * + * Pick one: + * - true (default) + * Creates a task with priority of 0 which calls idle hook functions. This + * option must be set to true to gain power savings provided by the Power + * module. + * - false + * No idle task is created. This option consumes less memory as no + * additional default task stack is needed. + * To gain power savings by the Power module without having the idle task, + * add Idle.run as the Task.allBlockedFunc. + */ +Task.enableIdleTask = true; +//Task.enableIdleTask = false; +//Task.allBlockedFunc = Idle.run; + +/* + * If Task.enableIdleTask is set to true, this option sets the idle task's + * stack size. + * + * Reducing the idle stack size yields greater memory savings. + */ +Task.idleTaskStackSize = 768; + +/* + * Reduce the number of task priorities. + * The default is 16. + * Decreasing the number of task priorities yield memory savings. + */ +Task.numPriorities = 6; + + + +/* ================ Text configuration ================ */ +var Text = xdc.useModule('xdc.runtime.Text'); +/* + * These strings are placed in the .const section. Setting this parameter to + * false will save space in the .const section. Error, Assert and Log messages + * will print raw ids and args instead of a formatted message. + * + * Pick one: + * - true (default) + * This option loads test string into the .const for easier debugging. + * - false + * This option reduces the .const footprint. + */ +//Text.isLoaded = true; +Text.isLoaded = false; + + + + +/* ================ Diagnostics configuration ================ */ +var Diags = xdc.useModule('xdc.runtime.Diags'); +/* + * You use the Diags module to set and clear bits in a module's diagnostics + * mask for the purpose of controlling diagnostics within that module. A + * module diagnostics mask controls both Assert and Log statements + * within that module, disabling these statements yields + * code savings. + */ + + + +/* ================ Main configuration ================ */ +var Main = xdc.useModule('xdc.runtime.Main'); +/* Configuration of this Main module is used for all code not in a module */ + +var Reset = xdc.useModule('xdc.runtime.Reset'); + + + +/* + * Heap Configuration defines the type of Heap you want to use for the system (application + Stack) + * Only one Heap buffer will be allocated. This heap will be shared by the system and the stack through + * one manager (HeapMem, HeapMem+HeapTrack or OSAL) + * You can still decide to create several heaps if you want, but at least one heap needs to be created. + * The stack must have a Heap to run. + * The different Heap manager available are : + * OSAL HEAP: legacy Heap manager provided with all BLE sdk. By default, this Heap manager is used. + * HeapMem:  heap manager provided by TI-RTOS (see TI-RTOS user guide for properties) + * HeapTrack: module on top of HeapMem allowing an easy debugging of memory allocated through HeapMem. + * + * The heap manager to use is selected by setting HEAPMGR_CONFIG to the corresponding value (see below) + * 0 = osal Heap manager, size is static. + * 0x80 = osal Heap manager, with auto-size: The remainning RAM (not used by the system) will be fully assign to the Heap. + * 1 = HeapMem with Static size + * 0x81 = HeapMem with auto-size. The remainning RAM (not used by the system) will be fully assign to the Heap. + * 2 = HeapTrack (with HeapMem) with fixe size + * 0x82 = HeapTrack (with HeapMem) with auto-size: The remainning RAM (not used by the system) will be fully assign to the Heap. + * + * If HEAPMGR_CONFIG is not defined, but the configuration file ble_stack_heap.cfg is used, then the value + * HEAPMGR_CONFIG = 0x80 is assumed. + * If HEAPMGR_CONFIG is not defined, and the file ble_stack_heap.cfg is not used, then the value + * HEAPMGR_CONFIG = 0x80 is assumed and the default Heap size will be 3072 + * unless you define HEAPMGR_SIZE to a different value in the project option (0 meaning auto-size). + * + * From the configuration below, two #define will be created that will be used by the application to setup the Heap: + * #define HEAPMGR_SIZE + * #define HEAPMGR_CONFIG + * In order to use those define, this include line needs to be added: #include + * + * In order for the auto-size Heap to work, the following symbol needs to be created by the linker: + * heapStart + * heapEnd + */ + +/* + * DISCLAIMER: The HeapMem module in ROM can only use a GateMutex module. This means the malloc() + * function cannot be used in a Hwi/Swi. + * This means also that other access to the heap, with Icall_alloc for example, can potentially break the Heap... + * Therefore this solution is most effective when TI-RTOS is located in FLASH, so that a GateHwi can be used. + * If you try to use it in ROM, a workaround using HeapCallback is used, which will degrade performance. + */ +var Memory = xdc.useModule('xdc.runtime.Memory'); +var HEAPMGR_CONFIG = 0x80; +var HEAPMGR_SIZE = 30000; //only valid if static size is used. This is the size of the buffer allocated for Heap. + +if (typeof HEAPMGR_CONFIG === 'undefined' ) +{ + var HEAPMGR_CONFIG = 0x80; +} + +// The following will create the #define HEAPMGR_CONFIG. It can then be used by include +Program.global.HEAPMGR_CONFIG = HEAPMGR_CONFIG; + +if (HEAPMGR_CONFIG === 1 || HEAPMGR_CONFIG === 0x81) +{ + var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem'); + var heapMemParams = new HeapMem.Params(); + + if (HEAPMGR_CONFIG === 0x1) + { + heapMemParams.size = HEAPMGR_SIZE; + Program.global.HEAPMGR_SIZE = HEAPMGR_SIZE; + } + else + { + // if you get an undefined error for the symbol bellow it means that AUTOHEAPSIZE has been defined in the application. + Program.global.HEAPMGR_SIZE = 0; + heapMemParams.usePrimaryHeap = true; + HeapMem.primaryHeapBaseAddr = "&heapStart"; + HeapMem.primaryHeapEndAddr = "&heapEnd"; + } + + Program.global.stackHeap = HeapMem.create(heapMemParams); + + var HeapCallback = xdc.useModule('ti.sysbios.heaps.HeapCallback'); + var params = new HeapCallback.Params(); + params.arg = 1; + Program.global.heap0 = HeapCallback.create(params); + HeapCallback.initInstFxn = '&myHeapMemInitFxn'; // Call First When BIOS boot. Initialize the Heap Manager. + HeapCallback.allocInstFxn = '&myHeapMemAllocFxn'; // Call for allocating a buffer + HeapCallback.freeInstFxn = '&myHeapMemFreeFxn'; // Call for Freeing a buffer + HeapCallback.getStatsInstFxn = '&myHeapMemGetStatsFxn'; // Return Statistic on the Heap. + HeapCallback.isBlockingInstFxn = '&myHeapMemIsBlockingFxn'; // Return TRUE: This heap is always blocking ('Hwi Gate' like ) + Memory.defaultHeapInstance = Program.global.heap0; +} +else if (HEAPMGR_CONFIG === 2 || HEAPMGR_CONFIG === 0x82) +{ + var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem'); + var heapMemParams = new HeapMem.Params(); + if (HEAPMGR_CONFIG === 2) + { + heapMemParams.size = HEAPMGR_SIZE; + Program.global.HEAPMGR_SIZE = HEAPMGR_SIZE; + } + else + { + // if you get an undefined error for the symbol bellow it means that AUTOHEAPSIZE has been defined in the application. + // + heapMemParams.usePrimaryHeap = true; + HeapMem.primaryHeapBaseAddr = "&heapStart"; + HeapMem.primaryHeapEndAddr = "&heapEnd"; + Program.global.HEAPMGR_SIZE = 0; + } + + var tempHeap = HeapMem.create(heapMemParams); + + var HeapTrack = xdc.useModule('ti.sysbios.heaps.HeapTrack'); + HeapTrack.common$.diags_ASSERT = xdc.module("xdc.runtime.Diags").ALWAYS_ON; + var heapTrackParams = new HeapTrack.Params(); + heapTrackParams.heap = tempHeap; + Program.global.stackHeap = HeapTrack.create(heapTrackParams) + + var HeapCallback = xdc.useModule('ti.sysbios.heaps.HeapCallback'); + var params = new HeapCallback.Params(); + params.arg = 1; + Program.global.heap0 = HeapCallback.create(params); + HeapCallback.initInstFxn = '&myHeapTrackInitFxn'; // Call First When BIOS boot. Initialize the Heap Manager. + HeapCallback.allocInstFxn = '&myHeapTrackAllocFxn'; // Call for allocating a buffer + HeapCallback.freeInstFxn = '&myHeapTrackFreeFxn'; // Call for Freeing a buffer + HeapCallback.getStatsInstFxn = '&myHeapTrackGetStatsFxn'; // Return Statistic on the Heap. + HeapCallback.isBlockingInstFxn = '&myHeapTrackIsBlockingFxn'; // Return TRUE: This heap is always blocking ('Hwi Gate' like ) + Memory.defaultHeapInstance = Program.global.heap0; +} +else if (HEAPMGR_CONFIG === 0 || HEAPMGR_CONFIG === 0x80) +{ + + var HeapCallback = xdc.useModule('ti.sysbios.heaps.HeapCallback'); + var params = new HeapCallback.Params(); + params.arg = 1; + Program.global.heap0 = HeapCallback.create(params); + HeapCallback.initInstFxn = '&osalHeapInitFxn'; // Call First When BIOS boot. Initialize the Heap Manager. + HeapCallback.allocInstFxn = '&osalHeapAllocFxn'; // Call for allocating a buffer + HeapCallback.freeInstFxn = '&osalHeapFreeFxn'; // Call for Freeing a buffer + HeapCallback.getStatsInstFxn = '&osalHeapGetStatsFxn'; // Return Statistic on the Heap. + HeapCallback.isBlockingInstFxn = '&osalHeapIsBlockingFxn'; // Return TRUE: This heap is always blocking ('Hwi Gate' like ) + //HeapCallback.createInstFxn = '&osalHeapCreateFxn'; // Not Supported + //HeapCallback.deleteInstFxn = '&osalHeapDeleteFxn'; // Not supported + Memory.defaultHeapInstance = Program.global.heap0; + + if (HEAPMGR_CONFIG === 0) + { + // the following definition will create the #define HEAPMGR_SIZE , + // which is used by thestack to have information about the heap manager size. + // if set to 0, this imply auto-size heap + Program.global.HEAPMGR_SIZE = HEAPMGR_SIZE; + } + else + { + // the following definition will create the #define HEAPMGR_SIZE , + // which is used by the stack to have information about the heap manager size. + // if set to 0, this imply auto-size heap + // The heap buffer will be created automaticaly by using all the remaiing RAM available at the end of the build/link. + // For this, 2 symbole needs to be created by teh linker file: heapStart and heapEnd + Program.global.HEAPMGR_SIZE = 0; + } +} + +/* ================ GateMutexPri configuration ================ */ +var GateMutexPri = xdc.useModule('ti.sysbios.gates.GateMutexPri'); \ No newline at end of file diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/build_config.opt b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/build_config.opt new file mode 100644 index 0000000..30b13ca --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/build_config.opt @@ -0,0 +1,134 @@ +/****************************************************************************** + + @file build_config.opt + + @brief This file contains the Bluetooth Low Energy (BLE) build config options. + + Group: CMCU, LPRF + Target Device: CC2652 + + ****************************************************************************** + + Copyright (c) 2011-2018, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + Release Name: simplelink_cc26x2_sdk_2_30_00_34 + Release Date: 2018-10-04 14:27:27 + *****************************************************************************/ + +/* + The following is a list of all possible build defines and corresponding options + that can be set for each define: + + GATT_DB_OFF_CHIP - Indicates that the GATT database is maintained off the chip on the + Application Processor (AP). + + GAP_BOND_MGR - Used to include the Bond Manager + + HOST_CONFIG (BLE Host Build Configurations) Possible Options: + PERIPHERAL_CFG - Used to include the GAP Peripheral Role support + CENTRAL_CFG - Used to include the GAP Central Role support + BROADCASTER_CFG - Used to include the GAP Broadcaster Role support + OBSERVER_CFG - Used to include the GAP Observer Role support + + BLE_V41_FEATURES Configure the stack to use features from the BLE 4.1 Specification + L2CAP_COC_CFG - Enable L2CAP Connection Oriented Channels + + BLE_V50_FEATURES Configure the stack to use features from the BLE 5.0 Specification + The following BLE 5.0 features are enabled by default and cannot + be disabled. + PHY_2MBPS_CFG - Enable 2 Mbps data rate in the Controller + HDC_NC_ADV_CFG - Enable High Duty Cycle Non-Connectable Advertising + CHAN_ALGO2_CFG - Enable Channel Selection Algorithm 2 + + HCI_TL_FULL - All supported HCI commands are available via the Tranport Layer's NPI. + - Intended for NP solution. + HCI_TL_PTM - Only those HCI commands needed for Production Test Mode are available + via the Transport Layer's NPI + - Intended for SOC solutions where, during production, accesss is temporarily + needed (e.g. for PHY testing using Direct Test Mode, etc.). + HCI_TL_NONE - No supported HCI commands are available via the Transport Layer's NPI. + - Intended for SOC solutions. + + Below is general information for using and/or changing this configuration option file: + + Combo Roles: Combo roles can be set by defining multiple roles for HOST_CONFIG. The possible + combo roles and HOST_CONFIG defines are: + Peripheral + Observer : PERIPHERAL_CFG+OBSERVER_CFG + Central + Broadcaster : CENTRAL_CFG+BROADCASTER_CFG + Peripheral + Central : PERIPHERAL_CFG+CENTRAL_CFG + + lib_search tool: There is a pre build action for every stack project that runs a tool + lib_search.exe. This tool aims to automatically import the correct library + files into your project based on the defines in this file. + + The locations of all library files and their correspond options are + /ble_core/ble_[host,ctrl]_lib/ for stack libs + and at /ble_core/hci_tl_lib/ for + HCI Transport Layer libs + + If an library is found that was built with matching options, it will be + copied into the project local directory at /../../lib/ and + subsequently linked with the stack. + + If you experience a build error with lib_search.exe, expand the build error + message by clicking Tools->Options->Messages->Show build messages:->All. + The error messages printed out by the lib_search tool should now appear in + your Build Message window. + +*/ + +/* BLE Host Build Configurations */ +/* -DHOST_CONFIG=PERIPHERAL_CFG */ +/* -DHOST_CONFIG=CENTRAL_CFG */ +/* -DHOST_CONFIG=BROADCASTER_CFG */ +/* -DHOST_CONFIG=OBSERVER_CFG */ +/* -DHOST_CONFIG=PERIPHERAL_CFG+OBSERVER_CFG */ +/* -DHOST_CONFIG=CENTRAL_CFG+BROADCASTER_CFG */ +-DHOST_CONFIG=PERIPHERAL_CFG+CENTRAL_CFG + +/* GATT Database being off chip */ +/* -DGATT_DB_OFF_CHIP */ + +/* Include GAP Bond Manager */ +-DGAP_BOND_MGR + +/* BLE v4.1 Features */ +/* -DV41_FEATURES=L2CAP_COC_CFG */ + +/* BLE v5.0 Features + * Note: The Long Range feature is for evaluation only. + */ + +/* Include Transport Layer (Full or PTM) */ +-DHCI_TL_NONE +/* -DHCI_TL_PTM */ +/* -DHCI_TL_FULL */ diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/ble5_tree_structure_network_cc26x2r1lp_app.projectspec b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/ble5_tree_structure_network_cc26x2r1lp_app.projectspec new file mode 100644 index 0000000..b759606 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/ble5_tree_structure_network_cc26x2r1lp_app.projectspec @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/ble5_tree_structure_network_cc26x2r1lp_stack_library.projectspec b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/ble5_tree_structure_network_cc26x2r1lp_stack_library.projectspec new file mode 100644 index 0000000..d17886e --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/ble5_tree_structure_network_cc26x2r1lp_stack_library.projectspec @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_app_FlashROM_Debug.opt b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_app_FlashROM_Debug.opt new file mode 100644 index 0000000..ca813f3 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_app_FlashROM_Debug.opt @@ -0,0 +1,19 @@ +-DBOARD_DISPLAY_USE_LCD=0 +-DBOARD_DISPLAY_USE_UART=1 +-DBOARD_DISPLAY_USE_UART_ANSI=1 +-DCC26X2 +-DCC26X2R1_LAUNCHXL +-DCC26XX +-DDeviceFamily_CC26X2 +-DxDisplay_DISABLE_ALL +-DICALL_EVENTS +-DICALL_JT +-DICALL_LITE +-DICALL_MAX_NUM_ENTITIES=6 +-DICALL_MAX_NUM_TASKS=3 +-DICALL_STACK0_ADDR +-DMAX_NUM_BLE_CONNS=8 +-DPOWER_SAVING +-DSTACK_LIBRARY +-DTBM_ACTIVE_ITEMS_ONLY +-DUSE_ICALL diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_app_FlashROM_Release.opt b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_app_FlashROM_Release.opt new file mode 100644 index 0000000..ca813f3 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_app_FlashROM_Release.opt @@ -0,0 +1,19 @@ +-DBOARD_DISPLAY_USE_LCD=0 +-DBOARD_DISPLAY_USE_UART=1 +-DBOARD_DISPLAY_USE_UART_ANSI=1 +-DCC26X2 +-DCC26X2R1_LAUNCHXL +-DCC26XX +-DDeviceFamily_CC26X2 +-DxDisplay_DISABLE_ALL +-DICALL_EVENTS +-DICALL_JT +-DICALL_LITE +-DICALL_MAX_NUM_ENTITIES=6 +-DICALL_MAX_NUM_TASKS=3 +-DICALL_STACK0_ADDR +-DMAX_NUM_BLE_CONNS=8 +-DPOWER_SAVING +-DSTACK_LIBRARY +-DTBM_ACTIVE_ITEMS_ONLY +-DUSE_ICALL diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_stack_library_FlashROM_Library.opt b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_stack_library_FlashROM_Library.opt new file mode 100644 index 0000000..acde5fe --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/ccs/defines/ble5_tree_structure_network_cc26x2r1lp_stack_library_FlashROM_Library.opt @@ -0,0 +1,13 @@ +-DCC26X2 +-DCC26X2R1_LAUNCHXL +-DCC26XX +-DDeviceFamily_CC26X2 +-DEXT_HAL_ASSERT +-DFLASH_ONLY_BUILD +-DICALL_EVENTS +-DICALL_JT +-DICALL_LITE +-DOSAL_CBTIMER_NUM_TASKS=1 +-DPOWER_SAVING +-DSTACK_LIBRARY +-DUSE_ICALL diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/cc26x2r1lp_app.ewd b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/cc26x2r1lp_app.ewd new file mode 100644 index 0000000..0b18f35 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/cc26x2r1lp_app.ewd @@ -0,0 +1,2834 @@ + + + 3 + + FlashROM_Release + + ARM + + 1 + + C-SPY + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + FlashROM_Debug + + ARM + + 1 + + C-SPY + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/cc26x2r1lp_app.ewp b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/cc26x2r1lp_app.ewp new file mode 100644 index 0000000..6cd59f6 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/cc26x2r1lp_app.ewp @@ -0,0 +1,2298 @@ + + + 3 + + FlashROM_Release + + ARM + + 1 + + General + 3 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + "$XDCROOT$\xs" --xdcpath="$XDCPATH$" iar.tools.configuro -c "$TOOLKIT_DIR$" --cc "$COMPILER_PATH$" --device "$DEVICE$" --compileOptions $COMPILER_ARGS_ROOT_QUOTED$ --linkOptions $LINKER_ARGS_QUOTED$ --profile release --projFile "$PROJ_PATH$" -o $PROJ_DIR$\..\config\configPkg $EXAMPLE_BLE_ROOT$\tirtos\ble_release.cfg + + + + + ILINK + 0 + + 20 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + FlashROM_Debug + + ARM + + 1 + + General + 3 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + "$XDCROOT$\xs" --xdcpath="$XDCPATH$" iar.tools.configuro -c "$TOOLKIT_DIR$" --cc "$COMPILER_PATH$" --device "$DEVICE$" --compileOptions $COMPILER_ARGS_ROOT_QUOTED$ --linkOptions $LINKER_ARGS_QUOTED$ --profile release --projFile "$PROJ_PATH$" -o $PROJ_DIR$\..\config\configPkg $EXAMPLE_BLE_ROOT$\tirtos\ble_debug.cfg + + + + + ILINK + 0 + + 20 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Application + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\common\cc26xx\board_key.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\common\cc26xx\board_key.h + + + $PROJ_DIR$\..\..\..\src\app\tree_structure_network.c + + + $PROJ_DIR$\..\..\..\src\app\tree_structure_network.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\common\cc26xx\util.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\common\cc26xx\util.h + + + + Drivers + + NV + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\services\src\nv\cc26xx\crc.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\services\src\nv\cc26xx\crc.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\services\src\nv\cc26xx\nvoctp.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\services\src\nv\cc26xx\nvoctp.h + + + + TRNG + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\hal\src\target\_common\TRNGCC26XX.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\hal\src\target\_common\TRNGCC26XX.h + + + + + ICall + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\src\icall.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\src\inc\icall.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\inc\icall_addrs.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\src\icall_cc2650.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\src\icall_platform.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\src\icall_user_config.c + + + + ICallBLE + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\app\ble_user_config.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\inc\ble_user_config.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\app\icall_api_lite.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\icall\inc\icall_ble_apimsg.h + + + + Include + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\inc\gap.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\inc\gapbondmgr.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\inc\gapgattserver.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\inc\gatt.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\inc\hci.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\osal\src\inc\osal_snv.h + + + + Profiles + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\profiles\dev_info\cc26xx\devinfoservice.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\profiles\dev_info\devinfoservice.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\inc\gatt_profile_uuid.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\host\gatt_uuid.c + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\host\gatt_uuid.h + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\host\gattservapp_util.c + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\source\ti\ble5stack\profiles\tree_structure_network\tree_network_service.c + + + $PROJ_DIR$\..\..\..\..\..\..\..\..\source\ti\ble5stack\profiles\tree_structure_network\tree_network_service.h + + + + StackLibrary + + $PROJ_DIR$\..\stack\FlashROM_Library\Exe\cc26x2r1lp_stack_FlashROM_Library.a + + + + Startup + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\target\board.c + + + $PROJ_DIR$\..\..\..\src\ccfg_app_ble.c + + + $PROJ_DIR$\..\..\..\src\app\main.c + + + + Tools + + defines + + $PROJ_DIR$\defines\cc26x2r1lp_app_FlashROM_Debug.opt + + FlashROM_Release + + + + $PROJ_DIR$\defines\cc26x2r1lp_app_FlashROM_Release.opt + + FlashROM_Debug + + + + + $PROJ_DIR$\..\..\ble_debug.cfg + + FlashROM_Release + + + + $PROJ_DIR$\..\..\ble_release.cfg + + FlashROM_Debug + + + + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack\common\cc26xx\iar\cc26xx_app_and_stack_agama.icf + + + diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/defines/cc26x2r1lp_app_FlashROM_Debug.opt b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/defines/cc26x2r1lp_app_FlashROM_Debug.opt new file mode 100644 index 0000000..3180286 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/defines/cc26x2r1lp_app_FlashROM_Debug.opt @@ -0,0 +1,19 @@ +-DBOARD_DISPLAY_USE_LCD=0 +-DBOARD_DISPLAY_USE_UART=1 +-DBOARD_DISPLAY_USE_UART_ANSI=1 +-DCC26X2 +-DCC26X2R1_LAUNCHXL +-DCC26XX +-DxDEBUG_SW_TRACE +-DDeviceFamily_CC26X2 +-DICALL_EVENTS +-DICALL_JT +-DICALL_LITE +-DICALL_MAX_NUM_ENTITIES=6 +-DICALL_MAX_NUM_TASKS=3 +-DICALL_STACK0_ADDR +-DMAX_NUM_BLE_CONNS=8 +-DPOWER_SAVING +-DSTACK_LIBRARY +-DTBM_ACTIVE_ITEMS_ONLY +-DUSE_ICALL diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/defines/cc26x2r1lp_app_FlashROM_Release.opt b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/defines/cc26x2r1lp_app_FlashROM_Release.opt new file mode 100644 index 0000000..def3368 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/app/defines/cc26x2r1lp_app_FlashROM_Release.opt @@ -0,0 +1,20 @@ +-DBOARD_DISPLAY_USE_LCD=0 +-DBOARD_DISPLAY_USE_UART=1 +-DBOARD_DISPLAY_USE_UART_ANSI=1 +-DCC26X2 +-DCC26X2R1_LAUNCHXL +-DCC26XX +-DxDEBUG_SW_TRACE +-DDeviceFamily_CC26X2 +-DICALL_EVENTS +-DICALL_JT +-DICALL_LITE +-DICALL_MAX_NUM_ENTITIES=6 +-DICALL_MAX_NUM_TASKS=3 +-DICALL_STACK0_ADDR +-DMAX_NUM_BLE_CONNS=25 +-DPOWER_SAVING +-DSTACK_LIBRARY +-DTBM_ACTIVE_ITEMS_ONLY +-DUSE_ICALL +-DHEAPMGR_METRICS \ No newline at end of file diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/stack/cc26x2r1lp_stack.ewp b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/stack/cc26x2r1lp_stack.ewp new file mode 100644 index 0000000..6e35718 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/stack/cc26x2r1lp_stack.ewp @@ -0,0 +1,1321 @@ + + + 3 + + FlashROM_Library + + ARM + + 1 + + General + 3 + + 30 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + $TOOLS_BLE_DIR$\lib_search\lib_search.exe --opt $EXAMPLE_BLE_ROOT$\tirtos\build_config.opt --lib-dir $SRC_BLE_DIR$\blelib\cc26x2r1 --cmd $PROJ_DIR$\..\config\lib_linker.cmd --xml $TOOLS_BLE_DIR$\lib_search\lib_search.xml --sym-dir $SRC_BLE_DIR$\symbols\cc26x2r1 + + + + + ILINK + 0 + + 20 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + HAL + + API + + $SRC_BLE_DIR$\hal\src\target\_common\crypto_api.h + + + $SRC_BLE_DIR$\hal\src\target\_common\ecc_api.h + + + $SRC_BLE_DIR$\hal\src\target\_common\rf_api.h + + + $SRC_BLE_DIR$\hal\src\target\_common\rtos_drivers.h + + + $SRC_BLE_DIR$\hal\src\target\_common\trng_api.h + + + + Common + + $SRC_BLE_DIR$\hal\src\common\hal_assert.c + + + + Include + + $SRC_BLE_DIR$\hal\src\inc\hal_adc.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_assert.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_board.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_defs.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_key.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_lcd.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_led.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_sleep.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_timer.h + + + $SRC_BLE_DIR$\hal\src\inc\hal_uart.h + + + + Target + + CC2650 + + _common + + $SRC_BLE_DIR$\hal\src\target\_common\hal_mcu.h + + + $SRC_BLE_DIR$\hal\src\target\_common\cc26xx\mb.h + + + $SRC_BLE_DIR$\hal\src\target\_common\cc26xx\rf_hal.h + + + + Config + + $SRC_BLE_DIR$\hal\src\target\_common\hal_board_cfg.h + + + + Drivers + + $SRC_BLE_DIR$\hal\src\target\_common\hal_flash_wrapper.c + + + $SRC_BLE_DIR$\hal\src\target\_common\hal_rtc_wrapper.h + + + $SRC_BLE_DIR$\hal\src\target\_common\hal_trng_wrapper.c + + + $SRC_BLE_DIR$\hal\src\target\_common\hal_trng_wrapper.h + + + + + + + Host + + $SRC_BLE_DIR$\host\gap.c + + + $SRC_BLE_DIR$\host\gapbondmgr.c + + + $SRC_BLE_DIR$\inc\gapbondmgr.h + + + $SRC_BLE_DIR$\inc\gapgattserver.h + + + $SRC_BLE_DIR$\host\gatt_uuid.c + + + $SRC_BLE_DIR$\inc\gatt_uuid.h + + + $SRC_BLE_DIR$\inc\gattservapp.h + + + $SRC_BLE_DIR$\host\gattservapp_util.c + + + $SRC_BLE_DIR$\host\sm_ecc.c + + + + ICallBLE + + $SRC_BLE_DIR$\icall\inc\ble_dispatch.h + + + $SRC_BLE_DIR$\icall\stack\ble_dispatch_JT.c + + + $SRC_BLE_DIR$\icall\stack\ble_dispatch_lite.c + + + $SRC_BLE_DIR$\icall\src\icall_lite_translation.c + + + + NPI + + $SRC_BLE_DIR$\common\cc26xx\npi\stack\npi.c + + + + OSAL + + $SRC_BLE_DIR$\osal\src\inc\comdef.h + + + $SRC_BLE_DIR$\osal\src\common\osal.c + + + $SRC_BLE_DIR$\osal\src\inc\osal.h + + + $SRC_BLE_DIR$\osal\src\common\osal_bufmgr.c + + + $SRC_BLE_DIR$\osal\src\inc\osal_bufmgr.h + + + $SRC_BLE_DIR$\osal\src\common\osal_cbtimer.c + + + $SRC_BLE_DIR$\osal\src\inc\osal_cbtimer.h + + + $SRC_BLE_DIR$\osal\src\common\osal_clock.c + + + $SRC_BLE_DIR$\osal\src\inc\osal_clock.h + + + $SRC_BLE_DIR$\osal\src\common\osal_list.c + + + $SRC_BLE_DIR$\osal\src\inc\osal_list.h + + + $SRC_BLE_DIR$\osal\src\inc\osal_memory.h + + + $SRC_BLE_DIR$\osal\src\common\osal_memory_icall.c + + + $SRC_BLE_DIR$\osal\src\common\osal_pwrmgr.c + + + $SRC_BLE_DIR$\osal\src\inc\osal_pwrmgr.h + + + $SRC_BLE_DIR$\osal\src\inc\osal_snv.h + + + $SRC_BLE_DIR$\osal\src\mcu\cc26xx\osal_snv_wrapper.c + + + $SRC_BLE_DIR$\osal\src\inc\osal_task.h + + + $SRC_BLE_DIR$\osal\src\common\osal_timers.c + + + $SRC_BLE_DIR$\osal\src\inc\osal_timers.h + + + + ROM + + $SRC_BLE_DIR$\rom\r2\common_rom_init.c + + FlashROM_Library + + + + $SRC_BLE_DIR$\rom\r2\rom_flash_jt.h + + FlashROM_Library + + + + $SRC_BLE_DIR$\rom\r2\rom_init.c + + FlashROM_Library + + + + + Startup + + $SRC_BLE_DIR$\icall\stack\ble_user_config.c + + + $SRC_BLE_DIR$\common\cc26xx\icall_startup.c + + + $EXAMPLE_BLE_ROOT$\src\stack\osal_icall_ble.c + + + + Tools + + defines + + $PROJ_DIR$\defines\cc26x2r1lp_stack_FlashROM_Library.opt + + + + $SRC_BLE_DIR$\config\build_components.opt + + + $PROJ_DIR$\..\..\build_config.opt + + + $SRC_BLE_DIR$\common\cc26xx\onboard.c + + + $SRC_BLE_DIR$\common\cc26xx\onboard.h + + + diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/stack/defines/cc26x2r1lp_stack_FlashROM_Library.opt b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/stack/defines/cc26x2r1lp_stack_FlashROM_Library.opt new file mode 100644 index 0000000..1b210e2 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/stack/defines/cc26x2r1lp_stack_FlashROM_Library.opt @@ -0,0 +1,17 @@ +-DCC26X2 +-DCC26X2R1_LAUNCHXL +-DCC26XX +-DxDEBUG +-DxDEBUG_ENC +-DxDEBUG_GPIO +-DxDEBUG_SW_TRACE +-DDeviceFamily_CC26X2 +-DEXT_HAL_ASSERT +-DFLASH_ONLY_BUILD +-DICALL_EVENTS +-DICALL_JT +-DICALL_LITE +-DOSAL_CBTIMER_NUM_TASKS=1 +-DPOWER_SAVING +-DSTACK_LIBRARY +-DUSE_ICALL diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/tree_structure_network.custom_argvars b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/tree_structure_network.custom_argvars new file mode 100644 index 0000000..acc1950 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/tree_structure_network.custom_argvars @@ -0,0 +1,34 @@ + + + + + + SIMPLELINK_CORE_SDK_INSTALL_DIR + C:\ti\simplelink_cc26x2_sdk_2_30_00_34 + + + XDCROOT + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\..\xdctools_3_50_08_24_core + + + EXAMPLE_BLE_ROOT + $PROJ_DIR$\..\..\.. + + + XDCPATH + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\kernel\tirtos\packages;$SIMPLELINK_CORE_SDK_INSTALL_DIR$\source;$SRC_BLE_DIR$ + + + SRC_BLE_DIR + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\source\ti\ble5stack + + + TOOLS_BLE_DIR + $SIMPLELINK_CORE_SDK_INSTALL_DIR$\tools\ble5stack + + + SRC_LOCAL_DIR + $EXAMPLE_BLE_ROOT$/../../../../../ + + + diff --git a/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/tree_structure_network.eww b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/tree_structure_network.eww new file mode 100644 index 0000000..b092630 --- /dev/null +++ b/examples/rtos/CC26X2R1_LAUNCHXL/ble5apps/tree_structure_network/tirtos/iar/tree_structure_network.eww @@ -0,0 +1,12 @@ + + + + + $WS_DIR$\app\cc26x2r1lp_app.ewp + + + $WS_DIR$\stack\cc26x2r1lp_stack.ewp + + + + diff --git a/source/ti/ble5stack/profiles/tree_structure_network/tree_network_service.c b/source/ti/ble5stack/profiles/tree_structure_network/tree_network_service.c new file mode 100644 index 0000000..215e8c4 --- /dev/null +++ b/source/ti/ble5stack/profiles/tree_structure_network/tree_network_service.c @@ -0,0 +1,477 @@ +/****************************************************************************** + + @file tree_network_service.c + + @brief This file contains the Simple GATT profile sample GATT service profile + for use with the BLE sample application. + + Group: CMCU, LPRF + Target Device: CC2652 + + ****************************************************************************** + + Copyright (c) 2010-2019, 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 +#include +#include "util.h" +/* This Header file contains all BLE API and icall structure definition */ +#include "icall_ble_api.h" + +#include "tree_network_service.h" + +/********************************************************************* + * MACROS + */ + +/********************************************************************* + * CONSTANTS + */ + +#define SERVAPP_NUM_ATTR_SUPPORTED 17 + +/********************************************************************* + * TYPEDEFS + */ + +/********************************************************************* + * GLOBAL VARIABLES + */ +// Simple GATT Profile Service UUID: 0xFFF0 +CONST uint8 treeNetworkServiceServUUID[ATT_BT_UUID_SIZE] = +{ + LO_UINT16(TREENETWORKSERVICE_SERV_UUID), HI_UINT16(TREENETWORKSERVICE_SERV_UUID) +}; + +// Characteristic 1 UUID: 0xFFF1 +CONST uint8 treeNetworkServicechar1UUID[ATT_BT_UUID_SIZE] = +{ + LO_UINT16(TREENETWORKSERVICE_CHAR1_UUID), HI_UINT16(TREENETWORKSERVICE_CHAR1_UUID) +}; + +/********************************************************************* + * EXTERNAL VARIABLES + */ + +/********************************************************************* + * EXTERNAL FUNCTIONS + */ + +/********************************************************************* + * LOCAL VARIABLES + */ + +static treeNetworkServiceCBs_t *treeNetworkService_AppCBs = NULL; + +/********************************************************************* + * Profile Attributes - variables + */ + +// Simple Profile Service attribute +static CONST gattAttrType_t treeNetworkServiceService = { ATT_BT_UUID_SIZE, treeNetworkServiceServUUID }; + + +// Simple Profile Characteristic 1 Properties +static uint8 treeNetworkServiceChar1Props = GATT_PROP_NOTIFY | GATT_PROP_WRITE; + +// Characteristic 1 Value +static uint8 treeNetworkServiceChar1[TREENETWORKSERVICE_CHAR1_LEN] = {0, 0, 0}; + +static gattCharCfg_t *treeNetworkServiceChar1Config; + +/********************************************************************* + * Profile Attributes - Table + */ + +static gattAttribute_t treeNetworkServiceAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] = +{ + // Simple Profile Service + { + { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */ + GATT_PERMIT_READ, /* permissions */ + 0, /* handle */ + (uint8 *)&treeNetworkServiceService /* pValue */ + }, + + // Characteristic 1 Declaration + { + { ATT_BT_UUID_SIZE, characterUUID }, + GATT_PERMIT_READ, + 0, + &treeNetworkServiceChar1Props + }, + + // Characteristic Value 1 + { + { ATT_BT_UUID_SIZE, treeNetworkServicechar1UUID }, + GATT_PERMIT_READ | GATT_PERMIT_WRITE, + 0, + treeNetworkServiceChar1 + }, + + // Characteristic 1 configuration + { + { ATT_BT_UUID_SIZE, clientCharCfgUUID }, + GATT_PERMIT_READ | GATT_PERMIT_WRITE, + 0, + (uint8 *)&treeNetworkServiceChar1Config + }, +}; + +/********************************************************************* + * LOCAL FUNCTIONS + */ +static bStatus_t treeNetworkService_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 treeNetworkService_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 treeNetworkServiceCBs = +{ + treeNetworkService_ReadAttrCB, // Read callback function pointer + treeNetworkService_WriteAttrCB, // Write callback function pointer + NULL // Authorization callback function pointer +}; + +/********************************************************************* + * PUBLIC FUNCTIONS + */ + +/********************************************************************* + * @fn TreeNetworkService_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 TreeNetworkService_AddService( uint32 services ) +{ + uint8 status; + + // Allocate Client Characteristic Configuration table + treeNetworkServiceChar1Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) * + MAX_NUM_BLE_CONNS ); + if ( treeNetworkServiceChar1Config == NULL ) + { + return ( bleMemAllocError ); + } + + // Initialize Client Characteristic Configuration attributes + GATTServApp_InitCharCfg( LINKDB_CONNHANDLE_INVALID, treeNetworkServiceChar1Config ); + + if ( services & TREENETWORKSERVICE_SERVICE ) + { + // Register GATT attribute list and CBs with GATT Server App + status = GATTServApp_RegisterService( treeNetworkServiceAttrTbl, + GATT_NUM_ATTRS( treeNetworkServiceAttrTbl ), + GATT_MAX_ENCRYPT_KEY_SIZE, + &treeNetworkServiceCBs ); + } + else + { + status = SUCCESS; + } + + return ( status ); +} + +/********************************************************************* + * @fn TreeNetworkService_RegisterAppCBs + * + * @brief Registers the application callback function. Only call + * this function once. + * + * @param callbacks - pointer to application callbacks. + * + * @return SUCCESS or bleAlreadyInRequestedMode + */ +bStatus_t TreeNetworkService_RegisterAppCBs( treeNetworkServiceCBs_t *appCallbacks ) +{ + if ( appCallbacks ) + { + treeNetworkService_AppCBs = appCallbacks; + + return ( SUCCESS ); + } + else + { + return ( bleAlreadyInRequestedMode ); + } +} + +/********************************************************************* + * @fn TreeNetworkService_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 TreeNetworkService_SetParameter( uint8 param, uint8 len, void *value ) +{ + bStatus_t ret = SUCCESS; + switch ( param ) + { + case TREENETWORKSERVICE_CHAR1: + //if ( len == TREENETWORKSERVICE_CHAR1_LEN ) + if ( len > 1 ) + { + VOID memcpy( treeNetworkServiceChar1, value, len ); + // See if Notification has been enabled + GATTServApp_ProcessCharCfg( treeNetworkServiceChar1Config, treeNetworkServiceChar1, FALSE, + treeNetworkServiceAttrTbl, GATT_NUM_ATTRS( treeNetworkServiceAttrTbl ), + INVALID_TASK_ID, treeNetworkService_ReadAttrCB ); + } + else + { + ret = bleInvalidRange; + } + break; + + default: + ret = INVALIDPARAMETER; + break; + } + + return ( ret ); +} + +/********************************************************************* + * @fn TreeNetworkService_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 TreeNetworkService_GetParameter( uint8 param, void *value ) +{ + bStatus_t ret = SUCCESS; + switch ( param ) + { + case TREENETWORKSERVICE_CHAR1: + VOID memcpy( value, treeNetworkServiceChar1, TREENETWORKSERVICE_CHAR1_LEN ); + break; + + default: + ret = INVALIDPARAMETER; + break; + } + + return ( ret ); +} + +/********************************************************************* + * @fn treeNetworkService_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 treeNetworkService_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 + + // characteristic 1 does not have read permissions, but because it + // can be sent as a notification, it is included here + case TREENETWORKSERVICE_CHAR1_UUID: + *pLen = TREENETWORKSERVICE_CHAR1_LEN; + VOID memcpy( pValue, pAttr->pValue, TREENETWORKSERVICE_CHAR1_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 treeNetworkService_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 treeNetworkService_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 TREENETWORKSERVICE_CHAR1_UUID: + + //Validate the value + // Make sure it's not a blob oper + if ( offset == 0 ) + { + //if ( len != 1 ) + if ( len > 255 ) + { + 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]; + memcpy(pCurValue, pValue, TREENETWORKSERVICE_CHAR1_LEN); + + if( pAttr->pValue == treeNetworkServiceChar1 ) + { + notifyApp = TREENETWORKSERVICE_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 ) && treeNetworkService_AppCBs && treeNetworkService_AppCBs->pfnTreeNetworkServiceChange ) + { + treeNetworkService_AppCBs->pfnTreeNetworkServiceChange( notifyApp ); + } + + return ( status ); +} + +/********************************************************************* +*********************************************************************/ diff --git a/source/ti/ble5stack/profiles/tree_structure_network/tree_network_service.h b/source/ti/ble5stack/profiles/tree_structure_network/tree_network_service.h new file mode 100644 index 0000000..1fd15a9 --- /dev/null +++ b/source/ti/ble5stack/profiles/tree_structure_network/tree_network_service.h @@ -0,0 +1,142 @@ +/****************************************************************************** + + @file tree_network_service.h + + @brief This file contains the Simple GATT profile definitions and prototypes + prototypes. + + Group: CMCU, LPRF + Target Device: CC2652 + + ****************************************************************************** + + Copyright (c) 2010-2019, 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. + + *****************************************************************************/ + +#ifndef TREENETWORKSERVICE_H +#define TREENETWORKSERVICE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + * INCLUDES + */ + +/********************************************************************* + * CONSTANTS + */ + +// Profile Parameters +#define TREENETWORKSERVICE_CHAR1 0 // RW uint8 - Profile Characteristic 1 value + +// Simple Profile Service UUID +#define TREENETWORKSERVICE_SERV_UUID 0xFFF0 + +// Key Pressed UUID +#define TREENETWORKSERVICE_CHAR1_UUID 0xFFF1 + +// Simple Keys Profile Services bit fields +#define TREENETWORKSERVICE_SERVICE 0x00000001 + +// Length of Characteristic 1 in bytes +#define TREENETWORKSERVICE_CHAR1_LEN 5 + +/********************************************************************* + * Profile Callbacks + */ + +// Callback when a characteristic value has changed +typedef void (*treeNetworkServiceChange_t)( uint8 paramID ); + +typedef struct +{ + treeNetworkServiceChange_t pfnTreeNetworkServiceChange; // Called when characteristic value changes +} treeNetworkServiceCBs_t; + +/********************************************************************* + * API FUNCTIONS + */ + + +/* + * TreeNetworkService_AddService- Initializes the Simple GATT 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. + */ + +extern bStatus_t TreeNetworkService_AddService( uint32 services ); + +/* + * TreeNetworkService_RegisterAppCBs - Registers the application callback function. + * Only call this function once. + * + * appCallbacks - pointer to application callbacks. + */ +extern bStatus_t TreeNetworkService_RegisterAppCBs( treeNetworkServiceCBs_t *appCallbacks ); + +/* + * TreeNetworkService_SetParameter - Set a Simple GATT Profile parameter. + * + * param - Profile parameter ID + * len - length of data to right + * 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). + */ +extern bStatus_t TreeNetworkService_SetParameter( uint8 param, uint8 len, void *value ); + +/* + * TreeNetworkService_GetParameter - Get a Simple GATT Profile parameter. + * + * param - Profile parameter ID + * 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). + */ +extern bStatus_t TreeNetworkService_GetParameter( uint8 param, void *value ); + + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* TREENETWORKSERVICE_H */