diff --git a/examples/lock-app/cc13x2_26x2/chip.syscfg b/examples/lock-app/cc13x2_26x2/chip.syscfg deleted file mode 100644 index 21978a1be2e902..00000000000000 --- a/examples/lock-app/cc13x2_26x2/chip.syscfg +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2020 Texas Instruments Incorporated - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * chip.syscfg - */ - -/* Modules */ -var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); -var AESECB = scripting.addModule("/ti/drivers/AESECB"); -var Button = scripting.addModule("/ti/drivers/apps/Button"); -var ECJPAKE = scripting.addModule("/ti/drivers/ECJPAKE"); -var LED = scripting.addModule("/ti/drivers/apps/LED"); -var NVS = scripting.addModule("/ti/drivers/NVS"); -var RF = scripting.addModule("/ti/drivers/RF"); -var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); -var RTOS = scripting.addModule("/ti/drivers/RTOS"); -var TRNG = scripting.addModule("/ti/drivers/TRNG"); -var Thread = scripting.addModule("/ti/thread/thread"); -var SHA2 = scripting.addModule("/ti/drivers/SHA2"); -var UART = scripting.addModule("/ti/drivers/UART"); - -/* Instances */ -var AESCCM = AESCCM.addInstance(); -var AESECB = AESECB.addInstance(); -var Button1 = Button.addInstance(); -var Button2 = Button.addInstance(); -var ECJPAKE = ECJPAKE.addInstance(); -var NVS1 = NVS.addInstance(); -var SHA21 = SHA2.addInstance(); -var LED1 = LED.addInstance(); -var LED2 = LED.addInstance(); -var TRNG1 = TRNG.addInstance(); -var UART1 = UART.addInstance(); -var UART2 = UART.addInstance(); - -/* RTOS */ -RTOS.name = "FreeRTOS"; - -/* Left Button */ -Button1.$name = "CONFIG_BTN_LEFT"; -Button1.$hardware = system.deviceData.board.components["BTN-1"]; -Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; -Button1.gpioPin.pull = "Pull Up"; -Button1.gpioPin.interruptTrigger = "Falling Edge"; -Button1.gpioPin.pinInstance.$name = "CONFIG_PIN_BTN1"; - -/* Left Button */ -Button2.$name = "CONFIG_BTN_RIGHT"; -Button2.$hardware = system.deviceData.board.components["BTN-2"]; -Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; -Button2.gpioPin.pull = "Pull Up"; -Button2.gpioPin.interruptTrigger = "Falling Edge"; -Button2.gpioPin.pinInstance.$name = "CONFIG_PIN_BTN2"; - -/* NVS */ -NVS1.$name = "CONFIG_NVSINTERNAL"; -NVS1.internalFlash.regionBase = 0x52000; // Base Address of Region -NVS1.internalFlash.regionSize = 0x4000; // Size of Region (in bytes) - -/* RF */ -RF.$name = "CONFIG_RF0"; -/* if an antenna component exists, assign it to the rf instance */ -if (system.deviceData.board && system.deviceData.board.components.RF) { - RF.$hardware = system.deviceData.board.components.RF; -} - -const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; -for(var setting in rfDesignSettings) -{ - RFDesign[setting] = rfDesignSettings[setting]; -} - -/* Red LED */ -LED1.$name = "CONFIG_LED_RED"; -LED1.$hardware = system.deviceData.board.components.LED_RED; -LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; -LED1.gpioPin.mode = "Output"; -LED1.gpioPin.callbackFunction = ""; -LED1.gpioPin.pinInstance.$name = "CONFIG_PIN_RLED"; - -/* Green LED */ -LED2.$name = "CONFIG_LED_GREEN"; -LED2.$hardware = system.deviceData.board.components.LED_GREEN; -LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; -LED2.gpioPin.mode = "Output"; -LED2.gpioPin.callbackFunction = ""; -LED2.gpioPin.pinInstance.$name = "CONFIG_PIN_GLED"; - -/* Debug UART */ -UART1.$hardware = system.deviceData.board.components.XDS110UART; -UART1.$name = "CONFIG_UART_DEBUG"; - -/* Display UART */ -UART2.$name = "CONFIG_DISPLAY_UART"; -UART2.uart.txPin.$suggestSolution = "boosterpack.32"; -UART2.uart.rxPin.$suggestSolution = "boosterpack.18"; - -/* TRNG */ -TRNG1.$name = "CONFIG_TRNG_0"; - -/* Thread */ -Thread.deviceType = "mtd"; -Thread.deviceTypeReadOnly = true; -/* Thread SysConfig generated sources are not used until the upstream modules - * can be updated to enable CHIP. - */ diff --git a/examples/lock-app/cc13x2_26x2/.gn b/examples/lock-app/cc13x2x7_26x2x7/.gn similarity index 100% rename from examples/lock-app/cc13x2_26x2/.gn rename to examples/lock-app/cc13x2x7_26x2x7/.gn diff --git a/examples/lock-app/cc13x2_26x2/BUILD.gn b/examples/lock-app/cc13x2x7_26x2x7/BUILD.gn similarity index 67% rename from examples/lock-app/cc13x2_26x2/BUILD.gn rename to examples/lock-app/cc13x2x7_26x2x7/BUILD.gn index 1a76acf2b2f782..3cadbc29731837 100644 --- a/examples/lock-app/cc13x2_26x2/BUILD.gn +++ b/examples/lock-app/cc13x2x7_26x2x7/BUILD.gn @@ -24,7 +24,7 @@ import("${ti_simplelink_sdk_build_root}/ti_simplelink_sdk.gni") assert(current_os == "freertos") -project_dir = "${chip_root}/examples/lock-app/cc13x2_26x2" +project_dir = "${chip_root}/examples/lock-app/cc13x2x7_26x2x7" ti_simplelink_sdk("sdk") { include_dirs = [ "${project_dir}/main/include" ] @@ -45,6 +45,10 @@ ti_sysconfig("sysconfig") { "ti_radio_config.h", "ti_drivers_config.c", "ti_drivers_config.h", + "ti_ble_config.c", + "ti_ble_config.h", + "ti_dmm_application_policy.c", + "ti_dmm_application_policy.h", # disabled until upstream generation is aligned #"tiop_config.h", @@ -55,6 +59,17 @@ ti_sysconfig("sysconfig") { #"syscfg_c.rov.xs", #"ti_utils_runtime_model.gv", #"ti_utils_runtime_Makefile", + #"ti_ble_app_config.opt", + #"ti_build_config.opt", + ] + public_configs = [ ":sdk_dmm_config" ] + + cflags = [ + "-Wno-comment", + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_ble_app_config.opt", + root_build_dir), + "@" + rebase_path("${target_gen_dir}/sysconfig/ti_build_config.opt", + root_build_dir), ] } @@ -67,14 +82,14 @@ ti_simplelink_executable("lock_app") { "${project_dir}/main/include", ] defines = [] - output_name = "chip-cc13x2_26x2-lock-example.out" + output_name = "chip-${ti_simplelink_board}-lock-example.out" public_deps = [ ":sdk", ":sysconfig", "${chip_root}/examples/lock-app/lock-common", "${chip_root}/src/lib", - "${openthread_root}:libopenthread-cli-mtd", + "${openthread_root}:libopenthread-cli-ftd", ] sources = [ @@ -84,17 +99,27 @@ ti_simplelink_executable("lock_app") { "${project_dir}/main/main.cpp", ] + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-sign-compare", + ] + output_dir = root_out_dir - ldscript = "${ti_simplelink_sdk_root}/source/ti/boards/cc13x2_cc26x2/cc13x2_cc26x2_freertos.lds" + ldscript = "${ti_simplelink_sdk_root}/source/ti/dmm/apps/common/freertos/cc13x2x7_cc26x2x7.lds" - ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ] + ldflags = [ + "-L${ti_simplelink_sdk_root}/source", + rebase_path("${target_gen_dir}/sysconfig/ti_utils_build_linker.cmd.genlibs", + root_build_dir), + "-T" + rebase_path(ldscript, root_build_dir), + ] } -group("cc13x2_26x2") { +group("cc13x2x7_26x2x7") { deps = [ ":lock_app" ] } group("default") { - deps = [ ":cc13x2_26x2" ] + deps = [ ":cc13x2x7_26x2x7" ] } diff --git a/examples/lock-app/cc13x2_26x2/README.md b/examples/lock-app/cc13x2x7_26x2x7/README.md similarity index 55% rename from examples/lock-app/cc13x2_26x2/README.md rename to examples/lock-app/cc13x2x7_26x2x7/README.md index 88a45f9d1e0662..64e6b1b9577240 100644 --- a/examples/lock-app/cc13x2_26x2/README.md +++ b/examples/lock-app/cc13x2x7_26x2x7/README.md @@ -15,6 +15,12 @@ CC13X2_26X2 family of Wireless MCUs. - [UniFlash](#uniflash) - [Code Composer Studio](#code-composer-studio) - [Viewing Logging Output](#viewing-logging-output) + - [Running the Example](#running-the-example) + - [Provisioning](#provisioning) + - [Bluetooth LE Advertising](#bluetooth-le-advertising) + - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) + - [CHIP Remote Commands](#chip-remote-commands) + - [TI Support](#ti-support) --- @@ -26,9 +32,10 @@ The CC13X2_26X2 lock example application provides a working demonstration of a connected door lock device. This uses the open-source CHIP implementation and the Texas Instruments SimpleLinkā„¢ CC13x2 and CC26x2 software development kit. -This example is enabled to build on all members of the `CC13X2_26X2` family of -MCUs [recommended for Thread][ti_thread_dnd]. By default this example targets -the [CC1352R1_LAUNCHXL][cc1352r1_launchxl] LaunchPad. +This example is enabled to build for CC2652R7 devices. This upcoming devices are +currently not yet in full production. For more information on device +availability or early access to an engineering build of our CHIP-enabled SDK, +please reach out [here][ti_cc13x2_26x2_r7_chip_request]. The lock example is intended to serve both as a means to explore the workings of CHIP, as well as a template for creating real products based on the Texas @@ -39,10 +46,16 @@ Instruments devices. This example application has a simple User Interface to depict the state of the door lock and to control the state. The user LEDs on the LaunchPad are set on when the lock is locked, and are set off when unlocked. The LEDs will flash when -in the transition state between locked and unlocked. The user buttons are used -for requesting lock and unlock of the door lock. The left button (`BTN-1`) is -used to request locking. The right button (`BTN-2`) us used to request -unlocking. +in the transition state between locked and unlocked. + +Short presses (less than 1000ms) of the user buttons are used for requesting +lock and unlock of the door lock. The left button (`BTN-1`) is used to request +locking. The right button (`BTN-2`) is used to request unlocking. + +Long presses (greater than 1000ms) of the user buttons are used for controlling +BLE advertisements. The left button (`BTN-1`) is used to disable advertisements +if they are enabled. The Right button (`BTN-2`) is used to enable +advertisements. ## Building @@ -51,8 +64,8 @@ unlocking. Some initial setup is necessary for preparing the build environment. This section will need to be done when migrating to new versions of the SDK. -- Download and install the [SimpleLinkā„¢ CC13x2 and CC26x2 software development - kit (SDK)][simplelink_sdk] ([4.30.00.54][simplelink_sdk_4.30.00.54]) +- An engineering SDK from TI is required. Please request access for it + [here][ti_cc13x2_26x2_r7_chip_request]. - Follow the default installation instructions when executing the installer. @@ -64,7 +77,7 @@ section will need to be done when migrating to new versions of the SDK. - Download and install [SysConfig][sysconfig] ([sysconfig-1.5.0_1397][sysconfig-1.5.0_1397]) - - This may have already been installed with your SimpleLink SDK install + - This may have already been installed with your SimpleLink SDK install. - If you have installed different versions, the build defaults will need to be changed to reflect this in @@ -82,7 +95,7 @@ section will need to be done when migrating to new versions of the SDK. - You will have to ensure that the default version of Python 3 is Python 3.8. -- run the bootstrap script to setup the build environment. +- Run the bootstrap script to setup the build environment. ``` $ cd ~/connectedhomeip @@ -90,23 +103,6 @@ section will need to be done when migrating to new versions of the SDK. ``` -#### Changes to the TI SDK - -The OpenThread library will set the short address assigned to the device as soon -as it receives the Child ID response. This may happen while the radio driver is -still in transmit mode. This is easilly fixed by removing state check in the -else condition in -`${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/radio.c` -on linke 1791. - -``` -- else if (sState != platformRadio_phyState_Transmit) -+ else - { - sReceiveCmd.localShortAddr = aAddress; - } -``` - ### Compilation It is necessary to activate the environment in every new shell. Then run GN and @@ -123,7 +119,7 @@ Ninja to build the executable. - Run the build to produce a default executable. By default on Linux both the TI SimpleLink SDK and Sysconfig are located in a `ti` folder in the user's home directory, and you must provide the absolute path to them. For example - `/home/username/ti/simplelink_cc13x2_26x2_sdk_4_30_00_54` and + `/home/username/ti/simplelink_cc13x2_26x2_sdk_4_40_05_02_eng` and `/home/username/ti/sysconfig_1.6.0`. On Windows the default directory is `C:\ti` @@ -163,8 +159,66 @@ terminal emulator to that port to see the output with the following options: | Parity | `None` | | Flow control | `None` | +## Running the Example + +Once a device has been flashed with this example, it can now join and operate in +an existing Thread network. The following sections assume that a Thread network +is already active, and has at least one [OpenThread Border +Router][ot_border_router_setup]. + +### Provisioning + +The first step to bring the CHIP device onto the network is to provision it. Our +example accomplishes this with Bluetooth Low Energy (BLE) and the +[CHIPTool](../../../src/android/CHIPTool/README.md) mobile app. + +#### Bluetooth LE Advertising + +To provision this example onto a Thread network, the device must be discoverable +over Bluetooth LE. BLE advertising is started by long pressing the right button +(greater than 1000ms), labeled `BTN-2` on the silkscreen. Once the device is +fully provisioned, BLE advertising will stop. + +#### Bluetooth LE Rendezvous + +In this example, the provisioning procedure (called Rendezvous) is done over +Bluetooth LE between a CHIP device (lock-app) and the CHIP controller +(CHIPTool), where the controller has the commissioner role. + +To start the rendezvous, the controller must get the commissioning information +from the CHIP device. + +This is done by scanning a QR code. A URL will be displayed on the lock-app's +log ([UART terminal](#viewing-logging-output)). It will look like the following: + +``` +SetupQRCode: [CH:.81TM -00 0C9SS0] +Copy/paste the below URL in a browser to see the QR Code: +https://dhrishi.github.io/connectedhomeip/qrcode.html?data=CH%3A.81TM%20-00%200C9SS0 +``` + +You can directly navigate to the webpage URL displayed (which has QR payload +pre-loaded). Alternatively, you can navigate to [the QR code +generator][qr_code_generator] and enter in the payload shown in `SetupQRCode` +(in this case `CH:.81TM -00 0C9SS0`). + +### CHIP Remote Commands + +Once the CHIP device is provisioned and operating on the network, CHIPTool can +be used to control the device. During the provisioning process, the CHIP device +would have sent one of its newly assigned IPv6 addresses to the CHIPTool. + +In the app, you should see an On/Off cluster; this corresponds to the lock-app. +You can now control the lock-app CHIP device from the smartphone! + +## TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + [chip]: https://github.com/project-chip/connectedhomeip [cc1352r1_launchxl]: https://www.ti.com/tool/LAUNCHXL-CC1352R1 +[e2e]: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread [simplelink_sdk]: https://www.ti.com/tool/SIMPLELINK-CC13X2-26X2-SDK [simplelink_sdk_4.30.00.54]: https://www.ti.com/tool/download/SIMPLELINK-CC13X2-26X2-SDK/4.30.00.54 @@ -173,3 +227,7 @@ terminal emulator to that port to see the output with the following options: http://software-dl.ti.com/ccs/esd/sysconfig/sysconfig-1.5.0_1397-setup.run [ti_thread_dnd]: https://www.ti.com/wireless-connectivity/thread/design-development.html +[ti_cc13x2_26x2_r7_chip_request]: https://ti.com/chip_sdk +[ot_border_router_setup]: + https://openthread.io/guides/border-router/beaglebone-black +[qr_code_generator]: https://dhrishi.github.io/connectedhomeip/qrcode.html diff --git a/examples/lock-app/cc13x2_26x2/args.gni b/examples/lock-app/cc13x2x7_26x2x7/args.gni similarity index 87% rename from examples/lock-app/cc13x2_26x2/args.gni rename to examples/lock-app/cc13x2x7_26x2x7/args.gni index ad369fe0d90291..96bab211852345 100644 --- a/examples/lock-app/cc13x2_26x2/args.gni +++ b/examples/lock-app/cc13x2x7_26x2x7/args.gni @@ -19,11 +19,11 @@ ti_simplelink_sdk_target = get_label_info(":sdk", "label_no_toolchain") ti_simplelink_sysconfig_target = get_label_info(":sysconfig", "label_no_toolchain") -ti_simplelink_board = "CC1352R1_LAUNCHXL" +ti_simplelink_board = "LP_CC2652R7" # use -Os instead of -Og #is_debug = false -# disable BLE for now -chip_config_network_layer_ble = false -chip_bypass_rendezvous = true +# BLE options +chip_config_network_layer_ble = true +chip_bypass_rendezvous = false diff --git a/examples/lock-app/cc13x2_26x2/build_overrides b/examples/lock-app/cc13x2x7_26x2x7/build_overrides similarity index 100% rename from examples/lock-app/cc13x2_26x2/build_overrides rename to examples/lock-app/cc13x2x7_26x2x7/build_overrides diff --git a/examples/lock-app/cc13x2x7_26x2x7/chip.syscfg b/examples/lock-app/cc13x2x7_26x2x7/chip.syscfg new file mode 100644 index 00000000000000..c93e60f4846aaa --- /dev/null +++ b/examples/lock-app/cc13x2x7_26x2x7/chip.syscfg @@ -0,0 +1,214 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Texas Instruments Incorporated + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Modules */ +var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); +var AESECB = scripting.addModule("/ti/drivers/AESECB"); +var Button = scripting.addModule("/ti/drivers/apps/Button"); +var ECJPAKE = scripting.addModule("/ti/drivers/ECJPAKE"); +var LED = scripting.addModule("/ti/drivers/apps/LED"); +var NVS = scripting.addModule("/ti/drivers/NVS"); +var RF = scripting.addModule("/ti/drivers/RF"); +var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); +var RTOS = scripting.addModule("/ti/drivers/RTOS"); +var TRNG = scripting.addModule("/ti/drivers/TRNG"); +var Thread = scripting.addModule("/ti/thread/thread"); +var SHA2 = scripting.addModule("/ti/drivers/SHA2"); +var UART = scripting.addModule("/ti/drivers/UART"); +var ble = scripting.addModule("/ti/ble5stack/ble"); +var dmm = scripting.addModule("/ti/dmm/dmm"); +var AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG"); +var ECDH = scripting.addModule("/ti/drivers/ECDH"); + +/* Instances */ +var AESCCM1 = AESCCM.addInstance(); +var AESCCM2 = AESCCM.addInstance(); +var AESECB1 = AESECB.addInstance(); +var AESECB2 = AESECB.addInstance(); +var Button1 = Button.addInstance(); +var Button2 = Button.addInstance(); +var ECJPAKE = ECJPAKE.addInstance(); +var NVS1 = NVS.addInstance(); +var SHA21 = SHA2.addInstance(); +var LED1 = LED.addInstance(); +var LED2 = LED.addInstance(); +var TRNG1 = TRNG.addInstance(); +var TRNG2 = TRNG.addInstance(); +var TRNG3 = TRNG.addInstance(); +var UART1 = UART.addInstance(); +var UART2 = UART.addInstance(); +var AESCTRDRBG1 = AESCTRDRBG.addInstance(); +var ECDH1 = ECDH.addInstance(); +var ECDH2 = ECDH.addInstance(); + +AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; +AESCTRDRBG1.aesctrObject.$name = "CONFIG_AESCTR_0"; + +AESCCM1.$name = "CONFIG_AESCCM0"; +AESCCM2.$name = "CONFIG_AESCCM_1"; + +AESECB1.$name = "CONFIG_AESECB0"; +AESECB2.$name = "CONFIG_AESECB_1"; + +ECDH1.$name = "CONFIG_ECDH0"; +ECDH2.$name = "CONFIG_ECDH_1"; + +/* RTOS */ +RTOS.name = "FreeRTOS"; + +/* Left Button */ +Button1.$name = "CONFIG_BTN_LEFT"; +Button1.$hardware = system.deviceData.board.components["BTN-1"]; +Button1.gpioPin.$name = "CONFIG_GPIO_BTN1"; +Button1.gpioPin.pull = "Pull Up"; +Button1.gpioPin.interruptTrigger = "Falling Edge"; +Button1.gpioPin.pinInstance.$name = "CONFIG_PIN_BTN1"; + +/* Left Button */ +Button2.$name = "CONFIG_BTN_RIGHT"; +Button2.$hardware = system.deviceData.board.components["BTN-2"]; +Button2.gpioPin.$name = "CONFIG_GPIO_BTN2"; +Button2.gpioPin.pull = "Pull Up"; +Button2.gpioPin.interruptTrigger = "Falling Edge"; +Button2.gpioPin.pinInstance.$name = "CONFIG_PIN_BTN2"; + +/* ======== CCFG ======== */ +var CCFG = scripting.addModule("/ti/devices/CCFG"); +const deviceName = system.getScript("/ti/ti154stack/ti154stack_common.js").getLaunchPadFromDevice(); +const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; +for(var setting in ccfgSettings) +{ + CCFG[setting] = ccfgSettings[setting]; +} + +// Update LF Clock Source for CC2652RB devices +if(deviceName.includes("RB")) +{ + CCFG.srcClkLF = "Derived from HF XOSC"; +} +/* NVS */ +NVS1.$name = "CONFIG_NVSINTERNAL"; +NVS1.internalFlash.regionBase = 0x78000; +NVS1.internalFlash.regionSize = 0x4000; + +/* RF */ +RF.$name = "CONFIG_RF0"; +/* if an antenna component exists, assign it to the rf instance */ +if (system.deviceData.board && system.deviceData.board.components.RF) { + RF.$hardware = system.deviceData.board.components.RF; +} + +const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; +for(var setting in rfDesignSettings) +{ + RFDesign[setting] = rfDesignSettings[setting]; +} + +/* Red LED */ +LED1.$name = "CONFIG_LED_RED"; +LED1.$hardware = system.deviceData.board.components.LED_RED; +LED1.gpioPin.$name = "CONFIG_GPIO_RLED"; +LED1.gpioPin.mode = "Output"; +LED1.gpioPin.callbackFunction = ""; +LED1.gpioPin.pinInstance.$name = "CONFIG_PIN_RLED"; + +/* Green LED */ +LED2.$name = "CONFIG_LED_GREEN"; +LED2.$hardware = system.deviceData.board.components.LED_GREEN; +LED2.gpioPin.$name = "CONFIG_GPIO_GLED"; +LED2.gpioPin.mode = "Output"; +LED2.gpioPin.callbackFunction = ""; +LED2.gpioPin.pinInstance.$name = "CONFIG_PIN_GLED"; + +/* Debug UART */ +UART1.$hardware = system.deviceData.board.components.XDS110UART; +UART1.$name = "CONFIG_UART_DEBUG"; + +/* Display UART */ +UART2.$name = "CONFIG_DISPLAY_UART"; +UART2.uart.txPin.$suggestSolution = "boosterpack.32"; +UART2.uart.rxPin.$suggestSolution = "boosterpack.18"; + +/* TRNG */ +TRNG1.$name = "CONFIG_TRNG_0"; +TRNG2.$name = "CONFIG_TRNG_1"; +TRNG3.$name = "CONFIG_TRNG_APP"; + +/* Thread */ +Thread.deviceType = "ftd"; +Thread.deviceTypeReadOnly = true; +/* Thread SysConfig generated sources are not used until the upstream modules + * can be updated to enable CHIP. + */ +RTOS.name = "FreeRTOS"; + +/* BLE */ +ble.addressMode = "ADDRMODE_RP_WITH_PUBLIC_ID"; +ble.maxConnNum = 1; +ble.numOfAdvSets = 1; +ble.lockProject = true; +ble.oneLibSizeOpt = true; +ble.maxPDUSize = 255; +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; +ble.connUpdateParamsPeripheral.reqMinConnInt = 30; +ble.connUpdateParamsPeripheral.reqMaxConnInt = 50; + +ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; +ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; +ble.advSet1.advParam1.primIntMin = 100; +ble.advSet1.advParam1.primIntMax = 200; + +/* DMM */ +dmm.project = "ti_thread_thermostat_remote_display"; +dmm.stackRoles = ["blePeripheral","threadFTD"]; +dmm.lockStackRoles = true; +dmm.numApplicationStates = 10; +dmm.applicationState0 = "ANY"; +dmm.applicationState1 = "DMMPOLICY_BLE_IDLE"; +dmm.applicationState2 = "DMMPOLICY_BLE_ADV"; +dmm.applicationState3 = "DMMPOLICY_BLE_CONNECTING"; +dmm.applicationState4 = "DMMPOLICY_BLE_HIGH_BANDWIDTH"; +dmm.applicationState5 = "DMMPOLICY_BLE_CONNECTED"; +dmm.applicationState6 = "DMMPOLICY_BLE_OAD"; +dmm.applicationState7 = "DMMPOLICY_THREAD_IDLE"; +dmm.applicationState8 = "DMMPOLICY_THREAD_LINK_EST"; +dmm.applicationState9 = "DMMPOLICY_THREAD_DATA"; +dmm.policyArray.create(4); +dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; +dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; +dmm.policyArray[0].blePeripheral.applicationStates = ["applicationState6"]; +dmm.policyArray[0].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread0"; +dmm.policyArray[0].threadFTD.pause = "DMMPOLICY_PAUSED"; +dmm.policyArray[1].$name = "ti_dmm_policy_dmm_policy1"; +dmm.policyArray[1].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble1"; +dmm.policyArray[1].blePeripheral.applicationStates = ["applicationState3","applicationState4"]; +dmm.policyArray[1].blePeripheral.weight = 25; +dmm.policyArray[1].blePeripheral.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_BLE_CONNECTION"]; +dmm.policyArray[1].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread1"; +dmm.policyArray[2].$name = "ti_dmm_policy_dmm_policy2"; +dmm.policyArray[2].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble2"; +dmm.policyArray[2].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread2"; +dmm.policyArray[2].threadFTD.weight = 30; +dmm.policyArray[2].threadFTD.applicationStates = ["applicationState8"]; +dmm.policyArray[2].threadFTD.appliedActivity = ["DMMPOLICY_APPLIED_ACTIVITY_ALL"]; +dmm.policyArray[3].$name = "ti_dmm_policy_dmm_policy3"; +dmm.policyArray[3].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble3"; +dmm.policyArray[3].threadFTD.$name = "ti_dmm_policy_stack_dmm_stack_thread3"; +dmm.policyArray[3].threadFTD.weight = 1; diff --git a/examples/lock-app/cc13x2_26x2/doc/images/cc1352r1_launchxl.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/cc1352r1_launchxl.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/cc1352r1_launchxl.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/cc1352r1_launchxl.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-1.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-1.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-1.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-1.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-10.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-10.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-10.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-10.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-11.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-11.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-11.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-11.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-12.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-12.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-12.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-12.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-13.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-13.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-13.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-13.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-2.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-2.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-2.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-2.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-3.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-3.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-3.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-3.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-4.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-4.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-4.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-4.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-5.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-5.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-5.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-5.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-6.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-6.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-6.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-6.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-7.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-7.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-7.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-7.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-8.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-8.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-8.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-8.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/ccs-9.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-9.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/ccs-9.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/ccs-9.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/uniflash-1.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/uniflash-1.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/uniflash-1.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/uniflash-1.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/uniflash-2.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/uniflash-2.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/uniflash-2.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/uniflash-2.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/images/uniflash-3.jpg b/examples/lock-app/cc13x2x7_26x2x7/doc/images/uniflash-3.jpg similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/images/uniflash-3.jpg rename to examples/lock-app/cc13x2x7_26x2x7/doc/images/uniflash-3.jpg diff --git a/examples/lock-app/cc13x2_26x2/doc/programming-ccs.md b/examples/lock-app/cc13x2x7_26x2x7/doc/programming-ccs.md similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/programming-ccs.md rename to examples/lock-app/cc13x2x7_26x2x7/doc/programming-ccs.md diff --git a/examples/lock-app/cc13x2_26x2/doc/programming-uniflash.md b/examples/lock-app/cc13x2x7_26x2x7/doc/programming-uniflash.md similarity index 100% rename from examples/lock-app/cc13x2_26x2/doc/programming-uniflash.md rename to examples/lock-app/cc13x2x7_26x2x7/doc/programming-uniflash.md diff --git a/examples/lock-app/cc13x2_26x2/main/AppTask.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp similarity index 87% rename from examples/lock-app/cc13x2_26x2/main/AppTask.cpp rename to examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp index 3faface6713d5c..828b717bc2df90 100644 --- a/examples/lock-app/cc13x2_26x2/main/AppTask.cpp +++ b/examples/lock-app/cc13x2x7_26x2x7/main/AppTask.cpp @@ -25,6 +25,10 @@ #include "FreeRTOS.h" #include +#include +#include + +#include "QRCodeUtil.h" #include "DataModelHandler.h" @@ -35,7 +39,7 @@ #include #define APP_TASK_STACK_SIZE (4096) -#define APP_TASK_PRIORITY 2 +#define APP_TASK_PRIORITY 4 #define APP_EVENT_QUEUE_SIZE 10 using namespace ::chip::DeviceLayer; @@ -82,6 +86,9 @@ int AppTask::Init() cc13x2_26x2LogInit(); + // Init Chip memory management before the stack + chip::Platform::MemoryInit(); + ret = PlatformMgr().InitChipStack(); if (ret != CHIP_NO_ERROR) { @@ -98,7 +105,7 @@ int AppTask::Init() ; } - ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); + ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); if (ret != CHIP_NO_ERROR) { PLAT_LOG("ConnectivityMgr().SetThreadDeviceType() failed"); @@ -144,11 +151,11 @@ int AppTask::Init() LED_Params_init(&ledParams); // default PWM LED sAppRedHandle = LED_open(CONFIG_LED_RED, &ledParams); - LED_setOn(sAppRedHandle, LED_BRIGHTNESS_MAX); + LED_setOff(sAppRedHandle); LED_Params_init(&ledParams); // default PWM LED sAppGreenHandle = LED_open(CONFIG_LED_GREEN, &ledParams); - LED_setOn(sAppGreenHandle, LED_BRIGHTNESS_MAX); + LED_setOff(sAppGreenHandle); // Initialize buttons PLAT_LOG("Initialize buttons"); @@ -170,6 +177,11 @@ int AppTask::Init() BoltLockMgr().SetCallbacks(ActionInitiated, ActionCompleted); + ConfigurationMgr().LogDeviceConfig(); + + // QR code will be used with CHIP Tool + PrintQRCode(chip::RendezvousInformationFlags::kBLE); + return 0; } @@ -288,24 +300,38 @@ void AppTask::DispatchEvent(AppEvent * aEvent) case AppEvent::kEventType_ButtonLeft: if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { - BoltLockMgr().InitiateAction(0, BoltLockManager::UNLOCK_ACTION); + if (!BoltLockMgr().IsUnlocked()) + { + BoltLockMgr().InitiateAction(0, BoltLockManager::UNLOCK_ACTION); + } } else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { - // TODO: factory reset device - BoltLockMgr().InitiateAction(0, BoltLockManager::UNLOCK_ACTION); + // Disable BLE advertisements + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + ConnectivityMgr().SetBLEAdvertisingEnabled(false); + PLAT_LOG("Disabled BLE Advertisements"); + } } break; case AppEvent::kEventType_ButtonRight: if (AppEvent::kAppEventButtonType_Clicked == aEvent->ButtonEvent.Type) { - BoltLockMgr().InitiateAction(0, BoltLockManager::LOCK_ACTION); + if (BoltLockMgr().IsUnlocked()) + { + BoltLockMgr().InitiateAction(0, BoltLockManager::LOCK_ACTION); + } } else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { - // TODO: factory reset device - BoltLockMgr().InitiateAction(0, BoltLockManager::LOCK_ACTION); + // Enable BLE advertisements + if (!ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + ConnectivityMgr().SetBLEAdvertisingEnabled(true); + PLAT_LOG("Enabled BLE Advertisements"); + } } break; diff --git a/examples/lock-app/cc13x2_26x2/main/BoltLockManager.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/BoltLockManager.cpp similarity index 100% rename from examples/lock-app/cc13x2_26x2/main/BoltLockManager.cpp rename to examples/lock-app/cc13x2x7_26x2x7/main/BoltLockManager.cpp diff --git a/examples/lock-app/cc13x2_26x2/main/ZclCallbacks.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/ZclCallbacks.cpp similarity index 100% rename from examples/lock-app/cc13x2_26x2/main/ZclCallbacks.cpp rename to examples/lock-app/cc13x2x7_26x2x7/main/ZclCallbacks.cpp diff --git a/examples/lock-app/cc13x2_26x2/main/include/AppConfig.h b/examples/lock-app/cc13x2x7_26x2x7/main/include/AppConfig.h similarity index 100% rename from examples/lock-app/cc13x2_26x2/main/include/AppConfig.h rename to examples/lock-app/cc13x2x7_26x2x7/main/include/AppConfig.h diff --git a/examples/lock-app/cc13x2_26x2/main/include/AppEvent.h b/examples/lock-app/cc13x2x7_26x2x7/main/include/AppEvent.h similarity index 100% rename from examples/lock-app/cc13x2_26x2/main/include/AppEvent.h rename to examples/lock-app/cc13x2x7_26x2x7/main/include/AppEvent.h diff --git a/examples/lock-app/cc13x2_26x2/main/include/AppTask.h b/examples/lock-app/cc13x2x7_26x2x7/main/include/AppTask.h similarity index 100% rename from examples/lock-app/cc13x2_26x2/main/include/AppTask.h rename to examples/lock-app/cc13x2x7_26x2x7/main/include/AppTask.h diff --git a/examples/lock-app/cc13x2_26x2/main/include/BoltLockManager.h b/examples/lock-app/cc13x2x7_26x2x7/main/include/BoltLockManager.h similarity index 100% rename from examples/lock-app/cc13x2_26x2/main/include/BoltLockManager.h rename to examples/lock-app/cc13x2x7_26x2x7/main/include/BoltLockManager.h diff --git a/examples/lock-app/cc13x2_26x2/main/include/CHIPProjectConfig.h b/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h similarity index 98% rename from examples/lock-app/cc13x2_26x2/main/include/CHIPProjectConfig.h rename to examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h index 30cd4b9912ff24..7972bb9f665a64 100644 --- a/examples/lock-app/cc13x2_26x2/main/include/CHIPProjectConfig.h +++ b/examples/lock-app/cc13x2x7_26x2x7/main/include/CHIPProjectConfig.h @@ -76,7 +76,7 @@ * * Disable Full Thread Device features */ -#define CHIP_DEVICE_CONFIG_THREAD_FTD 0 +#define CHIP_DEVICE_CONFIG_THREAD_FTD 1 /** * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID @@ -117,7 +117,7 @@ * * Enable support for CHIP-over-BLE (CHIPOBLE). */ -#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 0 +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 /** * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC diff --git a/examples/lock-app/cc13x2_26x2/main/include/OpenThreadConfig.h b/examples/lock-app/cc13x2x7_26x2x7/main/include/OpenThreadConfig.h similarity index 97% rename from examples/lock-app/cc13x2_26x2/main/include/OpenThreadConfig.h rename to examples/lock-app/cc13x2x7_26x2x7/main/include/OpenThreadConfig.h index bccc34b919a28b..29138dcf1b8a1f 100644 --- a/examples/lock-app/cc13x2_26x2/main/include/OpenThreadConfig.h +++ b/examples/lock-app/cc13x2x7_26x2x7/main/include/OpenThreadConfig.h @@ -46,7 +46,7 @@ #define OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_MAXIMUM_INTERVAL (60 * 10 * 1000) // default 1200000 ms #define OPENTHREAD_CONFIG_JOINER_ENABLE 1 -#define OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE 1 +#define OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE 0 #define UART_AS_SERIAL_TRANSPORT 1 #define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE 1 diff --git a/examples/lock-app/cc13x2_26x2/main/main.cpp b/examples/lock-app/cc13x2x7_26x2x7/main/main.cpp similarity index 89% rename from examples/lock-app/cc13x2_26x2/main/main.cpp rename to examples/lock-app/cc13x2x7_26x2x7/main/main.cpp index 7785e9f5c8eb5b..b721f9e594ed93 100644 --- a/examples/lock-app/cc13x2_26x2/main/main.cpp +++ b/examples/lock-app/cc13x2x7_26x2x7/main/main.cpp @@ -36,10 +36,16 @@ #include #include +#include +#define TOTAL_ICALL_HEAP_SIZE (0xf000) + using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::DeviceLayer; +__attribute__((section(".heap"))) uint8_t GlobalHeapZoneBuffer[TOTAL_ICALL_HEAP_SIZE]; +uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; + // ================================================================================ // FreeRTOS Callbacks // ================================================================================ @@ -59,6 +65,7 @@ int main(void) int ret = CHIP_ERROR_MAX; Board_init(); + bpool((void *) GlobalHeapZoneBuffer, TOTAL_ICALL_HEAP_SIZE); GPIO_init(); diff --git a/examples/lock-app/cc13x2_26x2/third_party/connectedhomeip b/examples/lock-app/cc13x2x7_26x2x7/third_party/connectedhomeip similarity index 100% rename from examples/lock-app/cc13x2_26x2/third_party/connectedhomeip rename to examples/lock-app/cc13x2x7_26x2x7/third_party/connectedhomeip diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index b36faddf39cd5c..7ed03dd275af00 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -241,6 +241,8 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { "cc13x2_26x2/ConfigurationManagerImpl.cpp", "cc13x2_26x2/ConnectivityManagerImpl.cpp", "cc13x2_26x2/ConnectivityManagerImpl.h", + "cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.cpp", + "cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.h", "cc13x2_26x2/InetPlatformConfig.h", "cc13x2_26x2/Logging.cpp", "cc13x2_26x2/PlatformManagerImpl.cpp", @@ -248,14 +250,29 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { "cc13x2_26x2/SystemPlatformConfig.h", ] + if (chip_enable_ble) { + sources += [ + "cc13x2_26x2/BLEManagerImpl.cpp", + "cc13x2_26x2/BLEManagerImpl.h", + ] + } + if (chip_enable_openthread) { + # needed for MTD/FTD + import("//build_overrides/ti_simplelink_sdk.gni") + import("${ti_simplelink_sdk_build_root}/ti_simplelink_board.gni") public_deps += [ "${chip_root}/third_party/ti_simplelink_sdk:mbedtls", "${chip_root}/third_party/ti_simplelink_sdk:ti_simplelink_sdk", "${chip_root}/third_party/ti_simplelink_sdk:ti_simplelink_sysconfig", - "${openthread_root}:libopenthread-mtd", ] + if (ti_simplelink_device_family == "cc13x2_26x2") { + public_deps += [ "${openthread_root}:libopenthread-mtd" ] + } else if (ti_simplelink_device_family == "cc13x2x7_26x2x7") { + public_deps += [ "${openthread_root}:libopenthread-ftd" ] + } + sources += [ "OpenThread/OpenThreadUtils.cpp", "cc13x2_26x2/ThreadStackManagerImpl.cpp", diff --git a/src/platform/cc13x2_26x2/BLEManagerImpl.cpp b/src/platform/cc13x2_26x2/BLEManagerImpl.cpp new file mode 100644 index 00000000000000..a5476acc3ed394 --- /dev/null +++ b/src/platform/cc13x2_26x2/BLEManagerImpl.cpp @@ -0,0 +1,1885 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager object for cc13xx_cc26xx + * platform using the Texas Instruments SDK and the OpenThread stack. + */ +#include + +/* this file behaves like a config.h, comes first */ +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include +#include + +#include "FreeRTOS.h" +#include +#include + +/* Include DMM module */ +#include "chipOBleProfile.h" +#include "hal_types.h" +#include "ti_dmm_application_policy.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "ti_ble_config.h" +#include "ti_drivers_config.h" +#ifndef ICALL_FEATURE_SEPARATE_IMGINFO +#include +#endif /* ICALL_FEATURE_SEPARATE_IMGINFO */ +} + +// BLE Manager Debug Logs +extern "C" { +#ifdef BLEMGR_DBG_LOGGING +extern void cc13x2_26x2Log(const char * aFormat, ...); +#define BLEMGR_LOG(...) cc13x2_26x2Log(__VA_ARGS__); +#else +#define BLEMGR_LOG(...) +#endif +} + +#ifndef USE_DEFAULT_USER_CFG +#include "ble_user_config.h" +// BLE user defined configuration. Required to be globally accesible for BLE initialization +icall_userCfg_t user0Cfg = BLE_USER_CFG; +#endif // USE_DEFAULT_USER_CFG + +using namespace ::chip; +using namespace ::chip::Ble; + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +/* Static class member initialization */ +BLEManagerImpl BLEManagerImpl::sInstance; +TaskHandle_t BLEManagerImpl::sBleTaskHndl; +ICall_EntityID BLEManagerImpl::sSelfEntity; +ICall_SyncHandle BLEManagerImpl::sSyncEvent; +QueueHandle_t BLEManagerImpl::sEventHandlerMsgQueueID; +chipOBleProfileCBs_t BLEManagerImpl::CHIPoBLEProfile_CBs = { + // Provisioning GATT Characteristic value change callback + CHIPoBLEProfile_charValueChangeCB +}; + +// GAP Bond Manager Callbacks +gapBondCBs_t BLEManagerImpl::BLEMgr_BondMgrCBs = { + PasscodeCb, // Passcode callback + PairStateCb // Pairing/Bonding state Callback +}; + +// ===== Members that implement the BLEManager internal interface. +CHIP_ERROR BLEManagerImpl::_Init(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + BLEMGR_LOG("BLEMGR: BLE Initialization Start"); + // Initialize the CHIP BleLayer. + err = BleLayer::Init(this, this, &SystemLayer); + if (err != CHIP_NO_ERROR) + { + return err; + } + + /* Register BLE Stack assert handler */ + RegisterAssertCback(AssertHandler); + + mFlags = CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART ? kFlag_AdvertisingEnabled : 0; + + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + OnChipBleConnectReceived = HandleIncomingBleConnection; + + err = CreateEventHandler(); + return err; +} + +BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void) +{ + return mServiceMode; +} + +CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(BLEManager::CHIPoBLEServiceMode val) +{ + mServiceMode = val; + + /* Trigger state update */ + return DriveBLEState(); +} + +bool BLEManagerImpl::_IsAdvertisingEnabled(void) +{ + return GetFlag(mFlags, kFlag_AdvertisingEnabled); +} + +/* Post event to app processing loop to begin CHIP advertising */ +CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) +{ + SetFlag(mFlags, kFlag_AdvertisingEnabled, val); + + /* Send event to process state change request */ + return DriveBLEState(); +} + +bool BLEManagerImpl::_IsFastAdvertisingEnabled(void) +{ + return GetFlag(mFlags, kFlag_FastAdvertisingEnabled); +} + +CHIP_ERROR BLEManagerImpl::_SetFastAdvertisingEnabled(bool val) +{ + CHIP_ERROR ret = CHIP_NO_ERROR; + + if (!GetFlag(mFlags, kFlag_FastAdvertisingEnabled)) + { + SetFlag(mFlags, kFlag_FastAdvertisingEnabled, val); + + /* Send event to process state change request */ + ret = DriveBLEState(); + } + return ret; +} + +bool BLEManagerImpl::_IsAdvertising(void) +{ + return GetFlag(mFlags, kFlag_Advertising); +} + +CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) +{ + CHIP_ERROR ret = CHIP_NO_ERROR; + + if (bufSize <= GAP_DEVICE_NAME_LEN) + { + strncpy(buf, mDeviceName, bufSize); + } + else + { + ret = CHIP_ERROR_BUFFER_TOO_SMALL; + } + + return ret; +} + +CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName) +{ + CHIP_ERROR ret = CHIP_NO_ERROR; + + if (strlen(deviceName) <= GAP_DEVICE_NAME_LEN) + { + strncpy(mDeviceName, deviceName, strlen(deviceName)); + + SetFlag(mFlags, kFlag_BLEStackGATTNameUpdate, true); + + ret = DriveBLEState(); + } + else + { + ret = CHIP_ERROR_BUFFER_TOO_SMALL; + } + + return ret; +} + +uint16_t BLEManagerImpl::_NumConnections(void) +{ + uint8_t i, numConns = 0; + + // Try to find an available entry + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle != LL_CONNHANDLE_INVALID) + { + numConns++; + } + } + + return numConns; +} + +void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLESubscribe: { + ChipDeviceEvent connEstEvent; + + BLEMGR_LOG("BLEMGR: OnPlatformEvent, kCHIPoBLESubscribe"); + HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + + connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + + PlatformMgr().PostEvent(&connEstEvent); + } + break; + + case DeviceEventType::kCHIPoBLEUnsubscribe: { + BLEMGR_LOG("BLEMGR: OnPlatformEvent, kCHIPoBLEUnsubscribe"); + HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + } + break; + + case DeviceEventType::kCHIPoBLEWriteReceived: { + BLEMGR_LOG("BLEMGR: OnPlatformEvent, kCHIPoBLEWriteReceived"); + HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX, + PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); + } + break; + + case DeviceEventType::kCHIPoBLEIndicateConfirm: + HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + break; + + case DeviceEventType::kCHIPoBLEConnectionError: { + BLEMGR_LOG("BLEMGR: OnPlatformEvent, kCHIPoBLEConnectionError"); + HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason); + } + break; + + default: + break; + } +} + +// ===== Members that implement virtual methods on BlePlatformDelegate. +bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + void * pMsg = (void *) ICall_malloc(sizeof(void *)); + pMsg = (void *) conId; + + EnqueueEvtHdrMsg(BLEManagerIMPL_CHIPOBLE_CLOSE_CONN_EVT, (void *) pMsg); + + return CHIP_NO_ERROR; +} + +uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + uint8_t index; + uint16_t mtu = 0; + + index = GetBLEConnIndex(*((uint32_t *) conId)); + + if (index != MAX_NUM_BLE_CONNS) + { + mtu = sInstance.connList[index].mtu; + /* Prior to MTU update event, MTU is determined by the below formula */ + if (mtu == 0) + { + mtu = MAX_PDU_SIZE - 4; + } + } + + return mtu; +} + +// ===== Members that implement virtual methods on BleApplicationDelegate. + +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + // Unused +} + +bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle data) +{ + BLEMGR_LOG("BLEMGR: BLE SendIndication "); + + // Allocate buffers to send to BLE app task + uint8_t dataLen = static_cast(data->DataLength()); + CHIPoBLEIndEvt_t * pMsg; + uint8_t * pBuf; + + pMsg = (CHIPoBLEIndEvt_t *) ICall_malloc(sizeof(CHIPoBLEIndEvt_t)); + if (NULL == pMsg) + { + return false; + } + + pBuf = (uint8_t *) ICall_malloc(dataLen); + if (NULL == pBuf) + { + ICall_free((void *) pMsg); + return false; + } + + memset(pBuf, 0x00, dataLen); + memcpy(pBuf, data->Start(), dataLen); + + pMsg->pData = pBuf; + pMsg->len = dataLen; + + EnqueueEvtHdrMsg(BLEManagerIMPL_CHIPOBLE_TX_IND_EVT, (void *) pMsg); + + BLEMGR_LOG("BLEMGR: BLE SendIndication RETURN, Length: %d ", dataLen); + return true; +} + +bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) +{ + /* Unsupported on TI peripheral device implementation */ + return false; +} + +bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) +{ + /* Unsupported on TI peripheral device implementation */ + return false; +} + +bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + /* Unsupported on TI peripheral device implementation */ + return false; +} + +bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + /* Unsupported on TI peripheral device implementation */ + return false; +} + +bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, + const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + /* Unsupported on TI peripheral device implementation */ + return false; +} + +void BLEManagerImpl::HandleIncomingBleConnection(BLEEndPoint * bleEP) +{ + BLEMGR_LOG("BLEMGR: HandleIncomingBleConnection"); +} + +// ===== Helper Members that implement the Low level BLE Stack behavior. + +/********************************************************************* + * @fn AdvInit + * + * @brief Initialize CHIPoBLE Advertisement. + * + * @param pMsg - message to process + */ +void BLEManagerImpl::AdvInit(void) +{ + bStatus_t status = FAILURE; + uint16_t deviceDiscriminator; + uint8_t localDeviceNameLen; + uint8_t scanIndex = 0; + uint8_t advIndex = 0; + uint8_t scanResLength; + uint8_t advLength; + uint8_t * advDatachipOBle; + uint8_t * scanResDatachipOBle; + + BLEMGR_LOG("BLEMGR: AdvInit"); + + ChipBLEDeviceIdentificationInfo mDeviceIdInfo; + ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); + + // Verify device name was not already set + if (!GetFlag(sInstance.mFlags, kFlag_BLEStackGATTNameSet)) + { + /* Default device name is CHIP- */ + deviceDiscriminator = mDeviceIdInfo.GetDeviceDiscriminator(); + + localDeviceNameLen = strlen(CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX) + sizeof(deviceDiscriminator); + + memset(sInstance.mDeviceName, 0, GAP_DEVICE_NAME_LEN); + snprintf(sInstance.mDeviceName, GAP_DEVICE_NAME_LEN, "%s%04u", CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, + deviceDiscriminator); + + // 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, sInstance.mDeviceName); + + BLEMGR_LOG("BLEMGR: AdvInit New device name set: %s", sInstance.mDeviceName); + } + else + { + localDeviceNameLen = strlen(sInstance.mDeviceName); + } + + scanResLength = localDeviceNameLen + CHIPOBLE_SCANRES_SIZE_NO_NAME; + + scanResDatachipOBle = (uint8_t *) ICall_malloc(scanResLength); + + scanResDatachipOBle[scanIndex++] = localDeviceNameLen + 1; + scanResDatachipOBle[scanIndex++] = GAP_ADTYPE_LOCAL_NAME_COMPLETE; + memcpy(&scanResDatachipOBle[scanIndex], sInstance.mDeviceName, localDeviceNameLen); + scanIndex += localDeviceNameLen; + scanResDatachipOBle[scanIndex++] = 0x03; + scanResDatachipOBle[scanIndex++] = GAP_ADTYPE_16BIT_COMPLETE; + scanResDatachipOBle[scanIndex++] = static_cast(LO_UINT16(CHIPOBLE_SERV_UUID)); + scanResDatachipOBle[scanIndex++] = static_cast(HI_UINT16(CHIPOBLE_SERV_UUID)); + + for (uint8_t temp = 0; temp < scanIndex; temp++) + { + BLEMGR_LOG("BLEMGR: AdvInit Scan Response Data: %x", scanResDatachipOBle[temp]); + } + + advLength = sizeof(static_cast(CHIPOBLE_SERV_UUID)) + static_cast(sizeof(mDeviceIdInfo)) + 1; + advDatachipOBle = (uint8_t *) ICall_malloc(CHIPOBLE_ADV_SIZE_NO_DEVICE_ID_INFO + advLength); + + BLEMGR_LOG("BLEMGR: AdvInit: MDeviceIDInfo Size: %d", sizeof(mDeviceIdInfo)); + BLEMGR_LOG("BLEMGR: AdvInit: advlength: %d", advLength); + BLEMGR_LOG("BLEMGR: AdvInit:Desc : %d", mDeviceIdInfo.GetDeviceDiscriminator()); + + advDatachipOBle[advIndex++] = 0x02; + advDatachipOBle[advIndex++] = GAP_ADTYPE_FLAGS; + advDatachipOBle[advIndex++] = GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED | GAP_ADTYPE_FLAGS_GENERAL; + advDatachipOBle[advIndex++] = advLength; + advDatachipOBle[advIndex++] = GAP_ADTYPE_SERVICE_DATA; + advDatachipOBle[advIndex++] = static_cast(LO_UINT16(CHIPOBLE_SERV_UUID)); + advDatachipOBle[advIndex++] = static_cast(HI_UINT16(CHIPOBLE_SERV_UUID)); + memcpy(&advDatachipOBle[advIndex], (void *) &mDeviceIdInfo, static_cast(sizeof(mDeviceIdInfo))); + + // Setup and start Advertising + // For more information, see the GAP section in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + + // Create Advertisement set #1 and assign handle + status = (bStatus_t) GapAdv_create(&advCallback, &advParams1, &sInstance.advHandleLegacy); + assert(status == SUCCESS); + + // Load advertising data for set #1 that is statically allocated by the app + status = (bStatus_t) GapAdv_loadByHandle(sInstance.advHandleLegacy, GAP_ADV_DATA_TYPE_ADV, + CHIPOBLE_ADV_SIZE_NO_DEVICE_ID_INFO + advLength, advDatachipOBle); + + // Load scan response data for set #1 that is statically allocated by the app + status = + (bStatus_t) GapAdv_loadByHandle(sInstance.advHandleLegacy, GAP_ADV_DATA_TYPE_SCAN_RSP, scanResLength, scanResDatachipOBle); + assert(status == SUCCESS); + + // Set event mask for set #1 + status = (bStatus_t) GapAdv_setEventMask(sInstance.advHandleLegacy, + GAP_ADV_EVT_MASK_START_AFTER_ENABLE | GAP_ADV_EVT_MASK_END_AFTER_DISABLE | + GAP_ADV_EVT_MASK_SET_TERMINATED); + + Util_constructClock(&sInstance.clkAdvTimeout, AdvTimeoutHandler, ADV_TIMEOUT, 0, false, (uintptr_t) NULL); +} + +/********************************************************************* + * @fn EventHandler_init + * + * @brief Called during initialization and contains application + * specific initialization (ie. hardware initialization/setup, + * table initialization, power up notification, etc), and + * profile initialization/setup. + */ +void BLEManagerImpl::EventHandler_init(void) +{ + BLEMGR_LOG("BLEMGR: EventHandler_init"); + + /* Update User Configuration of the stack */ + user0Cfg.appServiceInfo->timerTickPeriod = ICall_getTickPeriod(); + user0Cfg.appServiceInfo->timerMaxMillisecond = ICall_getMaxMSecs(); + + /* Initialize ICall module */ + ICall_init(); + + /* Start tasks of external images */ + ICall_createRemoteTasks(); + BLEManagerImpl::sBleTaskHndl = (TaskHandle_t)(*((TaskHandle_t *) ICall_getRemoteTaskHandle(0))); + DMMSch_registerClient((TaskHandle_t) BLEManagerImpl::sBleTaskHndl, DMMPolicy_StackRole_BlePeripheral); + /* set the stacks in default states */ + DMMPolicy_updateStackState(DMMPolicy_StackRole_BlePeripheral, DMMPOLICY_BLE_IDLE); + + vTaskPrioritySet(xTaskGetCurrentTaskHandle(), 3); + + // ****************************************************************** + // 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(&BLEManagerImpl::sSelfEntity, &BLEManagerImpl::sSyncEvent); + +#ifdef USE_RCOSC + RCOSC_enableCalibration(); +#endif // USE_RCOSC + + // Create an RTOS queue for message from profile to be sent to app. + Util_constructQueue(&BLEManagerImpl::sEventHandlerMsgQueueID); + + // 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); + } + + // Setup the GAP Bond Manager. For more information see the GAP Bond Manager + // section in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + setBondManagerParameters(); + + // Initialize GATT attributes + GGS_AddService(GATT_ALL_SERVICES); // GAP GATT Service + GATTServApp_AddService(GATT_ALL_SERVICES); // GATT Service + DevInfo_AddService(); // Device Information Service + + CHIPoBLEProfile_AddService(GATT_ALL_SERVICES); + + // Start Bond Manager and register callback + VOID GAPBondMgr_Register(BLEMgr_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(BLEManagerImpl::sSelfEntity); + + // Register for GATT local events and ATT Responses pending for transmission + GATT_RegisterForMsgs(BLEManagerImpl::sSelfEntity); + + CHIPoBLEProfile_RegisterAppCBs(&CHIPoBLEProfile_CBs); + // Set default values for Data Length Extension + // Extended Data Length Feature is already enabled by default + { + // 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(BLEMANAGER_SUGGESTED_PDU_SIZE, BLEMANAGER_SUGGESTED_TX_TIME); + } + + // Initialize GATT Client + GATT_InitClient(""); + + // Initialize Connection List + ClearBLEConnListEntry(LL_CONNHANDLE_ALL); + + // Initialize GAP layer for Peripheral role and register to receive GAP events + GAP_DeviceInit(GAP_PROFILE_PERIPHERAL, BLEManagerImpl::sSelfEntity, sInstance.addrMode, &pRandomAddress); + + // Initialize array to store connection handle and RSSI values + InitPHYRSSIArray(); +} + +/********************************************************************* + * @fn InitPHYRSSIArray + * + * @brief Initializes the array of structure/s to store data related + * RSSI based auto PHy change + * + * @param connHandle - the connection handle + * + * @param addr - pointer to device address + * + * @return index of connection handle + */ +void BLEManagerImpl::InitPHYRSSIArray(void) +{ + BLEMGR_LOG("BLEMGR: InitPHYRSSIArray"); + + // Initialize array to store connection handle and RSSI values + memset(sInstance.connList, 0, sizeof(sInstance.connList)); + + for (uint8_t index = 0; index < MAX_NUM_BLE_CONNS; index++) + { + sInstance.connList[index].connHandle = INVALID_HANDLE; + } +} + +/********************************************************************* + * @fn CreateEventHandler + * + * @brief Create FreeRTOS Task for BLE Event handling + * + */ +CHIP_ERROR BLEManagerImpl::CreateEventHandler(void) +{ + BLEMGR_LOG("BLEMGR: CreateEventHandler"); + + BaseType_t xReturned; + + /* Create the task, storing the handle. */ + xReturned = xTaskCreate(EventHandler, /* Function that implements the task. */ + "ble_hndlr", /* Text name for the task. */ + 4096 / sizeof(uint32_t), /* Stack size in words, not bytes. */ + this, /* Parameter passed into the task. */ + ICALL_TASK_PRIORITIES, /* Keep priority the same as ICALL until init is complete */ + NULL); /* Used to pass out the created task's handle. */ + + if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) + { + return CHIP_ERROR_NO_MEMORY; + } + else + { + return CHIP_NO_ERROR; + } +} + +/********************************************************************* + * @fn RemoteDisplay_processStackMsg + * + * @brief Process an incoming stack message. + * + * @param pMsg - message to process + * + * @return TRUE if safe to deallocate incoming message, FALSE otherwise. + */ +uint8_t BLEManagerImpl::ProcessStackEvent(ICall_Hdr * pMsg) +{ + BLEMGR_LOG("BLEMGR: BLE Process Stack Event"); + + // Always dealloc pMsg unless set otherwise + uint8_t safeToDealloc = TRUE; + + switch (pMsg->event) + { + case GAP_MSG_EVENT: + ProcessGapMessage((gapEventHdr_t *) pMsg); + break; + + case GATT_MSG_EVENT: + // Process GATT message + safeToDealloc = ProcessGATTMsg((gattMsgEvent_t *) pMsg); + break; + case HCI_GAP_EVENT_EVENT: { + // Process HCI message + switch (pMsg->status) + { + case HCI_COMMAND_COMPLETE_EVENT_CODE: + // Process HCI Command Complete Events here + { + // RemoteDisplay_processCmdCompleteEvt((hciEvt_CmdComplete_t *) pMsg); + break; + } + case HCI_BLE_HARDWARE_ERROR_EVENT_CODE: + assert(false); + 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) + { + /* PHY Change failure, peer does not support this */ + } + break; + } + default: + break; + } + break; + } + + case HCI_LE_EVENT_CODE: { + hciEvt_BLEPhyUpdateComplete_t * pPUC = (hciEvt_BLEPhyUpdateComplete_t *) pMsg; + + // A Phy Update Has Completed or Failed + if (pPUC->BLEEventCode == HCI_BLE_PHY_UPDATE_COMPLETE_EVENT) + { + if (pPUC->status != SUCCESS) + { + /* PHY Change failure */ + } + else + { + /* PHY Update successfull */ + } + } + break; + } + default: + break; + } + + break; + } + + default: + // do nothing + break; + } + + return safeToDealloc; +} + +/********************************************************************* + * @fn ProcessEvtHdrMsg + * + * @brief Process an incoming callback from a profile. + * + * @param pMsg - message to process + * + * @return None. + */ +void BLEManagerImpl::ProcessEvtHdrMsg(QueuedEvt_t * pMsg) +{ + bool dealloc = TRUE; + + BLEMGR_LOG("BLEMGR: ProcessEvtHdrMsg"); + + switch (pMsg->event) + { + /* External CHIPoBLE Event trigger */ + case BLEManagerIMPL_STATE_UPDATE_EVT: { + bStatus_t status; + + /* Verify BLE service mode is enabled */ + if (sInstance.mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled) + { + /* Advertising flag set, either advertising or fast adv is enabled: Do nothing */ + /* Advertising flag not set, neither advertising nor fast adv is enabled: do nothing */ + /* Advertising flag not set, either advertising or fast adv is enabled: Turn on */ + if (!GetFlag(sInstance.mFlags, kFlag_Advertising)) + { + BLEMGR_LOG("BLEMGR: BLE Process Application Message: Not advertising"); + + if (GetFlag(sInstance.mFlags, kFlag_AdvertisingEnabled)) + { + ClearFlag(sInstance.mFlags, kFlag_FastAdvertisingEnabled); + + BLEMGR_LOG("BLEMGR: BLE Process Application Message: Slow Advertising Enabled"); +// Send notification to thread manager that CHIPoBLE advertising is starting +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + ThreadStackMgr().OnCHIPoBLEAdvertisingStart(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + + // Enable legacy advertising for set #1 + status = (bStatus_t) GapAdv_enable(sInstance.advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX, 0); + + assert(status == SUCCESS); + + // Start advertisement timer + Util_startClock(&sInstance.clkAdvTimeout); + + SetFlag(sInstance.mFlags, kFlag_Advertising, true); + } + else if (GetFlag(sInstance.mFlags, kFlag_FastAdvertisingEnabled)) + { + ClearFlag(sInstance.mFlags, kFlag_AdvertisingEnabled); + + BLEMGR_LOG("BLEMGR: BLE Process Application Message: Fast Advertising Enabled"); + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + ThreadStackMgr().OnCHIPoBLEAdvertisingStart(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + + // Enable legacy advertising for set #1 + status = (bStatus_t) GapAdv_enable(sInstance.advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX, 0); + assert(status == SUCCESS); + SetFlag(sInstance.mFlags, kFlag_Advertising, true); + } + } + /* Advertising flag set, neither advertising nor fast adv is enabled: Turn off*/ + else if (!GetFlag(sInstance.mFlags, kFlag_AdvertisingEnabled) && + !GetFlag(sInstance.mFlags, kFlag_FastAdvertisingEnabled)) + { + BLEMGR_LOG("BLEMGR: BLE Process Application Message: Advertising disables"); + + // Stop advertising + GapAdv_disable(sInstance.advHandleLegacy); + ClearFlag(sInstance.mFlags, kFlag_Advertising); + + Util_stopClock(&sInstance.clkAdvTimeout); + } + } + + if (GetFlag(sInstance.mFlags, kFlag_BLEStackGATTNameUpdate)) + { + ClearFlag(sInstance.mFlags, kFlag_BLEStackGATTNameUpdate); + // Indicate that Device name has been set externally + SetFlag(mFlags, kFlag_BLEStackGATTNameSet, true); + + // Set the Device Name characteristic in the GAP GATT Service + GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, sInstance.mDeviceName); + } + } + break; + + case BLEManagerIMPL_CHIPOBLE_CLOSE_CONN_EVT: { + uint16_t connHandle = *((uint16_t *) (pMsg->pData)); + + // Close active connection + GAP_TerminateLinkReq(connHandle, HCI_DISCONNECT_REMOTE_USER_TERM); + } + break; + + case BLEManagerIMPL_CHIPOBLE_TX_IND_EVT: { + uint8_t dataLen = ((CHIPoBLEIndEvt_t *) (pMsg->pData))->len; + + CHIPoBLEProfile_SetParameter(CHIPOBLEPROFILE_TX_CHAR, dataLen, (void *) (((CHIPoBLEIndEvt_t *) (pMsg->pData))->pData), + BLEManagerImpl::sSelfEntity); + + BLEMGR_LOG("BLEMGR: BLE Process Application Message: BLEManagerIMPL_CHIPOBLE_TX_IND_EVT: Length: %d", dataLen); + + ICall_free((void *) (((CHIPoBLEIndEvt_t *) (pMsg->pData))->pData)); + + dealloc = TRUE; + } + break; + + case CHIPOBLE_CHAR_CHANGE_EVT: { + uint16_t writeLen = ((CHIPoBLEProfChgEvt_t *) (pMsg->pData))->len; + uint8_t paramId = ((CHIPoBLEProfChgEvt_t *) (pMsg->pData))->paramId; + uint16_t connHandleId = ((CHIPoBLEProfChgEvt_t *) (pMsg->pData))->connHandle; + void * connHandle; + ChipDeviceEvent event; + + uint8_t i; + ConnRec_t * activeConnObj = NULL; + + // Find active connection + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (sInstance.connList[i].connHandle == connHandleId) + { + activeConnObj = &sInstance.connList[i]; + } + } + + connHandle = (void *) &activeConnObj->connHandle; + + if (paramId == CHIPOBLEPROFILE_RX_CHAR) + { + BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, CHIPOBLEPROFILE_RX_CHAR"); + // Pull written data from CHIPOBLE Profile based on extern server write + uint8_t * rxBuf = (uint8_t *) ICall_malloc(writeLen); + + if (rxBuf == NULL) + { + // alloc error + return; + } + + memset(rxBuf, 0x00, writeLen); + + BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, length: %d", writeLen); + CHIPoBLEProfile_GetParameter(CHIPOBLEPROFILE_RX_CHAR, rxBuf, writeLen); + + System::PacketBufferHandle packetBuf = System::PacketBufferHandle::NewWithData(rxBuf, writeLen, 0, 0); + + ICall_free(rxBuf); + + if (packetBuf.IsNull()) + { + // alloc error + return; + } + + // Arrange to post a CHIPoBLERXWriteEvent event to the CHIP queue. + event.Type = DeviceEventType::kCHIPoBLEWriteReceived; + event.CHIPoBLEWriteReceived.ConId = (void *) connHandle; + event.CHIPoBLEWriteReceived.Data = std::move(packetBuf).UnsafeRelease(); + } + else if (paramId == CHIPOBLEPROFILE_CCCWrite) + { + BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, CHIPOBLEPROFILE_CCCWrite"); + + // TODO: Add check to see if subscribing OR unsubscribing from char indications + uint8_t cccValue; + + CHIPoBLEProfile_GetParameter(CHIPOBLEPROFILE_CCCWrite, &cccValue, 1); + + // Check whether it is a sub/unsub event. 0x1 = Notofications enabled, 0x2 = Indications enabled + if (cccValue & 2) + { + // Post event to CHIP + BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, Subscrbe"); + event.Type = DeviceEventType::kCHIPoBLESubscribe; + } + else + { + BLEMGR_LOG("BLEMGR: BLE Process Application Message: CHIPOBLE_CHAR_CHANGE_EVT, unsubscrbe"); + event.Type = DeviceEventType::kCHIPoBLEUnsubscribe; + } + + // Post event to CHIP + event.CHIPoBLESubscribe.ConId = (void *) connHandle; + } + PlatformMgr().PostEvent(&event); + } + break; + + case ADV_EVT: + ProcessAdvEvent((GapAdvEventData_t *) (pMsg->pData)); + break; + + case PAIR_STATE_EVT: { + BLEMGR_LOG("BLEMGR: PAIR_STATE_EVT"); + + // Send passcode response + GAPBondMgr_PasscodeRsp(((PasscodeData_t *) (pMsg->pData))->connHandle, SUCCESS, B_APP_DEFAULT_PASSCODE); + } + break; + + case PASSCODE_EVT: { + BLEMGR_LOG("BLEMGR: PASSCODE_EVT"); + } + break; + + case READ_RPA_EVT: + UpdateBLERPA(); + break; + + case SEND_PARAM_UPDATE_EVT: { + // Extract connection handle from data + uint16_t connHandle = *(uint16_t *) (((ClockEventData_t *) pMsg->pData)->data); + + if (CHIP_NO_ERROR != ProcessParamUpdate(connHandle)) + { + // error + return; + } + + // This data is not dynamically allocated + dealloc = FALSE; + + /* If we are sending a param update request then the service discovery + * should have ended. Changed state to connected */ + DMMPolicy_updateStackState(DMMPolicy_StackRole_BlePeripheral, DMMPOLICY_BLE_CONNECTED); + + break; + } + + case CONN_EVT: + break; + + default: + // Do nothing. + break; + } + + // Free message data if it exists and we are to dealloc + if ((dealloc == TRUE) && (pMsg->pData != NULL)) + { + ICall_free(pMsg->pData); + } +} + +/********************************************************************* + * @fn ProcessGapMessage + * + * @brief Process an incoming GAP event. + * + * @param pMsg - message to process + */ +void BLEManagerImpl::ProcessGapMessage(gapEventHdr_t * pMsg) +{ + BLEMGR_LOG("BLEMGR: ProcessGapMessage"); + + switch (pMsg->opcode) + { + case GAP_DEVICE_INIT_DONE_EVENT: { + BLEMGR_LOG("BLEMGR: ProcessGapMessage: 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); + + AdvInit(); + + SetFlag(sInstance.mFlags, kFlag_BLEStackInitialized, true); + + /* Trigger post-initialization state update */ + DriveBLEState(); + + if (sInstance.addrMode > ADDRMODE_RANDOM) + { + UpdateBLERPA(); + // Create one-shot clock for RPA check event. + Util_constructClock(&sInstance.clkRpaRead, ClockHandler, READ_RPA_EVT_PERIOD, 0, true, + (uintptr_t) &sInstance.argRpaRead); + } + } + break; + } + + case GAP_LINK_ESTABLISHED_EVENT: { + gapEstLinkReqEvent_t * pPkt = (gapEstLinkReqEvent_t *) pMsg; + BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_LINK_ESTABLISHED_EVENT"); + + // Display the amount of current connections + uint8_t numActive = (uint8_t) linkDB_NumActive(""); + + if (pPkt->hdr.status == SUCCESS) + { + // Add connection to list and start RSSI + AddBLEConn(pPkt->connectionHandle); + } + + DMMPolicy_updateStackState(DMMPolicy_StackRole_BlePeripheral, DMMPOLICY_BLE_HIGH_BANDWIDTH); + + if (numActive < MAX_NUM_BLE_CONNS) + { + // Start advertising since there is room for more connections. Advertisements stop automatically following connection. + ClearFlag(sInstance.mFlags, kFlag_Advertising); + } + else + { + // Stop advertising since there is no room for more connections + BLEMGR_LOG("BLEMGR: BLE event GAP_LINK_ESTABLISHED_EVENT: MAX connections"); + ClearFlag(sInstance.mFlags, kFlag_FastAdvertisingEnabled | kFlag_AdvertisingEnabled | kFlag_Advertising); + } + + /* Stop advertisement timeout timer */ + Util_stopClock(&sInstance.clkAdvTimeout); + + DriveBLEState(); + + break; + } + + case GAP_LINK_TERMINATED_EVENT: { + gapTerminateLinkEvent_t * pPkt = (gapTerminateLinkEvent_t *) pMsg; + BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_LINK_TERMINATED_EVENT, reason: %d", pPkt->reason); + + // Remove the connection from the list and disable RSSI if needed + RemoveBLEConn(pPkt->connectionHandle); + + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEConnectionError; + event.CHIPoBLEConnectionError.ConId = (void *) &pPkt->connectionHandle; + event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; + PlatformMgr().PostEvent(&event); + + DriveBLEState(); + + break; + } + + case GAP_UPDATE_LINK_PARAM_REQ_EVENT: { + BLEMGR_LOG("BLEMGR: ProcessGapMessage: 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; + BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_UPDATE_LINK_PARAM_REQ_EVENT Accecpted"); + } + else + { + rsp.accepted = FALSE; + BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_UPDATE_LINK_PARAM_REQ_EVENT Rejected"); + } + + // Send Reply + VOID GAP_UpdateLinkParamReqReply(&rsp); + + break; + } + + case GAP_LINK_PARAM_UPDATE_EVENT: { + BLEMGR_LOG("BLEMGR: ProcessGapMessage: GAP_LINK_PARAM_UPDATE_EVENT"); + + gapLinkUpdateEvent_t * pPkt = (gapLinkUpdateEvent_t *) pMsg; + + // Get the address from the connection handle + linkDBInfo_t linkInfo; + linkDB_GetInfo(pPkt->connectionHandle, &linkInfo); + + // Check if there are any queued parameter updates + ConnHandleEntry_t * connHandleEntry = (ConnHandleEntry_t *) List_get(&sInstance.paramUpdateList); + if (connHandleEntry != NULL) + { + // Attempt to send queued update now + ProcessParamUpdate(connHandleEntry->connHandle); + + // Free list element + ICall_free(connHandleEntry); + } + + break; + } + + default: + break; + } +} + +/********************************************************************* + * @fn ProcessGATTMsg + * + * @brief Process GATT messages and events. + * + * @return TRUE if safe to deallocate incoming message, FALSE otherwise. + */ +uint8_t BLEManagerImpl::ProcessGATTMsg(gattMsgEvent_t * pMsg) +{ + uint8_t index; + BLEMGR_LOG("BLEMGR: ProcessGATTMsg"); + + 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. + } + else if (pMsg->method == ATT_MTU_UPDATED_EVENT) + { + index = GetBLEConnIndex(pMsg->connHandle); + + sInstance.connList[index].mtu = pMsg->msg.mtuEvt.MTU; + BLEMGR_LOG("BLEMGR: ProcessGATTMsg, ATT_MTU_UPDATED_EVENT: %d", pMsg->msg.mtuEvt.MTU); + } + else if (pMsg->method == ATT_HANDLE_VALUE_CFM) + { + void * connHandle; + ChipDeviceEvent event; + + ConnRec_t * activeConnObj = NULL; + + activeConnObj = &sInstance.connList[0]; + connHandle = (void *) &activeConnObj->connHandle; + + event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; + event.CHIPoBLEIndicateConfirm.ConId = connHandle; + PlatformMgr().PostEvent(&event); + + BLEMGR_LOG("BLEMGR: ProcessGATTMsg, ATT_HANDLE_VALUE_CFM:"); + } + // 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 ProcessAdvEvent + * + * @brief Process advertising event in app context + * + * @param pEventData + */ +void BLEManagerImpl::ProcessAdvEvent(GapAdvEventData_t * pEventData) +{ + BLEMGR_LOG("BLEMGR: ProcessAdvEvent"); + + switch (pEventData->event) + { + case GAP_EVT_ADV_START_AFTER_ENABLE: { + BLEMGR_LOG("BLEMGR: ProcessAdvEvent: GAP_EVT_ADV_START_AFTER_ENABLE"); + + if (linkDB_NumActive("") == 0) + { + DMMPolicy_updateStackState(DMMPolicy_StackRole_BlePeripheral, DMMPOLICY_BLE_ADV); + } + } + break; + + case GAP_EVT_ADV_END_AFTER_DISABLE: { + BLEMGR_LOG("BLEMGR: ProcessAdvEvent: GAP_EVT_ADV_END_AFTER_DISABLE"); + } + break; + + case GAP_EVT_ADV_START: + break; + + case GAP_EVT_ADV_END: + break; + + // BLE Stack has ended advertising due to connection + case GAP_EVT_ADV_SET_TERMINATED: { + BLEMGR_LOG("BLEMGR: ProcessAdvEvent: GAP_EVT_ADV_SET_TERMINATED"); + } + 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); + } +} + +/********************************************************************* + * @fn ProcessParamUpdate + * + * @brief Process a parameters update request + * + * @return None + */ +CHIP_ERROR BLEManagerImpl::ProcessParamUpdate(uint16_t connHandle) +{ + gapUpdateLinkParamReq_t req; + uint8_t connIndex; + BLEMGR_LOG("BLEMGR: ProcessParamUpdate"); + + 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 = GetBLEConnIndex(connHandle); + if (!(connIndex < MAX_NUM_BLE_CONNS)) + { + return CHIP_ERROR_TOO_MANY_CONNECTIONS; + } + + // Deconstruct the clock object + ClockP_destruct(sInstance.connList[connIndex].pUpdateClock); + // Free clock struct + if (sInstance.connList[connIndex].pUpdateClock != NULL) + { + ICall_free(sInstance.connList[connIndex].pUpdateClock); + sInstance.connList[connIndex].pUpdateClock = NULL; + } + // Free ParamUpdateEventData + if (sInstance.connList[connIndex].pParamUpdateEventData != NULL) + { + ICall_free(sInstance.connList[connIndex].pParamUpdateEventData); + } + + BLEMGR_LOG("BLEMGR: ProcessParamUpdate Send Link Param Req"); + // 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) + { + + BLEMGR_LOG("BLEMGR: ProcessParamUpdate pending"); + ConnHandleEntry_t * connHandleEntry = (ConnHandleEntry_t *) (ICall_malloc(sizeof(ConnHandleEntry_t))); + if (connHandleEntry) + { + connHandleEntry->connHandle = connHandle; + List_put(&sInstance.paramUpdateList, (List_Elem *) connHandleEntry); + } + } + + return CHIP_NO_ERROR; +} + +/********************************************************************* + * @fn EnqueueEvtHdrMsg + * + * @brief Creates a message and puts the message in RTOS queue. + * + * @param event - message event. + * @param state - message state. + */ +status_t BLEManagerImpl::EnqueueEvtHdrMsg(uint8_t event, void * pData) +{ + uint8_t success; + QueuedEvt_t * pMsg = (QueuedEvt_t *) ICall_malloc(sizeof(QueuedEvt_t)); + BLEMGR_LOG("BLEMGR: EnqueueEvtHdrMsg"); + + // Create dynamic pointer to message. + if (pMsg) + { + pMsg->event = event; + pMsg->pData = pData; + + // Enqueue the message. + success = Util_enqueueMsg(sEventHandlerMsgQueueID, BLEManagerImpl::sSyncEvent, (uint8_t *) pMsg); + + return (success) ? SUCCESS : FAILURE; + } + + return bleMemAllocError; +} + +/********************************************************************* + * @fn AddBLEConn + * + * @brief Add a device to the connected device list + * + * @return index of the connected device list entry where the new connection + * info is put in. + * if there is no room, MAX_NUM_BLE_CONNS will be returned. + */ +uint8_t BLEManagerImpl::AddBLEConn(uint16_t connHandle) +{ + uint8_t i; + uint8_t status = bleNoResources; + BLEMGR_LOG("BLEMGR: AddBLEConn"); + + // Try to find an available entry + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (sInstance.connList[i].connHandle == LL_CONNHANDLE_INVALID) + { + // Found available entry to put a new connection info in + sInstance.connList[i].connHandle = connHandle; + + // Allocate data to send through clock handler + sInstance.connList[i].pParamUpdateEventData = + (ClockEventData_t *) ICall_malloc(sizeof(ClockEventData_t) + sizeof(uint16_t)); + if (sInstance.connList[i].pParamUpdateEventData) + { + sInstance.connList[i].pParamUpdateEventData->event = SEND_PARAM_UPDATE_EVT; + *((uint16_t *) sInstance.connList[i].pParamUpdateEventData->data) = connHandle; + + // Create a clock object and start + sInstance.connList[i].pUpdateClock = (ClockP_Struct *) ICall_malloc(sizeof(ClockP_Struct)); + + if (sInstance.connList[i].pUpdateClock) + { + Util_constructClock(sInstance.connList[i].pUpdateClock, ClockHandler, SEND_PARAM_UPDATE_DELAY, 0, true, + (uintptr_t) sInstance.connList[i].pParamUpdateEventData); + } + else + { + ICall_free(sInstance.connList[i].pParamUpdateEventData); + } + } + else + { + status = bleMemAllocError; + } + + break; + } + } + return status; +} + +/********************************************************************* + * @fn RemoveBLEConn + * + * @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. + */ +uint8_t BLEManagerImpl::RemoveBLEConn(uint16_t connHandle) +{ + uint8_t connIndex = GetBLEConnIndex(connHandle); + BLEMGR_LOG("BLEMGR: RemoveBLEConn"); + + if (connIndex != MAX_NUM_BLE_CONNS) + { + ClockP_Struct * pUpdateClock = sInstance.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 + ClockP_destruct(pUpdateClock); + // Free clock struct + ICall_free(pUpdateClock); + // Free ParamUpdateEventData + ICall_free(sInstance.connList[connIndex].pParamUpdateEventData); + } + // Clear pending update requests from paramUpdateList + ClearPendingBLEParamUpdate(connHandle); + + // Clear Connection List Entry + ClearBLEConnListEntry(connHandle); + } + return connIndex; +} + +/********************************************************************* + * @fn GetBLEConnIndex + * + * @brief Find index in the connected device list by connHandle + * + * @return the index of the entry that has the given connection handle. + * if there is no match, MAX_NUM_BLE_CONNS will be returned. + */ +uint8_t BLEManagerImpl::GetBLEConnIndex(uint16_t connHandle) const +{ + uint8_t i; + + BLEMGR_LOG("BLEMGR: GetBLEConnIndex"); + + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (sInstance.connList[i].connHandle == connHandle) + { + return i; + } + } + + return MAX_NUM_BLE_CONNS; +} + +/********************************************************************* + * @fn ClearBLEConnListEntry + * + * @brief Find index in the connected device list by connHandle + * + * @return the index of the entry that has the given connection handle. + * if there is no match, MAX_NUM_BLE_CONNS will be returned. + */ +uint8_t BLEManagerImpl::ClearBLEConnListEntry(uint16_t connHandle) +{ + uint8_t i; + // Set to invalid connection index initially + uint8_t connIndex = MAX_NUM_BLE_CONNS; + + BLEMGR_LOG("BLEMGR: ClearBLEConnListEntry"); + if (connHandle != LL_CONNHANDLE_ALL) + { + // Get connection index from handle + connIndex = GetBLEConnIndex(connHandle); + 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 == LL_CONNHANDLE_ALL)) + { + sInstance.connList[i].connHandle = LL_CONNHANDLE_INVALID; + sInstance.connList[i].currPhy = 0; + sInstance.connList[i].phyCngRq = 0; + sInstance.connList[i].phyRqFailCnt = 0; + sInstance.connList[i].rqPhy = 0; + memset(sInstance.connList[i].rssiArr, 0, MAX_RSSI_STORE_DEPTH); + sInstance.connList[i].rssiAvg = 0; + sInstance.connList[i].rssiCntr = 0; + sInstance.connList[i].isAutoPHYEnable = FALSE; + sInstance.connList[i].mtu = 0; + } + } + + return SUCCESS; +} + +/********************************************************************* + * @fn ClearPendingBLEParamUpdate + * + * @brief clean pending param update request in the paramUpdateList list + * + * @param connHandle - connection handle to clean + * + * @return none + */ +void BLEManagerImpl::ClearPendingBLEParamUpdate(uint16_t connHandle) +{ + List_Elem * curr; + + BLEMGR_LOG("BLEMGR: ClearPendingBLEParamUpdate"); + + for (curr = List_head(&sInstance.paramUpdateList); curr != NULL; curr = List_next(curr)) + { + if (((ConnHandleEntry_t *) curr)->connHandle == connHandle) + { + List_remove(&sInstance.paramUpdateList, curr); + } + } +} + +/********************************************************************* + * @fn UpdateBLERPA + * + * @brief Read the current RPA from the stack and update display + * if the RPA has changed. + * + * @param None. + * + * @return None. + */ +void BLEManagerImpl::UpdateBLERPA(void) +{ + uint8_t * pRpaNew; + BLEMGR_LOG("BLEMGR: UpdateBLERPA"); + + // Read the current RPA. + pRpaNew = GAP_GetDevAddress(FALSE); + + if (memcmp(pRpaNew, sInstance.rpa, B_ADDR_LEN)) + { + memcpy(sInstance.rpa, pRpaNew, B_ADDR_LEN); + } +} + +void BLEManagerImpl::EventHandler(void * arg) +{ + BLEMGR_LOG("BLEMGR: EventHandler"); + + sInstance.EventHandler_init(); + + 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 + xQueueReceive((QueueHandle_t) BLEManagerImpl::sSyncEvent, (char *) &events, portMAX_DELAY); + + if (events) + { + ICall_EntityID dest; + ICall_ServiceEnum src; + ICall_HciExtEvt * hcipMsg = NULL; + + /* Lock CHIP Stack while processing BLE Stack/App events */ + PlatformMgr().LockChipStack(); + + BLEMGR_LOG("BLEMGR: EventHandler: Events received"); + // Fetch any available messages that might have been sent from the stack + if (ICall_fetchServiceMsg(&src, &dest, (void **) &hcipMsg) == ICALL_ERRNO_SUCCESS) + { + BLEMGR_LOG("BLEMGR: EventHandler: Stack Event"); + + uint8 safeToDealloc = TRUE; + + if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == BLEManagerImpl::sSelfEntity)) + { + ICall_Stack_Event * pEvt = (ICall_Stack_Event *) hcipMsg; + + // Check for non-BLE stack events + if (pEvt->signature != 0xffff) + { + // Process inter-task message + safeToDealloc = sInstance.ProcessStackEvent((ICall_Hdr *) hcipMsg); + } + } + + if (hcipMsg && safeToDealloc) + { + ICall_freeMsg(hcipMsg); + } + } + + // If RTOS queue is not empty, process CHIP messages. + if (events & QUEUE_EVT) + { + BLEMGR_LOG("BLEMGR: EventHandler: App Event"); + + QueuedEvt_t * pMsg; + for (;;) + { + pMsg = (QueuedEvt_t *) Util_dequeueMsg(BLEManagerImpl::sEventHandlerMsgQueueID); + if (NULL != pMsg) + { + // Process message. + sInstance.ProcessEvtHdrMsg(pMsg); + + // Free the space from the message. + ICall_free(pMsg); + } + else + { + break; + } + } + } + + PlatformMgr().UnlockChipStack(); + } + } +} + +/* Post event to app processing loop to begin CHIP advertising */ +CHIP_ERROR BLEManagerImpl::DriveBLEState(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + BLEMGR_LOG("BLEMGR: DriveBLEState"); + + if (sInstance.EnqueueEvtHdrMsg(BLEManagerIMPL_STATE_UPDATE_EVT, NULL) != SUCCESS) + { + err = CHIP_ERROR_NO_MEMORY; + } + return err; +} + +/********************************************************************* + * @fn advCallback + * + * @brief GapAdv module callback + * + * @param pMsg - message to process + */ +void BLEManagerImpl::advCallback(uint32_t event, void * pBuf, uintptr_t arg) +{ + BLEMGR_LOG("BLEMGR: advCallback"); + + GapAdvEventData_t * pData = (GapAdvEventData_t *) ICall_malloc(sizeof(GapAdvEventData_t)); + + if (pData) + { + pData->event = event; + pData->pBuf = pBuf; + if (sInstance.EnqueueEvtHdrMsg(ADV_EVT, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +void BLEManagerImpl::AdvTimeoutHandler(uintptr_t arg) +{ + BLEMGR_LOG("BLEMGR: AdvTimeoutHandler"); + + if (GetFlag(sInstance.mFlags, kFlag_AdvertisingEnabled)) + { + BLEMGR_LOG("BLEMGR: AdvTimeoutHandler ble adv 15 minute timeout"); + + SetFlag(sInstance.mFlags, kFlag_AdvertisingEnabled, false); + + /* Send event to process state change request */ + DriveBLEState(); + } +} + +void BLEManagerImpl::ClockHandler(uintptr_t arg) +{ + ClockEventData_t * pData = (ClockEventData_t *) arg; + BLEMGR_LOG("BLEMGR: ClockHandler"); + + if (pData->event == READ_RPA_EVT) + { + BLEMGR_LOG("BLEMGR: ClockHandler RPA EVT"); + // Start the next period + Util_startClock(&sInstance.clkRpaRead); + + // Post event to read the current RPA + sInstance.EnqueueEvtHdrMsg(READ_RPA_EVT, NULL); + } + else if (pData->event == SEND_PARAM_UPDATE_EVT) + { + BLEMGR_LOG("BLEMGR: ClockHandler PARAM UPDATE EVT"); + // Send message to app + if (sInstance.EnqueueEvtHdrMsg(SEND_PARAM_UPDATE_EVT, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/********************************************************************* + * @fn CHIPoBLEProfile_charValueChangeCB + * + * @brief Callback from CHIPoBLE Profile indicating a characteristic + * value change. + * Calling context (BLE Stack Task) + * + * @param paramId - parameter Id of the value that was changed. + * + * @return None. + */ +void BLEManagerImpl::CHIPoBLEProfile_charValueChangeCB(uint8_t paramId, uint16_t len, uint16_t connHandle) +{ + CHIPoBLEProfChgEvt_t * pValue = (CHIPoBLEProfChgEvt_t *) ICall_malloc(sizeof(CHIPoBLEProfChgEvt_t)); + BLEMGR_LOG("BLEMGR: CHIPoBLEProfile_charValueChangeCB"); + + if (pValue) + { + pValue->paramId = paramId; + pValue->len = len; + pValue->connHandle = connHandle; + + if (sInstance.EnqueueEvtHdrMsg(CHIPOBLE_CHAR_CHANGE_EVT, pValue) != SUCCESS) + { + ICall_free(pValue); + } + } +} + +/********************************************************************* + * @fn RemoteDisplay_passcodeCb + * + * @brief Passcode callback. + * + * @return none + */ +void BLEManagerImpl::PasscodeCb(uint8_t * pDeviceAddr, uint16_t connHandle, uint8_t uiInputs, uint8_t uiOutputs, + uint32_t numComparison) +{ + PasscodeData_t * pData = (PasscodeData_t *) ICall_malloc(sizeof(PasscodeData_t)); + + // Allocate space for the passcode event. + if (pData) + { + pData->connHandle = connHandle; + memcpy(pData->deviceAddr, pDeviceAddr, B_ADDR_LEN); + pData->uiInputs = uiInputs; + pData->uiOutputs = uiOutputs; + pData->numComparison = numComparison; + + // Enqueue the event. + if (sInstance.EnqueueEvtHdrMsg(PASSCODE_EVT, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/********************************************************************* + * @fn PairStateCb + * + * @brief Pairing state callback. + * + * @return none + */ +void BLEManagerImpl::PairStateCb(uint16_t connHandle, uint8_t state, uint8_t status) +{ + PairStateData_t * pData = (PairStateData_t *) ICall_malloc(sizeof(PairStateData_t)); + + // Allocate space for the event data. + if (pData) + { + pData->state = state; + pData->connHandle = connHandle; + pData->status = status; + + // Queue the event. + if (sInstance.EnqueueEvtHdrMsg(PAIR_STATE_EVT, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/******************************************************************************* + * @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 BLEManagerImpl::AssertHandler(uint8 assertCause, uint8 assertSubcause) +{ + // check the assert cause + switch (assertCause) + { + case HAL_ASSERT_CAUSE_OUT_OF_MEMORY: + assert(false); + break; + + case HAL_ASSERT_CAUSE_INTERNAL_ERROR: + // check the subcause + if (assertSubcause == HAL_ASSERT_SUBCAUSE_FW_INERNAL_ERROR) + { + assert(false); + } + else + { + assert(false); + } + break; + case HAL_ASSERT_CAUSE_ICALL_ABORT: + assert(false); + + case HAL_ASSERT_CAUSE_ICALL_TIMEOUT: + assert(false); + break; + case HAL_ASSERT_CAUSE_WRONG_API_CALL: + assert(false); + break; + default: + assert(false); + break; + } + return; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif /* CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE */ diff --git a/src/platform/cc13x2_26x2/BLEManagerImpl.h b/src/platform/cc13x2_26x2/BLEManagerImpl.h new file mode 100644 index 00000000000000..70c5462d96666e --- /dev/null +++ b/src/platform/cc13x2_26x2/BLEManagerImpl.h @@ -0,0 +1,365 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Texas Instruments Incorporated + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager object for the Texas + * Instruments cc13xx_cc26xx platform. + */ + +#ifndef BLEManager_IMPL_H +#define BLEManager_IMPL_H + +#pragma once + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#ifdef __cplusplus +extern "C" { +#endif + +#include "FreeRTOS.h" +#include +#include + +#include +#include + +#include "hal_types.h" + +#include "chipOBleProfile.h" +#include "ti_ble_config.h" +#include "ti_drivers_config.h" + +#ifdef __cplusplus +} +#endif + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +using namespace chip::Ble; + +// Internal Events for RTOS application +#define ICALL_EVT ICALL_MSG_EVENT_ID // Event_Id_31 +#define QUEUE_EVT UTIL_QUEUE_EVENT_ID // Event_Id_30 + +// Application events +#define BLEManagerIMPL_STATE_UPDATE_EVT (0) + +// 500ms interval +#define BLEMANAGERIMPL_ADV_INT_SLOW (800) +// 100ms interval (Default) +#define BLEMANAGERIMPL_ADV_INT_FAST (160) + +#define CHIPOBLE_ADV_SIZE_NO_DEVICE_ID_INFO (4) + +#define CHIPOBLE_SCANRES_SIZE_NO_NAME (6) + +// How often to read current current RPA (in ms) +#define READ_RPA_EVT_PERIOD 3000 + +// 15 Minute Advertisement CHIP Timeout period +#define ADV_TIMEOUT (900000) + +#define STATE_CHANGE_EVT 0 +#define CHAR_CHANGE_EVT 1 +#define CHIPOBLE_CHAR_CHANGE_EVT 2 +#define BLEManagerIMPL_CHIPOBLE_TX_IND_EVT 3 +#define ADV_EVT 4 +#define PAIR_STATE_EVT 5 +#define PASSCODE_EVT 6 +#define READ_RPA_EVT 7 +#define SEND_PARAM_UPDATE_EVT 8 +#define BLEManagerIMPL_CHIPOBLE_CLOSE_CONN_EVT 9 +#define CONN_EVT 10 + +// For storing the active connections +#define RSSI_TRACK_CHNLS 1 // Max possible channels can be GAP_BONDINGS_MAX +#define MAX_RSSI_STORE_DEPTH 5 +#define INVALID_HANDLE 0xFFFF +#define RSSI_2M_THRSHLD -30 +#define RSSI_1M_THRSHLD -40 +#define RSSI_S2_THRSHLD -50 +#define RSSI_S8_THRSHLD -60 +#define PHY_NONE LL_PHY_NONE // No PHY set +#define AUTO_PHY_UPDATE 0xFF +// 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 BLEMANAGER_SUGGESTED_PDU_SIZE 251 // default is 27 octets(TX) +#define BLEMANAGER_SUGGESTED_TX_TIME 2120 // default is 328us(TX) + +typedef struct +{ + uint8_t len; // data length + void * pData; // pointer to message +} CHIPoBLEIndEvt_t; + +typedef struct +{ + uint8_t paramId; // Parameter written + uint16_t len; // data length + uint16_t connHandle; // Active connection which received the write +} CHIPoBLEProfChgEvt_t; + +// App event passed from stack modules. This type is defined by the application +// since it can queue events to itself however it wants. +typedef struct +{ + uint8_t event; // event type + void * pData; // pointer to message +} QueuedEvt_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; +} GapAdvEventData_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[]; +} ClockEventData_t; + +// List element for parameter update and PHY command status lists +typedef struct +{ + List_Elem elem; + uint16_t connHandle; +} ConnHandleEntry_t; + +// Connected device information +typedef struct +{ + uint16_t connHandle; // Connection Handle + ClockP_Struct * pUpdateClock; // pointer to clock struct + int8_t rssiArr[MAX_RSSI_STORE_DEPTH]; + uint8_t rssiCntr; + int8_t rssiAvg; + bool phyCngRq; // Set to true if PHY change request is in progress + uint8_t currPhy; + uint8_t rqPhy; + uint8_t phyRqFailCnt; // PHY change request count + bool isAutoPHYEnable; // Flag to indicate auto phy change + uint16_t mtu; + ClockEventData_t * pParamUpdateEventData; +} ConnRec_t; + +// Container to store passcode data when passing from gapbondmgr callback +// to app event. See the pfnPairStateCB_t documentation from the gapbondmgr.h +// header file for more information on each parameter. +typedef struct +{ + uint8_t state; + uint16_t connHandle; + uint8_t status; +} PairStateData_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; +} PasscodeData_t; + +/** + * Concrete implementation of the BLEManager singleton object for cc13x2_cc26x2. + */ +class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate + +{ + // Allow the BLEManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend BLEManager; + +public: + // ===== Platform-specific members that may be accessed directly by the application. + +private: + // ===== Members that implement the BLEManager internal interface. + + CHIP_ERROR _Init(void); + CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void); + CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val); + bool _IsAdvertisingEnabled(void); + CHIP_ERROR _SetAdvertisingEnabled(bool val); + bool _IsFastAdvertisingEnabled(void); + CHIP_ERROR _SetFastAdvertisingEnabled(bool val); + bool _IsAdvertising(void); + CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); + CHIP_ERROR _SetDeviceName(const char * deviceName); + uint16_t _NumConnections(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + BleLayer * _GetBleLayer(void); + + // ===== Members that implement virtual methods on BlePlatformDelegate. + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + bool CloseConnection(BLE_CONNECTION_OBJECT conId) override; + uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override; + + bool SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + + // ===== Members that implement virtual methods on BleApplicationDelegate. + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override; + + const ChipBleUUID chipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, + 0x9F, 0x9D, 0x11 } }; + const ChipBleUUID chipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, + 0x9F, 0x9D, 0x12 } }; + + friend BLEManager & BLEMgr(void); + friend BLEManagerImpl & BLEMgrImpl(void); + + static BLEManagerImpl sInstance; + + /* BLE stack task handle */ + static TaskHandle_t sBleTaskHndl; + // Entity ID globally used to check for source and/or destination of messages + static ICall_EntityID sSelfEntity; + + // Event globally used to post local events and pend on system and + // local events. + static ICall_SyncHandle sSyncEvent; + static QueueHandle_t sEventHandlerMsgQueueID; + static chipOBleProfileCBs_t CHIPoBLEProfile_CBs; + static gapBondCBs_t BLEMgr_BondMgrCBs; + + enum + { + kFlag_AdvertisingEnabled = 0x0001, /* App enabled CHIPoBLE advertising */ + kFlag_FastAdvertisingEnabled = 0x0002, /* App enabled Fash CHIPoBLE advertising */ + kFlag_Advertising = 0x0004, /* TI BLE stack actively advertising */ + kFlag_BLEStackInitialized = 0x0008, /* TI BLE Stack GAP Intilization complete */ + kFlag_BLEStackGATTNameUpdate = 0x0010, /* Trigger TI BLE Stack name update, must be performed prior to adv start */ + kFlag_BLEStackGATTNameSet = 0x0020, /* Device name has been set externally*/ + + }; + + uint16_t mFlags; + CHIPoBLEServiceMode mServiceMode; + char mDeviceName[GAP_DEVICE_NAME_LEN]; + + ConnRec_t connList[MAX_NUM_BLE_CONNS]; + // List to store connection handles for queued param updates + List_List paramUpdateList; + + // Advertising handles + uint8_t advHandleLegacy; + // Address mode + GAP_Addr_Modes_t addrMode = DEFAULT_ADDRESS_MODE; + // Current Random Private Address + uint8_t rpa[B_ADDR_LEN] = { 0 }; + + ClockP_Struct clkRpaRead; + ClockP_Struct clkAdvTimeout; + // Memory to pass RPA read event ID to clock handler + ClockEventData_t argRpaRead = { .event = READ_RPA_EVT }; + + // ===== Private BLE Stack Helper functions. + void AdvInit(void); + void EventHandler_init(void); + void InitPHYRSSIArray(void); + CHIP_ERROR CreateEventHandler(void); + uint8_t ProcessStackEvent(ICall_Hdr * pMsg); + void ProcessEvtHdrMsg(QueuedEvt_t * pMsg); + void ProcessGapMessage(gapEventHdr_t * pMsg); + uint8_t ProcessGATTMsg(gattMsgEvent_t * pMsg); + void ProcessAdvEvent(GapAdvEventData_t * pEventData); + CHIP_ERROR ProcessParamUpdate(uint16_t connHandle); + status_t EnqueueEvtHdrMsg(uint8_t event, void * pData); + uint8_t AddBLEConn(uint16_t connHandle); + uint8_t RemoveBLEConn(uint16_t connHandle); + uint8_t GetBLEConnIndex(uint16_t connHandle) const; + uint8_t ClearBLEConnListEntry(uint16_t connHandle); + void ClearPendingBLEParamUpdate(uint16_t connHandle); + void UpdateBLERPA(void); + + static void HandleIncomingBleConnection(Ble::BLEEndPoint * bleEP); + + /* Static helper function */ + static void EventHandler(void * arg); + static CHIP_ERROR DriveBLEState(void); + + /* Declared static to acquire function ptr */ + static void advCallback(uint32_t event, void * pBuf, uintptr_t arg); + static void ClockHandler(uintptr_t arg); + static void AdvTimeoutHandler(uintptr_t arg); + static void CHIPoBLEProfile_charValueChangeCB(uint8_t paramId, uint16_t len, uint16_t connHandle); + static void PasscodeCb(uint8_t * pDeviceAddr, uint16_t connHandle, uint8_t uiInputs, uint8_t uiOutputs, uint32_t numComparison); + static void PairStateCb(uint16_t connHandle, uint8_t state, uint8_t status); + static void AssertHandler(uint8 assertCause, uint8 assertSubcause); +}; + +/** + * Returns a reference to the public interface of the BLEManager singleton object. + * + * Internal components should use this to access features of the BLEManager object + * that are common to all platforms. + */ +inline BLEManager & BLEMgr(void) +{ + return BLEManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the BLEManager singleton object. + * + * Internal components can use this to gain access to features of the BLEManager + * that are specific to the cc13x2_cc26x2 platforms. + */ +inline BLEManagerImpl & BLEMgrImpl(void) +{ + return BLEManagerImpl::sInstance; +} + +inline BleLayer * BLEManagerImpl::_GetBleLayer() +{ + return this; +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#endif // BLEManager_IMPL_H diff --git a/src/platform/cc13x2_26x2/CHIPDevicePlatformConfig.h b/src/platform/cc13x2_26x2/CHIPDevicePlatformConfig.h index 42141b76166476..bd7b642a495d28 100644 --- a/src/platform/cc13x2_26x2/CHIPDevicePlatformConfig.h +++ b/src/platform/cc13x2_26x2/CHIPDevicePlatformConfig.h @@ -41,4 +41,8 @@ // ========== CHIP Platform Configuration ========= +#define BLEMANAGER_EVENT_HANDLER_STACK_SIZE (4096) +#define BLEMANAGER_EVENT_HANDLER_PRIORITY (2) +#define CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART 0 + #define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1 diff --git a/src/platform/cc13x2_26x2/ConnectivityManagerImpl.cpp b/src/platform/cc13x2_26x2/ConnectivityManagerImpl.cpp index 118030090c05d5..5308d9eba8d9e7 100644 --- a/src/platform/cc13x2_26x2/ConnectivityManagerImpl.cpp +++ b/src/platform/cc13x2_26x2/ConnectivityManagerImpl.cpp @@ -25,7 +25,7 @@ #include #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE -#include +#include #endif #if CHIP_DEVICE_CONFIG_ENABLE_THREAD diff --git a/src/platform/cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.cpp b/src/platform/cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.cpp new file mode 100644 index 00000000000000..4a756405871e6b --- /dev/null +++ b/src/platform/cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.cpp @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DeviceNetworkProvisioningDelegateImpl.h" + +#if CHIP_ENABLE_OPENTHREAD +#include +#endif + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR DeviceNetworkProvisioningDelegateImpl::_ProvisionThreadNetwork(DeviceLayer::Internal::DeviceNetworkInfo & threadData) +{ +#if CHIP_ENABLE_OPENTHREAD + CHIP_ERROR error = CHIP_NO_ERROR; + + SuccessOrExit(error = ThreadStackMgr().SetThreadEnabled(false)); + SuccessOrExit(error = ThreadStackMgr().SetThreadProvision(threadData)); + SuccessOrExit(error = ThreadStackMgr().SetThreadEnabled(true)); +exit: + return error; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; +#endif // CHIP_ENABLE_OPENTHREAD +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.h b/src/platform/cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.h index e3ba66ca9db3f4..05a642417934d4 100644 --- a/src/platform/cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.h +++ b/src/platform/cc13x2_26x2/DeviceNetworkProvisioningDelegateImpl.h @@ -36,7 +36,7 @@ class DeviceNetworkProvisioningDelegateImpl final private: CHIP_ERROR _ProvisionWiFiNetwork(const char * ssid, const char * passwd) { return CHIP_ERROR_NOT_IMPLEMENTED; } - CHIP_ERROR _ProvisionThreadNetwork(DeviceLayer::Internal::DeviceNetworkInfo & threadData) { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR _ProvisionThreadNetwork(DeviceLayer::Internal::DeviceNetworkInfo & threadData); }; } // namespace DeviceLayer diff --git a/src/platform/cc13x2_26x2/FreeRTOSConfig.h b/src/platform/cc13x2_26x2/FreeRTOSConfig.h index b4138ef1d7d59b..532b7767270d67 100644 --- a/src/platform/cc13x2_26x2/FreeRTOSConfig.h +++ b/src/platform/cc13x2_26x2/FreeRTOSConfig.h @@ -49,7 +49,7 @@ /* Constants related to the behaviour or the scheduler. */ #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 -#define configTICK_RATE_HZ ((TickType_t) 1000) +#define configTICK_RATE_HZ ((TickType_t) 100000) #define configUSE_PREEMPTION 1 #define configUSE_TIME_SLICING 0 #define configMAX_PRIORITIES (10UL) @@ -58,14 +58,18 @@ /* Constants that describe the hardware and memory usage. */ #define configCPU_CLOCK_HZ ((unsigned long) 48000000) -#define configMINIMAL_STACK_SIZE ((unsigned short) 256) +#define configMINIMAL_STACK_SIZE ((unsigned short) 1024) #define configMAX_TASK_NAME_LEN (12) -#define configTOTAL_HEAP_SIZE ((size_t)(0x8000)) +/* FreeRTOS heap size is 0 because currently "bget" heap is the + only heap available, for both FreeRTOS and application */ +//#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 0 ) ) +#define configTOTAL_HEAP_SIZE ((size_t)(0)) #define configSUPPORT_STATIC_ALLOCATION 1 +#define configAPPLICATION_ALLOCATED_HEAP 1 /* Default stack size for TI-POSIX threads (in words) */ -#define configPOSIX_STACK_SIZE ((unsigned short) 512) +#define configPOSIX_STACK_SIZE ((unsigned short) 1024) /* Constants that build features in or out. */ #define configUSE_MUTEXES 1 @@ -99,7 +103,7 @@ /* Software timer definitions. */ #define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (5) +#define configTIMER_TASK_PRIORITY (6) #define configTIMER_QUEUE_LENGTH (20) #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) diff --git a/src/platform/cc13x2_26x2/Logging.cpp b/src/platform/cc13x2_26x2/Logging.cpp index 668040a8abe794..87807d871cc804 100644 --- a/src/platform/cc13x2_26x2/Logging.cpp +++ b/src/platform/cc13x2_26x2/Logging.cpp @@ -5,6 +5,10 @@ #include #include +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#endif + #include "ti_drivers_config.h" #include @@ -71,7 +75,7 @@ void LogV(const char * module, uint8_t category, const char * msg, va_list v) cc13x2_26x2VLog(msg, v); - DeviceLayer::OnLogOutput(); + chip::DeviceLayer::OnLogOutput(); } } // namespace Platform @@ -89,7 +93,7 @@ extern "C" void LwIPLog(const char * msg, ...) cc13x2_26x2VLog(msg, v); - DeviceLayer::OnLogOutput(); + chip::DeviceLayer::OnLogOutput(); va_end(v); } @@ -104,7 +108,7 @@ extern "C" void cc13x2_26x2Log(const char * msg, ...) cc13x2_26x2VLog(msg, v); - DeviceLayer::OnLogOutput(); + chip::DeviceLayer::OnLogOutput(); va_end(v); } @@ -120,7 +124,7 @@ extern "C" void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const ch cc13x2_26x2VLog(aFormat, v); - DeviceLayer::OnLogOutput(); + chip::DeviceLayer::OnLogOutput(); va_end(v); } #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD diff --git a/src/platform/cc13x2_26x2/PlatformManagerImpl.cpp b/src/platform/cc13x2_26x2/PlatformManagerImpl.cpp index b8b7010275011c..be028c80b450bb 100644 --- a/src/platform/cc13x2_26x2/PlatformManagerImpl.cpp +++ b/src/platform/cc13x2_26x2/PlatformManagerImpl.cpp @@ -25,16 +25,80 @@ /* this file behaves like a config.h, comes first */ #include +#include #include #include #include +#include +#include +#include + +/* Include DMM module */ +#include +#include + +#include "ti_dmm_application_policy.h" +#include + +TRNG_Handle TRNG_handle_app; + namespace chip { namespace DeviceLayer { PlatformManagerImpl PlatformManagerImpl::sInstance; +static int app_get_random(uint8_t * aOutput, size_t aLen) +{ + int_fast16_t rtn; + CryptoKey entropyKey; + + /* + * prepare the data buffer + */ + CryptoKeyPlaintext_initBlankKey(&entropyKey, aOutput, aLen); + + /* get entropy */ + rtn = TRNG_generateEntropy(TRNG_handle_app, &entropyKey); + if (rtn != TRNG_STATUS_SUCCESS) + { + while (1) + ; + } + return CHIP_NO_ERROR; +} + +static void app_random_init(void) +{ + TRNG_Params TRNGParams; + + /* Init the TRNG HW */ + TRNG_init(); + + TRNG_Params_init(&TRNGParams); + /* use the polling mode */ + TRNGParams.returnBehavior = TRNG_RETURN_BEHAVIOR_POLLING; + + TRNG_handle_app = TRNG_open(CONFIG_TRNG_APP, &TRNGParams); + if (TRNG_handle_app == NULL) + { + while (1) + ; + } + + return; +} + +static int app_entropy_source(void * data, unsigned char * output, size_t len, size_t * olen) +{ + + app_get_random(reinterpret_cast(output), static_cast(len)); + *olen = len; + + return 0; +} + CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) { CHIP_ERROR err; @@ -43,6 +107,28 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) err = Internal::CC13X2_26X2Config::Init(); SuccessOrExit(err); + // DMM Addition + DMMPolicy_Params dmmPolicyParams; + DMMSch_Params dmmSchedulerParams; + + /* initialize and open the DMM policy manager */ + DMMPolicy_init(); + DMMPolicy_Params_init(&dmmPolicyParams); + dmmPolicyParams.numPolicyTableEntries = DMMPolicy_ApplicationPolicySize; + dmmPolicyParams.policyTable = DMMPolicy_ApplicationPolicyTable; + dmmPolicyParams.globalPriorityTable = globalPriorityTable_bleLthreadH; + DMMPolicy_open(&dmmPolicyParams); + + /* initialize and open the DMM scheduler */ + DMMSch_init(); + DMMSch_Params_init(&dmmSchedulerParams); + + // Copy stack roles and index table + memcpy(dmmSchedulerParams.stackRoles, DMMPolicy_ApplicationPolicyTable.stackRole, + sizeof(DMMPolicy_StackRole) * DMMPOLICY_NUM_STACKS); + dmmSchedulerParams.indexTable = DMMPolicy_ApplicationPolicyTable.indexTable; + DMMSch_open(&dmmSchedulerParams); + // Initialize LwIP. tcpip_init(NULL, NULL); @@ -51,6 +137,10 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(); SuccessOrExit(err); + app_random_init(); + err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16); + SuccessOrExit(err); + exit: return err; } diff --git a/src/platform/cc13x2_26x2/ThreadStackManagerImpl.cpp b/src/platform/cc13x2_26x2/ThreadStackManagerImpl.cpp index 688649ecbf713c..67a6b992968502 100644 --- a/src/platform/cc13x2_26x2/ThreadStackManagerImpl.cpp +++ b/src/platform/cc13x2_26x2/ThreadStackManagerImpl.cpp @@ -38,6 +38,14 @@ // platform folder in the TI SDK example application #include +// DMM Includes +#ifdef USE_DMM +#include "ti_dmm_application_policy.h" +#include +#include +#include +#endif + namespace chip { namespace DeviceLayer { @@ -45,6 +53,7 @@ using namespace ::chip::DeviceLayer::Internal; ThreadStackManagerImpl ThreadStackManagerImpl::sInstance; +#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE != 0 static void * ot_calloc(size_t n, size_t size) { void * p_ptr = NULL; @@ -60,6 +69,7 @@ static void ot_free(void * p_ptr) { vPortFree(p_ptr); } +#endif /* OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE != 0 */ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void) { @@ -73,12 +83,20 @@ CHIP_ERROR ThreadStackManagerImpl::InitThreadStack(otInstance * otInst) // Create FreeRTOS queue for platform driver messages procQueue = xQueueCreate(16U, sizeof(ThreadStackManagerImpl::procQueueMsg)); +#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE != 0 mbedtls_platform_set_calloc_free(ot_calloc, ot_free); otHeapSetCAllocFree(ot_calloc, ot_free); +#endif /* OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE != 0 */ // Initialize the OpenThread platform layer otSysInit(0, NULL); +#ifdef USE_DMM + // DMM Init + DMMSch_registerClient(xTaskGetCurrentTaskHandle(), DMMPolicy_StackRole_threadFtd); + DMMPolicy_updateStackState(DMMPolicy_StackRole_threadFtd, DMMPOLICY_THREAD_IDLE); +#endif + // Initialize the generic implementation base classes. err = GenericThreadStackManagerImpl_FreeRTOS::DoInit(); SuccessOrExit(err); diff --git a/src/platform/cc13x2_26x2/chipOBleProfile.c b/src/platform/cc13x2_26x2/chipOBleProfile.c new file mode 100644 index 00000000000000..d587ecf900949a --- /dev/null +++ b/src/platform/cc13x2_26x2/chipOBleProfile.c @@ -0,0 +1,377 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Texas Instruments Incorporated + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file chipOBLeProfile.c + * This file contains the CHIPOBLE profile sample GATT service profile + * for use with the BLE Manager. + */ +/********************************************************************* + * INCLUDES + */ +#include + +#include +#include + +#include "icall_ble_api.h" +#include "ti_ble_config.h" + +#include "chipOBleProfile.h" + +/********************************************************************* + * GLOBAL VARIABLES + */ +// CHIPoBLE GATT Profile Service UUID +const uint8 chipOBleServUUID[ATT_UUID_SIZE] = { CHIPOBLEPROFILE_SERV_UUID_BASE128(CHIPOBLE_SERV_UUID) }; + +// CHIPoBLE Tx characteristic UUID +const uint8 chipOBleProfileTxCharUUID[ATT_UUID_SIZE] = { + // 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 + CHIPOBLEPROFILE_CHAR_UUID_BASE128(CHIPOBLEPROFILE_TX_CHAR_UUID) +}; + +// CHIPoBLE Rx characteristic UUID +const uint8 chipOBleProfileRxCharUUID[ATT_UUID_SIZE] = { + // 0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 + CHIPOBLEPROFILE_CHAR_UUID_BASE128(CHIPOBLEPROFILE_RX_CHAR_UUID) +}; + +/********************************************************************* + * Profile Attributes - variables + */ + +// Remote Display Profile Service attribute +static const gattAttrType_t chipoBleProfile = { ATT_UUID_SIZE, chipOBleServUUID }; + +// ChipOBLE Tx Characteristic Properties +static uint8_t chipOBleProfileTxCharProps = GATT_PROP_READ | GATT_PROP_INDICATE; + +// ChipOBLE Tx Characteristic Value +static uint8_t chipOBleProfileTxCharVal[CHIPOBLEPROFILE_CHAR_LEN] = { 0x00 }; + +// ChipOBLE Tx Characteristic User Description +static uint8_t chipOBleProfileTxdDataUserDesp[CHIPOBLEPROFILE_MAX_DESCRIPTION_LEN] = "ChipOBLE Tx Char"; + +static gattCharCfg_t * chipOBleProfileTxStateDataConfig; + +// ChipOBLE Rx Characteristic Properties +static uint8_t chipOBleProfileRxCharProps = GATT_PROP_WRITE; + +// ChipOBLE Rx Characteristic Value +static uint8_t chipOBleProfileRxCharVal[CHIPOBLEPROFILE_CHAR_LEN] = { 0x00 }; + +// ChipOBLE Rx Characteristic User Description +static uint8_t chipOBleProfileRxdDataUserDesp[CHIPOBLEPROFILE_MAX_DESCRIPTION_LEN] = "ChipOBLE Rx Char"; + +/********************************************************************* + * LOCAL VARIABLES + */ + +static chipOBleProfileCBs_t * chipOBleProfile_AppCBs = NULL; + +/********************************************************************* + * Profile Attributes - Table + */ + +static gattAttribute_t chipoBleProfileAttrTbl[] = { + // CHIPoBLE Service + { + { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */ + GATT_PERMIT_READ, /* permissions */ + 0, /* handle */ + (uint8 *) &chipoBleProfile /* pValue */ + }, + // CHIPoBLE Tx Characteristic Declaration + { { ATT_BT_UUID_SIZE, characterUUID }, GATT_PERMIT_READ, 0, &chipOBleProfileTxCharProps }, + // CHIPoBLE Tx Characteristic Value + { { ATT_UUID_SIZE, chipOBleProfileTxCharUUID }, GATT_PERMIT_READ, 0, chipOBleProfileTxCharVal }, + + // CHIPoBLE Tx Characteristic configuration + { { ATT_BT_UUID_SIZE, clientCharCfgUUID }, + GATT_PERMIT_READ | GATT_PERMIT_WRITE, + 0, + (uint8 *) &chipOBleProfileTxStateDataConfig }, + + // CHIPoBLE Tx Characteristic User Description + { { ATT_BT_UUID_SIZE, charUserDescUUID }, GATT_PERMIT_READ, 0, chipOBleProfileTxdDataUserDesp }, + + // CHIPoBLE Rx Characteristic Declaration + { { ATT_BT_UUID_SIZE, characterUUID }, GATT_PERMIT_READ, 0, &chipOBleProfileRxCharProps }, + // CHIPoBLE Rx Characteristic Value + { { ATT_UUID_SIZE, chipOBleProfileRxCharUUID }, GATT_PERMIT_WRITE, 0, chipOBleProfileRxCharVal }, + + // CHIPoBLE Rx Characteristic User Description + { { ATT_BT_UUID_SIZE, charUserDescUUID }, GATT_PERMIT_READ, 0, chipOBleProfileRxdDataUserDesp }, +}; + +/********************************************************************* + * LOCAL FUNCTIONS + */ +static bStatus_t CHIPoBLEProfile_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 CHIPoBLEProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t * pAttr, uint8_t * pValue, uint16_t len, + uint16_t offset, uint8_t method); + +/********************************************************************* + * PROFILE CALLBACKS + */ + +// CHIPoBLE 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 chipOBleProfileCBs = { + CHIPoBLEProfile_ReadAttrCB, // Read callback function pointer + CHIPoBLEProfile_WriteAttrCB, // Write callback function pointer + NULL // Authorization callback function pointer +}; + +/********************************************************************* + * PUBLIC FUNCTIONS + */ + +/********************************************************************* + * @fn CHIPoBLEProfile_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 CHIPoBLEProfile_AddService(uint32 services) +{ + uint8 status; + + // Allocate Client Characteristic Configuration tables + chipOBleProfileTxStateDataConfig = (gattCharCfg_t *) ICall_malloc((uint_least16_t)(sizeof(gattCharCfg_t) * MAX_NUM_BLE_CONNS)); + if (chipOBleProfileTxStateDataConfig == NULL) + { + return bleMemAllocError; + } + + // Initialize Client Characteristic Configuration attributes + GATTServApp_InitCharCfg(LL_CONNHANDLE_INVALID, chipOBleProfileTxStateDataConfig); + + if (services & CHIPOBLEPROFILE_SERVICE) + { + // Register GATT attribute list and CBs with GATT Server App + status = GATTServApp_RegisterService(chipoBleProfileAttrTbl, GATT_NUM_ATTRS(chipoBleProfileAttrTbl), + GATT_MAX_ENCRYPT_KEY_SIZE, &chipOBleProfileCBs); + } + else + { + status = SUCCESS; + } + + return status; +} + +/********************************************************************* + * @fn CHIPoBLEProfile_RegisterAppCBs + * + * @brief Registers the application callback function. Only call + * this function once. + * + * @param callbacks - pointer to application callbacks. + * + * @return SUCCESS or bleAlreadyInRequestedMode + */ +bStatus_t CHIPoBLEProfile_RegisterAppCBs(chipOBleProfileCBs_t * appCallbacks) +{ + if (appCallbacks) + { + chipOBleProfile_AppCBs = appCallbacks; + + return SUCCESS; + } + else + { + return bleAlreadyInRequestedMode; + } +} + +/********************************************************************* + * @fn CHIPoBLEProfile_SetParameter + * + * @brief Set a CHIPoBLE Characteristic value + * + * @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 + */ +extern uint8 gattAppTaskID; +bStatus_t CHIPoBLEProfile_SetParameter(uint8 param, uint8 len, void * value, uint8_t taskId) +{ + bStatus_t ret = SUCCESS; + switch (param) + { + case CHIPOBLEPROFILE_TX_CHAR: + + VOID memcpy(chipOBleProfileTxCharVal, value, len); + + // See if Indications has been enabled + ret = GATTServApp_ProcessCharCfg(chipOBleProfileTxStateDataConfig, chipOBleProfileTxCharVal, FALSE, chipoBleProfileAttrTbl, + GATT_NUM_ATTRS(chipoBleProfileAttrTbl), taskId, CHIPoBLEProfile_ReadAttrCB); + break; + default: + ret = INVALIDPARAMETER; + break; + } + + return ret; +} + +/********************************************************************* + * @fn CHIPoBLEProfile_GetParameter + * + * @brief Get a CHIPoBLE Characteristic value + * + * @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 CHIPoBLEProfile_GetParameter(uint8 param, void * value, uint16_t len) +{ + bStatus_t ret = SUCCESS; + switch (param) + { + case CHIPOBLEPROFILE_RX_CHAR: + if (len != 0) + { + VOID memcpy(value, chipOBleProfileRxCharVal, len); + } + else + { + VOID memcpy(value, chipOBleProfileRxCharVal, CHIPOBLEPROFILE_CHAR_LEN); + } + break; + case CHIPOBLEPROFILE_CCCWrite: + *((uint8 *) value) = chipOBleProfileTxStateDataConfig->value; + break; + default: + ret = INVALIDPARAMETER; + break; + } + + return ret; +} + +/********************************************************************* + * @fn CHIPoBLEProfile_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 CHIPoBLEProfile_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; + uint8 len = maxLen; + + if (offset + maxLen > CHIPOBLEPROFILE_CHAR_LEN) + len = CHIPOBLEPROFILE_CHAR_LEN - offset; + + *pLen = len; + VOID osal_memcpy(pValue, (pAttr->pValue) + offset, len); + + return status; +} + +/********************************************************************* + * @fn CHIPoBLEProfile_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 CHIPoBLEProfile_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_UUID_SIZE) + { + if (!memcmp(pAttr->type.uuid, chipOBleProfileRxCharUUID, pAttr->type.len)) + { + VOID osal_memcpy((pAttr->pValue) + offset, pValue, len); + + // Send notification to BLE Event handler + notifyApp = CHIPOBLEPROFILE_RX_CHAR; + } + else + { + status = ATT_ERR_ATTR_NOT_FOUND; + } + } + + else if ((pAttr->type.len == ATT_BT_UUID_SIZE) && + (BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]) == GATT_CLIENT_CHAR_CFG_UUID)) + { + + notifyApp = CHIPOBLEPROFILE_CCCWrite; + + status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_INDICATE); + } + else + { + // unsupported length + status = ATT_ERR_INVALID_HANDLE; + } + + // If a characteristic value changed then callback function to notify application of change + if ((notifyApp != 0xFF) && chipOBleProfile_AppCBs && chipOBleProfile_AppCBs->pfnchipOBleProfileChange) + { + chipOBleProfile_AppCBs->pfnchipOBleProfileChange(notifyApp, len, connHandle); + } + + return status; +} diff --git a/src/platform/cc13x2_26x2/chipOBleProfile.h b/src/platform/cc13x2_26x2/chipOBleProfile.h new file mode 100644 index 00000000000000..b9ed01870e9cdf --- /dev/null +++ b/src/platform/cc13x2_26x2/chipOBleProfile.h @@ -0,0 +1,125 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Texas Instruments Incorporated + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file chipOBLeProfile.h + * This file contains the CHIPOBLE profile definitions and prototypes + * prototypes. + */ + +#ifndef CHIPOBLEPROFILE_H +#define CHIPOBLEPROFILE_H + +#ifdef __cplusplus +#include +#include +#include + +extern "C" { +#endif + +/********************************************************************* + * INCLUDES + */ + +/********************************************************************* + * CONSTANTS + */ + +// Simple Keys Profile Services bit fields +#define CHIPOBLEPROFILE_SERVICE 0x00000001 + +#define CHIPOBLE_SERV_UUID 0xFEAF // Servuce UUID +#define CHIPOBLEPROFILE_TX_CHAR_UUID 0x129D // GATT indications/read +#define CHIPOBLEPROFILE_RX_CHAR_UUID 0x119D // GATT Writes + +#define CHIPOBLEPROFILE_SERV_UUID_BASE128(uuid) \ + 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, LO_UINT16(uuid), HI_UINT16(uuid), 0x00, 0x00 + +#define CHIPOBLEPROFILE_CHAR_UUID_BASE128(uuid) \ + HI_UINT16(uuid), LO_UINT16(uuid), 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 + +#define CHIPOBLEPROFILE_TX_CHAR 0 // R uint8 - Profile Characteristic 1 (CHIPOBLE Tx) value +#define CHIPOBLEPROFILE_RX_CHAR 1 // W uint8 - Profile Characteristic 2 (CHIPOBLE Rx) value +#define CHIPOBLEPROFILE_CCCWrite 2 // Client Characteristic Configuration + +#define CHIPOBLEPROFILE_CHAR_LEN (244) +#define CHIPOBLEPROFILE_MAX_DESCRIPTION_LEN (20) + +/********************************************************************* + * TYPEDEFS + */ + +/* Callback when a characteristic value has changed */ +typedef void (*chipOBleProfileChange_t)(uint8 paramID, uint16 len, uint16_t connHandle); + +typedef struct +{ + chipOBleProfileChange_t pfnchipOBleProfileChange; // Called when characteristic value changes +} chipOBleProfileCBs_t; + +/********************************************************************* + * API FUNCTIONS + */ + +/* + * CHIPoBLEProfile_AddService- Initializes the CHIPoBLE 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. + */ + +bStatus_t CHIPoBLEProfile_AddService(uint32 services); + +/* + * CHIPoBLEProfile_RegisterAppCBs - Registers the application callback function. + * Only call this function once. + * + * appCallbacks - pointer to application callbacks. + */ +bStatus_t CHIPoBLEProfile_RegisterAppCBs(chipOBleProfileCBs_t * appCallbacks); + +/* + * CHIPoBLEProfile_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). + */ +bStatus_t CHIPoBLEProfile_SetParameter(uint8 param, uint8 len, void * value, uint8_t taskId); + +/* + * CHIPoBLEProfile_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). + */ +bStatus_t CHIPoBLEProfile_GetParameter(uint8 param, void * value, uint16_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* CHIPOBLEPROFILE_H */ diff --git a/src/platform/device.gni b/src/platform/device.gni index c0639e1f86f586..2c2dc3d1e35bf1 100644 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -42,7 +42,8 @@ declare_args() { # Enable ble support. chip_enable_ble = - chip_device_platform == "linux" || chip_device_platform == "darwin" + chip_device_platform == "linux" || chip_device_platform == "darwin" || + chip_device_platform == "cc13x2_26x2" chip_enable_mdns = chip_device_platform == "linux" || chip_device_platform == "esp32" diff --git a/third_party/ti_simplelink_sdk/BUILD.gn b/third_party/ti_simplelink_sdk/BUILD.gn index 9b8a69c55e56e5..09ca83c00ef2cb 100644 --- a/third_party/ti_simplelink_sdk/BUILD.gn +++ b/third_party/ti_simplelink_sdk/BUILD.gn @@ -40,7 +40,7 @@ config("ti_simplelink_mbedtls_config") { include_dirs = [ "${chip_root}/src/platform/cc13x2_26x2", "${ti_simplelink_sdk_root}/source", - "${ti_simplelink_sdk_root}/source/ti/thread/rtos/${ti_simplelink_board}/thread/libmbedcrypto/config", + "${ti_simplelink_sdk_root}/source/ti/thread/cc13x2_26x2/libmbedcrypto/config", ] } @@ -64,8 +64,14 @@ config("ti_simplelink_freertos_config") { freertos_target("freertos") { sources = [ "${freertos_root}/repo/portable/GCC/ARM_CM4F/port.c", - "${freertos_root}/repo/portable/MemMang/heap_4.c", + #"${freertos_root}/repo/portable/MemMang/heap_4.c", ] public_configs = [ ":ti_simplelink_freertos_config" ] + + if (ti_simplelink_device_family == "cc13x2x7_26x2x7") { + # BLE has to have it's own heap config + public_deps = + [ "${chip_root}/third_party/ti_simplelink_sdk:ti_simplelink_sysconfig" ] + } } diff --git a/third_party/ti_simplelink_sdk/ti_simplelink_arm_platform_config.gni b/third_party/ti_simplelink_sdk/ti_simplelink_arm_platform_config.gni index 956a4828197209..91cd5911d7df99 100644 --- a/third_party/ti_simplelink_sdk/ti_simplelink_arm_platform_config.gni +++ b/third_party/ti_simplelink_sdk/ti_simplelink_arm_platform_config.gni @@ -14,7 +14,8 @@ import("ti_simplelink_board.gni") -if (ti_simplelink_device_family == "cc13x2_26x2") { +if (ti_simplelink_device_family == "cc13x2_26x2" || + ti_simplelink_device_family == "cc13x2x7_26x2x7") { arm_arch = "armv7e-m" arm_abi = "aapcs" arm_cpu = "cortex-m4" diff --git a/third_party/ti_simplelink_sdk/ti_simplelink_board.gni b/third_party/ti_simplelink_sdk/ti_simplelink_board.gni index 9c8dacfc524fec..d2b6d9d240e853 100644 --- a/third_party/ti_simplelink_sdk/ti_simplelink_board.gni +++ b/third_party/ti_simplelink_sdk/ti_simplelink_board.gni @@ -25,10 +25,11 @@ assert(ti_simplelink_board != "", "ti_simplelink_board must be specified") # Differentiate between boards # -# | Development Kit | Device Family | SoC | -# | ----------------- | ------------- | ---------- | -# | CC1352R1_LAUNCHXL | cc13x2_26x2 | cc1352r1f3 | -# | CC2652R1_LAUNCHXL | cc13x2_26x2 | cc2652r1f3 | +# | Development Kit | Device Family | SoC | | +# | ----------------- | --------------- | ---------- | ------------------- | +# | CC1352R1_LAUNCHXL | cc13x2_26x2 | cc1352r1f3 | Thread MTD + no BLE | +# | CC2652R1_LAUNCHXL | cc13x2_26x2 | cc2652r1f3 | Thread MTD + no BLE | +# | LP_CC2652R7 | cc13x2x7_26x2x7 | cc2652r1f7 | Thread FTD + BLE | # XXX: Can we do an array with a case statement? if (ti_simplelink_board == "CC1352R1_LAUNCHXL") { @@ -43,6 +44,12 @@ if (ti_simplelink_board == "CC1352R1_LAUNCHXL") { # set -DDeviceFamily_CC26X2? ti_simplelink_soc = "cc2652r1f3" +} else if (ti_simplelink_board == "LP_CC2652R7") { + ti_simplelink_device_family = "cc13x2x7_26x2x7" + ti_simplelink_soc_family = "cc26x2" + + # set -DDeviceFamily_CC26X2? + ti_simplelink_soc = "cc2652r1f7" } else { print("Please provide a valid value for TI_SIMPLELINK_BOARD env variable") assert(false, "The board ${ti_simplelink_board} is unsupported as for now.") diff --git a/third_party/ti_simplelink_sdk/ti_simplelink_sdk.gni b/third_party/ti_simplelink_sdk/ti_simplelink_sdk.gni index b089217c9ea762..7d29bf2ea16160 100644 --- a/third_party/ti_simplelink_sdk/ti_simplelink_sdk.gni +++ b/third_party/ti_simplelink_sdk/ti_simplelink_sdk.gni @@ -58,11 +58,17 @@ template("ti_sysconfig") { } if (ti_simplelink_device_family == "cc13x2_26x2") { - assert(ti_simplelink_soc_family != "", - "ti_simplelink_soc_family must be specified") - ldflags += [ "-nostartfiles" ] defines += [ "DeviceFamily_CC13X2_CC26X2" ] + } else if (ti_simplelink_device_family == "cc13x2x7_26x2x7") { + ldflags += [ "-nostartfiles" ] + defines += [ "DeviceFamily_CC26X2X7" ] + } + if (defined(invoker.cflags)) { + cflags = invoker.cflags + } + if (defined(invoker.ldflags)) { + ldflags += invoker.ldflags } } @@ -93,6 +99,10 @@ template("ti_sysconfig") { public_configs = [ ":${target_name}_config" ] public_deps = [ ":${target_name}_gen" ] + + if (defined(invoker.public_configs)) { + public_configs += invoker.public_configs + } } } @@ -124,19 +134,27 @@ template("ti_simplelink_sdk") { ] defines = [] - if (ti_simplelink_device_family == "cc13x2_26x2") { + if (ti_simplelink_device_family == "cc13x2_26x2" || + ti_simplelink_device_family == "cc13x2x7_26x2x7") { assert(ti_simplelink_soc_family != "", "ti_simplelink_soc_family must be specified") - - defines += [ "DeviceFamily_CC13X2_CC26X2" ] + assert(ti_simplelink_device_family != "", + "ti_simplelink_device_family must be specified") libs += [ "${ti_simplelink_sdk_root}/source/ti/drivers/lib/gcc/m4f/drivers_${ti_simplelink_soc_family}.a", - "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2_cc26x2/driverlib/bin/gcc/driverlib.lib", "${ti_simplelink_sdk_root}/source/ti/drivers/rf/lib/rf_multiMode_${ti_simplelink_soc_family}.am4fg", ] } + if (ti_simplelink_device_family == "cc13x2_26x2") { + defines += [ "DeviceFamily_CC13X2_CC26X2" ] + libs += [ "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2_cc26x2/driverlib/bin/gcc/driverlib.lib" ] + } else if (ti_simplelink_device_family == "cc13x2x7_26x2x7") { + defines += [ "DeviceFamily_CC13X2X7_CC26X2X7" ] + libs += [ "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2x7_cc26x2x7/driverlib/bin/gcc/driverlib.lib" ] + } + if (defined(invoker.defines)) { defines += invoker.defines } @@ -175,8 +193,9 @@ template("ti_simplelink_sdk") { config("${sdk_target_name}_posix_config") { include_dirs = [ "${ti_simplelink_sdk_root}/source/ti/posix/gcc" ] + cflags_c = [ "-std=c11" ] + cflags_cc = [ "-std=c++14" ] cflags = [ - "-std=c11", "-Wno-maybe-uninitialized", "-Wno-sign-compare", ] @@ -209,14 +228,28 @@ template("ti_simplelink_sdk") { public_configs = [ ":${sdk_target_name}_config" ] } + if (ti_simplelink_device_family == "cc13x2_26x2") { + openthread_example = "cli_mtd" + } else if (ti_simplelink_device_family == "cc13x2x7_26x2x7") { + openthread_example = "cli_ftd" + } + config("${sdk_target_name}_openthread_platform_config") { defines = [ "NVOCMP_POSIX_MUTEX" ] include_dirs = [ "${chip_root}/third_party/openthread/repo/examples/platforms", "${chip_root}/third_party/openthread/repo/src/core", - "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2_cc26x2", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd", + "${ti_simplelink_sdk_root}/source/ti/devices/${ti_simplelink_device_family}", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}", ] + + if (ti_simplelink_device_family == "cc13x2_26x2") { + include_dirs += + [ "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2_cc26x2" ] + } else if (ti_simplelink_device_family == "cc13x2x7_26x2x7") { + include_dirs += + [ "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2x7_cc26x2x7" ] + } } source_set("${sdk_target_name}_openthread_platform") { @@ -224,6 +257,7 @@ template("ti_simplelink_sdk") { "-Wno-int-conversion", "-Wno-address-of-packed-member", "-Wno-implicit-fallthrough", + "-Wno-unused-label", ] public_deps = [ ":${sdk_target_name}_freertos", @@ -236,27 +270,174 @@ template("ti_simplelink_sdk") { configs -= [ "${build_root}/config/compiler:std_default" ] configs += [ ":${sdk_target_name}_posix_config" ] sources = [ - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/alarm.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/alarm_micro.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/crypto/aes_alt.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/crypto/ecjpake_alt.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/crypto/sha256_alt.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/diag.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/entropy.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/misc.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/nv/crc.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/nv/nvocmp.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/radio.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/settings.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/system.c", - "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/cli_mtd/platform/uart.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/alarm.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/alarm_micro.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/crypto/aes_alt.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/crypto/ecjpake_alt.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/crypto/sha256_alt.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/diag.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/entropy.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/misc.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/nv/crc.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/nv/nvocmp.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/radio.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/settings.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/system.c", + "${ti_simplelink_sdk_root}/examples/rtos/${ti_simplelink_board}/thread/${openthread_example}/platform/uart.c", ] public_configs = [ ":${sdk_target_name}_config", ":${sdk_target_name}_openthread_platform_config", "${chip_root}/third_party/openthread/repo:openthread_config", - "${chip_root}/third_party/openthread/repo:openthread_mtd_config", + ] + + if (ti_simplelink_device_family == "cc13x2_26x2") { + public_configs += + [ "${chip_root}/third_party/openthread/repo:openthread_mtd_config" ] + } else if (ti_simplelink_device_family == "cc13x2x7_26x2x7") { + public_configs += + [ "${chip_root}/third_party/openthread/repo:openthread_ftd_config" ] + } + } + + config("${sdk_target_name}_dmm_config") { + include_dirs = [] + libs = [] + + include_dirs += [ + # DMM/BLE: + "${ti_simplelink_sdk_root}/source", + + # CHIPoBLE Added include dirs + "${ti_simplelink_sdk_root}/source/ti/dmm/apps/common/freertos/", + "${ti_simplelink_sdk_root}/source/ti/dmm/apps/common/freertos/itm", + "${ti_simplelink_sdk_root}/source/ti/dmm/thread/platform", + "${ti_simplelink_sdk_root}/source/", + "${ti_simplelink_sdk_root}/source/ti/", + "${ti_simplelink_sdk_root}/source/ti/dmm/", + "${ti_simplelink_sdk_root}/source/ti/dmm/apps/", + "${ti_simplelink_sdk_root}/source/ti/common/nv", + + "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2x7_cc26x2x7", + "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2x7_cc26x2x7/inc", + "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2x7_cc26x2x7/rf_patches", + "${ti_simplelink_sdk_root}/source/ti/devices/cc13x2x7_cc26x2x7/driverlib", + + "${ti_simplelink_sdk_root}/source/ti/ble5stack/common/cc26xx/npi/stack/", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/common/cc26xx/rcosc", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/controller/cc26xx/inc", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/inc", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/rom", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/common/cc26xx", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/common/cc26xx/freertos", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/icall/inc", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/icall/src", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/hal/src/target/_common", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/hal/src/target/_common/cc26xx", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/hal/src/inc", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/heapmgr", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/profiles/dev_info", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/hal/src/target/_common/cc26xx/", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/profiles/simple_profile", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/icall/src/inc", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/osal/src/inc", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/controller/cc26xx/inc/", + "${ti_simplelink_sdk_root}/source/ti/common/cc26xx", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/common/cc26xx/freertos/", + ] + + defines = [ + "USE_DMM", + "FLASH_ROM_BUILD", + "NVOCMP_FREERTOS_MUTEX=1", + "USEOT", + "ONE_BLE_LIB_SIZE_OPTIMIZATION", + "ICALL_EVENTS", + "ICALL_JT", + "ICALL_LITE", + "ICALL_MAX_NUM_ENTITIES=6", + "ICALL_MAX_NUM_TASKS=3", + "ICALL_STACK0_ADDR", + "POWER_SAVING", + "STACK_LIBRARY", + "TBM_ACTIVE_ITEMS_ONLY", + "NPI_USE_UART", + "NPI_FLOW_CTRL=0", + "OSAL_CBTIMER_NUM_TASKS=1", + "USE_ICALL", + "BLE_START", + "CC26XX", + "CC26X2", + "CC26X2R1_LAUNCHXL", + "FREERTOS", + ] + + if (ti_simplelink_device_family == "cc13x2x7_26x2x7") { + libs += [ + "${ti_simplelink_sdk_root}/source/ti/dmm/library/freertos/gcc/bin/dmmlib_cc26x2.a", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/libraries/cc26x2r1/OneLib.a", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/libraries/cc26x2r1/StackWrapper.a", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/libraries/cc26x2r1/ble_r2.symbols", + ] + } + + cflags = [ + "-Wno-conversion", + "-Wno-comment", + "@${ti_simplelink_sdk_root}/source/ti/ble5stack/config/build_components.opt", + "@${ti_simplelink_sdk_root}/source/ti/ble5stack/config/factory_config.opt", + ] + } + + source_set("${sdk_target_name}_dmm") { + defines = [] + include_dirs = [] + + configs -= + [ "${build_root}/config/compiler:warnings_default" ] # removed for + # -Wshadow + + cflags = [ + "-Wno-sign-compare", + "-Wno-unused-variable", + "-Wno-implicit-function-declaration", # asm not defined + ] + + sources = [ + "${ti_simplelink_sdk_root}/source/ti/ble5stack/common/cc26xx/freertos/TI_heap_wrapper.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/common/cc26xx/freertos/bget.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/common/cc26xx/rcosc/rcosc_calibration.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/host/gatt_uuid.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/host/gattservapp_util.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/icall/app/ble_user_config.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/icall/app/icall_api_lite.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/icall/src/icall_cc2650.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/icall/src/icall_user_config.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/icall/stack/ble_user_config_stack.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/profiles/dev_info/cc26xx/devinfoservice.c", + "${ti_simplelink_sdk_root}/source/ti/ble5stack/rom/agama_r1/rom_init.c", + "${ti_simplelink_sdk_root}/source/ti/dmm/apps/common/ble_remote_display/stack/osal_icall_ble.c", + "${ti_simplelink_sdk_root}/source/ti/dmm/apps/common/freertos/icall_FreeRTOS.c", + "${ti_simplelink_sdk_root}/source/ti/dmm/apps/common/freertos/itm/itm.c", + "${ti_simplelink_sdk_root}/source/ti/dmm/apps/common/freertos/util.c", + "${ti_simplelink_sdk_root}/source/ti/dmm/dmm_priority_ble_thread.c", + + # Move this into the SDK + "${chip_root}/src/platform/cc13x2_26x2/chipOBleProfile.c", + ] + + configs -= [ "${build_root}/config/compiler:std_default" ] + configs += [ ":${sdk_target_name}_posix_config" ] + + public_deps = [ + "${chip_root}/third_party/ti_simplelink_sdk:freertos", + "${chip_root}/third_party/ti_simplelink_sdk:ti_simplelink_sysconfig", + ] + + public_configs = [ + ":${sdk_target_name}_config", + ":${sdk_target_name}_dmm_config", ] } @@ -265,8 +446,12 @@ template("ti_simplelink_sdk") { ":${sdk_target_name}_dpl", ":${sdk_target_name}_freertos", ] - if (ti_simplelink_device_family == "cc13x2_26x2") { - public_deps += [ ":${sdk_target_name}_openthread_platform" ] + if (ti_simplelink_device_family == "cc13x2_26x2" || + ti_simplelink_device_family == "cc13x2x7_26x2x7") { + public_deps += [ + ":${sdk_target_name}_dmm", + ":${sdk_target_name}_openthread_platform", + ] } } }