component/ble_mesh: ESP BLE Mesh v0.6 Beta Version Release

1. BLE Mesh Core

* Provisioning: Node Role
    * Advertising and GATT bearer
    * Authentication OOB

* Provisioning: Provisioner Role
    * Advertising and GATT bearer
    * Authentication OOB

* Networking
    * Relay
    * Segmentation and Reassembly
    * Key Refresh
    * IV Update

* Proxy Support

* Multiple Client Models Run Simultaneously
    * Support multiple client models send packets to different nodes simultaneously
    * No blocking between client model and server

* NVS Storage
    * Store Provisioning Data of BLE Mesh Nodes in Flash

2. BLE Mesh Applications

* BLE Mesh Node & Provisioner
    * Node Example
    * Provisioner Example
    * Node + Generic OnOff Client Example

* Fast Provisioning
    * Vendor Fast Prov Server Model
    * Vendor Fast Prov Client Model
    * Examples

* Wi-Fi & BLE Mesh Coexistence
    * Example

* BLE Mesh Console Commands
    * Example

3. BLE Mesh Models

* Foundation Models
    * Configuration Server Model
    * Configuration Client Model
    * Health Server Model
    * Health Client Model

* Generic Client Models
    * Generic OnOff Client
    * Generic Level Client
    * Generic Location Client
    * Generic Default Transition Timer Client
    * Generic Power OnOff Client
    * Generic Power Level Client
    * Generic Battery Client
    * Generic Property Client

* Generic Server Models
    * Generic OnOff Server (Example)

* Lighting Client Models
    * Light Lightness Client
    * Light CTL Client
    * Light HSL Client
    * Light xyL Client
    * Light LC Client

* Sensor Client Model
    * Sensor Client

* Time and Scenes Client Models
    * Time Client
    * Scene Client
    * Scheduler Client
This commit is contained in:
Yulong
2018-01-08 07:23:36 -05:00
committed by lly
parent c064e00842
commit a0e5518d82
246 changed files with 74822 additions and 3 deletions

11
.project Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>esp-idf(1)</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

124
IDF_README_Backup.md Normal file
View File

@@ -0,0 +1,124 @@
# Espressif IoT Development Framework
[![alt text](https://readthedocs.org/projects/docs/badge/?version=latest "Documentation Status")](https://docs.espressif.com/projects/esp-idf/en/latest/?badge=latest)
ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip.
# Developing With ESP-IDF
## Setting Up ESP-IDF
See setup guides for detailed instructions to set up the ESP-IDF:
* [Getting Started Guide for the stable ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/)
* [Getting Started Guide for the latest (master branch) ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
## Finding a Project
As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in Getting Started, ESP-IDF comes with some example projects in the [examples](examples) directory.
Once you've found the project you want to work with, change to its directory and you can configure and build it.
To start your own project based on an example, copy the example project directory outside of the ESP-IDF directory.
# Quick Reference
See the Getting Started guide links above for a detailed setup guide. This is a quick reference for common commands when working with ESP-IDF projects:
## Configuring the Project
`make menuconfig`
* Opens a text-based configuration menu for the project.
* Use up & down arrow keys to navigate the menu.
* Use Enter key to go into a submenu, Escape key to go out or to exit.
* Type `?` to see a help screen. Enter key exits the help screen.
* Use Space key, or `Y` and `N` keys to enable (Yes) and disable (No) configuration items with checkboxes "`[*]`"
* Pressing `?` while highlighting a configuration item displays help about that item.
* Type `/` to search the configuration items.
Once done configuring, press Escape multiple times to exit and say "Yes" to save the new configuration when prompted.
## Compiling the Project
`make -j4 all`
... will compile app, bootloader and generate a partition table based on the config.
NOTE: The `-j4` option causes `make` to run 4 parallel jobs. This is much faster than the default single job. The recommended number to pass to this option is `-j(number of CPUs + 1)`.
## Flashing the Project
When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running:
`make -j4 flash`
This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`.
You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it.
## Viewing Serial Output
The `make monitor` target uses the [idf_monitor tool](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/idf-monitor.html).
Exit the monitor by typing Ctrl-].
To build, flash and monitor output in one pass, you can run:
`make -j4 flash monitor`
## Compiling & Flashing Only the App
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
* `make app` - build just the app.
* `make app-flash` - flash just the app.
`make app-flash` will automatically rebuild the app if any source files have changed.
(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
## Parallel Builds
ESP-IDF supports compiling multiple files in parallel, so all of the above commands can be run as `make -jN` where `N` is the number of parallel make processes to run (generally N should be equal to the number of CPU cores in your system, plus one.)
Multiple make functions can be combined into one. For example: to build the app & bootloader using 5 jobs in parallel, then flash everything, and then display serial output from the ESP32 run:
```
make -j5 flash monitor
```
## The Partition Table
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x8000 in the flash.
Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
* "Single factory app, no OTA"
* "Factory app, two OTA definitions"
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
For more details about partition tables and how to create custom variations, view the [`docs/en/api-guides/partition-tables.rst`](docs/en/api-guides/partition-tables.rst) file.
## Erasing Flash
The `make flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `make erase_flash`.
This can be combined with other targets, ie `make erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
# Resources
* Documentation for the latest version: https://docs.espressif.com/projects/esp-idf/. This documentation is built from the [docs directory](docs) of this repository.
* The [esp32.com forum](https://esp32.com/) is a place to ask questions and find community resources.
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
* If you're interested in contributing to ESP-IDF, please check the [Contributions Guide](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/index.html).

View File

@@ -1269,3 +1269,782 @@ menu Bluetooth
default 0
endmenu
# Kconfig - Bluetooth Mesh configuration options
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
menuconfig BT_MESH
bool "Bluetooth Mesh support"
select TINYCRYPT
select TINYCRYPT_AES
select TINYCRYPT_AES_CMAC
help
This option enables Bluetooth Mesh support. The specific
features that are available may depend on other features
that have been enabled in the stack, such as GATT support.
if BT_MESH
config BT_MESH_FAST_PROV
bool "Enable BLE Mesh Fast Provisioning"
select BT_MESH_NODE
select BT_MESH_PROVISIONER
select BT_MESH_PB_ADV
default n
help
Enable this option to allow BLE Mesh fast provisioning solution
to be used.
config BT_MESH_NODE
bool "Support for BLE Mesh Node"
help
Enable the device to be provisioned into a node
config BT_MESH_PROVISIONER
bool "Support for BLE Mesh Provisioner"
help
Enable the device to be a provisioner
if BT_MESH_PROVISIONER
config BT_MESH_UNPROV_DEV_ADD
int "Maximum number of unprovisioned devices that can be added to device queue"
default 20
range 1 100
help
This option specifies how may unprovisioned devices can be added to device queue
for provisioning.
config BT_MESH_MAX_STORED_NODES
int "Maximum number of nodes whose information can be stored"
default 20
range 1 1000
help
This option specifies the maximum number of nodes whose information can be
stored by a provisioner in its upper layer.
config BT_MESH_MAX_PROV_NODES
int "Maximum number of devices that can be provisioned by provisioner"
default 20
range 1 100
help
This option specifies how many devices can be provisioned by
provisioner.
if BT_MESH_PB_ADV
config BT_MESH_PBA_SAME_TIME
int "Maximum number of PB-ADV running at the same time by provisioner"
default 10
range 1 30
help
This option specifies how many devices can be provisioned at the same
time using PB-ADV.
endif # BT_MESH_PB_ADV
if BT_MESH_PB_GATT
config BT_MESH_PBG_SAME_TIME
int "Maximum number of PB-GATT running at the same time by provisioner"
default 4
range 1 5
help
This option specifies how many devices can be provisioned at the same
time using PB-GATT.
endif # BT_MESH_PB_GATT
config BT_MESH_PROVISIONER_SUBNET_COUNT
int "Maximum number of mesh subnets that can be created by provisioner"
default 3
range 1 4096
help
This option specifies how many subnets per network a provisioner can create
config BT_MESH_PROVISIONER_APP_KEY_COUNT
int "Maximum number of application keys that can be owned by provisioner"
default 9
range 1 4096
help
This option specifies how many application keys the provisioner
can have.
endif # BT_MESH_PROVISIONER
# Virtual option enabled whenever Generic Provisioning layer is needed
config BT_MESH_PROV
bool
config BT_MESH_PB_ADV
bool "Provisioning support using the advertising bearer (PB-ADV)"
select BT_MESH_PROV
default y
help
Enable this option to allow the device to be provisioned over
the advertising bearer.
config BT_MESH_PB_GATT
bool "Provisioning support using GATT (PB-GATT)"
select BT_MESH_PROXY
select BT_MESH_PROV
help
Enable this option to allow the device to be provisioned over GATT.
# Virtual option enabled whenever any Proxy protocol is needed
config BT_MESH_PROXY
bool
config BT_MESH_GATT_PROXY
bool "GATT Proxy Service"
select BT_MESH_PROXY
help
This option enables support for Mesh GATT Proxy Service,
i.e. the ability to act as a proxy between a Mesh GATT Client
and a Mesh network.
config BT_MESH_NODE_ID_TIMEOUT
int "Node Identity advertising timeout"
depends on BT_MESH_GATT_PROXY
range 1 60
default 60
help
This option determines for how long the local node advertises
using Node Identity. The given value is in seconds. The specification
limits this to 60 seconds and lists it as the recommended value as well.
So leaving the default value is the safest option.
if BT_MESH_PROXY
config BT_MESH_PROXY_FILTER_SIZE
int "Maximum number of filter entries per Proxy Client"
default 1
default 3 if BT_MESH_GATT_PROXY
range 1 32767
help
This option specifies how many Proxy Filter entries the local
node supports.
endif # BT_MESH_PROXY
config NET_BUF_POOL_USAGE
bool "net buffer pool usage"
select BT_MESH_PROV
default n
help
Enable this macro to use the mesh buffer pool usage
config BT_MESH_SETTINGS
bool "Store Bluetooth Mesh key and configuration persistently"
default n
help
When selected, the Bluetooth stack will take care of storing/restoring the
Bluetooth state(e.g. pairing keys) and configuration persistently in flash.
if BT_MESH_SETTINGS
config BT_MESH_STORE_TIMEOUT
int "Delay (in seconds) before storing anything persistently"
range 0 1000000
default 2
help
This value defines in seconds how soon any pending changes
are actually written into persistent storage (flash) after
a change occurs.
config BT_MESH_SEQ_STORE_RATE
int "How often the sequence number gets updated in storage"
range 0 1000000
default 128
help
This value defines how often the local sequence number gets
updated in persistent storage (i.e. flash). e.g. a value of 100
means that the sequence number will be stored to flash on every
100th increment. If the node sends messages very frequently a
higher value makes more sense, whereas if the node sends
infrequently a value as low as 0 (update storage for every
increment) can make sense. When the stack gets initialized it
will add sequence number to the last stored one, so that it starts
off with a value that's guaranteed to be larger than the last
one used before power off.
config BT_MESH_RPL_STORE_TIMEOUT
int "Minimum frequency that the RPL gets updated in storage"
range 0 1000000
default 5
help
This value defines in seconds how soon the RPL gets written to
persistent storage after a change occurs. If the node receives
messages frequently, then a large value is recommended. If the
node receives messages rarely, then the value can be as low as
0 (which means the PRL is written into the storage immediately).
Note that if the node operates in a security-sensitive case, and
there is a risk of sudden power-off, then a value of 0 is strongly
recommended. Otherwise, a power loss before RPL being written into
the storage may introduce message replay attacks and system security
will be in a vulnerable state.
config SETTINGS_FCB
bool "Settings used fcb mode"
default y
help
Use FCB as a settings storage back-end.
endif # if BT_MESH_SETTINGS
config BT_MESH_SELF_TEST
bool "Perform self-tests"
help
This option adds extra self-tests which are run every time
mesh networking is initialized.
config BT_MESH_IV_UPDATE_TEST
bool "Test the IV Update Procedure"
help
This option removes the 96 hour limit of the IV Update
Procedure and lets the state to be changed at any time.
config BT_MESH_SUBNET_COUNT
int "Maximum number of mesh subnets per network"
default 1
range 1 4096
help
This option specifies how many subnets a Mesh network can
have at the same time.
config BT_MESH_APP_KEY_COUNT
int "Maximum number of application keys per network"
default 1
range 1 4096
help
This option specifies how many application keys the device can
store per network.
config BT_MESH_MODEL_KEY_COUNT
int "Maximum number of application keys per model"
default 1
range 1 4096
help
This option specifies the maximum number of application keys to which
each model can be bound.
config BT_MESH_MODEL_GROUP_COUNT
int "Maximum number of group address subscriptions per model"
default 1
range 1 4096
help
This option specifies the maximum number of addresses to which
each model can be subscribed.
config BT_MESH_LABEL_COUNT
int "Maximum number of Label UUIDs used for Virtual Addresses"
default 1
range 0 4096
help
This option specifies how many Label UUIDs can be stored.
config BT_MESH_CRPL
int "Maximum capacity of the replay protection list"
default 10
range 2 65535
help
This options specifies the maximum capacity of the replay
protection list. It is similar to Network message
cache size, but has a different purpose.
config BT_MESH_MSG_CACHE_SIZE
int "Network message cache size"
default 10
range 2 65535
help
Number of messages that are cached for the network. This helps
prevent unnecessary decryption operations and unnecessary
relays. This option is similar to Replay protection list,
but has a different purpose.
config BT_MESH_ADV_BUF_COUNT
int "Number of advertising buffers"
default 60
range 6 256
help
Number of advertising buffers available. The transport layer
reserves ADV_BUF_COUNT - 3 buffers for outgoing segments. The
maximum outgoing SDU size is 12 times this value (out of which
4 or 8 bytes are used for the Transport Layer MIC). For
example, 5 segments means the maximum SDU size is 60 bytes,
which leaves 56 bytes for application layer data using a
4-byte MIC, or 52 bytes using an 8-byte MIC.
config BT_MESH_TX_SEG_MSG_COUNT
int "Maximum number of simultaneous outgoing segmented messages"
default 1
range 1 BT_MESH_ADV_BUF_COUNT
help
Maximum number of simultaneous outgoing multi-segment and/or
reliable messages.
config BT_MESH_RX_SEG_MSG_COUNT
int "Maximum number of simultaneous incoming segmented messages"
default 1
range 1 255
help
Maximum number of simultaneous incoming multi-segment and/or
reliable messages.
config BT_MESH_RX_SDU_MAX
int "Maximum incoming Upper Transport Access PDU length"
default 384
range 36 384
help
Maximum incoming Upper Transport Access PDU length. Leave this
to the default value, unless you really need to optimize memory
usage.
config BT_MESH_RELAY
bool "Relay support"
help
Support for acting as a Mesh Relay Node.
config BT_MESH_LOW_POWER
bool "Support for Low Power features"
help
Enable this option to operate as a Low Power Node.
if BT_MESH_LOW_POWER
config BT_MESH_LPN_ESTABLISHMENT
bool "Perform Friendship establishment using low power"
default y
help
Perform the Friendship establishment using low power with
the help of a reduced scan duty cycle. The downside of this
is that the node may miss out on messages intended for it
until it has successfully set up Friendship with a Friend
node.
config BT_MESH_LPN_AUTO
bool "Automatically start looking for Friend nodes once provisioned"
default y
help
Once provisioned, automatically enable LPN functionality and start
looking for Friend nodes. If this option is disabled LPN mode
needs to be manually enabled by calling bt_mesh_lpn_set(true).
config BT_MESH_LPN_AUTO_TIMEOUT
int "Time from last received message before going to LPN mode"
default 15
range 0 3600
depends on BT_MESH_LPN_AUTO
help
Time in seconds from the last received message, that the node
waits out before starting to look for Friend nodes.
config BT_MESH_LPN_RETRY_TIMEOUT
int "Retry timeout for Friend requests"
default 8
range 1 3600
help
Time in seconds between Friend Requests, if a previous Friend
Request did not yield any acceptable Friend Offers.
config BT_MESH_LPN_RSSI_FACTOR
int "RSSIFactor, used in Friend Offer Delay calculation"
range 0 3
default 0
help
The contribution of the RSSI, measured by the Friend node, used
in Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5.
config BT_MESH_LPN_RECV_WIN_FACTOR
int "ReceiveWindowFactor, used in Friend Offer Delay calculation"
range 0 3
default 0
help
The contribution of the supported Receive Window used in
Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5.
config BT_MESH_LPN_MIN_QUEUE_SIZE
int "Minimum size of the acceptable friend queue (MinQueueSizeLog)"
range 1 7
default 1
help
The MinQueueSizeLog field is defined as log_2(N), where N is
the minimum number of maximum size Lower Transport PDUs that
the Friend node can store in its Friend Queue. As an example,
MinQueueSizeLog value 1 gives N = 2, and value 7 gives N = 128.
config BT_MESH_LPN_RECV_DELAY
int "Receive delay requested by the local node"
range 10 255
default 100
help
The ReceiveDelay is the time between the Low Power node
sending a request and listening for a response. This delay
allows the Friend node time to prepare the response. The value
is in units of milliseconds.
config BT_MESH_LPN_POLL_TIMEOUT
int "The value of the PollTimeout timer"
range 10 244735
default 300
help
PollTimeout timer is used to measure time between two
consecutive requests sent by a Low Power node. If no
requests are received by the Friend node before the
PollTimeout timer expires, then the friendship is considered
terminated. The value is in units of 100 milliseconds, so e.g.
a value of 300 means 30 seconds.
config BT_MESH_LPN_INIT_POLL_TIMEOUT
int "The starting value of the PollTimeout timer"
range 10 BT_MESH_LPN_POLL_TIMEOUT
default BT_MESH_LPN_POLL_TIMEOUT
help
The initial value of the PollTimeout timer when Friendship
is to be established for the first time. After this, the timeout
gradually grows toward the actual PollTimeout, doubling
in value for each iteration. The value is in units of 100
milliseconds, so e.g. a value of 300 means 30 seconds.
config BT_MESH_LPN_SCAN_LATENCY
int "Latency for enabling scanning"
range 0 50
default 10
help
Latency (in milliseconds) is the time it takes to enable scanning. In
practice, it means how much time in advance of the Receive Window,
the request to enable scanning is made.
config BT_MESH_LPN_GROUPS
int "Number of groups the LPN can subscribe to"
range 0 16384
default 8
help
Maximum number of groups to which the LPN can subscribe.
endif # BT_MESH_LOW_POWER
config BT_MESH_FRIEND
bool "Support for acting as a Friend Node"
help
Enable this option to be able to act as a Friend Node.
if BT_MESH_FRIEND
config BT_MESH_FRIEND_RECV_WIN
int "Friend Receive Window"
range 1 255
default 255
help
Receive Window in milliseconds supported by the Friend node.
config BT_MESH_FRIEND_QUEUE_SIZE
int "Minimum number of buffers supported per Friend Queue"
range 2 65536
default 16
help
Minimum number of buffers available to be stored for each
local Friend Queue.
config BT_MESH_FRIEND_SUB_LIST_SIZE
int "Friend Subscription List Size"
range 0 1023
default 3
help
Size of the Subscription List that can be supported by a
Friend node for a Low Power node.
config BT_MESH_FRIEND_LPN_COUNT
int "Number of supported LPN nodes"
range 1 1000
default 2
help
Number of Low Power Nodes with which a Friend can have Friendship
simultaneously.
config BT_MESH_FRIEND_SEG_RX
int "Number of incomplete segment lists per LPN"
range 1 1000
default 1
help
Number of incomplete segment lists tracked for each Friends' LPN.
In other words, this determines from how many elements can segmented
messages destined for the Friend queue be received simultaneously.
endif # BT_MESH_FRIEND
config BT_MESH_NO_LOG
bool "Disable BT MESH debug logs (minimize bin size)"
depends on BT_MESH
default n
help
Select this to save the rodata code size
menu "BT DEBUG LOG LEVEL"
depends on BT_MESH && !BT_MESH_NO_LOG
choice BT_MESH_STACK_INITIAL_TRACE_LEVEL
prompt "BT_MESH_STACK"
default BT_MESH_TRACE_LEVEL_WARNING
depends on BT_MESH && !BT_MESH_NO_LOG
help
Define BT trace level for bt mesh stack
config BT_MESH_TRACE_LEVEL_NONE
bool "NONE"
config BT_MESH_TRACE_LEVEL_ERROR
bool "ERROR"
config BT_MESH_TRACE_LEVEL_WARNING
bool "WARNING"
config BT_MESH_TRACE_LEVEL_INFO
bool "INFO"
config BT_MESH_TRACE_LEVEL_DEBUG
bool "DEBUG"
config BT_MESH_TRACE_LEVEL_VERBOSE
bool "VERBOSE"
endchoice
config BT_MESH_STACK_INITIAL_TRACE_LEVEL
int
depends on BT_MESH
default 0 if BT_MESH_TRACE_LEVEL_NONE
default 1 if BT_MESH_TRACE_LEVEL_ERROR
default 2 if BT_MESH_TRACE_LEVEL_WARNING
default 3 if BT_MESH_TRACE_LEVEL_INFO
default 4 if BT_MESH_TRACE_LEVEL_DEBUG
default 5 if BT_MESH_TRACE_LEVEL_VERBOSE
default 2
endmenu #BT NET NUFFER DEBUG LOG LEVEL
menu "BT NET NUFFER DEBUG LOG LEVEL"
depends on BT_MESH && !BT_MESH_NO_LOG
choice BT_MESH_NET_BUF_INITIAL_TRACE_LEVEL
prompt "BT_MESH_STACK"
default BT_MESH_NET_BUF_TRACE_LEVEL_WARNING
depends on BT_MESH && !BT_MESH_NO_LOG
help
Define BT trace level for bt mesh network buffer alloc debug
config BT_MESH_NET_BUF_TRACE_LEVEL_NONE
bool "NONE"
config BT_MESH_NET_BUF_TRACE_LEVEL_ERROR
bool "ERROR"
config BT_MESH_NET_BUF_TRACE_LEVEL_WARNING
bool "WARNING"
config BT_MESH_NET_BUF_TRACE_LEVEL_INFO
bool "INFO"
config BT_MESH_NET_BUF_TRACE_LEVEL_DEBUG
bool "DEBUG"
config BT_MESH_NET_BUF_TRACE_LEVEL_VERBOSE
bool "VERBOSE"
endchoice
config BT_MESH_NET_BUF_INITIAL_TRACE_LEVEL
int
depends on BT_MESH
default 0 if BT_MESH_NET_BUF_TRACE_LEVEL_NONE
default 1 if BT_MESH_NET_BUF_TRACE_LEVEL_ERROR
default 2 if BT_MESH_NET_BUF_TRACE_LEVEL_WARNING
default 3 if BT_MESH_NET_BUF_TRACE_LEVEL_INFO
default 4 if BT_MESH_NET_BUF_TRACE_LEVEL_DEBUG
default 5 if BT_MESH_NET_BUF_TRACE_LEVEL_VERBOSE
default 2
endmenu #BT DEBUG NET BUF LOG LEVEL
config BT_MESH_IRQ_LOCK
bool "Used the IRQ lock instead of task lock"
help
To improve the real-time requirements of bt controller in BLE Mesh, task lock is used to replace IRQ lock.
config BT_MESH_CLIENT_MSG_TIMEOUT
int "Timeout(ms) for client message response"
range 100 1200000
default 4000
help
Timeout value used by the node to get response to the sent message.
config BT_MESH_CFG_CLI
bool "Support for Configuration Client Model"
help
Enable support for Configuration client model.
config BT_MESH_HEALTH_CLI
bool "Support for Health Client Model"
help
Enable support for Health client model.
config BT_MESH_GENERIC_ONOFF_CLI
bool "Support for Generic OnOff Client Model"
help
Enable support for Generic OnOff client model.
config BT_MESH_GENERIC_LEVEL_CLI
bool "Support for Generic Level Client Model"
help
Enable support for Generic Level client model.
config BT_MESH_GENERIC_DEF_TRANS_TIME_CLI
bool "Support for Generic Default Transition Time Client Model"
help
Enable support for Generic Default Transition Time client model.
config BT_MESH_GENERIC_POWER_ONOFF_CLI
bool "Support for Generic Power Onoff Client Model"
help
Enable support for Generic Power Onoff client model.
config BT_MESH_GENERIC_POWER_LEVEL_CLI
bool "Support for Generic Power Level Client Model"
help
Enable support for Generic Power Level client model.
config BT_MESH_GENERIC_BATTERY_CLI
bool "Support for Generic Battery Client Model"
help
Enable support for Generic Battery client model.
config BT_MESH_GENERIC_LOCATION_CLI
bool "Support for Generic Location Client Model"
help
Enable support for Generic Location client model.
config BT_MESH_GENERIC_PROPERTY_CLI
bool "Support for Generic Property Client Model"
help
Enable support for Generic Property client model.
config BT_MESH_SENSOR_CLI
bool "Support for Sensor Client Model"
help
Enable support for Sensor client model.
config BT_MESH_TIME_CLI
bool "Support for Time Client Model"
help
Enable support for Time client model.
config BT_MESH_SCENE_CLI
bool "Support for Scene Client Model"
help
Enable support for Scene client model.
config BT_MESH_SCHEDULER_CLI
bool "Support for Scheduler Client Model"
help
Enable support for Scheduler client model.
config BT_MESH_LIGHT_LIGHTNESS_CLI
bool "Support for Light Lightness Client Model"
help
Enable support for Light Lightness client model.
config BT_MESH_LIGHT_CTL_CLI
bool "Support for Light CTL Client Model"
help
Enable support for Light CTL client model.
config BT_MESH_LIGHT_HSL_CLI
bool "Support for Light HSL Client Model"
help
Enable support for Light HSL client model.
config BT_MESH_LIGHT_XYL_CLI
bool "Support for Light XYL Client Model"
help
Enable support for Light XYL client model.
config BT_MESH_LIGHT_LC_CLI
bool "Support for Light LC Client Model"
help
Enable support for Light LC client model.
config BT_MESH_SHELL
bool "Enable Bluetooth Mesh shell"
select CONSOLE_SHELL
depends on BT_MESH_CFG_CLI
depends on BT_MESH_HEALTH_CLI
help
Activate shell module that provides Bluetooth Mesh commands to
the console.
config BT_MESH_DEBUG
bool "Enable debug logs"
depends on BT_DEBUG
help
Use this option to enable debug logs for the Bluetooth
Mesh functionality.
if BT_MESH_DEBUG
config BT_MESH_DEBUG_NET
bool "Network layer debug"
help
Use this option to enable Network layer debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_TRANS
bool "Transport layer debug"
help
Use this option to enable Transport layer debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_BEACON
bool "Beacon debug"
help
Use this option to enable Beacon-related debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_CRYPTO
bool "Crypto debug"
help
Use this option to enable cryptographic debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_PROV
bool "Provisioning debug"
help
Use this option to enable Provisioning debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_ACCESS
bool "Access layer debug"
help
Use this option to enable Access layer and device composition
related debug logs for Bluetooth Mesh.
config BT_MESH_DEBUG_MODEL
bool "Foundation model debug"
help
Use this option to enable debug logs for the Foundation
Models.
config BT_MESH_DEBUG_ADV
bool "Advertising debug"
help
Use this option to enable advertising debug logs for
the Bluetooth Mesh functionality.
config BT_MESH_DEBUG_LOW_POWER
bool "Low Power debug"
help
Use this option to enable Low Power debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_FRIEND
bool "Friend debug"
help
Use this option to enable Friend debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_PROXY
bool "Proxy debug"
depends on BT_MESH_PROXY
help
Use this option to enable Proxy protocol debug logs.
endif # BT_MESH_DEBUG
endif # BT_MESH

View File

@@ -0,0 +1,77 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "esp_bt_defs.h"
#include "esp_err.h"
#include "esp_bt_main.h"
#include "sdkconfig.h"
#include "btc_ble_mesh_prov.h"
#include "mesh.h"
#include "mesh_buf.h"
#include "transport.h"
#include "esp_ble_mesh_common_api.h"
#if CONFIG_BT_MESH
esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg = {0};
xSemaphoreHandle semaphore = NULL;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
// Create a semaphore
if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) {
LOG_ERROR("%s, unable to allocate memory for the semaphore.", __func__);
return ESP_ERR_NO_MEM;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_APP_REGISTER;
arg.mesh_reg.prov = prov;
arg.mesh_reg.comp = comp;
// semaphore pointer transport to BTC layer, we will give the semaphore in the BTC task.
arg.mesh_reg.semaphore = semaphore;
if (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) != BT_STATUS_SUCCESS) {
vSemaphoreDelete(semaphore);
LOG_ERROR("BLE Mesh initialise failed");
return ESP_FAIL;
}
// Take the Semaphore, wait to BLE Mesh init finish.
xSemaphoreTake(semaphore, portMAX_DELAY);
// Don't forget to delete the semaphore at the end.
vSemaphoreDelete(semaphore);
return ESP_OK;
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,90 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "esp_bt_defs.h"
#include "esp_err.h"
#include "esp_bt_main.h"
#include "sdkconfig.h"
#include "btc_ble_mesh_prov.h"
#include "mesh.h"
#include "mesh_buf.h"
#include "transport.h"
#include "esp_ble_mesh_defs.h"
#if CONFIG_BT_MESH
int32_t esp_ble_mesh_get_model_publish_period(esp_ble_mesh_model_t *model)
{
if (model == NULL) {
return -EINVAL;
}
return btc_ble_mesh_model_pub_period_get(model);
}
uint16_t esp_ble_mesh_get_primary_element_address(void)
{
return btc_ble_mesh_get_primary_addr();
}
uint16_t *esp_ble_mesh_is_model_subscribed_to_group(esp_ble_mesh_model_t *model, uint16_t group_addr)
{
if (model == NULL) {
return NULL;
}
return btc_ble_mesh_model_find_group(model, group_addr);
}
esp_ble_mesh_elem_t *esp_ble_mesh_find_element(uint16_t element_addr)
{
return btc_ble_mesh_elem_find(element_addr);
}
uint8_t esp_ble_mesh_get_element_count(void)
{
return btc_ble_mesh_elem_count();
}
esp_ble_mesh_model_t *esp_ble_mesh_find_vendor_model(esp_ble_mesh_elem_t *element,
uint16_t company_id, uint16_t model_id)
{
if (element == NULL) {
return NULL;
}
return btc_ble_mesh_model_find_vnd(element, company_id, model_id);
}
esp_ble_mesh_model_t *esp_ble_mesh_find_sig_model(esp_ble_mesh_elem_t *element, uint16_t model_id)
{
if (element == NULL) {
return NULL;
}
return btc_ble_mesh_model_find(element, model_id);
}
const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void)
{
return btc_ble_mesh_comp_get();
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,37 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "esp_bt_defs.h"
#include "esp_err.h"
#include "esp_bt_main.h"
#include "sdkconfig.h"
#include "btc_ble_mesh_prov.h"
#include "mesh.h"
#include "mesh_buf.h"
#include "transport.h"
#include "esp_ble_mesh_defs.h"
#if CONFIG_BT_MESH
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,344 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "esp_bt_defs.h"
#include "esp_err.h"
#include "esp_bt_main.h"
#include "sdkconfig.h"
#include "btc_ble_mesh_prov.h"
#include "mesh.h"
#include "mesh_buf.h"
#include "transport.h"
#include "provisioner_main.h"
#include "esp_ble_mesh_defs.h"
#include "esp_ble_mesh_networking_api.h"
#if CONFIG_BT_MESH
static esp_err_t ble_mesh_send_msg(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx,
uint32_t opcode,
btc_ble_mesh_model_act_t act,
uint16_t length, uint8_t *data,
int32_t msg_timeout, bool need_rsp,
esp_ble_mesh_dev_role_t device_role)
{
btc_msg_t msg;
btc_ble_mesh_model_args_t arg;
esp_err_t status;
uint8_t op_len = 0, mic_len = 0;
uint8_t *msg_data = NULL;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (device_role > ROLE_FAST_PROV) {
return ESP_ERR_INVALID_ARG;
}
/* When data is NULL, it is mandatory to set length to 0 to prevent users from misinterpreting parameters. */
if (data == NULL) {
length = 0;
}
if (opcode < 0x100) {
op_len = 1;
} else if (opcode < 0x10000) {
op_len = 2;
} else {
op_len = 3;
}
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
if (op_len + length > model->pub->msg->size) {
LOG_ERROR("%s: model->pub->msg->size %d is too small", __func__, model->pub->msg->size);
return ESP_ERR_INVALID_ARG;
}
}
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
mic_len = 4;
} else {
mic_len = ctx->send_rel ? 8 : 4;
}
if (op_len + length + mic_len > MIN(ESP_BLE_MESH_SDU_MAX_LEN, BT_MESH_TX_SDU_MAX)) {
LOG_ERROR("%s: The data length %d is too large", __func__, length);
return ESP_ERR_INVALID_ARG;
}
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
bt_mesh_model_msg_init(model->pub->msg, opcode);
net_buf_simple_add_mem(model->pub->msg, data, length);
} else {
msg_data = (uint8_t *)osi_malloc(op_len + length);
if (msg_data == NULL) {
return ESP_ERR_NO_MEM;
}
esp_ble_mesh_model_msg_opcode_init(msg_data, opcode);
memcpy(msg_data + op_len, data, length);
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_MODEL;
msg.act = act;
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
arg.model_publish.model = model;
arg.model_publish.device_role = device_role;
} else {
arg.model_send.model = model;
arg.model_send.ctx = ctx;
arg.model_send.need_rsp = need_rsp;
arg.model_send.opcode = opcode;
arg.model_send.length = op_len + length;
arg.model_send.data = msg_data;
arg.model_send.device_role = device_role;
arg.model_send.msg_timeout = msg_timeout;
}
status = (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_model_args_t), btc_ble_mesh_prov_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
osi_free(msg_data);
return status;
}
esp_err_t esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_MODEL, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_model_msg_opcode_init(uint8_t *data, uint32_t opcode)
{
uint16_t val;
if (data == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (opcode < 0x100) {
/* 1-byte OpCode */
data[0] = opcode & 0xff;
return ESP_OK;
}
if (opcode < 0x10000) {
/* 2-byte OpCode, big endian */
val = sys_cpu_to_be16 (opcode);
memcpy (data, &val, 2);
return ESP_OK;
}
/* 3-byte OpCode, note that little endian for the least 2 bytes(Company ID) of opcode */
data[0] = (opcode >> 16) & 0xff;
val = sys_cpu_to_le16(opcode & 0xffff);
memcpy (&data[1], &val, 2);
return ESP_OK;
}
int esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model)
{
return btc_ble_mesh_client_init(model);
}
esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode,
uint16_t length, uint8_t *data)
{
if (!model || !ctx) {
return ESP_ERR_INVALID_ARG;
}
return ble_mesh_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_SERVER_MODEL_SEND,
length, data, 0, false, ROLE_NODE);
}
esp_err_t esp_ble_mesh_client_model_send_msg(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode,
uint16_t length, uint8_t *data, int32_t msg_timeout,
bool need_rsp, esp_ble_mesh_dev_role_t device_role)
{
if (!model || !ctx) {
return ESP_ERR_INVALID_ARG;
}
return ble_mesh_send_msg(model, ctx, opcode, BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND,
length, data, msg_timeout, need_rsp, device_role);
}
esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcode,
uint16_t length, uint8_t *data,
esp_ble_mesh_dev_role_t device_role)
{
if (!model || !model->pub || !model->pub->msg) {
return ESP_ERR_INVALID_ARG;
}
return ble_mesh_send_msg(model, NULL, opcode, BTC_BLE_MESH_ACT_MODEL_PUBLISH,
length, data, 0, false, device_role);
}
esp_err_t esp_ble_mesh_node_local_reset(void)
{
btc_msg_t msg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_NODE_RESET;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#if (CONFIG_BT_MESH_PROVISIONER)
esp_err_t esp_ble_mesh_provisioner_set_node_name(int index, const char *name)
{
if (!name || (strlen(name) > ESP_BLE_MESH_NODE_NAME_MAX_LEN)) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_NODE_NAME;
arg.set_node_name.index = index;
memset(arg.set_node_name.name, 0, sizeof(arg.set_node_name.name));
memcpy(arg.set_node_name.name, name, strlen(name));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
const char *esp_ble_mesh_provisioner_get_node_name(int index)
{
return bt_mesh_provisioner_get_node_name(index);
}
int esp_ble_mesh_provisioner_get_node_index(const char *name)
{
if (!name || (strlen(name) > ESP_BLE_MESH_NODE_NAME_MAX_LEN)) {
return -EINVAL;
}
return bt_mesh_provisioner_get_node_index(name);
}
esp_err_t esp_ble_mesh_provisioner_add_local_app_key(const uint8_t app_key[16],
uint16_t net_idx, uint16_t app_idx)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_LOCAL_APP_KEY;
arg.add_local_app_key.net_idx = net_idx;
arg.add_local_app_key.app_idx = app_idx;
if (app_key) {
memcpy(arg.add_local_app_key.app_key, app_key, 16);
} else {
bzero(arg.add_local_app_key.app_key, 16);
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
const uint8_t *esp_ble_mesh_provisioner_get_local_app_key(uint16_t net_idx, uint16_t app_idx)
{
return bt_mesh_provisioner_local_app_key_get(net_idx, app_idx);
}
esp_err_t esp_ble_mesh_provisioner_bind_app_key_to_local_model(uint16_t element_addr, uint16_t app_idx,
uint16_t model_id, uint16_t company_id)
{
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr)) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_BIND_LOCAL_MOD_APP;
arg.local_mod_app_bind.elem_addr = element_addr;
arg.local_mod_app_bind.app_idx = app_idx;
arg.local_mod_app_bind.model_id = model_id;
arg.local_mod_app_bind.cid = company_id;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx)
{
if (net_idx == ESP_BLE_MESH_KEY_PRIMARY) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY;
arg.add_local_net_key.net_idx = net_idx;
if (net_key) {
memcpy(arg.add_local_net_key.net_key, net_key, 16);
} else {
bzero(arg.add_local_net_key.net_key, 16);
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx)
{
return bt_mesh_provisioner_local_net_key_get(net_idx);
}
#endif /* CONFIG_BT_MESH_PROVISIONER */
#if (CONFIG_BT_MESH_FAST_PROV)
const uint8_t *esp_ble_mesh_get_fast_prov_app_key(uint16_t net_idx, uint16_t app_idx)
{
return bt_mesh_get_fast_prov_app_key(net_idx, app_idx);
}
#endif /* CONFIG_BT_MESH_FAST_PROV */
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,436 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "esp_bt_defs.h"
#include "esp_err.h"
#include "esp_bt_main.h"
#include "sdkconfig.h"
#include "btc_ble_mesh_prov.h"
#include "mesh.h"
#include "mesh_buf.h"
#include "transport.h"
#include "provisioner_prov.h"
#include "esp_ble_mesh_defs.h"
#include "esp_ble_mesh_provisioning_api.h"
#if CONFIG_BT_MESH
#define MAX_PROV_LINK_IDX (CONFIG_BT_MESH_PBA_SAME_TIME + CONFIG_BT_MESH_PBG_SAME_TIME)
#define MAX_OOB_INPUT_NUM 0x5F5E0FF /* Decimal: 99999999 */
esp_err_t esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_PROV, callback) == 0 ? ESP_OK : ESP_FAIL);
}
bool esp_ble_mesh_node_is_provisioned(void)
{
return bt_mesh_is_provisioned();
}
esp_err_t esp_ble_mesh_node_prov_enable(esp_ble_mesh_prov_bearer_t bearers)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROV_ENABLE;
arg.mesh_prov_enable.bearers = bearers;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_node_prov_disable(esp_ble_mesh_prov_bearer_t bearers)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROV_DISABLE;
arg.mesh_prov_disable.bearers = bearers;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_node_set_oob_pub_key(uint8_t pub_key_x[32], uint8_t pub_key_y[32],
uint8_t private_key[32])
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (!pub_key_x || !pub_key_y || !private_key) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_SET_OOB_PUB_KEY;
memcpy(arg.set_oob_pub_key.pub_key_x, pub_key_x, 32);
memcpy(arg.set_oob_pub_key.pub_key_y, pub_key_y, 32);
memcpy(arg.set_oob_pub_key.private_key, private_key, 32);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_node_input_number(uint32_t number)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (number > MAX_OOB_INPUT_NUM) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_INPUT_NUMBER;
arg.input_num.number = number;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_node_input_string(const char *string)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (!string) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_INPUT_STRING;
memset(arg.input_str.string, 0, sizeof(arg.input_str.string));
strncpy(arg.input_str.string, string, strlen(string));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name)
{
if (!name || strlen(name) > ESP_BLE_MESH_DEVICE_NAME_MAX_LEN) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_SET_DEVICE_NAME;
memset(arg.set_device_name.name, 0, sizeof(arg.set_device_name.name));
memcpy(arg.set_device_name.name, name, strlen(name));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#if (CONFIG_BT_MESH_PROVISIONER)
esp_err_t esp_ble_mesh_provisioner_read_oob_pub_key(uint8_t link_idx, uint8_t pub_key_x[32],
uint8_t pub_key_y[32])
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (!pub_key_x || !pub_key_y || link_idx >= MAX_PROV_LINK_IDX) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_READ_OOB_PUB_KEY;
arg.provisioner_read_oob_pub_key.link_idx = link_idx;
memcpy(arg.provisioner_read_oob_pub_key.pub_key_x, pub_key_x, 32);
memcpy(arg.provisioner_read_oob_pub_key.pub_key_y, pub_key_y, 32);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link_idx)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (!string || link_idx >= MAX_PROV_LINK_IDX) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_INPUT_STR;
memset(arg.provisioner_input_str.string, 0, sizeof(arg.provisioner_input_str.string));
strncpy(arg.provisioner_input_str.string, string, strlen(string));
arg.provisioner_input_str.link_idx = link_idx;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_input_number(uint32_t number, uint8_t link_idx)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (number > MAX_OOB_INPUT_NUM || link_idx >= MAX_PROV_LINK_IDX) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_INPUT_NUM;
arg.provisioner_input_num.number = number;
arg.provisioner_input_num.link_idx = link_idx;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_prov_enable(esp_ble_mesh_prov_bearer_t bearers)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_ENABLE;
arg.provisioner_enable.bearers = bearers;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_prov_disable(esp_ble_mesh_prov_bearer_t bearers)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DISABLE;
arg.provisioner_disable.bearers = bearers;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t *add_dev,
esp_ble_mesh_dev_add_flag_t flags)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (add_dev == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DEV_ADD;
arg.provisioner_dev_add.add_dev.addr_type = add_dev->addr_type;
arg.provisioner_dev_add.add_dev.oob_info = add_dev->oob_info;
arg.provisioner_dev_add.add_dev.bearer = add_dev->bearer;
memcpy(arg.provisioner_dev_add.add_dev.addr, add_dev->addr, sizeof(esp_bd_addr_t));
memcpy(arg.provisioner_dev_add.add_dev.uuid, add_dev->uuid, 16);
arg.provisioner_dev_add.flags = flags;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_dev)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
uint8_t val = DEL_DEV_ADDR_FLAG | DEL_DEV_UUID_FLAG;
if (del_dev == NULL || (__builtin_popcount(del_dev->flag & val) != 1)) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_DEV_DEL;
arg.provisioner_dev_del.del_dev.flag = del_dev->flag;
if (del_dev->flag & DEL_DEV_ADDR_FLAG) {
arg.provisioner_dev_del.del_dev.addr_type = del_dev->addr_type;
memcpy(arg.provisioner_dev_del.del_dev.addr, del_dev->addr, sizeof(esp_bd_addr_t));
} else if (del_dev->flag & DEL_DEV_UUID_FLAG) {
memcpy(arg.provisioner_dev_del.del_dev.uuid, del_dev->uuid, 16);
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_set_dev_uuid_match(const uint8_t *match_val, uint8_t match_len,
uint8_t offset, bool prov_after_match)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_DEV_UUID_MATCH;
if (match_len && match_val) {
memcpy(arg.set_dev_uuid_match.match_val, match_val, match_len);
}
arg.set_dev_uuid_match.match_len = match_len;
arg.set_dev_uuid_match.offset = offset;
arg.set_dev_uuid_match.prov_after_match = prov_after_match;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_info_t *prov_data_info)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
uint8_t val = PROV_DATA_NET_IDX_FLAG | PROV_DATA_FLAGS_FLAG | PROV_DATA_IV_INDEX_FLAG;
if (prov_data_info == NULL || (__builtin_popcount(prov_data_info->flag & val) != 1)) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROVISIONER_SET_PROV_DATA_INFO;
arg.set_prov_data_info.prov_data.flag = prov_data_info->flag;
if (prov_data_info->flag & PROV_DATA_NET_IDX_FLAG) {
arg.set_prov_data_info.prov_data.net_idx = prov_data_info->net_idx;
} else if (prov_data_info->flag & PROV_DATA_FLAGS_FLAG) {
arg.set_prov_data_info.prov_data.flags = prov_data_info->flags;
} else if (prov_data_info->flag & PROV_DATA_IV_INDEX_FLAG) {
arg.set_prov_data_info.prov_data.iv_index = prov_data_info->iv_index;
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BT_MESH_PROVISIONER */
/* The following APIs are for fast provisioning */
#if (CONFIG_BT_MESH_FAST_PROV)
esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_prov_info)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (fast_prov_info == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO;
arg.set_fast_prov_info.unicast_min = fast_prov_info->unicast_min;
arg.set_fast_prov_info.unicast_max = fast_prov_info->unicast_max;
arg.set_fast_prov_info.net_idx = fast_prov_info->net_idx;
arg.set_fast_prov_info.flags = fast_prov_info->flags;
arg.set_fast_prov_info.iv_index = fast_prov_info->iv_index;
arg.set_fast_prov_info.offset = fast_prov_info->offset;
arg.set_fast_prov_info.match_len = fast_prov_info->match_len;
if (fast_prov_info->match_len && fast_prov_info->match_val) {
memcpy(arg.set_fast_prov_info.match_val, fast_prov_info->match_val, fast_prov_info->match_len);
}
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_set_fast_prov_action(esp_ble_mesh_fast_prov_action_t action)
{
btc_msg_t msg;
btc_ble_mesh_prov_args_t arg;
if (action >= FAST_PROV_ACT_MAX) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION;
arg.set_fast_prov_action.action = action;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BT_MESH_FAST_PROV */
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,75 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "esp_bt_defs.h"
#include "esp_err.h"
#include "esp_bt_main.h"
#include "sdkconfig.h"
#include "btc_ble_mesh_prov.h"
#include "mesh.h"
#include "mesh_buf.h"
#include "transport.h"
#if CONFIG_BT_MESH
esp_err_t esp_ble_mesh_proxy_identity_enable(void)
{
btc_msg_t msg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROXY_IDENTITY_ENABLE;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_proxy_gatt_enable(void)
{
btc_msg_t msg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROXY_GATT_ENABLE;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_proxy_gatt_disable(void)
{
btc_msg_t msg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_PROXY_GATT_DISABLE;
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,39 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _ESP_BLE_MESH_COMMON_API_H_
#define _ESP_BLE_MESH_COMMON_API_H_
#include "esp_ble_mesh_defs.h"
#if CONFIG_BT_MESH
/**
* @brief Initialize BLE Mesh module.
* This API initializes provisioning capabilities and composition data information.
*
* @note After calling this API, the device needs to call esp_ble_mesh_prov_enable()
* to enable provisioning functionality again.
*
* @param[in] prov: Pointer to the device provisioning capabilities.
* @param[in] comp: Pointer to the device composition data information.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp);
#endif /* #if CONFIG_BT_MESH */
#endif /* _ESP_BLE_MESH_COMMON_API_H_ */

View File

@@ -0,0 +1,117 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_
#define _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_
#include "esp_ble_mesh_defs.h"
#if CONFIG_BT_MESH
/**
* @brief Get the model publish period, the unit is ms.
*
* @param[in] model: Model instance pointer.
*
* @return Publish period value on success, 0 or (negative) error code from errno.h on failure.
*
*/
int32_t esp_ble_mesh_get_model_publish_period(esp_ble_mesh_model_t *model);
/**
* @brief Get the address of the primary element.
*
* @param None.
*
* @return Address of the primary element on success, or
* ESP_BLE_MESH_ADDR_UNASSIGNED on failure which means the device has not been provisioned.
*
*/
uint16_t esp_ble_mesh_get_primary_element_address(void);
/**
* @brief Check if the model has subscribed to the given group address.
* Note: E.g., once a status message is received and the destination address
* is a group address, the model uses this API to check if it is successfully subscribed
* to the given group address.
*
* @param[in] model: Pointer to the model.
* @param[in] group_addr: Group address.
*
* @return Pointer to the group address within the Subscription List of the model on success, or
* NULL on failure which means the model has not subscribed to the given group address.
* Note: With the pointer to the group address returned, you can reset the group address
* to 0x0000 in order to unsubscribe the model from the group.
*
*/
uint16_t *esp_ble_mesh_is_model_subscribed_to_group(esp_ble_mesh_model_t *model, uint16_t group_addr);
/**
* @brief Find the BLE Mesh element pointer via the element address.
*
* @param[in] element_addr: Element address.
*
* @return Pointer to the element on success, or NULL on failure.
*
*/
esp_ble_mesh_elem_t *esp_ble_mesh_find_element(uint16_t element_addr);
/**
* @brief Get the number of elements that have been registered.
*
* @param None.
*
* @return Number of elements.
*
*/
uint8_t esp_ble_mesh_get_element_count(void);
/**
* @brief Find the Vendor specific model with the given element,
* the company ID and the Vendor Model ID.
*
* @param[in] element: Element to which the model belongs.
* @param[in] company_id: A 16-bit company identifier assigned by the Bluetooth SIG.
* @param[in] model_id: A 16-bit vendor-assigned model identifier.
*
* @return Pointer to the Vendor Model on success, or NULL on failure which means the Vendor Model is not found.
*
*/
esp_ble_mesh_model_t *esp_ble_mesh_find_vendor_model(esp_ble_mesh_elem_t *element,
uint16_t company_id, uint16_t model_id);
/**
* @brief Find the SIG model with the given element and Model id.
*
* @param[in] element: Element to which the model belongs.
* @param[in] model_id: SIG model identifier.
*
* @return Pointer to the SIG Model on success, or NULL on failure which means the SIG Model is not found.
*
*/
esp_ble_mesh_model_t *esp_ble_mesh_find_sig_model(esp_ble_mesh_elem_t *element, uint16_t model_id);
/**
* @brief Get the Composition data which has been registered.
*
* @param None.
*
* @return Pointer to the Composition data on success, or NULL on failure which means the Composition data is not initialized.
*
*/
const esp_ble_mesh_comp_t *esp_ble_mesh_get_composition_data(void);
#endif /* #if CONFIG_BT_MESH */
#endif /* _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_ */

View File

@@ -0,0 +1,24 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _ESP_BLE_MESH_LOW_POWER_API_H_
#define _ESP_BLE_MESH_LOW_POWER_API_H_
#include "esp_ble_mesh_defs.h"
#if CONFIG_BT_MESH
#endif /* #if CONFIG_BT_MESH */
#endif /* _ESP_BLE_MESH_LOW_POWER_API_H_ */

View File

@@ -0,0 +1,274 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _ESP_BLE_MESH_NETWORKING_API_H_
#define _ESP_BLE_MESH_NETWORKING_API_H_
#include "esp_ble_mesh_defs.h"
#if CONFIG_BT_MESH
/** @brief: event, event code of user-defined model events; param, parameters of user-defined model events */
typedef void (* esp_ble_mesh_model_cb_t)(esp_ble_mesh_model_cb_event_t event,
esp_ble_mesh_model_cb_param_t *param);
/**
* @brief Register BLE Mesh callback for user-defined models' operations.
* This callback can report the following events generated for the user-defined models:
* - Call back the messages received by user-defined client and server models to the
* application layer;
* - If users call esp_ble_mesh_server/client_model_send, this callback notifies the
* application layer of the send_complete event;
* - If user-defined client model sends a message that requires response, and the response
* message is received after the timer expires, the response message will be reported
* to the application layer as published by a peer device;
* - If the user-defined client model fails to receive the response message during a specified
* period of time, a timeout event will be reported to the application layer.
*
* @note The client models (i.e. Config Client model, Health Client model, Generic
* Client models, Sensor Client model, Scene Client model and Lighting Client models)
* that have been realized internally have their specific register functions.
* For example, esp_ble_mesh_register_config_client_callback is the register
* function for Config Client Model.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb_t callback);
/**
* @brief Add the message opcode to the beginning of the model message
* before sending or publishing the model message.
*
* @note This API is only used to set the opcode of the message.
*
* @param[in] data: Pointer to the message data.
* @param[in] opcode: The message opcode.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_model_msg_opcode_init(uint8_t *data, uint32_t opcode);
/**
* @brief Initialize the user-defined client model. All user-defined client models
* shall call this function to initialize the client model internal data.
* Node: Before calling this API, the op_pair_size and op_pair variabled within
* the user_data(defined using esp_ble_mesh_client_t_) of the client model
* need to be initialized.
*
* @param[in] model: BLE Mesh Client model to which the message belongs.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model);
/**
* @brief Send server model messages(such as server model status messages).
*
* @param[in] model: BLE Mesh Server Model to which the message belongs.
* @param[in] ctx: Message context, includes keys, TTL, etc.
* @param[in] opcode: Message opcode.
* @param[in] length: Message length (exclude the message opcode).
* @param[in] data: Parameters of Access Payload (exclude the message opcode) to be sent.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode,
uint16_t length, uint8_t *data);
/**
* @brief Send client model message (such as model get, set, etc).
*
* @param[in] model: BLE Mesh Client Model to which the message belongs.
* @param[in] ctx: Message context, includes keys, TTL, etc.
* @param[in] opcode: Message opcode.
* @param[in] length: Message length (exclude the message opcode).
* @param[in] data: Parameters of the Access Payload (exclude the message opcode) to be sent.
* @param[in] msg_timeout: Time to get response to the message (in milliseconds).
* @param[in] need_rsp: TRUE if the opcode requires the peer device to reply, FALSE otherwise.
* @param[in] device_role: Role of the device (Node/Provisioner) that sends the message.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_client_model_send_msg(esp_ble_mesh_model_t *model,
esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode,
uint16_t length, uint8_t *data, int32_t msg_timeout,
bool need_rsp, esp_ble_mesh_dev_role_t device_role);
/**
* @brief Send a model publication message.
*
* @note Before calling this function, the user needs to ensure that the model
* publication message (@ref esp_ble_mesh_model_pub_t.msg) contains a valid
* message to be sent. And if users want to update the publishing message,
* this API should be called in ESP_BLE_MESH_MODEL_PUBLISH_UPDATE_EVT
* with the message updated.
*
*
* @param[in] model: Mesh (client) Model publishing the message.
* @param[in] opcode: Message opcode.
* @param[in] length: Message length (exclude the message opcode).
* @param[in] data: Parameters of the Access Payload (exclude the message opcode) to be sent.
* @param[in] device_role: Role of the device (node/provisioner) publishing the message of the type esp_ble_mesh_dev_role_t.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcode,
uint16_t length, uint8_t *data,
esp_ble_mesh_dev_role_t device_role);
/**
* @brief Reset the provisioning procedure of the local BLE Mesh node.
*
* @note All provisioning information in this node will be deleted and the node
* needs to be reprovisioned. The API function esp_ble_mesh_node_prov_enable()
* needs to be called to start a new provisioning procedure.
*
* @param None.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_local_reset(void);
#if defined(CONFIG_BT_MESH_PROVISIONER)
/**
* @brief This function is called to set the node (provisioned device) name.
*
* @param[in] index: Index of the node in the node queue.
* @param[in] name: Name (end by '\0') to be set for the node.
*
* @note index is obtained from the parameters of ESP_BLE_MESH_PROVISIONER_PROV_COMPLETE_EVT.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_node_name(int index, const char *name);
/**
* @brief This function is called to get the node (provisioned device) name.
*
* @param[in] index: Index of the node in the node queue.
*
* @note index is obtained from the parameters of ESP_BLE_MESH_PROVISIONER_PROV_COMPLETE_EVT.
*
* @return Node name on success, or NULL on failure.
*
*/
const char *esp_ble_mesh_provisioner_get_node_name(int index);
/**
* @brief This function is called to get the node (provisioned device) index.
*
* @param[in] name: Name of the node (end by '\0').
*
* @return Node index on success, or (negative) error code from errno.h on failure.
*
*/
int esp_ble_mesh_provisioner_get_node_index(const char *name);
/**
* @brief This function is called to set the app key for the local BLE Mesh stack.
*
* @param[in] app_key: The app key to be set for the local BLE Mesh stack.
* @param[in] net_idx: The network key index.
* @param[in] app_idx: The app key index.
*
* @note app_key: If set to NULL, app_key will be generated internally.
* net_idx: Should be an existing one.
* app_idx: If it is going to be generated internally, it should be set to
* 0xFFFF, and the new app_idx will be reported via an event.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_add_local_app_key(const uint8_t app_key[16], uint16_t net_idx, uint16_t app_idx);
/**
* @brief This function is called by Provisioner to get the local app key value.
*
* @param[in] net_idx: Network key index.
* @param[in] app_idx: Application key index.
*
* @return App key on success, or NULL on failure.
*
*/
const uint8_t *esp_ble_mesh_provisioner_get_local_app_key(uint16_t net_idx, uint16_t app_idx);
/**
* @brief This function is called by Provisioner to bind own model with proper app key.
*
* @param[in] element_addr: Provisioner local element address
* @param[in] app_idx: Provisioner local appkey index
* @param[in] model_id: Provisioner local model id
* @param[in] company_id: Provisioner local company id
*
* @note company_id: If going to bind app_key with local vendor model, company_id
* should be set to 0xFFFF.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_bind_app_key_to_local_model(uint16_t element_addr, uint16_t app_idx,
uint16_t model_id, uint16_t company_id);
/**
* @brief This function is called by Provisioner to add local network key.
*
* @param[in] net_key: The network key to be added to the Provisioner local BLE Mesh stack.
* @param[in] net_idx: The network key index.
*
* @note net_key: If set to NULL, net_key will be generated internally.
* net_idx: If it is going to be generated internally, it should be set to
* 0xFFFF, and the new net_idx will be reported via an event.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_add_local_net_key(const uint8_t net_key[16], uint16_t net_idx);
/**
* @brief This function is called by Provisioner to get the local network key value.
*
* @param[in] net_idx: Network key index.
*
* @return Network key on success, or NULL on failure.
*
*/
const uint8_t *esp_ble_mesh_provisioner_get_local_net_key(uint16_t net_idx);
#endif /* #if CONFIG_BT_MESH_PROVISIONER */
/**
* @brief This function is called to get fast provisioning application key.
*
* @param[in] net_idx: Network key index.
* @param[in] app_idx: Application key index.
*
* @return Application key on success, or NULL on failure.
*
*/
const uint8_t *esp_ble_mesh_get_fast_prov_app_key(uint16_t net_idx, uint16_t app_idx);
#endif /* #if CONFIG_BT_MESH */
#endif /* _ESP_BLE_MESH_NETWORKING_API_H_ */

View File

@@ -0,0 +1,324 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _ESP_BLE_MESH_PROVISIONING_API_H_
#define _ESP_BLE_MESH_PROVISIONING_API_H_
#include "esp_ble_mesh_defs.h"
#if CONFIG_BT_MESH
/** @brief: event, event code of provisioning events; param, parameters of provisioning events */
typedef void (* esp_ble_mesh_prov_cb_t)(esp_ble_mesh_prov_cb_event_t event,
esp_ble_mesh_prov_cb_param_t *param);
/**
* @brief Register BLE Mesh provisioning callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb_t callback);
/**
* @brief Check if a device has been provisioned.
*
* @param None.
*
* @return TRUE if the device is provisioned, FALSE if the device is unprovisioned.
*
*/
bool esp_ble_mesh_node_is_provisioned(void);
/**
* @brief Enable specific provisioning bearers to get the device ready for provisioning.
*
* @note PB-ADV: send unprovisioned device beacon.
* PB-GATT: send connectable advertising packets.
*
* @param bearers: Bit-wise OR of provisioning bearers.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_prov_enable(esp_ble_mesh_prov_bearer_t bearers);
/**
* @brief Disable specific provisioning bearers to make a device inaccessible for provisioning.
*
* @param bearers: Bit-wise OR of provisioning bearers.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_prov_disable(esp_ble_mesh_prov_bearer_t bearers);
/**
* @brief Unprovisioned device set own oob public key & private key pair.
*
* @param[in] pub_key_x: Unprovisioned device's Public Key X
* @param[in] pub_key_y: Unprovisioned device's Public Key Y
* @param[in] private_key: Unprovisioned device's Private Key
*
* @return ESP_OK on success or error code otherwise.
*/
esp_err_t esp_ble_mesh_node_set_oob_pub_key(uint8_t pub_key_x[32], uint8_t pub_key_y[32],
uint8_t private_key[32]);
/**
* @brief Provide provisioning input OOB number.
*
* @note This is intended to be called if the user has received ESP_BLE_MESH_NODE_PROV_INPUT_EVT
* with ESP_BLE_MESH_ENTER_NUMBER as the action.
*
* @param[in] number: Number input by device.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_input_number(uint32_t number);
/**
* @brief Provide provisioning input OOB string.
*
* @note This is intended to be called if the user has received ESP_BLE_MESH_NODE_PROV_INPUT_EVT
* with ESP_BLE_MESH_ENTER_STRING as the action.
*
* @param[in] string: String input by device.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_node_input_string(const char *string);
/**
* @brief Using this function, an unprovisioned device can set its own device name,
* which will be broadcasted in its advertising data.
*
* @param[in] name: Unprovisioned device name
*
* @note This API applicable to PB-GATT mode only by setting the name to the scan response data,
* it doesn't apply to PB-ADV mode.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name);
#if defined(CONFIG_BT_MESH_PROVISIONER)
/**
* @brief Provisioner inputs unprovisioned device's oob public key.
*
* @param[in] link_idx: The provisioning link index
* @param[in] pub_key_x: Unprovisioned device's Public Key X
* @param[in] pub_key_y: Unprovisioned device's Public Key Y
*
* @return ESP_OK on success or error code otherwise.
*/
esp_err_t esp_ble_mesh_provisioner_read_oob_pub_key(uint8_t link_idx, uint8_t pub_key_x[32],
uint8_t pub_key_y[32]);
/**
* @brief Provide provisioning input OOB string.
*
* This is intended to be called after the esp_ble_mesh_prov_t prov_input_num
* callback has been called with ESP_BLE_MESH_ENTER_STRING as the action.
*
* @param[in] string: String input by Provisioner.
* @param[in] link_idx: The provisioning link index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link_idx);
/**
* @brief Provide provisioning input OOB number.
*
* This is intended to be called after the esp_ble_mesh_prov_t prov_input_num
* callback has been called with ESP_BLE_MESH_ENTER_NUMBER as the action.
*
* @param[in] number: Number input by Provisioner.
* @param[in] link_idx: The provisioning link index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_input_number(uint32_t number, uint8_t link_idx);
/**
* @brief Enable one or more provisioning bearers.
*
* @param[in] bearers: Bit-wise OR of provisioning bearers.
*
* @note PB-ADV: Enable BLE scan.
* PB-GATT: Initialize corresponding BLE Mesh Proxy info.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_prov_enable(esp_ble_mesh_prov_bearer_t bearers);
/**
* @brief Disable one or more provisioning bearers.
*
* @param[in] bearers: Bit-wise OR of provisioning bearers.
*
* @note PB-ADV: Disable BLE scan.
* PB-GATT: Break any existing BLE Mesh Provisioning connections.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_prov_disable(esp_ble_mesh_prov_bearer_t bearers);
/**
* @brief Add unprovisioned device info to the unprov_dev queue.
*
* @param[in] add_dev: Pointer to a struct containing the device information
* @param[in] flags: Flags indicate several operations on the device information
* - Remove device information from queue after device has been provisioned (BIT0)
* - Start provisioning immediately after device is added to queue (BIT1)
* - Device can be removed if device queue is full (BIT2)
*
* @return ESP_OK on success or error code otherwise.
*
* @note: 1. Currently address type only supports public address and static random address.
* 2. If device UUID and/or device address as well as address type already exist in the
* device queue, but the bearer is different from the existing one, add operation
* will also be successful and it will update the provision bearer supported by
* the device.
* 3. For example, if the Provisioner wants to add an unprovisioned device info before
* receiving its unprovisioned device beacon or Mesh Provisioning advertising packets,
* the Provisioner can use this API to add the device info with each one or both of
* device UUID and device address added. When the Provisioner gets the device's
* advertising packets, it will start provisioning the device internally.
* - In this situation, the Provisioner can set bearers with each one or both of
* ESP_BLE_MESH_PROV_ADV and ESP_BLE_MESH_PROV_GATT enabled, and cannot set flags
* with ADD_DEV_START_PROV_NOW_FLAG enabled.
* 4. Another example is when the Provisioner receives the unprovisioned device's beacon or
* Mesh Provisioning advertising packets, the advertising packets will be reported on to
* the application layer using the callback registered by the function
* esp_ble_mesh_register_prov_callback. And in the callback, the Provisioner
* can call this API to start provisioning the device.
* - If the Provisioner uses PB-ADV to provision, either one or both of device UUID and
* device address can be added, bearers shall be set with ESP_BLE_MESH_PROV_ADV
* enabled and the flags shall be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
* - If the Provisioner uses PB-GATT to provision, both the device UUID and device
* address need to be added, bearers shall be set with ESP_BLE_MESH_PROV_GATT enabled,
* and the flags shall be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
* - If the Provisioner just wants to store the unprovisioned device info when receiving
* its advertising packets and start to provision it the next time (e.g. after receiving
* its advertising packets again), then it can add the device info with either one or both
* of device UUID and device address included. Bearers can be set with either one or both
* of ESP_BLE_MESH_PROV_ADV and ESP_BLE_MESH_PROV_GATT enabled (recommend to enable the
* bearer which will receive its advertising packets, because if the other bearer is
* enabled, the Provisioner is not aware if the device supports the bearer), and flags
* cannot be set with ADD_DEV_START_PROV_NOW_FLAG enabled.
* - Note: ESP_BLE_MESH_PROV_ADV, ESP_BLE_MESH_PROV_GATT and ADD_DEV_START_PROV_NOW_FLAG
* can not be enabled at the same time.
*
*/
esp_err_t esp_ble_mesh_provisioner_add_unprov_dev(esp_ble_mesh_unprov_dev_add_t *add_dev,
esp_ble_mesh_dev_add_flag_t flags);
/**
* @brief Delete device from queue, reset current provisioning link and reset the node.
*
* @note If the device is in the queue, remove it from the queue; if the device is being
* provisioned, terminate the provisioning procedure; if the device has already
* been provisioned, reset the device. And either one of the addr or device UUID
* can be input.
*
* @param[in] del_dev: Pointer to a struct containing the device information.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_delete_dev(esp_ble_mesh_device_delete_t *del_dev);
/**
* @brief Callback for Provisioner that received advertising packets from unprovisioned devices which are
* not in the unprovisioned device queue.
*
* Report on the unprovisioned device beacon and mesh provisioning service adv data to application.
*
* @param[in] addr: Pointer to the unprovisioned device address.
* @param[in] addr_type: Unprovisioned device address type.
* @param[in] adv_type: Adv packet type(ADV_IND or ADV_NONCONN_IND).
* @param[in] dev_uuid: Unprovisioned device UUID pointer.
* @param[in] oob_info: OOB information of the unprovisioned device.
* @param[in] bearer: Adv packet received from PB-GATT or PB-ADV bearer.
*
*/
typedef void (*esp_ble_mesh_prov_adv_cb_t)(const esp_bd_addr_t addr, const esp_ble_addr_type_t addr_type,
const uint8_t adv_type, const uint8_t *dev_uuid,
uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer);
/**
* @brief This function is called by Provisioner to set the part of the device UUID
* to be compared before starting to provision.
*
* @param[in] match_val: Value to be compared with the part of the device UUID.
* @param[in] match_len: Length of the compared match value.
* @param[in] offset: Offset of the device UUID to be compared (based on zero).
* @param[in] prov_after_match: Flag used to indicate whether provisioner should start to provision
* the device immediately if the part of the UUID matches.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_dev_uuid_match(const uint8_t *match_val, uint8_t match_len,
uint8_t offset, bool prov_after_match);
/**
* @brief This function is called by Provisioner to set provisioning data information
* before starting to provision.
*
* @param[in] prov_data_info: Pointer to a struct containing net_idx or flags or iv_index.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_provisioner_set_prov_data_info(esp_ble_mesh_prov_data_info_t *prov_data_info);
#endif /* #if CONFIG_BT_MESH_PROVISIONER */
/**
* @brief This function is called to set provisioning data information before starting
* fast provisioning.
*
* @param[in] fast_prov_info: Pointer to a struct containing unicast address range, net_idx, etc.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_prov_info);
/**
* @brief This function is called to start/suspend/exit fast provisioning.
*
* @param[in] action: fast provisioning action (i.e. enter, suspend, exit).
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_set_fast_prov_action(esp_ble_mesh_fast_prov_action_t action);
#endif /* #if CONFIG_BT_MESH */
#endif /* _ESP_BLE_MESH_PROVISIONING_API_H_ */

View File

@@ -0,0 +1,59 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _ESP_BLE_MESH_PROXY_API_H_
#define _ESP_BLE_MESH_PROXY_API_H_
#include "esp_ble_mesh_defs.h"
/**
* @brief Enable advertising with Node Identity.
*
* @note This API requires that GATT Proxy support be enabled. Once called,
* each subnet starts advertising using Node Identity for the next 60
* seconds, and after 60s Network ID will be advertised.
* Under normal conditions, the BLE Mesh Proxy Node Identity and
* Network ID advertising will be enabled automatically by BLE Mesh
* stack after the device is provisioned.
*
* @param None.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_identity_enable(void);
/**
* @brief Enable BLE Mesh GATT Proxy Service.
*
* @param None.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_gatt_enable(void);
/**
* @brief Disconnect the BLE Mesh GATT Proxy connection if there is any, and
* disable the BLE Mesh GATT Proxy Service.
*
* @param None.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_proxy_gatt_disable(void);
#endif /* _ESP_BLE_MESH_PROXY_API_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_config_client.h"
#include "esp_ble_mesh_config_model_api.h"
esp_err_t esp_ble_mesh_register_config_client_callback(esp_ble_mesh_cfg_client_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_CFG_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_register_config_server_callback(esp_ble_mesh_cfg_server_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_CFG_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_config_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_cfg_client_get_state_t *get_state)
{
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_cfg_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_CFG_CLIENT;
msg.act = BTC_BLE_MESH_ACT_CONFIG_CLIENT_GET_STATE;
arg.cfg_client_get_state.params = params;
arg.cfg_client_get_state.get_state = get_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_cfg_client_args_t), btc_ble_mesh_cfg_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_config_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_cfg_client_set_state_t *set_state)
{
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_cfg_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_CFG_CLIENT;
msg.act = BTC_BLE_MESH_ACT_CONFIG_CLIENT_SET_STATE;
arg.cfg_client_set_state.params = params;
arg.cfg_client_set_state.set_state = set_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_cfg_client_args_t), btc_ble_mesh_cfg_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -0,0 +1,75 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_generic_client.h"
#include "esp_ble_mesh_generic_model_api.h"
esp_err_t esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_client_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_GENERIC_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_generic_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_generic_client_get_state_t *get_state)
{
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_generic_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GENERIC_CLIENT;
msg.act = BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE;
arg.generic_client_get_state.params = params;
arg.generic_client_get_state.get_state = get_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_generic_client_args_t), btc_ble_mesh_generic_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_generic_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_generic_client_set_state_t *set_state)
{
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_generic_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GENERIC_CLIENT;
msg.act = BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE;
arg.generic_client_set_state.params = params;
arg.generic_client_set_state.set_state = set_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_generic_client_args_t), btc_ble_mesh_generic_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -0,0 +1,98 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_health.h"
#include "esp_ble_mesh_health_model_api.h"
esp_err_t esp_ble_mesh_register_health_client_callback(esp_ble_mesh_health_client_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_HEALTH_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_register_health_server_callback(esp_ble_mesh_health_server_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_HEALTH_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_health_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_get_state_t *get_state)
{
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_health_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HEALTH_CLIENT;
msg.act = BTC_BLE_MESH_ACT_HEALTH_CLIENT_GET_STATE;
arg.health_client_get_state.params = params;
arg.health_client_get_state.get_state = get_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_health_client_args_t), btc_ble_mesh_health_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_health_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_set_state_t *set_state)
{
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_health_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HEALTH_CLIENT;
msg.act = BTC_BLE_MESH_ACT_HEALTH_CLIENT_SET_STATE;
arg.health_client_set_state.params = params;
arg.health_client_set_state.set_state = set_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_health_client_args_t), btc_ble_mesh_health_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_health_server_fault_update(esp_ble_mesh_elem_t *element)
{
btc_ble_mesh_health_server_args_t arg = {0};
btc_msg_t msg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_HEALTH_SERVER;
msg.act = BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE;
arg.fault_update.element = element;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_health_server_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -0,0 +1,76 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_light_client.h"
#include "esp_ble_mesh_lighting_model_api.h"
esp_err_t esp_ble_mesh_register_light_client_callback(esp_ble_mesh_light_client_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_LIGHT_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_light_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_light_client_get_state_t *get_state)
{
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_light_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_LIGHT_CLIENT;
msg.act = BTC_BLE_MESH_ACT_LIGHT_CLIENT_GET_STATE;
arg.light_client_get_state.params = params;
arg.light_client_get_state.get_state = get_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_light_client_args_t), btc_ble_mesh_light_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_light_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_light_client_set_state_t *set_state)
{
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_light_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_LIGHT_CLIENT;
msg.act = BTC_BLE_MESH_ACT_LIGHT_CLIENT_SET_STATE;
arg.light_client_set_state.params = params;
arg.light_client_set_state.set_state = set_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_light_client_args_t), btc_ble_mesh_light_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -0,0 +1,76 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_sensor_client.h"
#include "esp_ble_mesh_sensor_model_api.h"
esp_err_t esp_ble_mesh_register_sensor_client_callback(esp_ble_mesh_sensor_client_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_SENSOR_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_sensor_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_sensor_client_get_state_t *get_state)
{
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_sensor_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SENSOR_CLIENT;
msg.act = BTC_BLE_MESH_ACT_SENSOR_CLIENT_GET_STATE;
arg.sensor_client_get_state.params = params;
arg.sensor_client_get_state.get_state = get_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_sensor_client_args_t), btc_ble_mesh_sensor_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_sensor_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_sensor_client_set_state_t *set_state)
{
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_sensor_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_SENSOR_CLIENT;
msg.act = BTC_BLE_MESH_ACT_SENSOR_CLIENT_SET_STATE;
arg.sensor_client_set_state.params = params;
arg.sensor_client_set_state.set_state = set_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_sensor_client_args_t), btc_ble_mesh_sensor_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -0,0 +1,76 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_time_scene_client.h"
#include "esp_ble_mesh_time_scene_model_api.h"
esp_err_t esp_ble_mesh_register_time_scene_client_callback(esp_ble_mesh_time_scene_client_cb_t callback)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_TIME_SCENE_CLIENT, callback) == 0 ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_time_scene_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_time_scene_client_get_state_t *get_state)
{
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_time_scene_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_TIME_SCENE_CLIENT;
msg.act = BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_GET_STATE;
arg.time_scene_client_get_state.params = params;
arg.time_scene_client_get_state.get_state = get_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_time_scene_client_args_t), btc_ble_mesh_time_scene_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_mesh_time_scene_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_time_scene_client_set_state_t *set_state)
{
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
btc_ble_mesh_time_scene_client_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_TIME_SCENE_CLIENT;
msg.act = BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_SET_STATE;
arg.time_scene_client_set_state.params = params;
arg.time_scene_client_set_state.set_state = set_state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_time_scene_client_args_t), btc_ble_mesh_time_scene_client_arg_deep_copy)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@@ -0,0 +1,670 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _ESP_BLE_MESH_CONFIG_MODEL_API_H_
#define _ESP_BLE_MESH_CONFIG_MODEL_API_H_
#include "esp_ble_mesh_defs.h"
/** @def ESP_BLE_MESH_MODEL_CFG_SRV
*
* @brief Define a new Config Server Model.
*
* @note The Config Server Model can only be included by a Primary Element.
*
* @param srv_data Pointer to a unique Config Server Model user_data.
*
* @return New Config Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_CFG_SRV(srv_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_CONFIG_SRV, \
NULL, NULL, srv_data)
/** @def ESP_BLE_MESH_MODEL_CFG_CLI
*
* @brief Define a new Config Client Model.
*
* @note The Config Client Model can only be included by a Primary Element.
*
* @param cli_data Pointer to a unique struct esp_ble_mesh_client_t.
*
* @return New Config Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_CFG_CLI(cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_CONFIG_CLI, \
NULL, NULL, cli_data)
typedef struct esp_ble_mesh_cfg_srv {
esp_ble_mesh_model_t *model;
uint8_t net_transmit; /*!< Network Transmit state */
uint8_t relay; /*!< Relay Mode state */
uint8_t relay_retransmit; /*!< Relay Retransmit state */
uint8_t beacon; /*!< Secure Network Beacon state */
uint8_t gatt_proxy; /*!< GATT Proxy state */
uint8_t friend_state; /*!< Friend state */
uint8_t default_ttl; /*!< Default TTL */
/** Heartbeat Publication */
struct {
struct k_delayed_work timer;
uint16_t dst;
uint16_t count;
uint8_t period;
uint8_t ttl;
uint16_t feature;
uint16_t net_idx;
} heartbeat_pub;
/** Heartbeat Subscription */
struct {
int64_t expiry;
uint16_t src;
uint16_t dst;
uint16_t count;
uint8_t min_hops;
uint8_t max_hops;
/** Optional subscription tracking function */
void (*func)(uint8_t hops, uint16_t feature);
} heartbeat_sub;
} esp_ble_mesh_cfg_srv_t;
/** Parameters of Composition Data Get. */
typedef struct {
uint8_t page; /*!< Page number of the Composition Data. */
} esp_ble_mesh_cfg_composition_data_get_t;
/** Parameters of Model Publication Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_pub_get_t;
/** Parameters of SIG Model Subscription Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
} esp_ble_mesh_cfg_sig_model_sub_get_t;
/** Parameters of Vendor Model Subscription Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_vnd_model_sub_get_t;
/** Parameters of Application Key Get. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
} esp_ble_mesh_cfg_app_key_get_t;
/** Parameters of Node Identity Get. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
} esp_ble_mesh_cfg_node_identity_get_t;
/** Parameters of SIG Model App Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
} esp_ble_mesh_cfg_sig_model_app_get_t;
/** Parameters of Vendor Model App Get. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_vnd_model_app_get_t;
/** Parameters of Key Refresh Phase Get. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
} esp_ble_mesh_cfg_kr_phase_get_t;
/** Parameters of Low Power Node PollTimeout Get. */
typedef struct {
uint16_t lpn_addr; /*!< The unicast address of the Low Power node */
} esp_ble_mesh_cfg_lpn_polltimeout_get_t;
/** Parameters of Beacon Set. */
typedef struct {
uint8_t beacon;
} esp_ble_mesh_cfg_beacon_set_t;
/** Parameters of Default TTL Set. */
typedef struct {
uint8_t ttl; /*!< The default TTL state value */
} esp_ble_mesh_cfg_default_ttl_set_t;
/** Parameters of Friend Set. */
typedef struct {
uint8_t friend_state; /*!< The friend state value */
} esp_ble_mesh_cfg_friend_set_t;
/** Parameters of GATT Proxy Set. */
typedef struct {
uint8_t gatt_proxy; /*!< The GATT Proxy state value */
} esp_ble_mesh_cfg_gatt_proxy_set_t;
/** Parameters of Relay Set. */
typedef struct {
uint8_t relay; /*!< The relay value */
uint8_t relay_retransmit; /*!< The relay retransmit value */
} esp_ble_mesh_cfg_relay_set_t;
/** Parameters of Network Key Add. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint8_t net_key[16]; /*!< The network key value */
} esp_ble_mesh_cfg_net_key_add_t;
/** Parameters of Application Key Add. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint16_t app_idx; /*!< The app key index */
uint8_t app_key[16]; /*!< The app key value */
} esp_ble_mesh_cfg_app_key_add_t;
/** Parameters of Model Application Key Bind. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_app_idx; /*!< Index of the app key to bind with the model */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_app_bind_t;
/** Parameters of Model Publication Set. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t publish_addr; /*!< Value of the publish address */
uint16_t publish_app_idx; /*!< Index of the application key */
bool cred_flag; /*!< Value of the Friendship Credential Flag */
uint8_t publish_ttl; /*!< Default TTL value for the publishing messages */
uint8_t publish_period; /*!< Period for periodic status publishing */
uint8_t publish_retransmit; /*!< Number of retransmissions and number of 50-millisecond steps between retransmissions */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_pub_set_t;
/** Parameters of Model Subscription Add. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t sub_addr; /*!< The address to be added to the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_add_t;
/** Parameters of Model Subscription Delete. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t sub_addr; /*!< The address to be removed from the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_delete_t;
/** Parameters of Model Subscription Overwrite. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t sub_addr; /*!< The address to be added to the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_overwrite_t;
/** Parameters of Model Subscription Virtual Address Add. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint8_t label_uuid[16]; /*!< The Label UUID of the virtual address to be added to the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_va_add_t;
/** Parameters of Model Subscription Virtual Address Delete. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint8_t label_uuid[16]; /*!< The Label UUID of the virtual address to be removed from the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_va_delete_t;
/** Parameters of Model Subscription Virtual Address Overwrite. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint8_t label_uuid[16]; /*!< The Label UUID of the virtual address to be added to the Subscription List */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_va_overwrite_t;
/** Parameters of Model Publication Virtual Address Set. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint8_t label_uuid[16]; /*!< Value of the Label UUID publish address */
uint16_t publish_app_idx; /*!< Index of the application key */
bool cred_flag; /*!< Value of the Friendship Credential Flag */
uint8_t publish_ttl; /*!< Default TTL value for the publishing messages */
uint8_t publish_period; /*!< Period for periodic status publishing */
uint8_t publish_retransmit; /*!< Number of retransmissions and number of 50-millisecond steps between retransmissions */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_pub_va_set_t;
/** Parameters of Model Subscription Delete All. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_sub_delete_all_t;
/** Parameters of Network Key Update. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint8_t net_key[16]; /*!< The network key value */
} esp_ble_mesh_cfg_net_key_update_t;
/** Parameters of Network Key Delete. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
} esp_ble_mesh_cfg_net_key_delete_t;
/** Parameters of Application Key Update. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint16_t app_idx; /*!< The app key index */
uint8_t app_key[16]; /*!< The app key value */
} esp_ble_mesh_cfg_app_key_update_t;
/** Parameters of Application Key Delete. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint16_t app_idx; /*!< The app key index */
} esp_ble_mesh_cfg_app_key_delete_t;
/** Parameters of Node Identity Set. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint8_t identity; /*!< New Node Identity state */
} esp_ble_mesh_cfg_node_identity_set_t;
/** Parameters of Model Application Key Unbind. */
typedef struct {
uint16_t element_addr; /*!< The element address */
uint16_t model_app_idx; /*!< Index of the app key to bind with the model */
uint16_t model_id; /*!< The model id */
uint16_t company_id; /*!< The company id, if not a vendor model, shall set to 0xFFFF */
} esp_ble_mesh_cfg_model_app_unbind_t;
/** Parameters of Key Refresh Phase Set. */
typedef struct {
uint16_t net_idx; /*!< The network key index */
uint8_t transition; /*!< New Key Refresh Phase Transition */
} esp_ble_mesh_cfg_kr_phase_set_t;
/** Parameters of Network Transmit Set. */
typedef struct {
uint8_t net_transmit; /*!< Network Transmit State */
} esp_ble_mesh_cfg_net_transmit_set_t;
/** Parameters of Model Heartbeat Publication Set. */
typedef struct {
uint16_t dst;
uint8_t count;
uint8_t period;
uint8_t ttl;
uint16_t feature;
uint16_t net_idx;
} esp_ble_mesh_cfg_heartbeat_pub_set_t;
/** Parameters of Model Heartbeat Subscription Set. */
typedef struct {
uint16_t src;
uint16_t dst;
uint8_t period;
} esp_ble_mesh_cfg_heartbeat_sub_set_t;
/**
* @brief For ESP_BLE_MESH_MODEL_OP_BEACON_GET
* ESP_BLE_MESH_MODEL_OP_COMPOSITION_DATA_GET
* ESP_BLE_MESH_MODEL_OP_DEFAULT_TTL_GET
* ESP_BLE_MESH_MODEL_OP_GATT_PROXY_GET
* ESP_BLE_MESH_MODEL_OP_RELAY_GET
* ESP_BLE_MESH_MODEL_OP_MODEL_PUB_GET
* ESP_BLE_MESH_MODEL_OP_FRIEND_GET
* ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_GET
* ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_GET
* the get_state parameter in the esp_ble_mesh_config_client_get_state function should not be set to NULL.
*/
typedef union {
esp_ble_mesh_cfg_model_pub_get_t model_pub_get; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_PUB_GET. */
esp_ble_mesh_cfg_composition_data_get_t comp_data_get; /*!< For ESP_BLE_MESH_MODEL_OP_COMPOSITION_DATA_GET. */
esp_ble_mesh_cfg_sig_model_sub_get_t sig_model_sub_get; /*!< For ESP_BLE_MESH_MODEL_OP_SIG_MODEL_SUB_GET */
esp_ble_mesh_cfg_vnd_model_sub_get_t vnd_model_sub_get; /*!< For ESP_BLE_MESH_MODEL_OP_VENDOR_MODEL_SUB_GET */
esp_ble_mesh_cfg_app_key_get_t app_key_get; /*!< For ESP_BLE_MESH_MODEL_OP_APP_KEY_GET. */
esp_ble_mesh_cfg_node_identity_get_t node_identity_get; /*!< For ESP_BLE_MESH_MODEL_OP_NODE_IDENTITY_GET. */
esp_ble_mesh_cfg_sig_model_app_get_t sig_model_app_get; /*!< For ESP_BLE_MESH_MODEL_OP_SIG_MODEL_APP_GET */
esp_ble_mesh_cfg_vnd_model_app_get_t vnd_model_app_get; /*!< For ESP_BLE_MESH_MODEL_OP_VENDOR_MODEL_APP_GET */
esp_ble_mesh_cfg_kr_phase_get_t kr_phase_get; /*!< For ESP_BLE_MESH_MODEL_OP_KEY_REFRESH_PHASE_GET */
esp_ble_mesh_cfg_lpn_polltimeout_get_t lpn_pollto_get; /*!< For ESP_BLE_MESH_MODEL_OP_LPN_POLLTIMEOUT_GET */
} esp_ble_mesh_cfg_client_get_state_t;
/**
* @brief For ESP_BLE_MESH_MODEL_OP_BEACON_SET
* ESP_BLE_MESH_MODEL_OP_DEFAULT_TTL_SET
* ESP_BLE_MESH_MODEL_OP_GATT_PROXY_SET
* ESP_BLE_MESH_MODEL_OP_RELAY_SET
* ESP_BLE_MESH_MODEL_OP_MODEL_PUB_SET
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_ADD
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_DELETE
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_OVERWRITE
* ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_OVERWRITE
* ESP_BLE_MESH_MODEL_OP_NET_KEY_ADD
* ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD
* ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND
* ESP_BLE_MESH_MODEL_OP_NODE_RESET
* ESP_BLE_MESH_MODEL_OP_FRIEND_SET
* ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_SET
* ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_SET
* the set_state parameter in the esp_ble_mesh_config_client_set_state function should not be set to NULL.
*/
typedef union {
esp_ble_mesh_cfg_beacon_set_t beacon_set; /*!< For ESP_BLE_MESH_MODEL_OP_BEACON_SET */
esp_ble_mesh_cfg_default_ttl_set_t default_ttl_set; /*!< For ESP_BLE_MESH_MODEL_OP_DEFAULT_TTL_SET */
esp_ble_mesh_cfg_friend_set_t friend_set; /*!< For ESP_BLE_MESH_MODEL_OP_FRIEND_SET */
esp_ble_mesh_cfg_gatt_proxy_set_t gatt_proxy_set; /*!< For ESP_BLE_MESH_MODEL_OP_GATT_PROXY_SET */
esp_ble_mesh_cfg_relay_set_t relay_set; /*!< For ESP_BLE_MESH_MODEL_OP_RELAY_SET */
esp_ble_mesh_cfg_net_key_add_t net_key_add; /*!< For ESP_BLE_MESH_MODEL_OP_NET_KEY_ADD */
esp_ble_mesh_cfg_app_key_add_t app_key_add; /*!< For ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD */
esp_ble_mesh_cfg_model_app_bind_t model_app_bind; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND */
esp_ble_mesh_cfg_model_pub_set_t model_pub_set; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_PUB_SET */
esp_ble_mesh_cfg_model_sub_add_t model_sub_add; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD */
esp_ble_mesh_cfg_model_sub_delete_t model_sub_delete; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE */
esp_ble_mesh_cfg_model_sub_overwrite_t model_sub_overwrite; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_OVERWRITE */
esp_ble_mesh_cfg_model_sub_va_add_t model_sub_va_add; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_ADD */
esp_ble_mesh_cfg_model_sub_va_delete_t model_sub_va_delete; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_DELETE */
esp_ble_mesh_cfg_model_sub_va_overwrite_t model_sub_va_overwrite; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_OVERWRITE */
esp_ble_mesh_cfg_heartbeat_pub_set_t heartbeat_pub_set; /*!< For ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_SET */
esp_ble_mesh_cfg_heartbeat_sub_set_t heartbeat_sub_set; /*!< For ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_SET */
esp_ble_mesh_cfg_model_pub_va_set_t model_pub_va_set; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_PUB_VIRTUAL_ADDR_SET */
esp_ble_mesh_cfg_model_sub_delete_all_t model_sub_delete_all; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE_ALL */
esp_ble_mesh_cfg_net_key_update_t net_key_update; /*!< For ESP_BLE_MESH_MODEL_OP_NET_KEY_UPDATE */
esp_ble_mesh_cfg_net_key_delete_t net_key_delete; /*!< For ESP_BLE_MESH_MODEL_OP_NET_KEY_DELETE */
esp_ble_mesh_cfg_app_key_update_t app_key_update; /*!< For ESP_BLE_MESH_MODEL_OP_APP_KEY_UPDATE */
esp_ble_mesh_cfg_app_key_delete_t app_key_delete; /*!< For ESP_BLE_MESH_MODEL_OP_APP_KEY_DELETE */
esp_ble_mesh_cfg_node_identity_set_t node_identity_set; /*!< For ESP_BLE_MESH_MODEL_OP_NODE_IDENTITY_SET */
esp_ble_mesh_cfg_model_app_unbind_t model_app_unbind; /*!< For ESP_BLE_MESH_MODEL_OP_MODEL_APP_UNBIND */
esp_ble_mesh_cfg_kr_phase_set_t kr_phase_set; /*!< For ESP_BLE_MESH_MODEL_OP_KEY_REFRESH_PHASE_SET */
esp_ble_mesh_cfg_net_transmit_set_t net_transmit_set; /*!< For ESP_BLE_MESH_MODEL_OP_NETWORK_TRANSMIT_SET */
} esp_ble_mesh_cfg_client_set_state_t;
typedef struct {
uint8_t beacon; /*!< Secure Network Beacon state value */
} esp_ble_mesh_cfg_beacon_status_cb_t;
typedef struct {
uint8_t page; /*!< Page number of the Composition Data */
struct net_buf_simple *composition_data; /*!< Pointer to Composition Data for the identified page */
} esp_ble_mesh_cfg_comp_data_status_cb_t;
typedef struct {
uint8_t default_ttl; /*!< Default TTL state value */
} esp_ble_mesh_cfg_default_ttl_status_cb_t;
typedef struct {
uint8_t gatt_proxy; /*!< GATT Proxy state value */
} esp_ble_mesh_cfg_gatt_proxy_status_cb_t;
typedef struct {
uint8_t relay; /*!< Relay state value */
uint8_t retransmit; /*!< Relay retransmit value(number of retransmissions and number of 10-millisecond steps between retransmissions) */
} esp_ble_mesh_cfg_relay_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t publish_addr; /*!< Value of the publish address */
uint16_t app_idx; /*!< Index of the application key */
bool cred_flag; /*!< Value of the Friendship Credential Flag */
uint8_t ttl; /*!< Default TTL value for the outgoing messages */
uint8_t period; /*!< Period for periodic status publishing */
uint8_t transmit; /*!< Number of retransmissions and number of 50-millisecond steps between retransmissions */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_cfg_model_pub_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t sub_addr; /*!< Value of the address */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_cfg_model_sub_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< Index of the NetKey */
} esp_ble_mesh_cfg_net_key_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< Index of the NetKey */
uint16_t app_idx; /*!< Index of the application key */
} esp_ble_mesh_cfg_app_key_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t app_idx; /*!< Index of the application key */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
} esp_ble_mesh_cfg_mod_app_status_cb_t;
typedef struct {
uint8_t friend_state; /*!< Friend state value */
} esp_ble_mesh_cfg_friend_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t dst; /*!< Destination address for Heartbeat messages */
uint8_t count; /*!< Number of Heartbeat messages remaining to be sent */
uint8_t period; /*!< Period for sending Heartbeat messages */
uint8_t ttl; /*!< TTL to be used when sending Heartbeat messages */
uint16_t features; /*!< Features that trigger Heartbeat messages when changed */
uint16_t net_idx; /*!< Index of the NetKey */
} esp_ble_mesh_cfg_hb_pub_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t src; /*!< Source address for Heartbeat messages */
uint16_t dst; /*!< Destination address for Heartbeat messages */
uint8_t period; /*!< Remaining Period for processing Heartbeat messages */
uint8_t count; /*!< Number of Heartbeat messages received */
uint8_t min_hops; /*!< Minimum hops when receiving Heartbeat messages */
uint8_t max_hops; /*!< Maximum hops when receiving Heartbeat messages */
} esp_ble_mesh_cfg_hb_sub_status_cb_t;
typedef struct {
uint8_t net_trans_count:3; /*!< Number of transmissions for each Network PDU originating from the node */
uint8_t net_trans_step :5; /*!< Maximum hops when receiving Heartbeat messages */
} esp_ble_mesh_cfg_net_trans_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
struct net_buf_simple *sub_addr; /*!< A block of all addresses from the Subscription List */
} esp_ble_mesh_cfg_model_sub_list_cb_t;
typedef struct {
struct net_buf_simple *net_idx; /*!< A list of NetKey Indexes known to the node */
} esp_ble_mesh_cfg_net_key_list_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< NetKey Index of the NetKey that the AppKeys are bound to */
struct net_buf_simple *app_idx; /*!< A list of AppKey indexes that are bound to the NetKey identified by NetKeyIndex */
} esp_ble_mesh_cfg_app_key_list_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< Index of the NetKey */
uint8_t identity; /*!< Node Identity state */
} esp_ble_mesh_cfg_node_id_status_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t element_addr; /*!< Address of the element */
uint16_t company_id; /*!< Company ID */
uint16_t model_id; /*!< Model ID */
struct net_buf_simple *app_idx; /*!< All AppKey indexes bound to the Model */
} esp_ble_mesh_cfg_model_app_list_cb_t;
typedef struct {
uint8_t status; /*!< Status Code for the request message */
uint16_t net_idx; /*!< Index of the NetKey */
uint8_t phase; /*!< Key Refresh Phase state */
} esp_ble_mesh_cfg_kr_phase_status_cb_t;
typedef struct {
uint16_t lpn_addr; /*!< The unicast address of the Low Power node */
int32_t poll_timeout; /*!< The current value of the PollTimeout timer of the Low Power node */
} esp_ble_mesh_cfg_lpn_pollto_status_cb_t;
typedef union {
esp_ble_mesh_cfg_beacon_status_cb_t beacon_status; /*!< The beacon status value */
esp_ble_mesh_cfg_comp_data_status_cb_t comp_data_status; /*!< The composition data status value */
esp_ble_mesh_cfg_default_ttl_status_cb_t default_ttl_status; /*!< The default_ttl status value */
esp_ble_mesh_cfg_gatt_proxy_status_cb_t gatt_proxy_status; /*!< The gatt_proxy status value */
esp_ble_mesh_cfg_relay_status_cb_t relay_status; /*!< The relay status value */
esp_ble_mesh_cfg_model_pub_status_cb_t model_pub_status; /*!< The model publication status value */
esp_ble_mesh_cfg_model_sub_status_cb_t model_sub_status; /*!< The model subscription status value */
esp_ble_mesh_cfg_net_key_status_cb_t netkey_status; /*!< The netkey status value */
esp_ble_mesh_cfg_app_key_status_cb_t appkey_status; /*!< The appkey status value */
esp_ble_mesh_cfg_mod_app_status_cb_t model_app_status; /*!< The model app status value */
esp_ble_mesh_cfg_friend_status_cb_t friend_status; /*!< The friend status value */
esp_ble_mesh_cfg_hb_pub_status_cb_t heartbeat_pub_status; /*!< The heartbeat publication status value */
esp_ble_mesh_cfg_hb_sub_status_cb_t heartbeat_sub_status; /*!< The heartbeat subscription status value */
esp_ble_mesh_cfg_net_trans_status_cb_t net_transmit_status; /*!< The network transmit status value */
esp_ble_mesh_cfg_model_sub_list_cb_t model_sub_list; /*!< The model subscription list value */
esp_ble_mesh_cfg_net_key_list_cb_t netkey_list; /*!< The network key index list value */
esp_ble_mesh_cfg_app_key_list_cb_t appkey_list; /*!< The application key index list value */
esp_ble_mesh_cfg_node_id_status_cb_t node_identity_status; /*!< The node identity status value */
esp_ble_mesh_cfg_model_app_list_cb_t model_app_list; /*!< The model application key index list value */
esp_ble_mesh_cfg_kr_phase_status_cb_t kr_phase_status; /*!< The key refresh phase status value */
esp_ble_mesh_cfg_lpn_pollto_status_cb_t lpn_timeout_status; /*!< The low power node poll timeout status value */
} esp_ble_mesh_cfg_client_common_cb_param_t;
typedef struct {
int error_code; /*!< Appropriate error code */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters */
esp_ble_mesh_cfg_client_common_cb_param_t status_cb; /*!< The config status message callback values */
} esp_ble_mesh_cfg_client_cb_param_t;
typedef enum {
ESP_BLE_MESH_CFG_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_CFG_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_CFG_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_CFG_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_CFG_CLIENT_EVT_MAX,
} esp_ble_mesh_cfg_client_cb_event_t;
typedef struct {
uint16_t app_idx; /* AppKey Index of the Config AppKey Add */
} esp_ble_mesh_cfg_srv_app_key_add_cb_t;
typedef union {
esp_ble_mesh_cfg_srv_app_key_add_cb_t app_key_add; /* !< The Config AppKey Add event value */
} esp_ble_mesh_cfg_server_common_cb_param_t;
typedef struct {
esp_ble_mesh_model_t *model; /*!< Pointer to the server model structure */
esp_ble_mesh_msg_ctx_t ctx; /*!< The context of the received message */
esp_ble_mesh_cfg_server_common_cb_param_t status_cb; /*!< The received configuration message callback values */
} esp_ble_mesh_cfg_server_cb_param_t;
typedef enum {
ESP_BLE_MESH_CFG_SERVER_RECV_MSG_EVT,
ESP_BLE_MESH_CFG_SERVER_EVT_MAX,
} esp_ble_mesh_cfg_server_cb_event_t;
/**
* @brief Bluetooth Mesh Config Client and Server Model functions.
*/
/** @brief: event, event code of Config Client Model events; param, parameters of Config Client Model events */
typedef void (* esp_ble_mesh_cfg_client_cb_t)(esp_ble_mesh_cfg_client_cb_event_t event,
esp_ble_mesh_cfg_client_cb_param_t *param);
/** @brief: event, event code of Config Client Model events; param, parameters of Config Client Model events */
typedef void (* esp_ble_mesh_cfg_server_cb_t)(esp_ble_mesh_cfg_server_cb_event_t event,
esp_ble_mesh_cfg_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Config Client Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_config_client_callback(esp_ble_mesh_cfg_client_cb_t callback);
/**
* @brief Register BLE Mesh Config Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_config_server_callback(esp_ble_mesh_cfg_server_cb_t callback);
/**
* @brief Get the value of Config Server Model states using the Config Client Model get messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_opcode_config_client_get_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to a union, each kind of opcode corresponds to one structure inside.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_config_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_cfg_client_get_state_t *get_state);
/**
* @brief Set the value of the Configuration Server Model states using the Config Client Model set messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_opcode_config_client_set_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to a union, each kind of opcode corresponds to one structure inside.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_config_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_cfg_client_set_state_t *set_state);
#endif /** _ESP_BLE_MESH_CONFIG_MODEL_API_H_ */

View File

@@ -0,0 +1,478 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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
* @brief Bluetooth Mesh Generic Client Model APIs.
*/
#ifndef _ESP_BLE_MESH_GENERIC_MODEL_API_H_
#define _ESP_BLE_MESH_GENERIC_MODEL_API_H_
#include "generic_client.h"
#include "esp_ble_mesh_defs.h"
/** @def ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI
*
* @brief Define a new Generic OnOff Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Generic OnOff Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Generic OnOff Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_GEN_LEVEL_CLI
*
* @brief Define a new Generic Level Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Generic Level Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Generic Level Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_LEVEL_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LEVEL_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_CLI
*
* @brief Define a new Generic Default Transition Time Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Generic Default Transition
* Time Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Generic Default Transition Time Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_CLI
*
* @brief Define a new Generic Power OnOff Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Generic Power OnOff Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Generic Power OnOff Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_CLI
*
* @brief Define a new Generic Power Level Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Generic Power Level Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Generic Power Level Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_GEN_BATTERY_CLI
*
* @brief Define a new Generic Battery Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Generic Battery Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Generic Battery Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_BATTERY_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_BATTERY_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_CLI
*
* @brief Define a new Generic Location Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Generic Location Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Generic Location Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_LOCATION_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_GEN_PROPERTY_CLI
*
* @brief Define a new Generic Property Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Generic Property Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Generic Location Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_GEN_PROPERTY_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_PROP_CLI, \
NULL, cli_pub, cli_data)
/**
* @brief Bluetooth Mesh Generic Client Model Get and Set parameters structure.
*/
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
uint8_t onoff; /* Target value of Generic OnOff state */
uint8_t tid; /* Transaction ID */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_gen_onoff_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
int16_t level; /* Target value of Generic Level state */
uint8_t tid; /* Transaction ID */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_gen_level_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
int32_t level; /* Delta change of Generic Level state */
uint8_t tid; /* Transaction ID */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_gen_delta_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
int16_t delta_level;/* Delta Level step to calculate Move speed for Generic Level state */
uint8_t tid; /* Transaction ID */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_gen_move_set_t;
typedef struct {
uint8_t trans_time; /* The value of the Generic Default Transition Time state */
} esp_ble_mesh_gen_def_trans_time_set_t;
typedef struct {
uint8_t onpowerup; /* The value of the Generic OnPowerUp state */
} esp_ble_mesh_gen_onpowerup_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
uint16_t power; /* Target value of Generic Power Actual state */
uint8_t tid; /* Transaction ID */
uint8_t trans_time; /* Time to complete state transition (optional) */
uint8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_gen_power_level_set_t;
typedef struct {
uint16_t power; /* The value of the Generic Power Default state */
} esp_ble_mesh_gen_power_default_set_t;
typedef struct {
uint16_t range_min; /* Value of Range Min field of Generic Power Range state */
uint16_t range_max; /* Value of Range Max field of Generic Power Range state */
} esp_ble_mesh_gen_power_range_set_t;
typedef struct {
int32_t global_latitude; /* Global Coordinates (Latitude) */
int32_t global_longitude; /* Global Coordinates (Longitude) */
int16_t global_altitude; /* Global Altitude */
} esp_ble_mesh_gen_loc_global_set_t;
typedef struct {
int16_t local_north; /* Local Coordinates (North) */
int16_t local_east; /* Local Coordinates (East) */
int16_t local_altitude; /* Local Altitude */
uint8_t floor_number; /* Floor Number */
uint16_t uncertainty; /* Uncertainty */
} esp_ble_mesh_gen_loc_local_set_t;
typedef struct {
uint16_t property_id; /* Property ID identifying a Generic User Property */
} esp_ble_mesh_gen_user_property_get_t;
typedef struct {
uint16_t property_id; /* Property ID identifying a Generic User Property */
struct net_buf_simple *property_value; /* Raw value for the User Property */
} esp_ble_mesh_gen_user_property_set_t;
typedef struct {
uint16_t property_id; /* Property ID identifying a Generic Admin Property */
} esp_ble_mesh_gen_admin_property_get_t;
typedef struct {
uint16_t property_id; /* Property ID identifying a Generic Admin Property */
uint8_t user_access; /* Enumeration indicating user access */
struct net_buf_simple *property_value; /* Raw value for the Admin Property */
} esp_ble_mesh_gen_admin_property_set_t;
typedef struct {
uint16_t property_id; /* Property ID identifying a Generic Manufacturer Property */
} esp_ble_mesh_gen_manufacturer_property_get_t;
typedef struct {
uint16_t property_id; /* Property ID identifying a Generic Manufacturer Property */
uint8_t user_access; /* Enumeration indicating user access */
} esp_ble_mesh_gen_manufacturer_property_set_t;
typedef struct {
uint16_t property_id; /* A starting Client Property ID present within an element */
} esp_ble_mesh_gen_client_properties_get_t;
typedef union {
esp_ble_mesh_gen_user_property_get_t user_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET */
esp_ble_mesh_gen_admin_property_get_t admin_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET*/
esp_ble_mesh_gen_manufacturer_property_get_t manufacturer_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET */
esp_ble_mesh_gen_client_properties_get_t client_properties_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET */
} esp_ble_mesh_generic_client_get_state_t;
typedef union {
esp_ble_mesh_gen_onoff_set_t onoff_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET & ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK */
esp_ble_mesh_gen_level_set_t level_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK */
esp_ble_mesh_gen_delta_set_t delta_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DELTA_SET & ESP_BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK */
esp_ble_mesh_gen_move_set_t move_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MOVE_SET & ESP_BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK */
esp_ble_mesh_gen_def_trans_time_set_t def_trans_time_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET & ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK */
esp_ble_mesh_gen_onpowerup_set_t power_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET & ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK */
esp_ble_mesh_gen_power_level_set_t power_level_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK */
esp_ble_mesh_gen_power_default_set_t power_default_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK */
esp_ble_mesh_gen_power_range_set_t power_range_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK */
esp_ble_mesh_gen_loc_global_set_t loc_global_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK */
esp_ble_mesh_gen_loc_local_set_t loc_local_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK */
esp_ble_mesh_gen_user_property_set_t user_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK */
esp_ble_mesh_gen_admin_property_set_t admin_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK */
esp_ble_mesh_gen_manufacturer_property_set_t manufacturer_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET_UNACK */
} esp_ble_mesh_generic_client_set_state_t;
/**
* @brief Bluetooth Mesh Generic Client Model Get and Set callback parameters structure.
*/
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
uint8_t present_onoff; /* Current value of Generic OnOff state */
uint8_t target_onoff; /* Target value of Generic OnOff state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_gen_onoff_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
int16_t present_level; /* Current value of Generic Level state */
int16_t target_level; /* Target value of the Generic Level state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_gen_level_status_cb_t;
typedef struct {
uint8_t trans_time; /* The value of the Generic Default Transition Time state */
} esp_ble_mesh_gen_def_trans_time_status_cb_t;
typedef struct {
uint8_t onpowerup; /* The value of the Generic OnPowerUp state */
} esp_ble_mesh_gen_onpowerup_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
uint16_t present_power; /* Current value of Generic Power Actual state */
uint16_t target_power; /* Target value of Generic Power Actual state (optional) */
uint8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_gen_power_level_status_cb_t;
typedef struct {
uint16_t power; /* The value of the Generic Power Last state */
} esp_ble_mesh_gen_power_last_status_cb_t;
typedef struct {
uint16_t power; /* The value of the Generic Default Last state */
} esp_ble_mesh_gen_power_default_status_cb_t;
typedef struct {
uint8_t status_code; /* Status Code for the request message */
uint16_t range_min; /* Value of Range Min field of Generic Power Range state */
uint16_t range_max; /* Value of Range Max field of Generic Power Range state */
} esp_ble_mesh_gen_power_range_status_cb_t;
typedef struct {
u32_t battery_level : 8; /* Value of Generic Battery Level state */
u32_t time_to_discharge : 24; /* Value of Generic Battery Time to Discharge state */
u32_t time_to_charge : 24; /* Value of Generic Battery Time to Charge state */
u32_t flags : 8; /* Value of Generic Battery Flags state */
} esp_ble_mesh_gen_battery_status_cb_t;
typedef struct {
int32_t global_latitude; /* Global Coordinates (Latitude) */
int32_t global_longitude; /* Global Coordinates (Longitude) */
int16_t global_altitude; /* Global Altitude */
} esp_ble_mesh_gen_loc_global_status_cb_t;
typedef struct {
int16_t local_north; /* Local Coordinates (North) */
int16_t local_east; /* Local Coordinates (East) */
int16_t local_altitude; /* Local Altitude */
uint8_t floor_number; /* Floor Number */
uint16_t uncertainty; /* Uncertainty */
} esp_ble_mesh_gen_loc_local_status_cb_t;
typedef struct {
struct net_buf_simple *property_ids; /* Buffer contains a sequence of N User Property IDs */
} esp_ble_mesh_gen_user_properties_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
uint16_t property_id; /* Property ID identifying a Generic User Property */
uint8_t user_access; /* Enumeration indicating user access (optional) */
struct net_buf_simple *property_value; /* Raw value for the User Property (C.1) */
} esp_ble_mesh_gen_user_property_status_cb_t;
typedef struct {
struct net_buf_simple *property_ids; /* Buffer contains a sequence of N Admin Property IDs */
} esp_ble_mesh_gen_admin_properties_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
uint16_t property_id; /* Property ID identifying a Generic Admin Property */
uint8_t user_access; /* Enumeration indicating user access (optional) */
struct net_buf_simple *property_value; /* Raw value for the Admin Property (C.1) */
} esp_ble_mesh_gen_admin_property_status_cb_t;
typedef struct {
struct net_buf_simple *property_ids; /* Buffer contains a sequence of N Manufacturer Property IDs */
} esp_ble_mesh_gen_manufacturer_properties_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
uint16_t property_id; /* Property ID identifying a Generic Manufacturer Property */
uint8_t user_access; /* Enumeration indicating user access (optional) */
struct net_buf_simple *property_value; /* Raw value for the Manufacturer Property (C.1) */
} esp_ble_mesh_gen_manufacturer_property_status_cb_t;
typedef struct {
struct net_buf_simple *property_ids; /* Buffer contains a sequence of N Client Property IDs */
} esp_ble_mesh_gen_client_properties_status_cb_t;
typedef union {
esp_ble_mesh_gen_onoff_status_cb_t onoff_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS */
esp_ble_mesh_gen_level_status_cb_t level_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS */
esp_ble_mesh_gen_def_trans_time_status_cb_t def_trans_time_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS */
esp_ble_mesh_gen_onpowerup_status_cb_t onpowerup_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS */
esp_ble_mesh_gen_power_level_status_cb_t power_level_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS */
esp_ble_mesh_gen_power_last_status_cb_t power_last_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS */
esp_ble_mesh_gen_power_default_status_cb_t power_default_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS */
esp_ble_mesh_gen_power_range_status_cb_t power_range_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS */
esp_ble_mesh_gen_battery_status_cb_t battery_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS */
esp_ble_mesh_gen_loc_global_status_cb_t location_global_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS */
esp_ble_mesh_gen_loc_local_status_cb_t location_local_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS */
esp_ble_mesh_gen_user_properties_status_cb_t user_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS */
esp_ble_mesh_gen_user_property_status_cb_t user_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS */
esp_ble_mesh_gen_admin_properties_status_cb_t admin_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS */
esp_ble_mesh_gen_admin_property_status_cb_t admin_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS */
esp_ble_mesh_gen_manufacturer_properties_status_cb_t manufacturer_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_STATUS */
esp_ble_mesh_gen_manufacturer_property_status_cb_t manufacturer_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_STATUS */
esp_ble_mesh_gen_client_properties_status_cb_t client_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS */
} esp_ble_mesh_gen_client_status_cb_t;
typedef struct {
int error_code; /*!< Appropriate error code */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
esp_ble_mesh_gen_client_status_cb_t status_cb; /*!< The generic status message callback values */
} esp_ble_mesh_generic_client_cb_param_t;
typedef enum {
ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_GENERIC_CLIENT_EVT_MAX,
} esp_ble_mesh_generic_client_cb_event_t;
/**
* @brief Bluetooth Mesh Generic Client Model function.
*/
/** @brief: event, event code of Generic Client Model events; param, parameters of Generic Client Model events */
typedef void (* esp_ble_mesh_generic_client_cb_t)(esp_ble_mesh_generic_client_cb_event_t event,
esp_ble_mesh_generic_client_cb_param_t *param);
/**
* @brief Register BLE Mesh Generic Client Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_client_cb_t callback);
/**
* @brief Get the value of Generic Server Model states using the Generic Client Model get messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_generic_message_opcode_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to generic get message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_generic_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_generic_client_get_state_t *get_state);
/**
* @brief Set the value of Generic Server Model states using the Generic Client Model set messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_generic_message_opcode_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to generic set message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_generic_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_generic_client_set_state_t *set_state);
#endif /* _ESP_BLE_MESH_GENERIC_MODEL_API_H_ */

View File

@@ -0,0 +1,261 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _ESP_BLE_MESH_HEALTH_MODEL_API_H_
#define _ESP_BLE_MESH_HEALTH_MODEL_API_H_
#include "esp_ble_mesh_defs.h"
/** @def ESP_BLE_MESH_MODEL_HEALTH_SRV
*
* @brief Define a new Health Server Model.
*
* @note The Health Server Model can only be included by a Primary Element.
*
* @param srv Pointer to the unique struct esp_ble_mesh_health_srv_t.
* @param pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
*
* @return New Health Server Model instance.
*/
#define ESP_BLE_MESH_MODEL_HEALTH_SRV(srv, pub) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_HEALTH_SRV, \
NULL, pub, srv)
/** @def ESP_BLE_MESH_MODEL_HEALTH_CLI
*
* @brief Define a new Health Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Health Client Model.
*
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Health Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_HEALTH_CLI(cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_HEALTH_CLI, \
NULL, NULL, cli_data)
typedef struct {
/* Fetch current faults */
int (*fault_get_cur)(esp_ble_mesh_model_t *model, uint8_t *test_id,
uint16_t *company_id, uint8_t *faults, uint8_t *fault_count);
/* Fetch registered faults */
int (*fault_get_reg)(esp_ble_mesh_model_t *model, uint16_t company_id,
uint8_t *test_id, uint8_t *faults, uint8_t *fault_count);
/* Clear registered faults */
int (*fault_clear)(esp_ble_mesh_model_t *model, uint16_t company_id);
/* Run a specific test */
int (*fault_test)(esp_ble_mesh_model_t *model, uint8_t test_id, uint16_t company_id);
/* Attention on */
void (*attn_on)(esp_ble_mesh_model_t *model);
/* Attention off */
void (*attn_off)(esp_ble_mesh_model_t *model);
} esp_ble_mesh_health_srv_cb_t;
/** ESP BLE Mesh Health Server Model Context */
typedef struct {
esp_ble_mesh_model_t *model;
/* Optional callback struct */
const esp_ble_mesh_health_srv_cb_t *cb;
/* Attention Timer state */
struct k_delayed_work attn_timer;
} esp_ble_mesh_health_srv_t;
/** BLE Mesh Health Client Model fault get Context */
typedef struct {
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
} esp_ble_mesh_health_fault_get_t;
/** Mesh Health Client Model attention set Context */
typedef struct {
uint8_t attention; /*!< Value of the Attention Timer state */
} esp_ble_mesh_health_attention_set_t;
/** Mesh Health client Model period set Context */
typedef struct {
uint8_t fast_period_divisor; /*!< Divider for the Publish Period */
} esp_ble_mesh_health_period_set_t;
/** BLE Mesh Health Client Model fault test Context */
typedef struct {
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
uint8_t test_id; /*!< ID of a specific test to be performed */
} esp_ble_mesh_health_fault_test_t;
/** BLE Mesh Health Client Model fault clear Context */
typedef struct {
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
} esp_ble_mesh_health_fault_clear_t;
/**
* @brief For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_GET
* ESP_BLE_MESH_MODEL_OP_ATTENTION_GET
* ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_GET
* the get_state parameter in the esp_ble_mesh_health_client_get_state function should not be set to NULL.
*/
typedef union {
esp_ble_mesh_health_fault_get_t fault_get; /*!< For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_GET. */
} esp_ble_mesh_health_client_get_state_t;
/**
* @brief For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR
* ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR_UNACK
* ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST
* ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST_UNACK
* ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET
* ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET_UNACK
* ESP_BLE_MESH_MODEL_OP_ATTENTION_SET
* ESP_BLE_MESH_MODEL_OP_ATTENTION_SET_UNACK
* the set_state parameter in the esp_ble_mesh_health_client_set_state function should not be set to NULL.
*/
typedef union {
esp_ble_mesh_health_attention_set_t attention_set; /*!< For ESP_BLE_MESH_MODEL_OP_ATTENTION_SET or ESP_BLE_MESH_MODEL_OP_ATTENTION_SET_UNACK. */
esp_ble_mesh_health_period_set_t period_set; /*!< For ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET or ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET_UNACK. */
esp_ble_mesh_health_fault_test_t fault_test; /*!< For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST or ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST_UNACK. */
esp_ble_mesh_health_fault_clear_t fault_clear; /*!< For ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR or ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR_UNACK. */
} esp_ble_mesh_health_client_set_state_t;
typedef struct {
uint8_t test_id; /*!< ID of a most recently performed test */
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
struct net_buf_simple *fault_array; /*!< FaultArray field contains a sequence of 1-octet fault values */
} esp_ble_mesh_health_current_status_cb_t;
typedef struct {
uint8_t test_id; /*!< ID of a most recently performed test */
uint16_t company_id; /*!< Bluetooth assigned 16-bit Company ID */
struct net_buf_simple *fault_array; /*!< FaultArray field contains a sequence of 1-octet fault values */
} esp_ble_mesh_health_fault_status_cb_t;
typedef struct {
uint8_t fast_period_divisor; /*!< Divider for the Publish Period */
} esp_ble_mesh_health_period_status_cb_t;
typedef struct {
uint8_t attention; /*!< Value of the Attention Timer state */
} esp_ble_mesh_health_attention_status_cb_t;
typedef union {
esp_ble_mesh_health_current_status_cb_t current_status; /*!< The health current status value */
esp_ble_mesh_health_fault_status_cb_t fault_status; /*!< The health fault status value */
esp_ble_mesh_health_period_status_cb_t period_status; /*!< The health period status value */
esp_ble_mesh_health_attention_status_cb_t attention_status; /*!< The health attention status value */
} esp_ble_mesh_health_client_common_cb_param_t;
typedef struct {
int error_code; /*!< Appropriate error code */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
esp_ble_mesh_health_client_common_cb_param_t status_cb; /*!< The health message status callback values */
} esp_ble_mesh_health_client_cb_param_t;
typedef enum {
ESP_BLE_MESH_HEALTH_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_HEALTH_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_HEALTH_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_HEALTH_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_HEALTH_CLIENT_EVT_MAX,
} esp_ble_mesh_health_client_cb_event_t;
typedef struct {
int error_code; /*!< Appropriate error code */
} esp_ble_mesh_health_server_cb_param_t;
typedef enum {
ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT,
ESP_BLE_MESH_HEALTH_SERVER_EVT_MAX,
} esp_ble_mesh_health_server_cb_event_t;
/**
* @brief Bluetooth Mesh Health Client and Server Model function.
*/
/** @brief: event, event code of Health Client Model event; param, parameters of Health Client Model event) */
typedef void (* esp_ble_mesh_health_client_cb_t)(esp_ble_mesh_health_client_cb_event_t event,
esp_ble_mesh_health_client_cb_param_t *param);
/** @brief: event, event code of Health Server Model event; param, parameters of Health Server Model event) */
typedef void (* esp_ble_mesh_health_server_cb_t)(esp_ble_mesh_health_server_cb_event_t event,
esp_ble_mesh_health_server_cb_param_t *param);
/**
* @brief Register BLE Mesh Health Model callback, the callback will report Health Client & Server Model events.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_health_client_callback(esp_ble_mesh_health_client_cb_t callback);
/**
* @brief Register BLE Mesh Health Server Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_health_server_callback(esp_ble_mesh_health_server_cb_t callback);
/**
* @brief This function is called to get the Health Server states using the Health Client Model get messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_opcode_health_client_get_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to a union, each kind of opcode corresponds to one structure inside.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_health_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_get_state_t *get_state);
/**
* @brief This function is called to set the Health Server states using the Health Client Model set messages.
*
* @note If you want to find the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_opcode_health_client_set_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to a union, each kind of opcode corresponds to one structure inside.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_health_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_set_state_t *set_state);
/**
* @brief This function is called by the Health Server Model to start to publish its Current Health Fault.
*
* @param[in] element: The element to which the Health Server Model belongs.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_health_server_fault_update(esp_ble_mesh_elem_t *element);
#endif /** _ESP_BLE_MESH_HEALTH_MODEL_API_H_ */

View File

@@ -0,0 +1,526 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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
* @brief Bluetooth Mesh Light Client Model APIs.
*/
#ifndef _ESP_BLE_MESH_LIGHTING_MODEL_API_H_
#define _ESP_BLE_MESH_LIGHTING_MODEL_API_H_
#include "light_client.h"
#include "esp_ble_mesh_defs.h"
/** @def ESP_BLE_MESH_MODEL_LIGHT_LIGHTNESS_CLI
*
* @brief Define a new Light Lightness Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Light Lightness Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Light Lightness Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_LIGHT_LIGHTNESS_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_LIGHT_CTL_CLI
*
* @brief Define a new Light CTL Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Light CTL Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Light CTL Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_LIGHT_CTL_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_LIGHT_CTL_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_LIGHT_HSL_CLI
*
* @brief Define a new Light HSL Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Light HSL Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Light HSL Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_LIGHT_HSL_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_LIGHT_HSL_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_LIGHT_XYL_CLI
*
* @brief Define a new Light xyL Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Light xyL Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Light xyL Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_LIGHT_XYL_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_LIGHT_XYL_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_LIGHT_LC_CLI
*
* @brief Define a new Light LC Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Light LC Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Light LC Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_LIGHT_LC_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_LIGHT_LC_CLI, \
NULL, cli_pub, cli_data)
/**
* @brief Bluetooth Mesh Light Lightness Client Model Get and Set parameters structure.
*/
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t lightness; /* Target value of light lightness actual state */
u8_t tid; /* Transaction ID */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_lightness_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t lightness; /* Target value of light lightness linear state */
u8_t tid; /* Transaction ID */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_lightness_linear_set_t;
typedef struct {
u16_t lightness; /* The value of the Light Lightness Default state */
} esp_ble_mesh_light_lightness_default_set_t;
typedef struct {
u16_t range_min; /* Value of range min field of light lightness range state */
u16_t range_max; /* Value of range max field of light lightness range state */
} esp_ble_mesh_light_lightness_range_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t ctl_lightness; /* Target value of light ctl lightness state */
u16_t ctl_temperatrue; /* Target value of light ctl temperature state */
s16_t ctl_delta_uv; /* Target value of light ctl delta UV state */
u8_t tid; /* Transaction ID */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_ctl_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t ctl_temperatrue; /* Target value of light ctl temperature state */
s16_t ctl_delta_uv; /* Target value of light ctl delta UV state */
u8_t tid; /* Transaction ID */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_ctl_temperature_set_t;
typedef struct {
u16_t range_min; /* Value of temperature range min field of light ctl temperature range state */
u16_t range_max; /* Value of temperature range max field of light ctl temperature range state */
} esp_ble_mesh_light_ctl_temperature_range_set_t;
typedef struct {
u16_t lightness; /* Value of light lightness default state */
u16_t temperature; /* Value of light temperature default state */
s16_t delta_uv; /* Value of light delta UV default state */
} esp_ble_mesh_light_ctl_default_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t hsl_lightness; /* Target value of light hsl lightness state */
u16_t hsl_hue; /* Target value of light hsl hue state */
u16_t hsl_saturation; /* Target value of light hsl saturation state */
u8_t tid; /* Transaction ID */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_hsl_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t hue; /* Target value of light hsl hue state */
u8_t tid; /* Transaction ID */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_hsl_hue_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t saturation; /* Target value of light hsl hue state */
u8_t tid; /* Transaction ID */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_hsl_saturation_set_t;
typedef struct {
u16_t lightness; /* Value of light lightness default state */
u16_t hue; /* Value of light hue default state */
u16_t saturation; /* Value of light saturation default state */
} esp_ble_mesh_light_hsl_default_set_t;
typedef struct {
u16_t hue_range_min; /* Value of hue range min field of light hsl hue range state */
u16_t hue_range_max; /* Value of hue range max field of light hsl hue range state */
u16_t saturation_range_min; /* Value of saturation range min field of light hsl saturation range state */
u16_t saturation_range_max; /* Value of saturation range max field of light hsl saturation range state */
} esp_ble_mesh_light_hsl_range_set_t;
typedef struct {
bool op_en; /* Indicate whether optional parameters included */
u16_t xyl_lightness; /* The target value of the Light xyL Lightness state */
u16_t xyl_x; /* The target value of the Light xyL x state */
u16_t xyl_y; /* The target value of the Light xyL y state */
u8_t tid; /* Transaction Identifier */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_xyl_set_t;
typedef struct {
u16_t lightness; /* The value of the Light Lightness Default state */
u16_t xyl_x; /* The value of the Light xyL x Default state */
u16_t xyl_y; /* The value of the Light xyL y Default state */
} esp_ble_mesh_light_xyl_default_set_t;
typedef struct {
u16_t xyl_x_range_min; /* The value of the xyL x Range Min field of the Light xyL x Range state */
u16_t xyl_x_range_max; /* The value of the xyL x Range Max field of the Light xyL x Range state */
u16_t xyl_y_range_min; /* The value of the xyL y Range Min field of the Light xyL y Range state */
u16_t xyl_y_range_max; /* The value of the xyL y Range Max field of the Light xyL y Range state */
} esp_ble_mesh_light_xyl_range_set_t;
typedef struct {
u8_t mode; /* The target value of the Light LC Mode state */
} esp_ble_mesh_light_lc_mode_set_t;
typedef struct {
u8_t mode; /* The target value of the Light LC Occupancy Mode state */
} esp_ble_mesh_light_lc_om_set_t;
typedef struct {
bool op_en; /* Indicate whether optional parameters included */
u8_t light_onoff; /* The target value of the Light LC Light OnOff state */
u8_t tid; /* Transaction Identifier */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_light_lc_light_onoff_set_t;
typedef struct {
u16_t property_id; /* Property ID identifying a Light LC Property */
} esp_ble_mesh_light_lc_property_get_t;
typedef struct {
u16_t property_id; /* Property ID identifying a Light LC Property */
struct net_buf_simple *property_value; /* Raw value for the Light LC Property */
} esp_ble_mesh_light_lc_property_set_t;
typedef union {
esp_ble_mesh_light_lc_property_get_t lc_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET */
} esp_ble_mesh_light_client_get_state_t;
typedef union {
esp_ble_mesh_light_lightness_set_t lightness_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_SET_UNACK */
esp_ble_mesh_light_lightness_linear_set_t lightness_linear_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_SET_UNACK */
esp_ble_mesh_light_lightness_default_set_t lightness_default_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_SET_UNACK */
esp_ble_mesh_light_lightness_range_set_t lightness_range_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_SET_UNACK */
esp_ble_mesh_light_ctl_set_t ctl_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_SET_UNACK */
esp_ble_mesh_light_ctl_temperature_set_t ctl_temperature_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_SET_UNACK */
esp_ble_mesh_light_ctl_temperature_range_set_t ctl_temperature_range_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_SET_UNACK */
esp_ble_mesh_light_ctl_default_set_t ctl_default_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_SET_UNACK */
esp_ble_mesh_light_hsl_set_t hsl_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_SET_UNACK */
esp_ble_mesh_light_hsl_hue_set_t hsl_hue_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_SET_UNACK */
esp_ble_mesh_light_hsl_saturation_set_t hsl_saturation_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_SET_UNACK */
esp_ble_mesh_light_hsl_default_set_t hsl_default_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_SET_UNACK */
esp_ble_mesh_light_hsl_range_set_t hsl_range_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_SET_UNACK */
esp_ble_mesh_light_xyl_set_t xyl_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_SET_UNACK */
esp_ble_mesh_light_xyl_default_set_t xyl_default_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_SET_UNACK */
esp_ble_mesh_light_xyl_range_set_t xyl_range_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_SET_UNACK */
esp_ble_mesh_light_lc_mode_set_t lc_mode_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_LC_MODE_SET_UNACK */
esp_ble_mesh_light_lc_om_set_t lc_om_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_LC_OM_SET_UNACK */
esp_ble_mesh_light_lc_light_onoff_set_t lc_light_onoff_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_SET_UNACK */
esp_ble_mesh_light_lc_property_set_t lc_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET_UNACK */
} esp_ble_mesh_light_client_set_state_t;
/**
* @brief Bluetooth Mesh Light Lightness Client Model Get and Set callback parameters structure.
*/
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t present_lightness; /* Current value of light lightness actual state */
u16_t target_lightness; /* Target value of light lightness actual state (optional) */
u8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_light_lightness_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t present_lightness; /* Current value of light lightness linear state */
u16_t target_lightness; /* Target value of light lightness linear state (optional) */
u8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_light_lightness_linear_status_cb_t;
typedef struct {
u16_t lightness; /* The value of the Light Lightness Last state */
} esp_ble_mesh_light_lightness_last_status_cb_t;
typedef struct {
u16_t lightness; /* The value of the Light Lightness default State */
} esp_ble_mesh_light_lightness_default_status_cb_t;
typedef struct {
u8_t status_code; /* Status Code for the request message */
u16_t range_min; /* Value of range min field of light lightness range state */
u16_t range_max; /* Value of range max field of light lightness range state */
} esp_ble_mesh_light_lightness_range_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t present_ctl_lightness; /* Current value of light ctl lightness state */
u16_t present_ctl_temperature; /* Current value of light ctl temperature state */
u16_t target_ctl_lightness; /* Target value of light ctl lightness state (optional) */
u16_t target_ctl_temperature; /* Target value of light ctl temperature state (C.1) */
u8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_light_ctl_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t present_ctl_temperature; /* Current value of light ctl temperature state */
u16_t present_ctl_delta_uv; /* Current value of light ctl delta UV state */
u16_t target_ctl_temperature; /* Target value of light ctl temperature state (optional) */
u16_t target_ctl_delta_uv; /* Target value of light ctl delta UV state (C.1) */
u8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_light_ctl_temperature_status_cb_t;
typedef struct {
u8_t status_code; /* Status code for the request message */
u16_t range_min; /* Value of temperature range min field of light ctl temperature range state */
u16_t range_max; /* Value of temperature range max field of light ctl temperature range state */
} esp_ble_mesh_light_ctl_temperature_range_status_cb_t;
typedef struct {
u16_t lightness; /* Value of light lightness default state */
u16_t temperature; /* Value of light temperature default state */
s16_t delta_uv; /* Value of light delta UV default state */
} esp_ble_mesh_light_ctl_default_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t hsl_lightness; /* Current value of light hsl lightness state */
u16_t hsl_hue; /* Current value of light hsl hue state */
u16_t hsl_saturation; /* Current value of light hsl saturation state */
u8_t remain_time; /* Time to complete state transition (optional) */
} esp_ble_mesh_light_hsl_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t hsl_lightness_target; /* Target value of light hsl lightness state */
u16_t hsl_hue_target; /* Target value of light hsl hue state */
u16_t hsl_saturation_target; /* Target value of light hsl saturation state */
u8_t remain_time; /* Time to complete state transition (optional) */
} esp_ble_mesh_light_hsl_target_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t present_hue; /* Current value of light hsl hue state */
u16_t target_hue; /* Target value of light hsl hue state (optional) */
u8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_light_hsl_hue_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t present_saturation; /* Current value of light hsl saturation state */
u16_t target_saturation; /* Target value of light hsl saturation state (optional) */
u8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_light_hsl_saturation_status_cb_t;
typedef struct {
u16_t lightness; /* Value of light lightness default state */
u16_t hue; /* Value of light hue default state */
u16_t saturation; /* Value of light saturation default state */
} esp_ble_mesh_light_hsl_default_status_cb_t;
typedef struct {
u8_t status_code; /* Status code for the request message */
u16_t hue_range_min; /* Value of hue range min field of light hsl hue range state */
u16_t hue_range_max; /* Value of hue range max field of light hsl hue range state */
u16_t saturation_range_min; /* Value of saturation range min field of light hsl saturation range state */
u16_t saturation_range_max; /* Value of saturation range max field of light hsl saturation range state */
} esp_ble_mesh_light_hsl_range_status_cb_t;
typedef struct {
bool op_en; /* Indicate whether optional parameters included */
u16_t xyl_lightness; /* The present value of the Light xyL Lightness state */
u16_t xyl_x; /* The present value of the Light xyL x state */
u16_t xyl_y; /* The present value of the Light xyL y state */
u8_t remain_time; /* Time to complete state transition (optional) */
} esp_ble_mesh_light_xyl_status_cb_t;
typedef struct {
bool op_en; /* Indicate whether optional parameters included */
u16_t target_xyl_lightness; /* The target value of the Light xyL Lightness state */
u16_t target_xyl_x; /* The target value of the Light xyL x state */
u16_t target_xyl_y; /* The target value of the Light xyL y state */
u8_t remain_time; /* Time to complete state transition (optional) */
} esp_ble_mesh_light_xyl_target_status_cb_t;
typedef struct {
u16_t lightness; /* The value of the Light Lightness Default state */
u16_t xyl_x; /* The value of the Light xyL x Default state */
u16_t xyl_y; /* The value of the Light xyL y Default state */
} esp_ble_mesh_light_xyl_default_status_cb_t;
typedef struct {
u8_t status_code; /* Status Code for the requesting message */
u16_t xyl_x_range_min; /* The value of the xyL x Range Min field of the Light xyL x Range state */
u16_t xyl_x_range_max; /* The value of the xyL x Range Max field of the Light xyL x Range state */
u16_t xyl_y_range_min; /* The value of the xyL y Range Min field of the Light xyL y Range state */
u16_t xyl_y_range_max; /* The value of the xyL y Range Max field of the Light xyL y Range state */
} esp_ble_mesh_light_xyl_range_status_cb_t;
typedef struct {
u8_t mode; /* The present value of the Light LC Mode state */
} esp_ble_mesh_light_lc_mode_status_cb_t;
typedef struct {
u8_t mode; /* The present value of the Light LC Occupancy Mode state */
} esp_ble_mesh_light_lc_om_status_cb_t;
typedef struct {
bool op_en; /* Indicate whether optional parameters included */
u8_t present_light_onoff; /* The present value of the Light LC Light OnOff state */
u8_t target_light_onoff; /* The target value of the Light LC Light OnOff state (Optional) */
u8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_light_lc_light_onoff_status_cb_t;
typedef struct {
u16_t property_id; /* Property ID identifying a Light LC Property */
struct net_buf_simple *property_value; /* Raw value for the Light LC Property */
} esp_ble_mesh_light_lc_property_status_cb_t;
typedef union {
esp_ble_mesh_light_lightness_status_cb_t lightness_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_STATUS */
esp_ble_mesh_light_lightness_linear_status_cb_t lightness_linear_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LINEAR_STATUS */
esp_ble_mesh_light_lightness_last_status_cb_t lightness_last_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_LAST_STATUS */
esp_ble_mesh_light_lightness_default_status_cb_t lightness_default_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_DEFAULT_STATUS */
esp_ble_mesh_light_lightness_range_status_cb_t lightness_range_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LIGHTNESS_RANGE_STATUS */
esp_ble_mesh_light_ctl_status_cb_t ctl_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_STATUS */
esp_ble_mesh_light_ctl_temperature_status_cb_t ctl_temperature_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_STATUS */
esp_ble_mesh_light_ctl_temperature_range_status_cb_t ctl_temperature_range_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_TEMPERATURE_RANGE_STATUS */
esp_ble_mesh_light_ctl_default_status_cb_t ctl_default_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_CTL_DEFAULT_STATUS */
esp_ble_mesh_light_hsl_status_cb_t hsl_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_STATUS */
esp_ble_mesh_light_hsl_target_status_cb_t hsl_target_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_TARGET_STATUS */
esp_ble_mesh_light_hsl_hue_status_cb_t hsl_hue_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_HUE_STATUS */
esp_ble_mesh_light_hsl_saturation_status_cb_t hsl_saturation_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_SATURATION_STATUS */
esp_ble_mesh_light_hsl_default_status_cb_t hsl_default_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_DEFAULT_STATUS */
esp_ble_mesh_light_hsl_range_status_cb_t hsl_range_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_HSL_RANGE_STATUS */
esp_ble_mesh_light_xyl_status_cb_t xyl_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_STATUS */
esp_ble_mesh_light_xyl_target_status_cb_t xyl_target_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_TARGET_STATUS */
esp_ble_mesh_light_xyl_default_status_cb_t xyl_default_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_DEFAULT_STATUS */
esp_ble_mesh_light_xyl_range_status_cb_t xyl_range_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_XYL_RANGE_STATUS */
esp_ble_mesh_light_lc_mode_status_cb_t lc_mode_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_MODE_STATUS */
esp_ble_mesh_light_lc_om_status_cb_t lc_om_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_OM_STATUS */
esp_ble_mesh_light_lc_light_onoff_status_cb_t lc_light_onoff_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_LIGHT_ONOFF_STATUS */
esp_ble_mesh_light_lc_property_status_cb_t lc_property_status; /*!< For ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS */
} esp_ble_mesh_light_client_status_cb_t;
typedef struct {
int error_code; /*!< Appropriate error code */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
esp_ble_mesh_light_client_status_cb_t status_cb; /*!< The light status message callback values */
} esp_ble_mesh_light_client_cb_param_t;
typedef enum {
ESP_BLE_MESH_LIGHT_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_LIGHT_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_LIGHT_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_LIGHT_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_LIGHT_CLIENT_EVT_MAX,
} esp_ble_mesh_light_client_cb_event_t;
/**
* @brief Bluetooth Mesh Light Client Model function.
*/
/** @brief: event, event code of Light Client Model events; param, parameters of Light Client Model events */
typedef void (* esp_ble_mesh_light_client_cb_t)(esp_ble_mesh_light_client_cb_event_t event,
esp_ble_mesh_light_client_cb_param_t *param);
/**
* @brief Register BLE Mesh Light Client Model callback.
*
* @param[in] callback: pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_light_client_callback(esp_ble_mesh_light_client_cb_t callback);
/**
* @brief Get the value of Light Server Model states using the Light Client Model get messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_light_message_opcode_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer of light get message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_light_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_light_client_get_state_t *get_state);
/**
* @brief Set the value of Light Server Model states using the Light Client Model set messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_light_message_opcode_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer of generic set message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_light_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_light_client_set_state_t *set_state);
#endif /* _ESP_BLE_MESH_LIGHTING_MODEL_API_H_ */

View File

@@ -0,0 +1,230 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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
* @brief Bluetooth Mesh Sensor Client Model APIs.
*/
#ifndef _ESP_BLE_MESH_SENSOR_MODEL_API_H_
#define _ESP_BLE_MESH_SENSOR_MODEL_API_H_
#include "sensor_client.h"
#include "esp_ble_mesh_defs.h"
/** @def ESP_BLE_MESH_MODEL_SENSOR_CLI
*
* @brief Define a new Sensor Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Sensor Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Sensor Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_SENSOR_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SENSOR_CLI, \
NULL, cli_pub, cli_data)
/**
* @brief Bluetooth Mesh Sensor Client Model Get and Set parameters structure.
*/
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t property_id; /* Property ID of a sensor (optional) */
} esp_ble_mesh_sensor_descriptor_get_t;
typedef struct {
u16_t property_id; /* Property ID of a sensor */
} esp_ble_mesh_sensor_cadence_get_t;
typedef struct {
u16_t property_id; /* Property ID for the sensor */
u8_t fast_cadence_period_divisor : 7, /* Divisor for the publish period */
status_trigger_type : 1; /* The unit and format of the Status Trigger Delta fields */
struct net_buf_simple *status_trigger_delta_down; /* Delta down value that triggers a status message */
struct net_buf_simple *status_trigger_delta_up; /* Delta up value that triggers a status message */
u8_t status_min_interval; /* Minimum interval between two consecutive Status messages */
struct net_buf_simple *fast_cadence_low; /* Low value for the fast cadence range */
struct net_buf_simple *fast_cadence_high; /* Fast value for the fast cadence range */
} esp_ble_mesh_sensor_cadence_set_t;
typedef struct {
u16_t sensor_property_id; /* Property ID of a sensor */
} esp_ble_mesh_sensor_settings_get_t;
typedef struct {
u16_t sensor_property_id; /* Property ID of a sensor */
u16_t sensor_setting_property_id; /* Setting ID identifying a setting within a sensor */
} esp_ble_mesh_sensor_setting_get_t;
typedef struct {
u16_t sensor_property_id; /* Property ID identifying a sensor */
u16_t sensor_setting_property_id; /* Setting ID identifying a setting within a sensor */
struct net_buf_simple *sensor_setting_raw; /* Raw value for the setting */
} esp_ble_mesh_sensor_setting_set_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t property_id; /* Property ID for the sensor (optional) */
} esp_ble_mesh_sensor_get_t;
typedef struct {
u16_t property_id; /* Property identifying a sensor */
struct net_buf_simple *raw_value_x; /* Raw value identifying a column */
} esp_ble_mesh_sensor_column_get_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t property_id; /* Property identifying a sensor */
struct net_buf_simple *raw_value_x1; /* Raw value identifying a starting column (optional) */
struct net_buf_simple *raw_value_x2; /* Raw value identifying an ending column (C.1) */
} esp_ble_mesh_sensor_series_get_t;
typedef union {
esp_ble_mesh_sensor_descriptor_get_t descriptor_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET */
esp_ble_mesh_sensor_cadence_get_t cadence_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET */
esp_ble_mesh_sensor_settings_get_t settings_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET */
esp_ble_mesh_sensor_setting_get_t setting_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_GET */
esp_ble_mesh_sensor_get_t sensor_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_GET */
esp_ble_mesh_sensor_column_get_t column_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET */
esp_ble_mesh_sensor_series_get_t series_get; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET */
} esp_ble_mesh_sensor_client_get_state_t;
typedef union {
esp_ble_mesh_sensor_cadence_set_t cadence_set; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET & ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET_UNACK */
esp_ble_mesh_sensor_setting_set_t setting_set; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET & ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET_UNACK */
} esp_ble_mesh_sensor_client_set_state_t;
/**
* @brief Bluetooth Mesh Sensor Client Model Get and Set callback parameters structure.
*/
typedef struct {
struct net_buf_simple *descriptor; /* Sequence of 8-octet sensor descriptors (optional) */
} esp_ble_mesh_sensor_descriptor_status_cb_t;
typedef struct {
u16_t property_id; /* Property for the sensor */
struct net_buf_simple *sensor_cadence_value; /* Value of sensor cadence state */
} esp_ble_mesh_sensor_cadence_status_cb_t;
typedef struct {
u16_t sensor_property_id; /* Property ID identifying a sensor */
struct net_buf_simple *sensor_setting_property_ids; /* A sequence of N sensor setting property IDs (optional) */
} esp_ble_mesh_sensor_settings_status_cb_t;
typedef struct {
bool op_en; /* Indicate id optional parameters are included */
u16_t sensor_property_id; /* Property ID identifying a sensor */
u16_t sensor_setting_property_id; /* Setting ID identifying a setting within a sensor */
u8_t sensor_setting_access; /* Read/Write access rights for the setting (optional) */
struct net_buf_simple *sensor_setting_raw; /* Raw value for the setting */
} esp_ble_mesh_sensor_setting_status_cb_t;
typedef struct {
struct net_buf_simple *marshalled_sensor_data; /* Value of sensor data state (optional) */
} esp_ble_mesh_sensor_status_cb_t;
typedef struct {
u16_t property_id; /* Property identifying a sensor and the Y axis */
struct net_buf_simple *sensor_column_value; /* Left values of sensor column status */
} esp_ble_mesh_sensor_column_status_cb_t;
typedef struct {
u16_t property_id; /* Property identifying a sensor and the Y axis */
struct net_buf_simple *sensor_series_value; /* Left values of sensor series status */
} esp_ble_mesh_sensor_series_status_cb_t;
typedef union {
esp_ble_mesh_sensor_descriptor_status_cb_t descriptor_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS */
esp_ble_mesh_sensor_cadence_status_cb_t cadence_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS */
esp_ble_mesh_sensor_settings_status_cb_t settings_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS */
esp_ble_mesh_sensor_setting_status_cb_t setting_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS */
esp_ble_mesh_sensor_status_cb_t sensor_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_STATUS */
esp_ble_mesh_sensor_column_status_cb_t column_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS */
esp_ble_mesh_sensor_series_status_cb_t series_status; /*!< For ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS */
} esp_ble_mesh_sensor_client_status_cb_t;
typedef struct {
int error_code; /*!< 0: success,
* otherwise failure. For the error code values please refer to errno.h file.
* A negative sign is added to the standard error codes in errno.h. */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
esp_ble_mesh_sensor_client_status_cb_t status_cb; /*!< The sensor status message callback values */
} esp_ble_mesh_sensor_client_cb_param_t;
typedef enum {
ESP_BLE_MESH_SENSOR_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_SENSOR_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_SENSOR_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_SENSOR_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_SENSOR_CLIENT_EVT_MAX,
} esp_ble_mesh_sensor_client_cb_event_t;
/**
* @brief Bluetooth Mesh Sensor Client Model function.
*/
/** @brief: event, event code of Sensor Client Model events; param, parameters of Sensor Client Model events */
typedef void (* esp_ble_mesh_sensor_client_cb_t)(esp_ble_mesh_sensor_client_cb_event_t event,
esp_ble_mesh_sensor_client_cb_param_t *param);
/**
* @brief Register BLE Mesh Sensor Client Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_sensor_client_callback(esp_ble_mesh_sensor_client_cb_t callback);
/**
* @brief Get the value of Sensor Server Model states using the Sensor Client Model get messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_sensor_message_opcode_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to sensor get message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_sensor_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_sensor_client_get_state_t *get_state);
/**
* @brief Set the value of Sensor Server Model states using the Sensor Client Model set messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_sensor_message_opcode_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to sensor set message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_sensor_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_sensor_client_set_state_t *set_state);
#endif /* _ESP_BLE_MESH_SENSOR_MODEL_API_H_ */

View File

@@ -0,0 +1,292 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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
* @brief Bluetooth Mesh Time and Scene Client Model APIs.
*/
#ifndef _ESP_BLE_MESH_TIME_SCENE_MODEL_API_H_
#define _ESP_BLE_MESH_TIME_SCENE_MODEL_API_H_
#include "time_scene_client.h"
#include "esp_ble_mesh_defs.h"
/** @def ESP_BLE_MESH_MODEL_TIME_CLI
*
* @brief Define a new Time Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Time Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Time Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_TIME_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_TIME_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_SCENE_CLI
*
* @brief Define a new Scene Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Scene Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Scene Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCENE_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCENE_CLI, \
NULL, cli_pub, cli_data)
/** @def ESP_BLE_MESH_MODEL_SCHEDULER_CLI
*
* @brief Define a new Scheduler Client Model.
*
* @note This API needs to be called for each element on which
* the application needs to have a Scheduler Client Model.
*
* @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
* @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
*
* @return New Scheduler Client Model instance.
*/
#define ESP_BLE_MESH_MODEL_SCHEDULER_CLI(cli_pub, cli_data) \
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_SCHEDULER_CLI, \
NULL, cli_pub, cli_data)
/**
* @brief Bluetooth Mesh Time Scene Client Model Get and Set parameters structure.
*/
typedef struct {
u8_t tai_seconds[5]; /* The current TAI time in seconds */
u8_t sub_second; /* The sub-second time in units of 1/256 second */
u8_t uncertainty; /* The estimated uncertainty in 10-millisecond steps */
u16_t time_authority : 1; /* 0 = No Time Authority, 1 = Time Authority */
u16_t tai_utc_delta : 15; /* Current difference between TAI and UTC in seconds */
u8_t time_zone_offset; /* The local time zone offset in 15-minute increments */
} esp_ble_mesh_time_set_t;
typedef struct {
u8_t time_zone_offset_new; /* Upcoming local time zone offset */
u8_t tai_zone_change[5]; /* TAI Seconds time of the upcoming Time Zone Offset change */
} esp_ble_mesh_time_zone_set_t;
typedef struct {
u16_t tai_utc_delta_new : 15; /* Upcoming difference between TAI and UTC in seconds */
u16_t padding : 1; /* Always 0b0. Other values are Prohibited. */
u8_t tai_delta_change[5]; /* TAI Seconds time of the upcoming TAI-UTC Delta change */
} esp_ble_mesh_tai_utc_delta_set_t;
typedef struct {
u8_t time_role; /* The Time Role for the element */
} esp_ble_mesh_time_role_set_t;
typedef struct {
u16_t scene_number; /* The number of scenes to be stored */
} esp_ble_mesh_scene_store_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u16_t scene_number; /* The number of scenes to be recalled */
u8_t tid; /* Transaction ID */
u8_t trans_time; /* Time to complete state transition (optional) */
u8_t delay; /* Indicate message execution delay (C.1) */
} esp_ble_mesh_scene_recall_t;
typedef struct {
u16_t scene_number; /* The number of scenes to be deleted */
} esp_ble_mesh_scene_delete_t;
typedef struct {
u8_t index; /* Index of the Schedule Register entry to get */
} esp_ble_mesh_scheduler_act_get_t;
typedef struct {
u64_t index : 4; /* Index of the Schedule Register entry to set */
u64_t year : 7; /* Scheduled year for the action */
u64_t month : 12; /* Scheduled month for the action */
u64_t day : 5; /* Scheduled day of the month for the action */
u64_t hour : 5; /* Scheduled hour for the action */
u64_t minute : 6; /* Scheduled minute for the action */
u64_t second : 6; /* Scheduled second for the action */
u64_t day_of_week : 7; /* Schedule days of the week for the action */
u64_t action : 4; /* Action to be performed at the scheduled time */
u64_t trans_time : 8; /* Transition time for this action */
u16_t scene_number; /* Transition time for this action */
} esp_ble_mesh_scheduler_act_set_t;
/**
* @brief For
*
* the get_state parameter in the esp_ble_mesh_time_scene_client_get_state function should be set to NULL.
*/
typedef union {
esp_ble_mesh_scheduler_act_get_t scheduler_act_get; /*!< For ESP_BLE_MESH_MODEL_OP_SCHEDULER_ACT_GET */
} esp_ble_mesh_time_scene_client_get_state_t;
typedef union {
esp_ble_mesh_time_set_t time_set; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_SET */
esp_ble_mesh_time_zone_set_t time_zone_set; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_ZONE_SET */
esp_ble_mesh_tai_utc_delta_set_t tai_utc_delta_set; /*!< For ESP_BLE_MESH_MODEL_OP_TAI_UTC_DELTA_SET */
esp_ble_mesh_time_role_set_t time_role_set; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_ROLE_SET */
esp_ble_mesh_scene_store_t scene_store; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_STORE & ESP_BLE_MESH_MODEL_OP_SCENE_STORE_UNACK */
esp_ble_mesh_scene_recall_t scene_recall; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_RECALL & ESP_BLE_MESH_MODEL_OP_SCENE_RECALL_UNACK */
esp_ble_mesh_scene_delete_t scene_delete; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_DELETE & ESP_BLE_MESH_MODEL_OP_SCENE_DELETE_UNACK */
esp_ble_mesh_scheduler_act_set_t scheduler_act_set; /*!< For ESP_BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET & ESP_BLE_MESH_MODEL_OP_SCHEDULER_ACT_SET_UNACK */
} esp_ble_mesh_time_scene_client_set_state_t;
/**
* @brief Bluetooth Mesh Time Scene Client Model Get and Set callback parameters structure.
*/
typedef struct {
u8_t tai_seconds[5]; /* The current TAI time in seconds */
u8_t sub_second; /* The sub-second time in units of 1/256 second */
u8_t uncertainty; /* The estimated uncertainty in 10-millisecond steps */
u16_t time_authority : 1; /* 0 = No Time Authority, 1 = Time Authority */
u16_t tai_utc_delta : 15; /* Current difference between TAI and UTC in seconds */
u8_t time_zone_offset; /* The local time zone offset in 15-minute increments */
} esp_ble_mesh_time_status_cb_t;
typedef struct {
u8_t time_zone_offset_curr; /* Current local time zone offset */
u8_t time_zone_offset_new; /* Upcoming local time zone offset */
u8_t tai_zone_change[5]; /* TAI Seconds time of the upcoming Time Zone Offset change */
} esp_ble_mesh_time_zone_status_cb_t;
typedef struct {
u16_t tai_utc_delta_curr : 15; /* Current difference between TAI and UTC in seconds */
u16_t padding_1 : 1; /* Always 0b0. Other values are Prohibited. */
u16_t tai_utc_delta_new : 15; /* Upcoming difference between TAI and UTC in seconds */
u16_t padding_2 : 1; /* Always 0b0. Other values are Prohibited. */
u8_t tai_delta_change[5]; /* TAI Seconds time of the upcoming TAI-UTC Delta change */
} esp_ble_mesh_tai_utc_delta_status_cb_t;
typedef struct {
u8_t time_role; /* The Time Role for the element */
} esp_ble_mesh_time_role_status_cb_t;
typedef struct {
bool op_en; /* Indicate if optional parameters are included */
u8_t status_code; /* Status code of the last operation */
u16_t current_scene; /* Scene Number of the current scene */
u16_t target_scene; /* Scene Number of the target scene (optional) */
u8_t remain_time; /* Time to complete state transition (C.1) */
} esp_ble_mesh_scene_status_cb_t;
typedef struct {
u8_t status_code; /* Status code for the previous operation */
u16_t current_scene; /* Scene Number of the current scene */
struct net_buf_simple *scenes; /* A list of scenes stored within an element */
} esp_ble_mesh_scene_register_status_cb_t;
typedef struct {
u16_t schedules; /* Bit field indicating defined Actions in the Schedule Register */
} esp_ble_mesh_scheduler_status_cb_t;
typedef struct {
u64_t index : 4; /* Enumerates (selects) a Schedule Register entry */
u64_t year : 7; /* Scheduled year for the action */
u64_t month : 12; /* Scheduled month for the action */
u64_t day : 5; /* Scheduled day of the month for the action */
u64_t hour : 5; /* Scheduled hour for the action */
u64_t minute : 6; /* Scheduled minute for the action */
u64_t second : 6; /* Scheduled second for the action */
u64_t day_of_week : 7; /* Schedule days of the week for the action */
u64_t action : 4; /* Action to be performed at the scheduled time */
u64_t trans_time : 8; /* Transition time for this action */
u16_t scene_number; /* Transition time for this action */
} esp_ble_mesh_scheduler_act_status_cb_t;
typedef union {
esp_ble_mesh_time_status_cb_t time_status; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_STATUS */
esp_ble_mesh_time_zone_status_cb_t time_zone_status; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_ZONE_STATUS */
esp_ble_mesh_tai_utc_delta_status_cb_t tai_utc_delta_status; /*!< For ESP_BLE_MESH_MODEL_OP_TAI_UTC_DELTA_STATUS */
esp_ble_mesh_time_role_status_cb_t time_role_status; /*!< For ESP_BLE_MESH_MODEL_OP_TIME_ROLE_STATUS */
esp_ble_mesh_scene_status_cb_t scene_status; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_STATUS */
esp_ble_mesh_scene_register_status_cb_t scene_register_status; /*!< For ESP_BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS */
esp_ble_mesh_scheduler_status_cb_t scheduler_status; /*!< For ESP_BLE_MESH_MODEL_OP_SCHEDULER_STATUS */
esp_ble_mesh_scheduler_act_status_cb_t scheduler_act_status; /*!< For ESP_BLE_MESH_MODEL_OP_SCHEDULER_ACT_STATUS */
} esp_ble_mesh_time_scene_client_status_cb_t;
typedef struct {
int error_code; /*!< Appropriate error code */
esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
esp_ble_mesh_time_scene_client_status_cb_t status_cb; /*!< The scene status message callback values */
} esp_ble_mesh_time_scene_client_cb_param_t;
typedef enum {
ESP_BLE_MESH_TIME_SCENE_CLIENT_GET_STATE_EVT,
ESP_BLE_MESH_TIME_SCENE_CLIENT_SET_STATE_EVT,
ESP_BLE_MESH_TIME_SCENE_CLIENT_PUBLISH_EVT,
ESP_BLE_MESH_TIME_SCENE_CLIENT_TIMEOUT_EVT,
ESP_BLE_MESH_TIME_SCENE_CLIENT_EVT_MAX,
} esp_ble_mesh_time_scene_client_cb_event_t;
/**
* @brief Bluetooth Mesh Time Scene Client Model function.
*/
/** @brief: event, event code of Time Scene Client Model events; param, parameters of Time Scene Client Model events */
typedef void (* esp_ble_mesh_time_scene_client_cb_t)(esp_ble_mesh_time_scene_client_cb_event_t event,
esp_ble_mesh_time_scene_client_cb_param_t *param);
/**
* @brief Register BLE Mesh Time Scene Client Model callback.
*
* @param[in] callback: Pointer to the callback function.
*
* @return ESP_OK on success or error code otherwise.
*
*/
esp_err_t esp_ble_mesh_register_time_scene_client_callback(esp_ble_mesh_time_scene_client_cb_t callback);
/**
* @brief Get the value of Time Scene Server Model states using the Time Scene Client Model get messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_time_scene_message_opcode_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] get_state: Pointer to time scene get message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*/
esp_err_t esp_ble_mesh_time_scene_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_time_scene_client_get_state_t *get_state);
/**
* @brief Set the value of Time Scene Server Model states using the Time Scene Client Model set messages.
*
* @note If you want to know the opcodes and corresponding meanings accepted by this API,
* please refer to (@ref esp_ble_mesh_time_scene_message_opcode_t).
*
* @param[in] params: Pointer to BLE Mesh common client parameters.
* @param[in] set_state: Pointer to time scene set message value.
* Shall not be set to NULL.
*
* @return ESP_OK on success or error code otherwise.
*/
esp_err_t esp_ble_mesh_time_scene_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_time_scene_client_set_state_t *set_state);
#endif /* _ESP_BLE_MESH_TIME_SCENE_MODEL_API_H_ */

View File

@@ -0,0 +1,730 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "cfg_cli.h"
#include "common.h"
#include "btc_ble_mesh_config_client.h"
#include "esp_ble_mesh_config_model_api.h"
#define CID_NVAL 0xffff
extern s32_t config_msg_timeout;
static inline void btc_ble_mesh_cfg_client_cb_to_app(esp_ble_mesh_cfg_client_cb_event_t event,
esp_ble_mesh_cfg_client_cb_param_t *param)
{
esp_ble_mesh_cfg_client_cb_t btc_mesh_cb = (esp_ble_mesh_cfg_client_cb_t)btc_profile_cb_get(BTC_PID_CFG_CLIENT);
if (btc_mesh_cb) {
btc_mesh_cb(event, param);
}
}
static inline void btc_ble_mesh_cfg_server_cb_to_app(esp_ble_mesh_cfg_server_cb_event_t event,
esp_ble_mesh_cfg_server_cb_param_t *param)
{
esp_ble_mesh_cfg_server_cb_t btc_mesh_cb = (esp_ble_mesh_cfg_server_cb_t)btc_profile_cb_get(BTC_PID_CFG_SERVER);
if (btc_mesh_cb) {
btc_mesh_cb(event, param);
}
}
void btc_ble_mesh_cfg_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_cfg_client_args_t *dst = (btc_ble_mesh_cfg_client_args_t *)p_dest;
btc_ble_mesh_cfg_client_args_t *src = (btc_ble_mesh_cfg_client_args_t *)p_src;
if (!msg || !dst || !src) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_CONFIG_CLIENT_GET_STATE: {
dst->cfg_client_get_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->cfg_client_get_state.get_state = (esp_ble_mesh_cfg_client_get_state_t *)osi_malloc(sizeof(esp_ble_mesh_cfg_client_get_state_t));
if (dst->cfg_client_get_state.params && dst->cfg_client_get_state.get_state) {
memcpy(dst->cfg_client_get_state.params, src->cfg_client_get_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->cfg_client_get_state.get_state, src->cfg_client_get_state.get_state,
sizeof(esp_ble_mesh_cfg_client_get_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
case BTC_BLE_MESH_ACT_CONFIG_CLIENT_SET_STATE: {
dst->cfg_client_set_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->cfg_client_set_state.set_state = (esp_ble_mesh_cfg_client_set_state_t *)osi_malloc(sizeof(esp_ble_mesh_cfg_client_set_state_t));
if (dst->cfg_client_set_state.params && dst->cfg_client_set_state.set_state) {
memcpy(dst->cfg_client_set_state.params, src->cfg_client_set_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->cfg_client_set_state.set_state, src->cfg_client_set_state.set_state,
sizeof(esp_ble_mesh_cfg_client_set_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s Unhandled deep copy %d", __func__, msg->act);
break;
}
}
static void btc_ble_mesh_cfg_client_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_cfg_client_cb_param_t *p_dest_data = (esp_ble_mesh_cfg_client_cb_param_t *)p_dest;
esp_ble_mesh_cfg_client_cb_param_t *p_src_data = (esp_ble_mesh_cfg_client_cb_param_t *)p_src;
u32_t opcode;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_CFG_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_CFG_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_CFG_CLIENT_PUBLISH_EVT:
if (p_src_data->params) {
opcode = p_src_data->params->opcode;
switch (opcode) {
case OP_DEV_COMP_DATA_GET:
case OP_DEV_COMP_DATA_STATUS:
if (p_src_data->status_cb.comp_data_status.composition_data) {
length = p_src_data->status_cb.comp_data_status.composition_data->len;
p_dest_data->status_cb.comp_data_status.composition_data = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.comp_data_status.composition_data) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.comp_data_status.composition_data, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.comp_data_status.composition_data,
p_src_data->status_cb.comp_data_status.composition_data->data,
p_src_data->status_cb.comp_data_status.composition_data->len);
}
break;
case OP_MOD_SUB_GET:
case OP_MOD_SUB_GET_VND:
case OP_MOD_SUB_LIST:
case OP_MOD_SUB_LIST_VND:
if (p_src_data->status_cb.model_sub_list.sub_addr) {
length = p_src_data->status_cb.model_sub_list.sub_addr->len;
p_dest_data->status_cb.model_sub_list.sub_addr = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.model_sub_list.sub_addr) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.model_sub_list.sub_addr, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.model_sub_list.sub_addr,
p_src_data->status_cb.model_sub_list.sub_addr->data,
p_src_data->status_cb.model_sub_list.sub_addr->len);
}
break;
case OP_NET_KEY_GET:
case OP_NET_KEY_LIST:
if (p_src_data->status_cb.netkey_list.net_idx) {
length = p_src_data->status_cb.netkey_list.net_idx->len;
p_dest_data->status_cb.netkey_list.net_idx = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.netkey_list.net_idx) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.netkey_list.net_idx, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.netkey_list.net_idx,
p_src_data->status_cb.netkey_list.net_idx->data,
p_src_data->status_cb.netkey_list.net_idx->len);
}
break;
case OP_APP_KEY_GET:
case OP_APP_KEY_LIST:
if (p_src_data->status_cb.appkey_list.app_idx) {
length = p_src_data->status_cb.appkey_list.app_idx->len;
p_dest_data->status_cb.appkey_list.app_idx = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.appkey_list.app_idx) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.appkey_list.app_idx, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.appkey_list.app_idx,
p_src_data->status_cb.appkey_list.app_idx->data,
p_src_data->status_cb.appkey_list.app_idx->len);
}
break;
case OP_SIG_MOD_APP_GET:
case OP_VND_MOD_APP_GET:
case OP_SIG_MOD_APP_LIST:
case OP_VND_MOD_APP_LIST:
if (p_src_data->status_cb.model_app_list.app_idx) {
length = p_src_data->status_cb.model_app_list.app_idx->len;
p_dest_data->status_cb.model_app_list.app_idx = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.model_app_list.app_idx) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.model_app_list.app_idx, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.model_app_list.app_idx,
p_src_data->status_cb.model_app_list.app_idx->data,
p_src_data->status_cb.model_app_list.app_idx->len);
}
break;
default:
break;
}
}
case ESP_BLE_MESH_CFG_CLIENT_TIMEOUT_EVT:
if (p_src_data->params) {
p_dest_data->params = osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
if (p_dest_data->params) {
memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_cfg_client_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_cfg_client_cb_param_t *arg = NULL;
u32_t opcode;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (esp_ble_mesh_cfg_client_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_CFG_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_CFG_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_CFG_CLIENT_PUBLISH_EVT:
if (arg->params) {
opcode = arg->params->opcode;
switch (opcode) {
case OP_DEV_COMP_DATA_GET:
case OP_DEV_COMP_DATA_STATUS:
bt_mesh_free_buf(arg->status_cb.comp_data_status.composition_data);
break;
case OP_MOD_SUB_GET:
case OP_MOD_SUB_GET_VND:
case OP_MOD_SUB_LIST:
case OP_MOD_SUB_LIST_VND:
bt_mesh_free_buf(arg->status_cb.model_sub_list.sub_addr);
break;
case OP_NET_KEY_GET:
case OP_NET_KEY_LIST:
bt_mesh_free_buf(arg->status_cb.netkey_list.net_idx);
break;
case OP_APP_KEY_GET:
case OP_APP_KEY_LIST:
bt_mesh_free_buf(arg->status_cb.appkey_list.app_idx);
break;
case OP_SIG_MOD_APP_GET:
case OP_VND_MOD_APP_GET:
case OP_SIG_MOD_APP_LIST:
case OP_VND_MOD_APP_LIST:
bt_mesh_free_buf(arg->status_cb.model_app_list.app_idx);
break;
default:
break;
}
}
case ESP_BLE_MESH_CFG_CLIENT_TIMEOUT_EVT:
if (arg->params) {
osi_free(arg->params);
}
break;
default:
break;
}
}
void btc_ble_mesh_cfg_client_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_cfg_client_args_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_cfg_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_CONFIG_CLIENT_GET_STATE:
if (arg->cfg_client_get_state.params) {
osi_free(arg->cfg_client_get_state.params);
}
if (arg->cfg_client_get_state.get_state) {
osi_free(arg->cfg_client_get_state.get_state);
}
break;
case BTC_BLE_MESH_ACT_CONFIG_CLIENT_SET_STATE:
if (arg->cfg_client_set_state.params) {
osi_free(arg->cfg_client_set_state.params);
}
if (arg->cfg_client_set_state.set_state) {
osi_free(arg->cfg_client_set_state.set_state);
}
break;
default:
break;
}
return;
}
static void btc_mesh_cfg_client_callback(esp_ble_mesh_cfg_client_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_CFG_CLIENT;
msg.act = act;
btc_transfer_context(&msg, cb_params,
sizeof(esp_ble_mesh_cfg_client_cb_param_t), btc_ble_mesh_cfg_client_copy_req_data);
}
void bt_mesh_callback_config_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_cfg_client_cb_param_t cb_params = {0};
esp_ble_mesh_client_common_param_t params = {0};
size_t length;
uint8_t act;
if (!model || !ctx) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
switch (evt_type) {
case 0x00:
act = ESP_BLE_MESH_CFG_CLIENT_GET_STATE_EVT;
break;
case 0x01:
act = ESP_BLE_MESH_CFG_CLIENT_SET_STATE_EVT;
break;
case 0x02:
act = ESP_BLE_MESH_CFG_CLIENT_PUBLISH_EVT;
break;
case 0x03:
act = ESP_BLE_MESH_CFG_CLIENT_TIMEOUT_EVT;
break;
default:
LOG_ERROR("%s: unknown config status event type", __func__);
return;
}
params.opcode = opcode;
params.model = (esp_ble_mesh_model_t *)model;
params.ctx.net_idx = ctx->net_idx;
params.ctx.app_idx = ctx->app_idx;
params.ctx.addr = ctx->addr;
params.ctx.recv_ttl = ctx->recv_ttl;
params.ctx.recv_op = ctx->recv_op;
params.ctx.recv_dst = ctx->recv_dst;
cb_params.error_code = 0;
cb_params.params = &params;
if (val && len) {
length = (len <= sizeof(cb_params.status_cb)) ? len : sizeof(cb_params.status_cb);
memcpy(&cb_params.status_cb, val, length);
}
btc_mesh_cfg_client_callback(&cb_params, act);
}
void btc_mesh_cfg_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
{
if (!model || !ctx || !buf) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
bt_mesh_callback_config_status_to_btc(opcode, 0x02, model, ctx, buf->data, buf->len);
}
void btc_mesh_cfg_client_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_cfg_client_cb_param_t cfg_client_cb = {0};
btc_ble_mesh_cfg_client_args_t *arg = NULL;
bt_mesh_role_param_t role_param = {0};
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_cfg_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_CONFIG_CLIENT_GET_STATE: {
cfg_client_cb.params = arg->cfg_client_get_state.params;
role_param.model = (struct bt_mesh_model *)cfg_client_cb.params->model;
role_param.role = cfg_client_cb.params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
btc_ble_mesh_config_client_get_state(arg->cfg_client_get_state.params,
arg->cfg_client_get_state.get_state,
&cfg_client_cb);
if (cfg_client_cb.error_code) {
btc_mesh_cfg_client_callback(&cfg_client_cb, ESP_BLE_MESH_CFG_CLIENT_GET_STATE_EVT);
}
break;
}
case BTC_BLE_MESH_ACT_CONFIG_CLIENT_SET_STATE: {
cfg_client_cb.params = arg->cfg_client_set_state.params;
role_param.model = (struct bt_mesh_model *)cfg_client_cb.params->model;
role_param.role = cfg_client_cb.params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
btc_ble_mesh_config_client_set_state(arg->cfg_client_set_state.params,
arg->cfg_client_set_state.set_state,
&cfg_client_cb);
if (cfg_client_cb.error_code) {
btc_mesh_cfg_client_callback(&cfg_client_cb, ESP_BLE_MESH_CFG_CLIENT_SET_STATE_EVT);
}
break;
}
default:
break;
}
btc_ble_mesh_cfg_client_arg_deep_free(msg);
}
void btc_mesh_cfg_client_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_cfg_client_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
param = (esp_ble_mesh_cfg_client_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_CFG_CLIENT_EVT_MAX) {
btc_ble_mesh_cfg_client_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_cfg_client_free_req_data(msg);
}
int btc_ble_mesh_config_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_cfg_client_get_state_t *get_state,
esp_ble_mesh_cfg_client_cb_param_t *cfg_client_cb)
{
struct bt_mesh_msg_ctx ctx = {0};
if (!params || !cfg_client_cb) {
LOG_ERROR("%s: parameter is NULL", __func__);
return -EINVAL;
}
ctx.net_idx = params->ctx.net_idx;
ctx.app_idx = BT_MESH_KEY_DEV;
ctx.addr = params->ctx.addr;
ctx.send_rel = params->ctx.send_rel;
ctx.send_ttl = params->ctx.send_ttl;
config_msg_timeout = params->msg_timeout;
switch (params->opcode) {
case ESP_BLE_MESH_MODEL_OP_BEACON_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_beacon_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_DEFAULT_TTL_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_ttl_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_FRIEND_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_friend_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_GATT_PROXY_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_gatt_proxy_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_RELAY_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_relay_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_MODEL_PUB_GET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_pub_get(&ctx, get_state->model_pub_get.element_addr, get_state->model_pub_get.model_id,
get_state->model_pub_get.company_id));
case ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_hb_pub_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_hb_sub_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_COMPOSITION_DATA_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_comp_data_get(&ctx, get_state->comp_data_get.page));
case ESP_BLE_MESH_MODEL_OP_SIG_MODEL_SUB_GET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_get(&ctx, get_state->sig_model_sub_get.element_addr, get_state->sig_model_sub_get.model_id));
case ESP_BLE_MESH_MODEL_OP_VENDOR_MODEL_SUB_GET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_get_vnd(&ctx, get_state->vnd_model_sub_get.element_addr,
get_state->vnd_model_sub_get.model_id, get_state->vnd_model_sub_get.company_id));
case ESP_BLE_MESH_MODEL_OP_NET_KEY_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_net_key_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_APP_KEY_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_app_key_get(&ctx, get_state->app_key_get.net_idx));
case ESP_BLE_MESH_MODEL_OP_NODE_IDENTITY_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_node_identity_get(&ctx, get_state->node_identity_get.net_idx));
case ESP_BLE_MESH_MODEL_OP_SIG_MODEL_APP_GET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_app_get(&ctx, get_state->sig_model_app_get.element_addr, get_state->sig_model_app_get.model_id));
case ESP_BLE_MESH_MODEL_OP_VENDOR_MODEL_APP_GET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_app_get_vnd(&ctx, get_state->vnd_model_app_get.element_addr,
get_state->vnd_model_app_get.model_id, get_state->vnd_model_app_get.company_id));
case ESP_BLE_MESH_MODEL_OP_KEY_REFRESH_PHASE_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_kr_phase_get(&ctx, get_state->kr_phase_get.net_idx));
case ESP_BLE_MESH_MODEL_OP_LPN_POLLTIMEOUT_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_lpn_timeout_get(&ctx, get_state->lpn_pollto_get.lpn_addr));
case ESP_BLE_MESH_MODEL_OP_NETWORK_TRANSMIT_GET:
return (cfg_client_cb->error_code = bt_mesh_cfg_net_transmit_get(&ctx));
default:
BT_WARN("%s, invalid opcode 0x%x", __func__, params->opcode);
return (cfg_client_cb->error_code = -EINVAL);
}
return 0;
}
int btc_ble_mesh_config_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_cfg_client_set_state_t *set_state,
esp_ble_mesh_cfg_client_cb_param_t *cfg_client_cb)
{
struct bt_mesh_msg_ctx ctx = {0};
if (!params || !set_state || !cfg_client_cb) {
LOG_ERROR("%s: parameter is NULL", __func__);
return -EINVAL;
}
ctx.net_idx = params->ctx.net_idx;
ctx.app_idx = BT_MESH_KEY_DEV;
ctx.addr = params->ctx.addr;
ctx.send_rel = params->ctx.send_rel;
ctx.send_ttl = params->ctx.send_ttl;
config_msg_timeout = params->msg_timeout;
switch (params->opcode) {
case ESP_BLE_MESH_MODEL_OP_BEACON_SET:
return (cfg_client_cb->error_code = bt_mesh_cfg_beacon_set(&ctx, set_state->beacon_set.beacon));
case ESP_BLE_MESH_MODEL_OP_DEFAULT_TTL_SET:
return (cfg_client_cb->error_code = bt_mesh_cfg_ttl_set(&ctx, set_state->default_ttl_set.ttl));
case ESP_BLE_MESH_MODEL_OP_FRIEND_SET:
return (cfg_client_cb->error_code = bt_mesh_cfg_friend_set(&ctx, set_state->friend_set.friend_state));
case ESP_BLE_MESH_MODEL_OP_GATT_PROXY_SET:
return (cfg_client_cb->error_code = bt_mesh_cfg_gatt_proxy_set(&ctx, set_state->gatt_proxy_set.gatt_proxy));
case ESP_BLE_MESH_MODEL_OP_RELAY_SET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_relay_set(&ctx, set_state->relay_set.relay, set_state->relay_set.relay_retransmit));
case ESP_BLE_MESH_MODEL_OP_NET_KEY_ADD:
return (cfg_client_cb->error_code =
bt_mesh_cfg_net_key_add(&ctx, set_state->net_key_add.net_idx, &set_state->net_key_add.net_key[0]));
case ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD:
return (cfg_client_cb->error_code =
bt_mesh_cfg_app_key_add(&ctx, set_state->app_key_add.net_idx,
set_state->app_key_add.app_idx, &set_state->app_key_add.app_key[0]));
case ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_app_bind(&ctx, set_state->model_app_bind.element_addr, set_state->model_app_bind.model_app_idx,
set_state->model_app_bind.model_id, set_state->model_app_bind.company_id));
case ESP_BLE_MESH_MODEL_OP_MODEL_PUB_SET: {
struct bt_mesh_cfg_mod_pub model_pub = {
.addr = set_state->model_pub_set.publish_addr,
.app_idx = set_state->model_pub_set.publish_app_idx,
.cred_flag = set_state->model_pub_set.cred_flag,
.ttl = set_state->model_pub_set.publish_ttl,
.period = set_state->model_pub_set.publish_period,
.transmit = set_state->model_pub_set.publish_retransmit,
};
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_pub_set(&ctx, set_state->model_pub_set.element_addr, set_state->model_pub_set.model_id,
set_state->model_pub_set.company_id, &model_pub));
}
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_add(&ctx, set_state->model_sub_add.element_addr, set_state->model_sub_add.sub_addr,
set_state->model_sub_add.model_id, set_state->model_sub_add.company_id));
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_del(&ctx, set_state->model_sub_delete.element_addr, set_state->model_sub_delete.sub_addr,
set_state->model_sub_delete.model_id, set_state->model_sub_delete.company_id));
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_OVERWRITE:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_overwrite(&ctx, set_state->model_sub_overwrite.element_addr, set_state->model_sub_overwrite.sub_addr,
set_state->model_sub_overwrite.model_id, set_state->model_sub_overwrite.company_id));
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_ADD:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_va_add(&ctx, set_state->model_sub_va_add.element_addr, &set_state->model_sub_va_add.label_uuid[0],
set_state->model_sub_va_add.model_id, set_state->model_sub_va_add.company_id));
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_OVERWRITE:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_va_overwrite(&ctx, set_state->model_sub_va_overwrite.element_addr, &set_state->model_sub_va_overwrite.label_uuid[0],
set_state->model_sub_va_overwrite.model_id, set_state->model_sub_va_overwrite.company_id));
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_VIRTUAL_ADDR_DELETE:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_va_del(&ctx, set_state->model_sub_va_delete.element_addr, &set_state->model_sub_va_delete.label_uuid[0],
set_state->model_sub_va_delete.model_id, set_state->model_sub_va_delete.company_id));
case ESP_BLE_MESH_MODEL_OP_HEARTBEAT_SUB_SET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_hb_sub_set(&ctx, (struct bt_mesh_cfg_hb_sub *)&set_state->heartbeat_sub_set));
case ESP_BLE_MESH_MODEL_OP_HEARTBEAT_PUB_SET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_hb_pub_set(&ctx, (const struct bt_mesh_cfg_hb_pub *)&set_state->heartbeat_pub_set));
case ESP_BLE_MESH_MODEL_OP_NODE_RESET:
return (cfg_client_cb->error_code = bt_mesh_cfg_node_reset(&ctx));
case ESP_BLE_MESH_MODEL_OP_MODEL_PUB_VIRTUAL_ADDR_SET: {
struct bt_mesh_cfg_mod_pub model_pub = {
.app_idx = set_state->model_pub_va_set.publish_app_idx,
.cred_flag = set_state->model_pub_va_set.cred_flag,
.ttl = set_state->model_pub_va_set.publish_ttl,
.period = set_state->model_pub_va_set.publish_period,
.transmit = set_state->model_pub_va_set.publish_retransmit,
};
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_pub_va_set(&ctx, set_state->model_pub_va_set.element_addr, set_state->model_pub_va_set.model_id,
set_state->model_pub_va_set.company_id, set_state->model_pub_va_set.label_uuid, &model_pub));
}
case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_DELETE_ALL:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_sub_del_all(&ctx, set_state->model_sub_delete_all.element_addr,
set_state->model_sub_delete_all.model_id, set_state->model_sub_delete_all.company_id));
case ESP_BLE_MESH_MODEL_OP_NET_KEY_UPDATE:
return (cfg_client_cb->error_code =
bt_mesh_cfg_net_key_update(&ctx, set_state->net_key_update.net_idx, set_state->net_key_update.net_key));
case ESP_BLE_MESH_MODEL_OP_NET_KEY_DELETE:
return (cfg_client_cb->error_code =
bt_mesh_cfg_net_key_delete(&ctx, set_state->net_key_delete.net_idx));
case ESP_BLE_MESH_MODEL_OP_APP_KEY_UPDATE:
return (cfg_client_cb->error_code =
bt_mesh_cfg_app_key_update(&ctx, set_state->app_key_update.net_idx, set_state->app_key_update.app_idx,
set_state->app_key_update.app_key));
case ESP_BLE_MESH_MODEL_OP_APP_KEY_DELETE:
return (cfg_client_cb->error_code =
bt_mesh_cfg_app_key_delete(&ctx, set_state->app_key_delete.net_idx, set_state->app_key_delete.app_idx));
case ESP_BLE_MESH_MODEL_OP_NODE_IDENTITY_SET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_node_identity_set(&ctx, set_state->node_identity_set.net_idx, set_state->node_identity_set.identity));
case ESP_BLE_MESH_MODEL_OP_MODEL_APP_UNBIND:
return (cfg_client_cb->error_code =
bt_mesh_cfg_mod_app_unbind(&ctx, set_state->model_app_unbind.element_addr, set_state->model_app_unbind.model_app_idx,
set_state->model_app_unbind.model_id, set_state->model_app_unbind.company_id));
case ESP_BLE_MESH_MODEL_OP_KEY_REFRESH_PHASE_SET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_kr_phase_set(&ctx, set_state->kr_phase_set.net_idx, set_state->kr_phase_set.transition));
case ESP_BLE_MESH_MODEL_OP_NETWORK_TRANSMIT_SET:
return (cfg_client_cb->error_code =
bt_mesh_cfg_net_transmit_set(&ctx, set_state->net_transmit_set.net_transmit));
default:
BT_WARN("%s, invalid opcode 0x%x", __func__, params->opcode);
return (cfg_client_cb->error_code = -EINVAL);
}
return 0;
}
static void btc_mesh_cfg_server_callback(esp_ble_mesh_cfg_server_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_CFG_SERVER;
msg.act = act;
btc_transfer_context(&msg, cb_params, sizeof(esp_ble_mesh_cfg_server_cb_param_t), NULL);
}
void bt_mesh_callback_cfg_server_event_to_btc(u8_t evt_type, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_cfg_server_cb_param_t cb_params = {0};
size_t length;
uint8_t act;
if (!model || !ctx) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
switch (evt_type) {
case 0x00:
act = ESP_BLE_MESH_CFG_SERVER_RECV_MSG_EVT;
break;
default:
LOG_ERROR("%s: unknown config sever event type", __func__);
return;
}
cb_params.model = (esp_ble_mesh_model_t *)model;
cb_params.ctx.net_idx = ctx->net_idx;
cb_params.ctx.app_idx = ctx->app_idx;
cb_params.ctx.addr = ctx->addr;
cb_params.ctx.recv_ttl = ctx->recv_ttl;
cb_params.ctx.recv_op = ctx->recv_op;
cb_params.ctx.recv_dst = ctx->recv_dst;
if (val && len) {
length = (len <= sizeof(cb_params.status_cb)) ? len : sizeof(cb_params.status_cb);
memcpy(&cb_params.status_cb, val, length);
}
btc_mesh_cfg_server_callback(&cb_params, act);
}
void btc_mesh_cfg_server_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_cfg_server_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
param = (esp_ble_mesh_cfg_server_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_CFG_SERVER_EVT_MAX) {
btc_ble_mesh_cfg_server_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
}
}

View File

@@ -0,0 +1,549 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "cfg_cli.h"
#include "btc_ble_mesh_generic_client.h"
#include "esp_ble_mesh_generic_model_api.h"
static inline void btc_ble_mesh_cb_to_app(esp_ble_mesh_generic_client_cb_event_t event,
esp_ble_mesh_generic_client_cb_param_t *param)
{
esp_ble_mesh_generic_client_cb_t btc_mesh_cb = (esp_ble_mesh_generic_client_cb_t)btc_profile_cb_get(BTC_PID_GENERIC_CLIENT);
if (btc_mesh_cb) {
btc_mesh_cb(event, param);
}
}
void btc_ble_mesh_generic_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_generic_client_args_t *dst = (btc_ble_mesh_generic_client_args_t *)p_dest;
btc_ble_mesh_generic_client_args_t *src = (btc_ble_mesh_generic_client_args_t *)p_src;
u32_t opcode;
u16_t length;
if (!msg || !dst || !src) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE: {
dst->generic_client_get_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->generic_client_get_state.get_state = (esp_ble_mesh_generic_client_get_state_t *)osi_malloc(sizeof(esp_ble_mesh_generic_client_get_state_t));
if (dst->generic_client_get_state.params && dst->generic_client_get_state.get_state) {
memcpy(dst->generic_client_get_state.params, src->generic_client_get_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->generic_client_get_state.get_state, src->generic_client_get_state.get_state,
sizeof(esp_ble_mesh_generic_client_get_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
case BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE: {
dst->generic_client_set_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->generic_client_set_state.set_state = (esp_ble_mesh_generic_client_set_state_t *)osi_malloc(sizeof(esp_ble_mesh_generic_client_set_state_t));
if (dst->generic_client_set_state.params && dst->generic_client_set_state.set_state) {
memcpy(dst->generic_client_set_state.params, src->generic_client_set_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->generic_client_set_state.set_state, src->generic_client_set_state.set_state,
sizeof(esp_ble_mesh_generic_client_set_state_t));
opcode = src->generic_client_set_state.params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
if (src->generic_client_set_state.set_state->user_property_set.property_value) {
length = src->generic_client_set_state.set_state->user_property_set.property_value->len;
dst->generic_client_set_state.set_state->user_property_set.property_value = bt_mesh_alloc_buf(length);
if (!dst->generic_client_set_state.set_state->user_property_set.property_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->generic_client_set_state.set_state->user_property_set.property_value, 0);
net_buf_simple_add_mem(dst->generic_client_set_state.set_state->user_property_set.property_value,
src->generic_client_set_state.set_state->user_property_set.property_value->data,
src->generic_client_set_state.set_state->user_property_set.property_value->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
if (src->generic_client_set_state.set_state->admin_property_set.property_value) {
length = src->generic_client_set_state.set_state->admin_property_set.property_value->len;
dst->generic_client_set_state.set_state->admin_property_set.property_value = bt_mesh_alloc_buf(length);
if (!dst->generic_client_set_state.set_state->admin_property_set.property_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->generic_client_set_state.set_state->admin_property_set.property_value, 0);
net_buf_simple_add_mem(dst->generic_client_set_state.set_state->admin_property_set.property_value,
src->generic_client_set_state.set_state->admin_property_set.property_value->data,
src->generic_client_set_state.set_state->admin_property_set.property_value->len);
}
break;
default:
break;
}
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s Unhandled deep copy %d", __func__, msg->act);
break;
}
}
static void btc_ble_mesh_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_generic_client_cb_param_t *p_dest_data = (esp_ble_mesh_generic_client_cb_param_t *)p_dest;
esp_ble_mesh_generic_client_cb_param_t *p_src_data = (esp_ble_mesh_generic_client_cb_param_t *)p_src;
u32_t opcode;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT:
if (p_src_data->params) {
opcode = p_src_data->params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS:
if (p_src_data->status_cb.user_properties_status.property_ids) {
length = p_src_data->status_cb.user_properties_status.property_ids->len;
p_dest_data->status_cb.user_properties_status.property_ids = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.user_properties_status.property_ids) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.user_properties_status.property_ids, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.user_properties_status.property_ids,
p_src_data->status_cb.user_properties_status.property_ids->data,
p_src_data->status_cb.user_properties_status.property_ids->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS:
if (p_src_data->status_cb.user_property_status.property_value) {
length = p_src_data->status_cb.user_property_status.property_value->len;
p_dest_data->status_cb.user_property_status.property_value = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.user_property_status.property_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.user_property_status.property_value, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.user_property_status.property_value,
p_src_data->status_cb.user_property_status.property_value->data,
p_src_data->status_cb.user_property_status.property_value->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS:
if (p_src_data->status_cb.admin_properties_status.property_ids) {
length = p_src_data->status_cb.admin_properties_status.property_ids->len;
p_dest_data->status_cb.admin_properties_status.property_ids = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.admin_properties_status.property_ids) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.admin_properties_status.property_ids, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.admin_properties_status.property_ids,
p_src_data->status_cb.admin_properties_status.property_ids->data,
p_src_data->status_cb.admin_properties_status.property_ids->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS:
if (p_src_data->status_cb.admin_property_status.property_value) {
length = p_src_data->status_cb.admin_property_status.property_value->len;
p_dest_data->status_cb.admin_property_status.property_value = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.admin_property_status.property_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.admin_property_status.property_value, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.admin_property_status.property_value,
p_src_data->status_cb.admin_property_status.property_value->data,
p_src_data->status_cb.admin_property_status.property_value->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_STATUS:
if (p_src_data->status_cb.manufacturer_properties_status.property_ids) {
length = p_src_data->status_cb.manufacturer_properties_status.property_ids->len;
p_dest_data->status_cb.manufacturer_properties_status.property_ids = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.manufacturer_properties_status.property_ids) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.manufacturer_properties_status.property_ids, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.manufacturer_properties_status.property_ids,
p_src_data->status_cb.manufacturer_properties_status.property_ids->data,
p_src_data->status_cb.manufacturer_properties_status.property_ids->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_STATUS:
if (p_src_data->status_cb.manufacturer_property_status.property_value) {
length = p_src_data->status_cb.manufacturer_property_status.property_value->len;
p_dest_data->status_cb.manufacturer_property_status.property_value = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.manufacturer_property_status.property_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.manufacturer_property_status.property_value, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.manufacturer_property_status.property_value,
p_src_data->status_cb.manufacturer_property_status.property_value->data,
p_src_data->status_cb.manufacturer_property_status.property_value->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS:
if (p_src_data->status_cb.client_properties_status.property_ids) {
length = p_src_data->status_cb.client_properties_status.property_ids->len;
p_dest_data->status_cb.client_properties_status.property_ids = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.client_properties_status.property_ids) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.client_properties_status.property_ids, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.client_properties_status.property_ids,
p_src_data->status_cb.client_properties_status.property_ids->data,
p_src_data->status_cb.client_properties_status.property_ids->len);
}
break;
default:
break;
}
}
case ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT:
if (p_src_data->params) {
p_dest_data->params = osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
if (p_dest_data->params) {
memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_generic_client_cb_param_t *arg = NULL;
u32_t opcode;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (esp_ble_mesh_generic_client_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT:
if (arg->params) {
opcode = arg->params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS:
bt_mesh_free_buf(arg->status_cb.user_properties_status.property_ids);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS:
bt_mesh_free_buf(arg->status_cb.user_property_status.property_value);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS:
bt_mesh_free_buf(arg->status_cb.admin_properties_status.property_ids);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS:
bt_mesh_free_buf(arg->status_cb.admin_property_status.property_value);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_STATUS:
bt_mesh_free_buf(arg->status_cb.manufacturer_properties_status.property_ids);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_STATUS:
bt_mesh_free_buf(arg->status_cb.manufacturer_property_status.property_value);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET:
case ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS:
bt_mesh_free_buf(arg->status_cb.client_properties_status.property_ids);
break;
default:
break;
}
}
case ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT:
if (arg->params) {
osi_free(arg->params);
}
break;
default:
break;
}
}
void btc_ble_mesh_generic_client_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_generic_client_args_t *arg = NULL;
u32_t opcode = 0;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_generic_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE:
if (arg->generic_client_get_state.params) {
osi_free(arg->generic_client_get_state.params);
}
if (arg->generic_client_get_state.get_state) {
osi_free(arg->generic_client_get_state.get_state);
}
break;
case BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE:
if (arg->generic_client_set_state.params) {
opcode = arg->generic_client_set_state.params->opcode;
osi_free(arg->generic_client_set_state.params);
}
if (arg->generic_client_set_state.set_state) {
if (opcode) {
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET:
bt_mesh_free_buf(arg->generic_client_set_state.set_state->user_property_set.property_value);
break;
case ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET:
bt_mesh_free_buf(arg->generic_client_set_state.set_state->admin_property_set.property_value);
break;
default:
break;
}
}
osi_free(arg->generic_client_set_state.set_state);
}
break;
default:
break;
}
return;
}
static void btc_mesh_generic_client_callback(esp_ble_mesh_generic_client_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GENERIC_CLIENT;
msg.act = act;
btc_transfer_context(&msg, cb_params,
sizeof(esp_ble_mesh_generic_client_cb_param_t), btc_ble_mesh_copy_req_data);
}
void bt_mesh_callback_generic_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_generic_client_cb_param_t cb_params = {0};
esp_ble_mesh_client_common_param_t params = {0};
size_t length;
uint8_t act;
if (!model || !ctx) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
switch (evt_type) {
case 0x00:
act = ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT;
break;
case 0x01:
act = ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT;
break;
case 0x02:
act = ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT;
break;
case 0x03:
act = ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT;
break;
default:
LOG_ERROR("%s: unknown generic status event type", __func__);
return;
}
params.opcode = opcode;
params.model = (esp_ble_mesh_model_t *)model;
params.ctx.net_idx = ctx->net_idx;
params.ctx.app_idx = ctx->app_idx;
params.ctx.addr = ctx->addr;
params.ctx.recv_ttl = ctx->recv_ttl;
params.ctx.recv_op = ctx->recv_op;
params.ctx.recv_dst = ctx->recv_dst;
cb_params.error_code = 0;
cb_params.params = &params;
if (val && len) {
length = (len <= sizeof(cb_params.status_cb)) ? len : sizeof(cb_params.status_cb);
memcpy(&cb_params.status_cb, val, length);
}
btc_mesh_generic_client_callback(&cb_params, act);
}
void btc_mesh_generic_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
{
if (!model || !ctx || !buf) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
bt_mesh_callback_generic_status_to_btc(opcode, 0x02, model, ctx, buf->data, buf->len);
}
void btc_mesh_generic_client_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_generic_client_cb_param_t generic_client_cb = {0};
esp_ble_mesh_client_common_param_t *params = NULL;
btc_ble_mesh_generic_client_args_t *arg = NULL;
struct bt_mesh_common_param common = {0};
bt_mesh_role_param_t role_param = {0};
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_generic_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE: {
params = arg->generic_client_get_state.params;
role_param.model = (struct bt_mesh_model *)params->model;
role_param.role = params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
common.opcode = params->opcode;
common.model = (struct bt_mesh_model *)params->model;
common.ctx.net_idx = params->ctx.net_idx;
common.ctx.app_idx = params->ctx.app_idx;
common.ctx.addr = params->ctx.addr;
common.ctx.send_rel = params->ctx.send_rel;
common.ctx.send_ttl = params->ctx.send_ttl;
common.msg_timeout = params->msg_timeout;
generic_client_cb.params = arg->generic_client_get_state.params;
generic_client_cb.error_code =
bt_mesh_generic_client_get_state(&common,
(void *)arg->generic_client_get_state.get_state,
(void *)&generic_client_cb.status_cb);
if (generic_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_generic_client_callback(&generic_client_cb,
ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT);
}
break;
}
case BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE: {
params = arg->generic_client_set_state.params;
role_param.model = (struct bt_mesh_model *)params->model;
role_param.role = params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
common.opcode = params->opcode;
common.model = (struct bt_mesh_model *)params->model;
common.ctx.net_idx = params->ctx.net_idx;
common.ctx.app_idx = params->ctx.app_idx;
common.ctx.addr = params->ctx.addr;
common.ctx.send_rel = params->ctx.send_rel;
common.ctx.send_ttl = params->ctx.send_ttl;
common.msg_timeout = params->msg_timeout;
generic_client_cb.params = arg->generic_client_set_state.params;
generic_client_cb.error_code =
bt_mesh_generic_client_set_state(&common,
(void *)arg->generic_client_set_state.set_state,
(void *)&generic_client_cb.status_cb);
if (generic_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_generic_client_callback(&generic_client_cb,
ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT);
}
break;
}
default:
break;
}
btc_ble_mesh_generic_client_arg_deep_free(msg);
}
void btc_mesh_generic_client_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_generic_client_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
param = (esp_ble_mesh_generic_client_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_GENERIC_CLIENT_EVT_MAX) {
btc_ble_mesh_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_free_req_data(msg);
}

View File

@@ -0,0 +1,593 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_manage.h"
#include "btc/btc_task.h"
#include "osi/allocator.h"
#include "health_srv.h"
#include "health_cli.h"
#include "common.h"
#include "btc_ble_mesh_health.h"
#include "esp_ble_mesh_defs.h"
extern s32_t health_msg_timeout;
static inline void btc_ble_mesh_health_client_cb_to_app(esp_ble_mesh_health_client_cb_event_t event,
esp_ble_mesh_health_client_cb_param_t *param)
{
esp_ble_mesh_health_client_cb_t btc_mesh_cb = (esp_ble_mesh_health_client_cb_t)btc_profile_cb_get(BTC_PID_HEALTH_CLIENT);
if (btc_mesh_cb) {
btc_mesh_cb(event, param);
}
}
static inline void btc_ble_mesh_health_server_cb_to_app(esp_ble_mesh_health_server_cb_event_t event,
esp_ble_mesh_health_server_cb_param_t *param)
{
esp_ble_mesh_health_server_cb_t btc_mesh_cb = (esp_ble_mesh_health_server_cb_t)btc_profile_cb_get(BTC_PID_HEALTH_SERVER);
if (btc_mesh_cb) {
btc_mesh_cb(event, param);
}
}
void btc_ble_mesh_health_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_health_client_args_t *dst = (btc_ble_mesh_health_client_args_t *)p_dest;
btc_ble_mesh_health_client_args_t *src = (btc_ble_mesh_health_client_args_t *)p_src;
if (!msg || !dst || !src) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_HEALTH_CLIENT_GET_STATE: {
dst->health_client_get_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->health_client_get_state.get_state = (esp_ble_mesh_health_client_get_state_t *)osi_malloc(sizeof(esp_ble_mesh_health_client_get_state_t));
if (dst->health_client_get_state.params && dst->health_client_get_state.get_state) {
memcpy(dst->health_client_get_state.params, src->health_client_get_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->health_client_get_state.get_state, src->health_client_get_state.get_state,
sizeof(esp_ble_mesh_health_client_get_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
case BTC_BLE_MESH_ACT_HEALTH_CLIENT_SET_STATE: {
dst->health_client_set_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->health_client_set_state.set_state = (esp_ble_mesh_health_client_set_state_t *)osi_malloc(sizeof(esp_ble_mesh_health_client_set_state_t));
if (dst->health_client_set_state.params && dst->health_client_set_state.set_state) {
memcpy(dst->health_client_set_state.params, src->health_client_set_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->health_client_set_state.set_state, src->health_client_set_state.set_state,
sizeof(esp_ble_mesh_health_client_set_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s Unhandled deep copy %d", __func__, msg->act);
break;
}
}
static void btc_ble_mesh_health_client_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_health_client_args_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_health_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_HEALTH_CLIENT_GET_STATE:
if (arg->health_client_get_state.params) {
osi_free(arg->health_client_get_state.params);
}
if (arg->health_client_get_state.get_state) {
osi_free(arg->health_client_get_state.get_state);
}
break;
case BTC_BLE_MESH_ACT_HEALTH_CLIENT_SET_STATE:
if (arg->health_client_set_state.params) {
osi_free(arg->health_client_set_state.params);
}
if (arg->health_client_set_state.set_state) {
osi_free(arg->health_client_set_state.set_state);
}
break;
default:
break;
}
return;
}
void btc_ble_mesh_health_server_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
if (!msg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE:
break;
default:
break;
}
}
static void btc_ble_mesh_health_server_arg_deep_free(btc_msg_t *msg)
{
if (!msg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE:
break;
default:
break;
}
}
static void btc_ble_mesh_health_client_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_health_client_cb_param_t *p_dest_data = (esp_ble_mesh_health_client_cb_param_t *)p_dest;
esp_ble_mesh_health_client_cb_param_t *p_src_data = (esp_ble_mesh_health_client_cb_param_t *)p_src;
u32_t opcode;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_HEALTH_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_HEALTH_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_HEALTH_CLIENT_PUBLISH_EVT:
if (p_src_data->params) {
opcode = p_src_data->params->opcode;
switch (opcode) {
case OP_HEALTH_CURRENT_STATUS:
if (p_src_data->status_cb.current_status.fault_array) {
length = p_src_data->status_cb.current_status.fault_array->len;
p_dest_data->status_cb.current_status.fault_array = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.current_status.fault_array) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.current_status.fault_array, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.current_status.fault_array,
p_src_data->status_cb.current_status.fault_array->data,
p_src_data->status_cb.current_status.fault_array->len);
}
break;
case OP_HEALTH_FAULT_GET:
case OP_HEALTH_FAULT_CLEAR:
case OP_HEALTH_FAULT_TEST:
case OP_HEALTH_FAULT_STATUS:
if (p_src_data->status_cb.fault_status.fault_array) {
length = p_src_data->status_cb.fault_status.fault_array->len;
p_dest_data->status_cb.fault_status.fault_array = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.fault_status.fault_array) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.fault_status.fault_array, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.fault_status.fault_array,
p_src_data->status_cb.fault_status.fault_array->data,
p_src_data->status_cb.fault_status.fault_array->len);
}
break;
default:
break;
}
}
case ESP_BLE_MESH_HEALTH_CLIENT_TIMEOUT_EVT:
if (p_src_data->params) {
p_dest_data->params = osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
if (p_dest_data->params) {
memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_health_client_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_health_client_cb_param_t *arg = NULL;
u32_t opcode;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (esp_ble_mesh_health_client_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_HEALTH_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_HEALTH_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_HEALTH_CLIENT_PUBLISH_EVT:
if (arg->params) {
opcode = arg->params->opcode;
switch (opcode) {
case OP_HEALTH_CURRENT_STATUS:
bt_mesh_free_buf(arg->status_cb.current_status.fault_array);
break;
case OP_HEALTH_FAULT_GET:
case OP_HEALTH_FAULT_CLEAR:
case OP_HEALTH_FAULT_TEST:
case OP_HEALTH_FAULT_STATUS:
bt_mesh_free_buf(arg->status_cb.fault_status.fault_array);
break;
default:
break;
}
}
case ESP_BLE_MESH_HEALTH_CLIENT_TIMEOUT_EVT:
if (arg->params) {
osi_free(arg->params);
}
break;
default:
break;
}
}
static void btc_ble_mesh_health_server_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
if (!msg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT:
break;
default:
break;
}
}
static void btc_ble_mesh_health_server_free_req_data(btc_msg_t *msg)
{
if (!msg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT:
break;
default:
break;
}
}
static void btc_mesh_health_client_callback(esp_ble_mesh_health_client_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_HEALTH_CLIENT;
msg.act = act;
btc_transfer_context(&msg, cb_params,
sizeof(esp_ble_mesh_health_client_cb_param_t), btc_ble_mesh_health_client_copy_req_data);
}
static void btc_mesh_health_server_callback(esp_ble_mesh_health_server_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_HEALTH_SERVER;
msg.act = act;
btc_transfer_context(&msg, cb_params,
sizeof(esp_ble_mesh_health_server_cb_param_t), btc_ble_mesh_health_server_copy_req_data);
}
int btc_ble_mesh_health_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_get_state_t *get_state,
esp_ble_mesh_health_client_cb_param_t *client_cb)
{
struct bt_mesh_msg_ctx ctx = {0};
if (!params || !client_cb) {
LOG_ERROR("%s: parameter is NULL", __func__);
return -EINVAL;
}
ctx.net_idx = params->ctx.net_idx;
ctx.app_idx = params->ctx.app_idx;
ctx.addr = params->ctx.addr;
ctx.send_rel = params->ctx.send_rel;
ctx.send_ttl = params->ctx.send_ttl;
health_msg_timeout = params->msg_timeout;
switch (params->opcode) {
case ESP_BLE_MESH_MODEL_OP_ATTENTION_GET:
return (client_cb->error_code = bt_mesh_health_attention_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_GET:
return (client_cb->error_code = bt_mesh_health_period_get(&ctx));
case ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_GET:
return (client_cb->error_code = bt_mesh_health_fault_get(&ctx, get_state->fault_get.company_id));
default:
BT_WARN("%s, invalid opcode 0x%x", __func__, params->opcode);
return (client_cb->error_code = -EINVAL);
}
return 0;
}
int btc_ble_mesh_health_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_set_state_t *set_state,
esp_ble_mesh_health_client_cb_param_t *client_cb)
{
struct bt_mesh_msg_ctx ctx = {0};
if (!params || !set_state || !client_cb) {
LOG_ERROR("%s: parameter is NULL", __func__);
return -EINVAL;
}
ctx.net_idx = params->ctx.net_idx;
ctx.app_idx = params->ctx.app_idx;
ctx.addr = params->ctx.addr;
ctx.send_rel = params->ctx.send_rel;
ctx.send_ttl = params->ctx.send_ttl;
health_msg_timeout = params->msg_timeout;
switch (params->opcode) {
case ESP_BLE_MESH_MODEL_OP_ATTENTION_SET:
return (client_cb->error_code =
bt_mesh_health_attention_set(&ctx, set_state->attention_set.attention, true));
case ESP_BLE_MESH_MODEL_OP_ATTENTION_SET_UNACK:
return (client_cb->error_code =
bt_mesh_health_attention_set(&ctx, set_state->attention_set.attention, false));
case ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET:
return (client_cb->error_code =
bt_mesh_health_period_set(&ctx, set_state->period_set.fast_period_divisor, true));
case ESP_BLE_MESH_MODEL_OP_HEALTH_PERIOD_SET_UNACK:
return (client_cb->error_code =
bt_mesh_health_period_set(&ctx, set_state->period_set.fast_period_divisor, false));
case ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST:
return (client_cb->error_code =
bt_mesh_health_fault_test(&ctx, set_state->fault_test.company_id, set_state->fault_test.test_id, true));
case ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_TEST_UNACK:
return (client_cb->error_code =
bt_mesh_health_fault_test(&ctx, set_state->fault_test.company_id, set_state->fault_test.test_id, false));
case ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR:
return (client_cb->error_code =
bt_mesh_health_fault_clear(&ctx, set_state->fault_clear.company_id, true));
case ESP_BLE_MESH_MODEL_OP_HEALTH_FAULT_CLEAR_UNACK:
return (client_cb->error_code =
bt_mesh_health_fault_clear(&ctx, set_state->fault_clear.company_id, false));
default:
BT_WARN("%s, invalid opcode 0x%x", __func__, params->opcode);
return (client_cb->error_code = -EINVAL);
}
return 0;
}
void bt_mesh_callback_health_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, u16_t len)
{
esp_ble_mesh_health_client_cb_param_t cb_params = {0};
esp_ble_mesh_client_common_param_t params = {0};
size_t length;
uint8_t act;
if (!model || !ctx) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
switch (evt_type) {
case 0x00:
act = ESP_BLE_MESH_HEALTH_CLIENT_GET_STATE_EVT;
break;
case 0x01:
act = ESP_BLE_MESH_HEALTH_CLIENT_SET_STATE_EVT;
break;
case 0x02:
act = ESP_BLE_MESH_HEALTH_CLIENT_PUBLISH_EVT;
break;
case 0x03:
act = ESP_BLE_MESH_HEALTH_CLIENT_TIMEOUT_EVT;
break;
default:
LOG_ERROR("%s: unknown health status event type", __func__);
return;
}
params.opcode = opcode;
params.model = (esp_ble_mesh_model_t *)model;
params.ctx.net_idx = ctx->net_idx;
params.ctx.app_idx = ctx->app_idx;
params.ctx.addr = ctx->addr;
params.ctx.recv_ttl = ctx->recv_ttl;
params.ctx.recv_op = ctx->recv_op;
params.ctx.recv_dst = ctx->recv_dst;
cb_params.error_code = 0;
cb_params.params = &params;
if (val && len) {
length = (len <= sizeof(cb_params.status_cb)) ? len : sizeof(cb_params.status_cb);
memcpy(&cb_params.status_cb, val, length);
}
btc_mesh_health_client_callback(&cb_params, act);
}
void btc_mesh_health_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
{
if (!model || !ctx || !buf) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
bt_mesh_callback_health_status_to_btc(opcode, 0x02, model, ctx, buf->data, buf->len);
}
void btc_mesh_health_client_call_handler(btc_msg_t *msg)
{
btc_ble_mesh_health_client_args_t *arg = NULL;
esp_ble_mesh_health_client_cb_param_t health_client_cb = {0};
bt_mesh_role_param_t role_param = {0};
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_health_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_HEALTH_CLIENT_GET_STATE: {
health_client_cb.params = arg->health_client_get_state.params;
role_param.model = (struct bt_mesh_model *)health_client_cb.params->model;
role_param.role = health_client_cb.params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
btc_ble_mesh_health_client_get_state(arg->health_client_get_state.params,
arg->health_client_get_state.get_state,
&health_client_cb);
if (health_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_health_client_callback(&health_client_cb, ESP_BLE_MESH_HEALTH_CLIENT_GET_STATE_EVT);
}
break;
}
case BTC_BLE_MESH_ACT_HEALTH_CLIENT_SET_STATE: {
health_client_cb.params = arg->health_client_set_state.params;
role_param.model = (struct bt_mesh_model *)health_client_cb.params->model;
role_param.role = health_client_cb.params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
btc_ble_mesh_health_client_set_state(arg->health_client_set_state.params,
arg->health_client_set_state.set_state,
&health_client_cb);
if (health_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_health_client_callback(&health_client_cb, ESP_BLE_MESH_HEALTH_CLIENT_SET_STATE_EVT);
}
break;
}
default:
break;
}
btc_ble_mesh_health_client_arg_deep_free(msg);
return;
}
void btc_mesh_health_client_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_health_client_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
param = (esp_ble_mesh_health_client_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_HEALTH_CLIENT_EVT_MAX) {
btc_ble_mesh_health_client_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_health_client_free_req_data(msg);
}
void btc_mesh_health_server_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_health_server_cb_param_t health_server_cb = {0};
btc_ble_mesh_health_server_args_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_health_server_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE: {
health_server_cb.error_code = bt_mesh_fault_update((struct bt_mesh_elem *)arg->fault_update.element);
btc_mesh_health_server_callback(&health_server_cb, ESP_BLE_MESH_HEALTH_SERVER_FAULT_UPDATE_COMPLETE_EVT);
}
default:
break;
}
btc_ble_mesh_health_server_arg_deep_free(msg);
}
void btc_mesh_health_server_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_health_server_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
param = (esp_ble_mesh_health_server_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_HEALTH_SERVER_EVT_MAX) {
btc_ble_mesh_health_server_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_health_server_free_req_data(msg);
}

View File

@@ -0,0 +1,382 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "light_client.h"
#include "btc_ble_mesh_light_client.h"
#include "esp_ble_mesh_lighting_model_api.h"
static inline void btc_ble_mesh_cb_to_app(esp_ble_mesh_light_client_cb_event_t event,
esp_ble_mesh_light_client_cb_param_t *param)
{
esp_ble_mesh_light_client_cb_t btc_mesh_cb = (esp_ble_mesh_light_client_cb_t)btc_profile_cb_get(BTC_PID_LIGHT_CLIENT);
if (btc_mesh_cb) {
btc_mesh_cb(event, param);
}
}
void btc_ble_mesh_light_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_light_client_args_t *dst = (btc_ble_mesh_light_client_args_t *)p_dest;
btc_ble_mesh_light_client_args_t *src = (btc_ble_mesh_light_client_args_t *)p_src;
if (!msg || !dst || !src) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_LIGHT_CLIENT_GET_STATE: {
dst->light_client_get_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->light_client_get_state.get_state = (esp_ble_mesh_light_client_get_state_t *)osi_malloc(sizeof(esp_ble_mesh_light_client_get_state_t));
if (dst->light_client_get_state.params && dst->light_client_get_state.get_state) {
memcpy(dst->light_client_get_state.params, src->light_client_get_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->light_client_get_state.get_state, src->light_client_get_state.get_state,
sizeof(esp_ble_mesh_light_client_get_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
case BTC_BLE_MESH_ACT_LIGHT_CLIENT_SET_STATE: {
dst->light_client_set_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->light_client_set_state.set_state = (esp_ble_mesh_light_client_set_state_t *)osi_malloc(sizeof(esp_ble_mesh_light_client_set_state_t));
if (dst->light_client_set_state.params && dst->light_client_set_state.set_state) {
memcpy(dst->light_client_set_state.params, src->light_client_set_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->light_client_set_state.set_state, src->light_client_set_state.set_state,
sizeof(esp_ble_mesh_light_client_set_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s Unhandled deep copy %d", __func__, msg->act);
break;
}
}
static void btc_ble_mesh_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_light_client_cb_param_t *p_dest_data = (esp_ble_mesh_light_client_cb_param_t *)p_dest;
esp_ble_mesh_light_client_cb_param_t *p_src_data = (esp_ble_mesh_light_client_cb_param_t *)p_src;
u32_t opcode;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_LIGHT_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_LIGHT_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_LIGHT_CLIENT_PUBLISH_EVT:
if (p_src_data->params) {
opcode = p_src_data->params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS:
if (p_src_data->status_cb.lc_property_status.property_value) {
length = p_src_data->status_cb.lc_property_status.property_value->len;
p_dest_data->status_cb.lc_property_status.property_value = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.lc_property_status.property_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.lc_property_status.property_value, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.lc_property_status.property_value,
p_src_data->status_cb.lc_property_status.property_value->data,
p_src_data->status_cb.lc_property_status.property_value->len);
}
break;
default:
break;
}
}
case ESP_BLE_MESH_LIGHT_CLIENT_TIMEOUT_EVT:
if (p_src_data->params) {
p_dest_data->params = osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
if (p_dest_data->params) {
memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_light_client_cb_param_t *arg = NULL;
u32_t opcode;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (esp_ble_mesh_light_client_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_LIGHT_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_LIGHT_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_LIGHT_CLIENT_PUBLISH_EVT:
if (arg->params) {
opcode = arg->params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_GET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_SET:
case ESP_BLE_MESH_MODEL_OP_LIGHT_LC_PROPERTY_STATUS:
bt_mesh_free_buf(arg->status_cb.lc_property_status.property_value);
break;
default:
break;
}
}
case ESP_BLE_MESH_LIGHT_CLIENT_TIMEOUT_EVT:
if (arg->params) {
osi_free(arg->params);
}
break;
default:
break;
}
}
void btc_ble_mesh_light_client_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_light_client_args_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_light_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_LIGHT_CLIENT_GET_STATE:
if (arg->light_client_get_state.params) {
osi_free(arg->light_client_get_state.params);
}
if (arg->light_client_get_state.get_state) {
osi_free(arg->light_client_get_state.get_state);
}
break;
case BTC_BLE_MESH_ACT_LIGHT_CLIENT_SET_STATE:
if (arg->light_client_set_state.params) {
osi_free(arg->light_client_set_state.params);
}
if (arg->light_client_set_state.set_state) {
osi_free(arg->light_client_set_state.set_state);
}
break;
default:
break;
}
return;
}
static void btc_mesh_light_client_callback(esp_ble_mesh_light_client_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_LIGHT_CLIENT;
msg.act = act;
btc_transfer_context(&msg, cb_params,
sizeof(esp_ble_mesh_light_client_cb_param_t), btc_ble_mesh_copy_req_data);
}
void bt_mesh_callback_light_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_light_client_cb_param_t cb_params = {0};
esp_ble_mesh_client_common_param_t params = {0};
size_t length;
uint8_t act;
if (!model || !ctx) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
switch (evt_type) {
case 0x00:
act = ESP_BLE_MESH_LIGHT_CLIENT_GET_STATE_EVT;
break;
case 0x01:
act = ESP_BLE_MESH_LIGHT_CLIENT_SET_STATE_EVT;
break;
case 0x02:
act = ESP_BLE_MESH_LIGHT_CLIENT_PUBLISH_EVT;
break;
case 0x03:
act = ESP_BLE_MESH_LIGHT_CLIENT_TIMEOUT_EVT;
break;
default:
LOG_ERROR("%s: unknown light status event type", __func__);
return;
}
params.opcode = opcode;
params.model = (esp_ble_mesh_model_t *)model;
params.ctx.net_idx = ctx->net_idx;
params.ctx.app_idx = ctx->app_idx;
params.ctx.addr = ctx->addr;
params.ctx.recv_ttl = ctx->recv_ttl;
params.ctx.recv_op = ctx->recv_op;
params.ctx.recv_dst = ctx->recv_dst;
cb_params.error_code = 0;
cb_params.params = &params;
if (val && len) {
length = (len <= sizeof(cb_params.status_cb)) ? len : sizeof(cb_params.status_cb);
memcpy(&cb_params.status_cb, val, length);
}
btc_mesh_light_client_callback(&cb_params, act);
}
void btc_mesh_light_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
{
if (!model || !ctx || !buf) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
bt_mesh_callback_light_status_to_btc(opcode, 0x02, model, ctx, buf->data, buf->len);
}
void btc_mesh_light_client_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_light_client_cb_param_t light_client_cb = {0};
esp_ble_mesh_client_common_param_t *params = NULL;
btc_ble_mesh_light_client_args_t *arg = NULL;
struct bt_mesh_common_param common = {0};
bt_mesh_role_param_t role_param = {0};
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_light_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_LIGHT_CLIENT_GET_STATE: {
params = arg->light_client_get_state.params;
role_param.model = (struct bt_mesh_model *)params->model;
role_param.role = params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
common.opcode = params->opcode;
common.model = (struct bt_mesh_model *)params->model;
common.ctx.net_idx = params->ctx.net_idx;
common.ctx.app_idx = params->ctx.app_idx;
common.ctx.addr = params->ctx.addr;
common.ctx.send_rel = params->ctx.send_rel;
common.ctx.send_ttl = params->ctx.send_ttl;
common.msg_timeout = params->msg_timeout;
light_client_cb.params = arg->light_client_get_state.params;
light_client_cb.error_code =
bt_mesh_light_client_get_state(&common,
(void *)arg->light_client_get_state.get_state,
(void *)&light_client_cb.status_cb);
if (light_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_light_client_callback(&light_client_cb,
ESP_BLE_MESH_LIGHT_CLIENT_GET_STATE_EVT);
}
break;
}
case BTC_BLE_MESH_ACT_LIGHT_CLIENT_SET_STATE: {
params = arg->light_client_set_state.params;
role_param.model = (struct bt_mesh_model *)params->model;
role_param.role = params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
common.opcode = params->opcode;
common.model = (struct bt_mesh_model *)params->model;
common.ctx.net_idx = params->ctx.net_idx;
common.ctx.app_idx = params->ctx.app_idx;
common.ctx.addr = params->ctx.addr;
common.ctx.send_rel = params->ctx.send_rel;
common.ctx.send_ttl = params->ctx.send_ttl;
common.msg_timeout = params->msg_timeout;
light_client_cb.params = arg->light_client_set_state.params;
light_client_cb.error_code =
bt_mesh_light_client_set_state(&common,
(void *)arg->light_client_set_state.set_state,
(void *)&light_client_cb.status_cb);
if (light_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_light_client_callback(&light_client_cb,
ESP_BLE_MESH_LIGHT_CLIENT_SET_STATE_EVT);
}
break;
}
default:
break;
}
btc_ble_mesh_light_client_arg_deep_free(msg);
}
void btc_mesh_light_client_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_light_client_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
param = (esp_ble_mesh_light_client_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_LIGHT_CLIENT_EVT_MAX) {
btc_ble_mesh_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_free_req_data(msg);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,647 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "sensor_client.h"
#include "btc_ble_mesh_sensor_client.h"
#include "esp_ble_mesh_sensor_model_api.h"
static inline void btc_ble_mesh_cb_to_app(esp_ble_mesh_sensor_client_cb_event_t event,
esp_ble_mesh_sensor_client_cb_param_t *param)
{
esp_ble_mesh_sensor_client_cb_t btc_mesh_cb = (esp_ble_mesh_sensor_client_cb_t)btc_profile_cb_get(BTC_PID_SENSOR_CLIENT);
if (btc_mesh_cb) {
btc_mesh_cb(event, param);
}
}
void btc_ble_mesh_sensor_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_sensor_client_args_t *dst = (btc_ble_mesh_sensor_client_args_t *)p_dest;
btc_ble_mesh_sensor_client_args_t *src = (btc_ble_mesh_sensor_client_args_t *)p_src;
u32_t opcode;
u16_t length;
if (!msg || !dst || !src) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_SENSOR_CLIENT_GET_STATE: {
dst->sensor_client_get_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->sensor_client_get_state.get_state = (esp_ble_mesh_sensor_client_get_state_t *)osi_malloc(sizeof(esp_ble_mesh_sensor_client_get_state_t));
if (dst->sensor_client_get_state.params && dst->sensor_client_get_state.get_state) {
memcpy(dst->sensor_client_get_state.params, src->sensor_client_get_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->sensor_client_get_state.get_state, src->sensor_client_get_state.get_state,
sizeof(esp_ble_mesh_sensor_client_get_state_t));
opcode = src->sensor_client_get_state.params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET:
if (src->sensor_client_get_state.get_state->column_get.raw_value_x) {
length = src->sensor_client_get_state.get_state->column_get.raw_value_x->len;
dst->sensor_client_get_state.get_state->column_get.raw_value_x = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_get_state.get_state->column_get.raw_value_x) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->sensor_client_get_state.get_state->column_get.raw_value_x, 0);
net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->column_get.raw_value_x,
src->sensor_client_get_state.get_state->column_get.raw_value_x->data,
src->sensor_client_get_state.get_state->column_get.raw_value_x->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET:
if (src->sensor_client_get_state.get_state->series_get.raw_value_x1) {
length = src->sensor_client_get_state.get_state->series_get.raw_value_x1->len;
dst->sensor_client_get_state.get_state->series_get.raw_value_x1 = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_get_state.get_state->series_get.raw_value_x1) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->sensor_client_get_state.get_state->series_get.raw_value_x1, 0);
net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->series_get.raw_value_x1,
src->sensor_client_get_state.get_state->series_get.raw_value_x1->data,
src->sensor_client_get_state.get_state->series_get.raw_value_x1->len);
}
if (src->sensor_client_get_state.get_state->series_get.raw_value_x2) {
length = src->sensor_client_get_state.get_state->series_get.raw_value_x2->len;
dst->sensor_client_get_state.get_state->series_get.raw_value_x2 = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_get_state.get_state->series_get.raw_value_x2) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->sensor_client_get_state.get_state->series_get.raw_value_x2, 0);
net_buf_simple_add_mem(dst->sensor_client_get_state.get_state->series_get.raw_value_x2,
src->sensor_client_get_state.get_state->series_get.raw_value_x2->data,
src->sensor_client_get_state.get_state->series_get.raw_value_x2->len);
}
break;
default:
break;
}
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
case BTC_BLE_MESH_ACT_SENSOR_CLIENT_SET_STATE: {
dst->sensor_client_set_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->sensor_client_set_state.set_state = (esp_ble_mesh_sensor_client_set_state_t *)osi_malloc(sizeof(esp_ble_mesh_sensor_client_set_state_t));
if (dst->sensor_client_set_state.params && dst->sensor_client_set_state.set_state) {
memcpy(dst->sensor_client_set_state.params, src->sensor_client_set_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->sensor_client_set_state.set_state, src->sensor_client_set_state.set_state,
sizeof(esp_ble_mesh_sensor_client_set_state_t));
opcode = src->sensor_client_set_state.params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET:
if (src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) {
length = src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->len;
dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down, 0);
net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down,
src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->data,
src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down->len);
}
if (src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) {
length = src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->len;
dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up, 0);
net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up,
src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->data,
src->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up->len);
}
if (src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low) {
length = src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->len;
dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low, 0);
net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_low,
src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->data,
src->sensor_client_set_state.set_state->cadence_set.fast_cadence_low->len);
}
if (src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high) {
length = src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->len;
dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high, 0);
net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->cadence_set.fast_cadence_high,
src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->data,
src->sensor_client_set_state.set_state->cadence_set.fast_cadence_high->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET:
if (src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw) {
length = src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->len;
dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw = bt_mesh_alloc_buf(length);
if (!dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw, 0);
net_buf_simple_add_mem(dst->sensor_client_set_state.set_state->setting_set.sensor_setting_raw,
src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->data,
src->sensor_client_set_state.set_state->setting_set.sensor_setting_raw->len);
}
break;
default:
break;
}
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s Unhandled deep copy %d", __func__, msg->act);
break;
}
}
static void btc_ble_mesh_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_sensor_client_cb_param_t *p_dest_data = (esp_ble_mesh_sensor_client_cb_param_t *)p_dest;
esp_ble_mesh_sensor_client_cb_param_t *p_src_data = (esp_ble_mesh_sensor_client_cb_param_t *)p_src;
u32_t opcode;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_SENSOR_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_SENSOR_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_SENSOR_CLIENT_PUBLISH_EVT:
if (p_src_data->params) {
opcode = p_src_data->params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS:
if (p_src_data->status_cb.descriptor_status.descriptor) {
length = p_src_data->status_cb.descriptor_status.descriptor->len;
p_dest_data->status_cb.descriptor_status.descriptor = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.descriptor_status.descriptor) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.descriptor_status.descriptor, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.descriptor_status.descriptor,
p_src_data->status_cb.descriptor_status.descriptor->data,
p_src_data->status_cb.descriptor_status.descriptor->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS:
if (p_src_data->status_cb.cadence_status.sensor_cadence_value) {
length = p_src_data->status_cb.cadence_status.sensor_cadence_value->len;
p_dest_data->status_cb.cadence_status.sensor_cadence_value = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.cadence_status.sensor_cadence_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.cadence_status.sensor_cadence_value, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.cadence_status.sensor_cadence_value,
p_src_data->status_cb.cadence_status.sensor_cadence_value->data,
p_src_data->status_cb.cadence_status.sensor_cadence_value->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS:
if (p_src_data->status_cb.settings_status.sensor_setting_property_ids) {
length = p_src_data->status_cb.settings_status.sensor_setting_property_ids->len;
p_dest_data->status_cb.settings_status.sensor_setting_property_ids = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.settings_status.sensor_setting_property_ids) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.settings_status.sensor_setting_property_ids, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.settings_status.sensor_setting_property_ids,
p_src_data->status_cb.settings_status.sensor_setting_property_ids->data,
p_src_data->status_cb.settings_status.sensor_setting_property_ids->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS:
if (p_src_data->status_cb.setting_status.sensor_setting_raw) {
length = p_src_data->status_cb.setting_status.sensor_setting_raw->len;
p_dest_data->status_cb.setting_status.sensor_setting_raw = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.setting_status.sensor_setting_raw) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.setting_status.sensor_setting_raw, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.setting_status.sensor_setting_raw,
p_src_data->status_cb.setting_status.sensor_setting_raw->data,
p_src_data->status_cb.setting_status.sensor_setting_raw->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_STATUS:
if (p_src_data->status_cb.sensor_status.marshalled_sensor_data) {
length = p_src_data->status_cb.sensor_status.marshalled_sensor_data->len;
p_dest_data->status_cb.sensor_status.marshalled_sensor_data = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.sensor_status.marshalled_sensor_data) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.sensor_status.marshalled_sensor_data, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.sensor_status.marshalled_sensor_data,
p_src_data->status_cb.sensor_status.marshalled_sensor_data->data,
p_src_data->status_cb.sensor_status.marshalled_sensor_data->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS:
if (p_src_data->status_cb.column_status.sensor_column_value) {
length = p_src_data->status_cb.column_status.sensor_column_value->len;
p_dest_data->status_cb.column_status.sensor_column_value = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.column_status.sensor_column_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.column_status.sensor_column_value, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.column_status.sensor_column_value,
p_src_data->status_cb.column_status.sensor_column_value->data,
p_src_data->status_cb.column_status.sensor_column_value->len);
}
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS:
if (p_src_data->status_cb.series_status.sensor_series_value) {
length = p_src_data->status_cb.series_status.sensor_series_value->len;
p_dest_data->status_cb.series_status.sensor_series_value = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.series_status.sensor_series_value) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.series_status.sensor_series_value, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.series_status.sensor_series_value,
p_src_data->status_cb.series_status.sensor_series_value->data,
p_src_data->status_cb.series_status.sensor_series_value->len);
}
break;
default:
break;
}
}
case ESP_BLE_MESH_SENSOR_CLIENT_TIMEOUT_EVT:
if (p_src_data->params) {
p_dest_data->params = osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
if (p_dest_data->params) {
memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_sensor_client_cb_param_t *arg = NULL;
u32_t opcode;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (esp_ble_mesh_sensor_client_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_SENSOR_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_SENSOR_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_SENSOR_CLIENT_PUBLISH_EVT:
if (arg->params) {
opcode = arg->params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_DESCRIPTOR_STATUS:
bt_mesh_free_buf(arg->status_cb.descriptor_status.descriptor);
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_STATUS:
bt_mesh_free_buf(arg->status_cb.cadence_status.sensor_cadence_value);
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTINGS_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTINGS_STATUS:
bt_mesh_free_buf(arg->status_cb.settings_status.sensor_setting_property_ids);
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_STATUS:
bt_mesh_free_buf(arg->status_cb.setting_status.sensor_setting_raw);
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_STATUS:
bt_mesh_free_buf(arg->status_cb.sensor_status.marshalled_sensor_data);
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_STATUS:
bt_mesh_free_buf(arg->status_cb.column_status.sensor_column_value);
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET:
case ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_STATUS:
bt_mesh_free_buf(arg->status_cb.series_status.sensor_series_value);
break;
default:
break;
}
}
case ESP_BLE_MESH_SENSOR_CLIENT_TIMEOUT_EVT:
if (arg->params) {
osi_free(arg->params);
}
break;
default:
break;
}
}
void btc_ble_mesh_sensor_client_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_sensor_client_args_t *arg = NULL;
u32_t opcode = 0;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_sensor_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_SENSOR_CLIENT_GET_STATE:
if (arg->sensor_client_get_state.params) {
opcode = arg->sensor_client_get_state.params->opcode;
osi_free(arg->sensor_client_get_state.params);
}
if (arg->sensor_client_get_state.get_state) {
if (opcode) {
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_SENSOR_COLUMN_GET:
bt_mesh_free_buf(arg->sensor_client_get_state.get_state->column_get.raw_value_x);
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SERIES_GET:
bt_mesh_free_buf(arg->sensor_client_get_state.get_state->series_get.raw_value_x1);
bt_mesh_free_buf(arg->sensor_client_get_state.get_state->series_get.raw_value_x2);
break;
default:
break;
}
}
osi_free(arg->sensor_client_get_state.get_state);
}
break;
case BTC_BLE_MESH_ACT_SENSOR_CLIENT_SET_STATE:
if (arg->sensor_client_set_state.params) {
opcode = arg->sensor_client_set_state.params->opcode;
osi_free(arg->sensor_client_set_state.params);
}
if (arg->sensor_client_set_state.set_state) {
if (opcode) {
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_SENSOR_CADENCE_SET:
bt_mesh_free_buf(arg->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_down);
bt_mesh_free_buf(arg->sensor_client_set_state.set_state->cadence_set.status_trigger_delta_up);
bt_mesh_free_buf(arg->sensor_client_set_state.set_state->cadence_set.fast_cadence_low);
bt_mesh_free_buf(arg->sensor_client_set_state.set_state->cadence_set.fast_cadence_high);
break;
case ESP_BLE_MESH_MODEL_OP_SENSOR_SETTING_SET:
bt_mesh_free_buf(arg->sensor_client_set_state.set_state->setting_set.sensor_setting_raw);
break;
default:
break;
}
}
osi_free(arg->sensor_client_set_state.set_state);
}
break;
default:
break;
}
return;
}
static void btc_mesh_sensor_client_callback(esp_ble_mesh_sensor_client_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_SENSOR_CLIENT;
msg.act = act;
btc_transfer_context(&msg, cb_params,
sizeof(esp_ble_mesh_sensor_client_cb_param_t), btc_ble_mesh_copy_req_data);
}
void bt_mesh_callback_sensor_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_sensor_client_cb_param_t cb_params = {0};
esp_ble_mesh_client_common_param_t params = {0};
size_t length;
uint8_t act;
if (!model || !ctx) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
switch (evt_type) {
case 0x00:
act = ESP_BLE_MESH_SENSOR_CLIENT_GET_STATE_EVT;
break;
case 0x01:
act = ESP_BLE_MESH_SENSOR_CLIENT_SET_STATE_EVT;
break;
case 0x02:
act = ESP_BLE_MESH_SENSOR_CLIENT_PUBLISH_EVT;
break;
case 0x03:
act = ESP_BLE_MESH_SENSOR_CLIENT_TIMEOUT_EVT;
break;
default:
LOG_ERROR("%s: unknown sensor status event type", __func__);
return;
}
params.opcode = opcode;
params.model = (esp_ble_mesh_model_t *)model;
params.ctx.net_idx = ctx->net_idx;
params.ctx.app_idx = ctx->app_idx;
params.ctx.addr = ctx->addr;
params.ctx.recv_ttl = ctx->recv_ttl;
params.ctx.recv_op = ctx->recv_op;
params.ctx.recv_dst = ctx->recv_dst;
cb_params.error_code = 0;
cb_params.params = &params;
if (val && len) {
length = (len <= sizeof(cb_params.status_cb)) ? len : sizeof(cb_params.status_cb);
memcpy(&cb_params.status_cb, val, length);
}
btc_mesh_sensor_client_callback(&cb_params, act);
}
void btc_mesh_sensor_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
{
if (!model || !ctx || !buf) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
bt_mesh_callback_sensor_status_to_btc(opcode, 0x02, model, ctx, buf->data, buf->len);
}
void btc_mesh_sensor_client_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_sensor_client_cb_param_t sensor_client_cb = {0};
esp_ble_mesh_client_common_param_t *params = NULL;
btc_ble_mesh_sensor_client_args_t *arg = NULL;
struct bt_mesh_common_param common = {0};
bt_mesh_role_param_t role_param = {0};
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_sensor_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_SENSOR_CLIENT_GET_STATE: {
params = arg->sensor_client_get_state.params;
role_param.model = (struct bt_mesh_model *)params->model;
role_param.role = params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
common.opcode = params->opcode;
common.model = (struct bt_mesh_model *)params->model;
common.ctx.net_idx = params->ctx.net_idx;
common.ctx.app_idx = params->ctx.app_idx;
common.ctx.addr = params->ctx.addr;
common.ctx.send_rel = params->ctx.send_rel;
common.ctx.send_ttl = params->ctx.send_ttl;
common.msg_timeout = params->msg_timeout;
sensor_client_cb.params = arg->sensor_client_get_state.params;
sensor_client_cb.error_code =
bt_mesh_sensor_client_get_state(&common,
(void *)arg->sensor_client_get_state.get_state,
(void *)&sensor_client_cb.status_cb);
if (sensor_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_sensor_client_callback(&sensor_client_cb,
ESP_BLE_MESH_SENSOR_CLIENT_GET_STATE_EVT);
}
break;
}
case BTC_BLE_MESH_ACT_SENSOR_CLIENT_SET_STATE: {
params = arg->sensor_client_set_state.params;
role_param.model = (struct bt_mesh_model *)params->model;
role_param.role = params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
common.opcode = params->opcode;
common.model = (struct bt_mesh_model *)params->model;
common.ctx.net_idx = params->ctx.net_idx;
common.ctx.app_idx = params->ctx.app_idx;
common.ctx.addr = params->ctx.addr;
common.ctx.send_rel = params->ctx.send_rel;
common.ctx.send_ttl = params->ctx.send_ttl;
common.msg_timeout = params->msg_timeout;
sensor_client_cb.params = arg->sensor_client_set_state.params;
sensor_client_cb.error_code =
bt_mesh_sensor_client_set_state(&common,
(void *)arg->sensor_client_set_state.set_state,
(void *)&sensor_client_cb.status_cb);
if (sensor_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_sensor_client_callback(&sensor_client_cb,
ESP_BLE_MESH_SENSOR_CLIENT_SET_STATE_EVT);
}
break;
}
default:
break;
}
btc_ble_mesh_sensor_client_arg_deep_free(msg);
}
void btc_mesh_sensor_client_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_sensor_client_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
param = (esp_ble_mesh_sensor_client_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_SENSOR_CLIENT_EVT_MAX) {
btc_ble_mesh_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_free_req_data(msg);
}

View File

@@ -0,0 +1,384 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <string.h>
#include <errno.h>
#include "btc/btc_manage.h"
#include "osi/allocator.h"
#include "time_scene_client.h"
#include "btc_ble_mesh_time_scene_client.h"
#include "esp_ble_mesh_time_scene_model_api.h"
static inline void btc_ble_mesh_cb_to_app(esp_ble_mesh_time_scene_client_cb_event_t event,
esp_ble_mesh_time_scene_client_cb_param_t *param)
{
esp_ble_mesh_time_scene_client_cb_t btc_mesh_cb = (esp_ble_mesh_time_scene_client_cb_t)btc_profile_cb_get(BTC_PID_TIME_SCENE_CLIENT);
if (btc_mesh_cb) {
btc_mesh_cb(event, param);
}
}
void btc_ble_mesh_time_scene_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
btc_ble_mesh_time_scene_client_args_t *dst = (btc_ble_mesh_time_scene_client_args_t *)p_dest;
btc_ble_mesh_time_scene_client_args_t *src = (btc_ble_mesh_time_scene_client_args_t *)p_src;
if (!msg || !dst || !src) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_GET_STATE: {
dst->time_scene_client_get_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->time_scene_client_get_state.get_state = (esp_ble_mesh_time_scene_client_get_state_t *)osi_malloc(sizeof(esp_ble_mesh_time_scene_client_get_state_t));
if (dst->time_scene_client_get_state.params && dst->time_scene_client_get_state.get_state) {
memcpy(dst->time_scene_client_get_state.params, src->time_scene_client_get_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->time_scene_client_get_state.get_state, src->time_scene_client_get_state.get_state,
sizeof(esp_ble_mesh_time_scene_client_get_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
case BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_SET_STATE: {
dst->time_scene_client_set_state.params = (esp_ble_mesh_client_common_param_t *)osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
dst->time_scene_client_set_state.set_state = (esp_ble_mesh_time_scene_client_set_state_t *)osi_malloc(sizeof(esp_ble_mesh_time_scene_client_set_state_t));
if (dst->time_scene_client_set_state.params && dst->time_scene_client_set_state.set_state) {
memcpy(dst->time_scene_client_set_state.params, src->time_scene_client_set_state.params,
sizeof(esp_ble_mesh_client_common_param_t));
memcpy(dst->time_scene_client_set_state.set_state, src->time_scene_client_set_state.set_state,
sizeof(esp_ble_mesh_time_scene_client_set_state_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s Unhandled deep copy %d", __func__, msg->act);
break;
}
}
static void btc_ble_mesh_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_mesh_time_scene_client_cb_param_t *p_dest_data = (esp_ble_mesh_time_scene_client_cb_param_t *)p_dest;
esp_ble_mesh_time_scene_client_cb_param_t *p_src_data = (esp_ble_mesh_time_scene_client_cb_param_t *)p_src;
u32_t opcode;
u16_t length;
if (!msg || !p_src_data || !p_dest_data) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
switch (msg->act) {
case ESP_BLE_MESH_TIME_SCENE_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_TIME_SCENE_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_TIME_SCENE_CLIENT_PUBLISH_EVT:
if (p_src_data->params) {
opcode = p_src_data->params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_SCENE_STORE:
case ESP_BLE_MESH_MODEL_OP_SCENE_REGISTER_GET:
case ESP_BLE_MESH_MODEL_OP_SCENE_DELETE:
case ESP_BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS:
if (p_src_data->status_cb.scene_register_status.scenes) {
length = p_src_data->status_cb.scene_register_status.scenes->len;
p_dest_data->status_cb.scene_register_status.scenes = bt_mesh_alloc_buf(length);
if (!p_dest_data->status_cb.scene_register_status.scenes) {
LOG_ERROR("%s %d no mem", __func__, msg->act);
return;
}
net_buf_simple_init(p_dest_data->status_cb.scene_register_status.scenes, 0);
net_buf_simple_add_mem(p_dest_data->status_cb.scene_register_status.scenes,
p_src_data->status_cb.scene_register_status.scenes->data,
p_src_data->status_cb.scene_register_status.scenes->len);
}
break;
default:
break;
}
}
case ESP_BLE_MESH_TIME_SCENE_CLIENT_TIMEOUT_EVT:
if (p_src_data->params) {
p_dest_data->params = osi_malloc(sizeof(esp_ble_mesh_client_common_param_t));
if (p_dest_data->params) {
memcpy(p_dest_data->params, p_src_data->params, sizeof(esp_ble_mesh_client_common_param_t));
} else {
LOG_ERROR("%s %d no mem", __func__, msg->act);
}
}
break;
default:
break;
}
}
static void btc_ble_mesh_free_req_data(btc_msg_t *msg)
{
esp_ble_mesh_time_scene_client_cb_param_t *arg = NULL;
u32_t opcode;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (esp_ble_mesh_time_scene_client_cb_param_t *)(msg->arg);
switch (msg->act) {
case ESP_BLE_MESH_TIME_SCENE_CLIENT_GET_STATE_EVT:
case ESP_BLE_MESH_TIME_SCENE_CLIENT_SET_STATE_EVT:
case ESP_BLE_MESH_TIME_SCENE_CLIENT_PUBLISH_EVT:
if (arg->params) {
opcode = arg->params->opcode;
switch (opcode) {
case ESP_BLE_MESH_MODEL_OP_SCENE_STORE:
case ESP_BLE_MESH_MODEL_OP_SCENE_REGISTER_GET:
case ESP_BLE_MESH_MODEL_OP_SCENE_DELETE:
case ESP_BLE_MESH_MODEL_OP_SCENE_REGISTER_STATUS:
bt_mesh_free_buf(arg->status_cb.scene_register_status.scenes);
break;
default:
break;
}
}
case ESP_BLE_MESH_TIME_SCENE_CLIENT_TIMEOUT_EVT:
if (arg->params) {
osi_free(arg->params);
}
break;
default:
break;
}
}
void btc_ble_mesh_time_scene_client_arg_deep_free(btc_msg_t *msg)
{
btc_ble_mesh_time_scene_client_args_t *arg = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_time_scene_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_GET_STATE:
if (arg->time_scene_client_get_state.params) {
osi_free(arg->time_scene_client_get_state.params);
}
if (arg->time_scene_client_get_state.get_state) {
osi_free(arg->time_scene_client_get_state.get_state);
}
break;
case BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_SET_STATE:
if (arg->time_scene_client_set_state.params) {
osi_free(arg->time_scene_client_set_state.params);
}
if (arg->time_scene_client_set_state.set_state) {
osi_free(arg->time_scene_client_set_state.set_state);
}
break;
default:
break;
}
return;
}
static void btc_mesh_time_scene_client_callback(esp_ble_mesh_time_scene_client_cb_param_t *cb_params, uint8_t act)
{
btc_msg_t msg = {0};
LOG_DEBUG("%s", __func__);
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_TIME_SCENE_CLIENT;
msg.act = act;
btc_transfer_context(&msg, cb_params,
sizeof(esp_ble_mesh_time_scene_client_cb_param_t), btc_ble_mesh_copy_req_data);
}
void bt_mesh_callback_time_scene_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len)
{
esp_ble_mesh_time_scene_client_cb_param_t cb_params = {0};
esp_ble_mesh_client_common_param_t params = {0};
size_t length;
uint8_t act;
if (!model || !ctx) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
switch (evt_type) {
case 0x00:
act = ESP_BLE_MESH_TIME_SCENE_CLIENT_GET_STATE_EVT;
break;
case 0x01:
act = ESP_BLE_MESH_TIME_SCENE_CLIENT_SET_STATE_EVT;
break;
case 0x02:
act = ESP_BLE_MESH_TIME_SCENE_CLIENT_PUBLISH_EVT;
break;
case 0x03:
act = ESP_BLE_MESH_TIME_SCENE_CLIENT_TIMEOUT_EVT;
break;
default:
LOG_ERROR("%s: unknown time scene status event type", __func__);
return;
}
params.opcode = opcode;
params.model = (esp_ble_mesh_model_t *)model;
params.ctx.net_idx = ctx->net_idx;
params.ctx.app_idx = ctx->app_idx;
params.ctx.addr = ctx->addr;
params.ctx.recv_ttl = ctx->recv_ttl;
params.ctx.recv_op = ctx->recv_op;
params.ctx.recv_dst = ctx->recv_dst;
cb_params.error_code = 0;
cb_params.params = &params;
if (val && len) {
length = (len <= sizeof(cb_params.status_cb)) ? len : sizeof(cb_params.status_cb);
memcpy(&cb_params.status_cb, val, length);
}
btc_mesh_time_scene_client_callback(&cb_params, act);
}
void btc_mesh_time_scene_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
{
if (!model || !ctx || !buf) {
LOG_ERROR("%s: invalid parameter", __func__);
return;
}
bt_mesh_callback_time_scene_status_to_btc(opcode, 0x02, model, ctx, buf->data, buf->len);
}
void btc_mesh_time_scene_client_call_handler(btc_msg_t *msg)
{
esp_ble_mesh_time_scene_client_cb_param_t time_scene_client_cb = {0};
btc_ble_mesh_time_scene_client_args_t *arg = NULL;
esp_ble_mesh_client_common_param_t *params = NULL;
struct bt_mesh_common_param common = {0};
bt_mesh_role_param_t role_param = {0};
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
arg = (btc_ble_mesh_time_scene_client_args_t *)(msg->arg);
switch (msg->act) {
case BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_GET_STATE: {
params = arg->time_scene_client_get_state.params;
role_param.model = (struct bt_mesh_model *)params->model;
role_param.role = params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
common.opcode = params->opcode;
common.model = (struct bt_mesh_model *)params->model;
common.ctx.net_idx = params->ctx.net_idx;
common.ctx.app_idx = params->ctx.app_idx;
common.ctx.addr = params->ctx.addr;
common.ctx.send_rel = params->ctx.send_rel;
common.ctx.send_ttl = params->ctx.send_ttl;
common.msg_timeout = params->msg_timeout;
time_scene_client_cb.params = arg->time_scene_client_get_state.params;
time_scene_client_cb.error_code =
bt_mesh_time_scene_client_get_state(&common,
(void *)arg->time_scene_client_get_state.get_state,
(void *)&time_scene_client_cb.status_cb);
if (time_scene_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_time_scene_client_callback(&time_scene_client_cb,
ESP_BLE_MESH_TIME_SCENE_CLIENT_GET_STATE_EVT);
}
break;
}
case BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_SET_STATE: {
params = arg->time_scene_client_set_state.params;
role_param.model = (struct bt_mesh_model *)params->model;
role_param.role = params->msg_role;
if (bt_mesh_copy_msg_role(&role_param)) {
LOG_ERROR("%s: copy msg_role fail", __func__);
return;
}
common.opcode = params->opcode;
common.model = (struct bt_mesh_model *)params->model;
common.ctx.net_idx = params->ctx.net_idx;
common.ctx.app_idx = params->ctx.app_idx;
common.ctx.addr = params->ctx.addr;
common.ctx.send_rel = params->ctx.send_rel;
common.ctx.send_ttl = params->ctx.send_ttl;
common.msg_timeout = params->msg_timeout;
time_scene_client_cb.params = arg->time_scene_client_set_state.params;
time_scene_client_cb.error_code =
bt_mesh_time_scene_client_set_state(&common,
(void *)arg->time_scene_client_set_state.set_state,
(void *)&time_scene_client_cb.status_cb);
if (time_scene_client_cb.error_code) {
/* If send failed, callback error_code to app layer immediately */
btc_mesh_time_scene_client_callback(&time_scene_client_cb,
ESP_BLE_MESH_TIME_SCENE_CLIENT_SET_STATE_EVT);
}
break;
}
default:
break;
}
btc_ble_mesh_time_scene_client_arg_deep_free(msg);
}
void btc_mesh_time_scene_client_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_time_scene_client_cb_param_t *param = NULL;
if (!msg || !msg->arg) {
LOG_ERROR("%s: parameter is NULL", __func__);
return;
}
param = (esp_ble_mesh_time_scene_client_cb_param_t *)(msg->arg);
if (msg->act < ESP_BLE_MESH_TIME_SCENE_CLIENT_EVT_MAX) {
btc_ble_mesh_cb_to_app(msg->act, param);
} else {
LOG_ERROR("%s, unknown msg->act = %d", __func__, msg->act);
}
btc_ble_mesh_free_req_data(msg);
}

View File

@@ -0,0 +1,64 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _BTC_BLE_MESH_CONFIG_CLIENT_H_
#define _BTC_BLE_MESH_CONFIG_CLIENT_H_
#include <stdint.h>
#include "btc/btc_task.h"
#include "esp_ble_mesh_config_model_api.h"
typedef enum {
BTC_BLE_MESH_ACT_CONFIG_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_CONFIG_CLIENT_SET_STATE,
} btc_ble_mesh_cfg_client_act_t;
typedef union {
struct ble_mesh_clg_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_cfg_client_get_state_t *get_state;
} cfg_client_get_state;
struct ble_mesh_clg_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_cfg_client_set_state_t *set_state;
} cfg_client_set_state;
} btc_ble_mesh_cfg_client_args_t;
void btc_mesh_cfg_client_call_handler(btc_msg_t *msg);
void btc_mesh_cfg_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_cfg_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
int btc_ble_mesh_config_client_get_state(esp_ble_mesh_client_common_param_t *params, esp_ble_mesh_cfg_client_get_state_t *get_state,
esp_ble_mesh_cfg_client_cb_param_t *cfg_client_cb);
int btc_ble_mesh_config_client_set_state(esp_ble_mesh_client_common_param_t *params, esp_ble_mesh_cfg_client_set_state_t *set_state,
esp_ble_mesh_cfg_client_cb_param_t *cfg_client_cb);
void btc_mesh_cfg_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
void bt_mesh_callback_config_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
void btc_mesh_cfg_server_cb_handler(btc_msg_t *msg);
void bt_mesh_callback_cfg_server_event_to_btc(u8_t evt_type, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
#endif /* _BTC_BLE_MESH_CONFIG_CLIENT_H_ */

View File

@@ -0,0 +1,51 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _BTC_BLE_MESH_GENERIC_CLIENT_H_
#define _BTC_BLE_MESH_GENERIC_CLIENT_H_
#include <stdint.h>
#include "btc/btc_task.h"
#include "esp_ble_mesh_generic_model_api.h"
typedef enum {
BTC_BLE_MESH_ACT_GENERIC_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_GENERIC_CLIENT_SET_STATE,
} btc_ble_mesh_generic_client_act_t;
typedef union {
struct ble_mesh_generic_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_generic_client_get_state_t *get_state;
} generic_client_get_state;
struct ble_mesh_generic_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_generic_client_set_state_t *set_state;
} generic_client_set_state;
} btc_ble_mesh_generic_client_args_t;
void btc_mesh_generic_client_call_handler(btc_msg_t *msg);
void btc_mesh_generic_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_generic_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_mesh_generic_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
void bt_mesh_callback_generic_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
#endif /* _BTC_BLE_MESH_GENERIC_CLIENT_H_ */

View File

@@ -0,0 +1,79 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _BTC_BLE_MESH_HEALTH_H_
#define _BTC_BLE_MESH_HEALTH_H_
#include <stdint.h>
#include "btc/btc_task.h"
#include "esp_ble_mesh_defs.h"
#include "esp_ble_mesh_health_model_api.h"
typedef enum {
BTC_BLE_MESH_ACT_HEALTH_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_HEALTH_CLIENT_SET_STATE,
BTC_BLE_MESH_ACT_HEALTH_CLIENT_MAX,
} btc_ble_mesh_health_client_act_t;
typedef enum {
BTC_BLE_MESH_ACT_HEALTH_SERVER_FAULT_UPDATE,
BTC_BLE_MESH_ACT_HEALTH_SERVER_MAX,
} btc_ble_mesh_health_server_act_t;
typedef union {
struct ble_mesh_health_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_health_client_get_state_t *get_state;
} health_client_get_state;
struct ble_mesh_health_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_health_client_set_state_t *set_state;
} health_client_set_state;
} btc_ble_mesh_health_client_args_t;
typedef union {
struct ble_mesh_health_server_fault_update_args {
esp_ble_mesh_elem_t *element;
} fault_update;
} btc_ble_mesh_health_server_args_t;
void btc_mesh_health_client_call_handler(btc_msg_t *msg);
void btc_mesh_health_client_cb_handler(btc_msg_t *msg);
void btc_mesh_health_server_call_handler(btc_msg_t *msg);
void btc_mesh_health_server_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_health_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_ble_mesh_health_server_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
int btc_ble_mesh_health_client_get_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_get_state_t *get_state,
esp_ble_mesh_health_client_cb_param_t *client_cb);
int btc_ble_mesh_health_client_set_state(esp_ble_mesh_client_common_param_t *params,
esp_ble_mesh_health_client_set_state_t *set_state,
esp_ble_mesh_health_client_cb_param_t *client_cb);
void btc_mesh_health_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
void bt_mesh_callback_health_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, u16_t len);
#endif /* _BTC_BLE_MESH_HEALTH_H_ */

View File

@@ -0,0 +1,53 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _BTC_BLE_MESH_LIGHT_CLIENT_H_
#define _BTC_BLE_MESH_LIGHT_CLIENT_H_
#include <stdint.h>
#include "btc/btc_task.h"
#include "esp_ble_mesh_lighting_model_api.h"
typedef enum {
BTC_BLE_MESH_ACT_LIGHT_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_LIGHT_CLIENT_SET_STATE,
} btc_ble_mesh_light_client_act_t;
typedef union {
struct ble_mesh_light_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_light_client_get_state_t *get_state;
} light_client_get_state;
struct ble_mesh_light_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_light_client_set_state_t *set_state;
} light_client_set_state;
} btc_ble_mesh_light_client_args_t;
void btc_mesh_light_client_call_handler(btc_msg_t *msg);
void btc_mesh_light_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_light_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_mesh_light_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
void bt_mesh_callback_light_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
#endif /* _BTC_BLE_MESH_LIGHT_CLIENT_H_ */

View File

@@ -0,0 +1,220 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _BTC_BLE_MESH_PROV_H_
#define _BTC_BLE_MESH_PROV_H_
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "btc/btc_task.h"
#include "esp_bt_defs.h"
#include "mesh_access.h"
#include "mesh_buf.h"
#include "mesh_main.h"
#include "esp_ble_mesh_defs.h"
#if CONFIG_BT_MESH
typedef enum {
BTC_BLE_MESH_ACT_APP_REGISTER = 0,
BTC_BLE_MESH_ACT_PROV_ENABLE,
BTC_BLE_MESH_ACT_PROV_DISABLE,
BTC_BLE_MESH_ACT_NODE_RESET,
BTC_BLE_MESH_ACT_SET_OOB_PUB_KEY,
BTC_BLE_MESH_ACT_INPUT_NUMBER,
BTC_BLE_MESH_ACT_INPUT_STRING,
BTC_BLE_MESH_ACT_SET_DEVICE_NAME,
BTC_BLE_MESH_ACT_PROXY_IDENTITY_ENABLE,
BTC_BLE_MESH_ACT_PROXY_GATT_ENABLE,
BTC_BLE_MESH_ACT_PROXY_GATT_DISABLE,
#if (CONFIG_BT_MESH_PROVISIONER)
BTC_BLE_MESH_ACT_PROVISIONER_READ_OOB_PUB_KEY,
BTC_BLE_MESH_ACT_PROVISIONER_INPUT_STR,
BTC_BLE_MESH_ACT_PROVISIONER_INPUT_NUM,
BTC_BLE_MESH_ACT_PROVISIONER_ENABLE,
BTC_BLE_MESH_ACT_PROVISIONER_DISABLE,
BTC_BLE_MESH_ACT_PROVISIONER_DEV_ADD,
BTC_BLE_MESH_ACT_PROVISIONER_DEV_DEL,
BTC_BLE_MESH_ACT_PROVISIONER_SET_DEV_UUID_MATCH,
BTC_BLE_MESH_ACT_PROVISIONER_SET_PROV_DATA_INFO,
BTC_BLE_MESH_ACT_PROVISIONER_SET_NODE_NAME,
BTC_BLE_MESH_ACT_PROVISIONER_SET_LOCAL_APP_KEY,
BTC_BLE_MESH_ACT_PROVISIONER_BIND_LOCAL_MOD_APP,
BTC_BLE_MESH_ACT_PROVISIONER_ADD_LOCAL_NET_KEY,
#endif /* CONFIG_BT_MESH_PROVISIONER */
BTC_BLE_MESH_ACT_SET_FAST_PROV_INFO,
BTC_BLE_MESH_ACT_SET_FAST_PROV_ACTION,
} btc_ble_mesh_prov_act_t;
typedef enum {
BTC_BLE_MESH_ACT_MODEL_PUBLISH,
BTC_BLE_MESH_ACT_SERVER_MODEL_SEND,
BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND
} btc_ble_mesh_model_act_t;
typedef union {
struct ble_mesh_reg_args {
esp_ble_mesh_prov_t *prov;
esp_ble_mesh_comp_t *comp;
xSemaphoreHandle semaphore;
uint8_t mesh_if;
} mesh_reg;
struct ble_mesh_prov_enable_args {
esp_ble_mesh_prov_bearer_t bearers;
} mesh_prov_enable;
struct ble_mesh_prov_disable_args {
esp_ble_mesh_prov_bearer_t bearers;
} mesh_prov_disable;
struct ble_mesh_set_oob_pub_key_args {
uint8_t pub_key_x[32];
uint8_t pub_key_y[32];
uint8_t private_key[32];
} set_oob_pub_key;
struct ble_mesh_input_num_args {
uint32_t number;
} input_num;
struct ble_mesh_input_str_args {
char string[8];
} input_str;
struct ble_mesh_set_device_name_args {
char name[ESP_BLE_MESH_DEVICE_NAME_MAX_LEN];
} set_device_name;
#if (CONFIG_BT_MESH_PROVISIONER)
struct ble_mesh_provisioner_read_oob_pub_key_args {
uint8_t link_idx;
uint8_t pub_key_x[32];
uint8_t pub_key_y[32];
} provisioner_read_oob_pub_key;
struct ble_mesh_provisioner_input_str_args {
char string[8];
uint8_t link_idx;
} provisioner_input_str;
struct ble_mesh_provisioner_input_num_args {
uint32_t number;
uint8_t link_idx;
} provisioner_input_num;
struct ble_mesh_provisioner_enable_args {
esp_ble_mesh_prov_bearer_t bearers;
} provisioner_enable;
struct ble_mesh_provisioner_disable_args {
esp_ble_mesh_prov_bearer_t bearers;
} provisioner_disable;
struct ble_mesh_provisioner_dev_add_args {
esp_ble_mesh_unprov_dev_add_t add_dev;
esp_ble_mesh_dev_add_flag_t flags;
} provisioner_dev_add;
struct ble_mesh_provisioner_dev_del_args {
esp_ble_mesh_device_delete_t del_dev;
} provisioner_dev_del;
struct ble_mesh_provisioner_set_dev_uuid_match_args {
uint8_t offset;
uint8_t match_len;
uint8_t match_val[16];
bool prov_after_match;
} set_dev_uuid_match;
struct ble_mesh_provisioner_set_prov_net_idx_args {
esp_ble_mesh_prov_data_info_t prov_data;
} set_prov_data_info;
struct ble_mesh_provisioner_set_node_name_args {
int index;
char name[ESP_BLE_MESH_NODE_NAME_MAX_LEN];
} set_node_name;
struct ble_mesh_provisioner_add_local_app_key_args {
uint8_t app_key[16];
uint16_t net_idx;
uint16_t app_idx;
} add_local_app_key;
struct ble_mesh_provisioner_bind_local_mod_app_args {
uint16_t elem_addr;
uint16_t model_id;
uint16_t cid;
uint16_t app_idx;
} local_mod_app_bind;
struct ble_mesh_provisioner_add_local_net_key_args {
uint8_t net_key[16];
uint16_t net_idx;
} add_local_net_key;
#endif /* CONFIG_BT_MESH_PROVISIONER */
#if (CONFIG_BT_MESH_FAST_PROV)
struct ble_mesh_set_fast_prov_info_args {
uint16_t unicast_min;
uint16_t unicast_max;
uint16_t net_idx;
uint8_t flags;
uint32_t iv_index;
uint8_t offset;
uint8_t match_len;
uint8_t match_val[16];
} set_fast_prov_info;
struct ble_mesh_set_fast_prov_action_args {
uint8_t action;
} set_fast_prov_action;
#endif /* CONFIG_BT_MESH_FAST_PROV */
} btc_ble_mesh_prov_args_t;
typedef union {
struct ble_mesh_model_publish_args {
esp_ble_mesh_model_t *model;
uint8_t device_role;
} model_publish;
struct ble_mesh_model_send_args {
esp_ble_mesh_model_t *model;
esp_ble_mesh_msg_ctx_t *ctx;
uint32_t opcode;
bool need_rsp;
uint16_t length;
uint8_t *data;
uint8_t device_role;
int32_t msg_timeout;
} model_send;
} btc_ble_mesh_model_args_t;
void btc_ble_mesh_prov_arg_deep_free(btc_msg_t *msg);
void btc_ble_mesh_prov_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
int btc_ble_mesh_client_init(esp_ble_mesh_model_t *model);
int32_t btc_ble_mesh_model_pub_period_get(esp_ble_mesh_model_t *mod);
uint16_t btc_ble_mesh_get_primary_addr(void);
uint16_t *btc_ble_mesh_model_find_group(esp_ble_mesh_model_t *mod, uint16_t addr);
esp_ble_mesh_elem_t *btc_ble_mesh_elem_find(u16_t addr);
uint8_t btc_ble_mesh_elem_count(void);
esp_ble_mesh_model_t *btc_ble_mesh_model_find_vnd(esp_ble_mesh_elem_t *elem,
uint16_t company, uint16_t id);
esp_ble_mesh_model_t *btc_ble_mesh_model_find(esp_ble_mesh_elem_t *elem,
u16_t id);
const esp_ble_mesh_comp_t *btc_ble_mesh_comp_get(void);
void btc_mesh_model_call_handler(btc_msg_t *msg);
void btc_mesh_model_cb_handler(btc_msg_t *msg);
void btc_mesh_prov_call_handler(btc_msg_t *msg);
void btc_mesh_prov_cb_handler(btc_msg_t *msg);
#endif /* _BTC_BLE_MESH_PROV_H_ */
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,53 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _BTC_BLE_MESH_SENSOR_CLIENT_H_
#define _BTC_BLE_MESH_SENSOR_CLIENT_H_
#include <stdint.h>
#include "btc/btc_task.h"
#include "esp_ble_mesh_sensor_model_api.h"
typedef enum {
BTC_BLE_MESH_ACT_SENSOR_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_SENSOR_CLIENT_SET_STATE,
} btc_ble_mesh_sensor_client_act_t;
typedef union {
struct ble_mesh_sensor_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_sensor_client_get_state_t *get_state;
} sensor_client_get_state;
struct ble_mesh_sensor_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_sensor_client_set_state_t *set_state;
} sensor_client_set_state;
} btc_ble_mesh_sensor_client_args_t;
void btc_mesh_sensor_client_call_handler(btc_msg_t *msg);
void btc_mesh_sensor_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_sensor_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_mesh_sensor_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
void bt_mesh_callback_sensor_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
#endif /* _BTC_BLE_MESH_SENSOR_CLIENT_H_ */

View File

@@ -0,0 +1,53 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _BTC_BLE_MESH_TIME_SCENE_CLIENT_H_
#define _BTC_BLE_MESH_TIME_SCENE_CLIENT_H_
#include <stdint.h>
#include "btc/btc_task.h"
#include "esp_ble_mesh_time_scene_model_api.h"
typedef enum {
BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_GET_STATE,
BTC_BLE_MESH_ACT_TIME_SCENE_CLIENT_SET_STATE,
} btc_ble_mesh_time_scene_client_act_t;
typedef union {
struct ble_mesh_time_scene_client_get_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_time_scene_client_get_state_t *get_state;
} time_scene_client_get_state;
struct ble_mesh_time_scene_client_set_state_reg_args {
esp_ble_mesh_client_common_param_t *params;
esp_ble_mesh_time_scene_client_set_state_t *set_state;
} time_scene_client_set_state;
} btc_ble_mesh_time_scene_client_args_t;
void btc_mesh_time_scene_client_call_handler(btc_msg_t *msg);
void btc_mesh_time_scene_client_cb_handler(btc_msg_t *msg);
void btc_ble_mesh_time_scene_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_mesh_time_scene_client_publish_callback(u32_t opcode, struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
void bt_mesh_callback_time_scene_status_to_btc(u32_t opcode, u8_t evt_type,
struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
const u8_t *val, size_t len);
#endif /* _BTC_BLE_MESH_TIME_SCENE_CLIENT_H_ */

View File

@@ -0,0 +1,459 @@
# Kconfig - Bluetooth Mesh configuration options
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
menuconfig BT_MESH
bool "Bluetooth Mesh support"
select TINYCRYPT
select TINYCRYPT_AES
select TINYCRYPT_AES_CMAC
help
This option enables Bluetooth Mesh support. The specific
features that are available may depend on other features
that have been enabled in the stack, such as GATT support.
if BT_MESH
# Virtual option enabled whenever Generic Provisioning layer is needed
config BT_MESH_PROV
bool
config BT_MESH_PB_ADV
bool "Provisioning support using the advertising bearer (PB-ADV)"
select BT_MESH_PROV
default y
help
Enable this option to allow the device to be provisioned over
the advertising bearer.
if BT_CONN
# Virtual option enabled whenever any Proxy protocol is needed
config BT_MESH_PROXY
bool
config BT_MESH_PB_GATT
bool "Provisioning support using GATT (PB-GATT)"
select BT_MESH_PROXY
select BT_MESH_PROV
help
Enable this option to allow the device to be provisioned over
GATT.
config BT_MESH_GATT_PROXY
bool "GATT Proxy Service"
select BT_MESH_PROXY
help
This option enables support for the Mesh GATT Proxy Service,
i.e. the ability to act as a proxy between a Mesh GATT Client
and a Mesh network.
config BT_MESH_NODE_ID_TIMEOUT
int "Node Identity advertising timeout"
depends on BT_MESH_GATT_PROXY
range 1 60
default 60
help
This option determines for how long the local node advertises
using Node Identity. The given value is in seconds. The
specification limits this to 60 seconds, and implies that to
be the appropriate value as well, so just leaving this as the
default is the safest option.
if BT_MESH_PROXY
config BT_MESH_PROXY_FILTER_SIZE
int "Maximum number of filter entries per Proxy Client"
default 1
default 3 if BT_MESH_GATT_PROXY
range 1 32767
help
This option specifies how many Proxy Filter entries the local
node supports.
endif # BT_MESH_PROXY
endif # BT_CONN
config BT_MESH_SELF_TEST
bool "Perform self-tests"
help
This option adds extra self-tests which are run every time
mesh networking is initialized.
config BT_MESH_IV_UPDATE_TEST
bool "Test the IV Update Procedure"
help
This option removes the 96 hour limit of the IV Update
Procedure and lets the state be changed at any time.
config BT_MESH_SUBNET_COUNT
int "Maximum number of mesh subnets per network"
default 1
range 1 4096
help
This option specifies how many subnets a Mesh network can
participate in at the same time.
config BT_MESH_APP_KEY_COUNT
int "Maximum number of application keys per network"
default 1
range 1 4096
help
This option specifies how many application keys the device can
store per network.
config BT_MESH_MODEL_KEY_COUNT
int "Maximum number of application keys per model"
default 1
range 1 4096
help
This option specifies how many application keys each model can
at most be bound to.
config BT_MESH_MODEL_GROUP_COUNT
int "Maximum number of group address subscriptions per model"
default 1
range 1 4096
help
This option specifies how many group addresses each model can
at most be subscribed to.
config BT_MESH_LABEL_COUNT
int "Maximum number of Label UUIDs used for Virtual Addresses"
default 1
range 0 4096
help
This option specifies how many Label UUIDs can be stored.
config BT_MESH_CRPL
int "Maximum capacity of the replay protection list"
default 10
range 2 65535
help
This options specifies the maximum capacity of the replay
protection list. This option is similar to the network message
cache size, but has a different purpose.
config BT_MESH_MSG_CACHE_SIZE
int "Network message cache size"
default 10
range 2 65535
help
Number of messages that are cached for the network. This helps
prevent unnecessary decryption operations and unnecessary
relays. This option is similar to the replay protection list,
but has a different purpose.
config BT_MESH_ADV_BUF_COUNT
int "Number of advertising buffers"
default 6
range 6 256
help
Number of advertising buffers available. The transport layer
reserves ADV_BUF_COUNT - 3 buffers for outgoing segments. The
maximum outgoing SDU size is 12 times this number (out of which
4 or 8 bytes is used for the Transport Layer MIC). For
example, 5 segments means the maximum SDU size is 60 bytes,
which leaves 56 bytes for application layer data using a
4-byte MIC and 52 bytes using an 8-byte MIC.
config BT_MESH_TX_SEG_MSG_COUNT
int "Maximum number of simultaneous outgoing segmented messages"
default 1
range 1 BT_MESH_ADV_BUF_COUNT
help
Maximum number of simultaneous outgoing multi-segment and/or
reliable messages.
config BT_MESH_RX_SEG_MSG_COUNT
int "Maximum number of simultaneous incoming segmented messages"
default 1
range 1 255
help
Maximum number of simultaneous incoming multi-segment and/or
reliable messages.
config BT_MESH_RX_SDU_MAX
int "Maximum incoming Upper Transport Access PDU length"
default 384
range 36 384
help
Maximum incoming Upper Transport Access PDU length. Leave this
to the default value, unless you really need to optimize memory
usage.
config BT_MESH_RELAY
bool "Relay support"
help
Support for acting as a Mesh Relay Node.
config BT_MESH_LOW_POWER
bool "Support for Low Power features"
help
Enable this option to be able to act as a Low Power Node.
if BT_MESH_LOW_POWER
config BT_MESH_LPN_ESTABLISHMENT
bool "Perform Friendship establishment using low power"
default y
help
Perform the Friendship establishment using low power, with
the help of a reduced scan duty cycle. The downside of this
is that the node may miss out on messages intended for it
until it has successfully set up Friendship with a Friend
node.
config BT_MESH_LPN_AUTO
bool "Automatically start looking for Friend nodes once provisioned"
default y
help
Automatically enable LPN functionality once provisioned and start
looking for Friend nodes. If this option is disabled LPN mode
needs to be manually enabled by calling bt_mesh_lpn_set(true).
config BT_MESH_LPN_AUTO_TIMEOUT
int "Time from last received message before going to LPN mode"
default 15
range 0 3600
depends on BT_MESH_LPN_AUTO
help
Time in seconds from the last received message, that the node
will wait before starting to look for Friend nodes.
config BT_MESH_LPN_RETRY_TIMEOUT
int "Retry timeout for Friend requests"
default 8
range 1 3600
help
Time in seconds between Friend Requests, if a previous Friend
Request did not receive any acceptable Friend Offers.
config BT_MESH_LPN_RSSI_FACTOR
int "RSSIFactor, used in the Friend Offer Delay calculation"
range 0 3
default 0
help
The contribution of the RSSI measured by the Friend node used
in Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5.
config BT_MESH_LPN_RECV_WIN_FACTOR
int "ReceiveWindowFactor, used in the Friend Offer Delay calculation"
range 0 3
default 0
help
The contribution of the supported Receive Window used in
Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5.
config BT_MESH_LPN_MIN_QUEUE_SIZE
int "Minimum size of acceptable friend queue (MinQueueSizeLog)"
range 1 7
default 1
help
The MinQueueSizeLog field is defined as log_2(N), where N is
the minimum number of maximum size Lower Transport PDUs that
the Friend node can store in its Friend Queue. As an example,
MinQueueSizeLog value 1 gives N = 2, and value 7 gives N = 128.
config BT_MESH_LPN_RECV_DELAY
int "Receive delay requested by the local node"
range 10 255
default 100
help
The ReceiveDelay is the time between the Low Power node
sending a request and listening for a response. This delay
allows the Friend node time to prepare the response. The value
is in units of milliseconds.
config BT_MESH_LPN_POLL_TIMEOUT
int "The value of the PollTimeout timer"
range 10 244735
default 300
help
PollTimeout timer is used to measure time between two
consecutive requests sent by the Low Power node. If no
requests are received by the Friend node before the
PollTimeout timer expires, then the friendship is considered
terminated. The value is in units of 100 milliseconds, so e.g.
a value of 300 means 30 seconds.
config BT_MESH_LPN_INIT_POLL_TIMEOUT
int "The starting value of the PollTimeout timer"
range 10 BT_MESH_LPN_POLL_TIMEOUT
default BT_MESH_LPN_POLL_TIMEOUT
help
The initial value of the PollTimeout timer when Friendship
gets established for the first time. After this the timeout
will gradually grow toward the actual PollTimeout, doubling
in value for each iteration. The value is in units of 100
milliseconds, so e.g. a value of 300 means 30 seconds.
config BT_MESH_LPN_SCAN_LATENCY
int "Latency for enabling scanning"
range 0 50
default 10
help
Latency in milliseconds that it takes to enable scanning. This
is in practice how much time in advance before the Receive Window
that scanning is requested to be enabled.
config BT_MESH_LPN_GROUPS
int "Number of groups the LPN can subscribe to"
range 0 16384
default 8
help
Maximum number of groups that the LPN can subscribe to.
endif # BT_MESH_LOW_POWER
config BT_MESH_FRIEND
bool "Support for acting as a Friend Node"
help
Enable this option to be able to act as a Friend Node.
if BT_MESH_FRIEND
config BT_MESH_FRIEND_RECV_WIN
int "Friend Receive Window"
range 1 255
default 255
help
Receive Window in milliseconds supported by the Friend node.
config BT_MESH_FRIEND_QUEUE_SIZE
int "Minimum number of buffers supported per Friend Queue"
range 2 65536
default 16
help
Minimum number of buffers available to be stored for each
local Friend Queue.
config BT_MESH_FRIEND_SUB_LIST_SIZE
int "Friend Subscription List Size"
range 0 1023
default 3
help
Size of the Subscription List that can be supported by a
Friend node for a Low Power node.
config BT_MESH_FRIEND_LPN_COUNT
int "Number of supported LPN nodes"
range 1 1000
default 2
help
Number of Low Power Nodes the Friend can have a Friendship
with simultaneously.
config BT_MESH_FRIEND_SEG_RX
int "Number of incomplete segment lists per LPN"
range 1 1000
default 1
help
Number of incomplete segment lists that we track for each LPN
that we are Friends for. In other words, this determines how
many elements we can simultaneously be receiving segmented
messages from when the messages are going into the Friend queue.
endif # BT_MESH_FRIEND
config BT_MESH_CFG_CLI
bool "Support for Configuration Client Model"
help
Enable support for the configuration client model.
config BT_MESH_HEALTH_CLI
bool "Support for Health Client Model"
help
Enable support for the health client model.
config BT_MESH_SHELL
bool "Enable Bluetooth Mesh shell"
select CONSOLE_SHELL
depends on BT_MESH_CFG_CLI
depends on BT_MESH_HEALTH_CLI
help
Activate shell module that provides Bluetooth Mesh commands to
the console.
config BT_MESH_DEBUG
bool "Enable debug logs"
depends on BT_DEBUG
help
Use this option to enable debug logs for the Bluetooth
Mesh functionality.
if BT_MESH_DEBUG
config BT_MESH_DEBUG_NET
bool "Network layer debug"
help
Use this option to enable Network layer debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_TRANS
bool "Transport layer debug"
help
Use this option to enable Transport layer debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_BEACON
bool "Beacon debug"
help
Use this option to enable Beacon-related debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_CRYPTO
bool "Crypto debug"
help
Use this option to enable cryptographic debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_PROV
bool "Provisioning debug"
help
Use this option to enable Provisioning debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_ACCESS
bool "Access layer debug"
help
Use this option to enable Access layer and device composition
related debug logs for Bluetooth Mesh.
config BT_MESH_DEBUG_MODEL
bool "Foundation model debug"
help
Use this option to enable debug logs for the Foundation
Models.
config BT_MESH_DEBUG_ADV
bool "Advertising debug"
help
Use this option to enable advertising debug logs for
the Bluetooth Mesh functionality.
config BT_MESH_DEBUG_LOW_POWER
bool "Low Power debug"
help
Use this option to enable Low Power debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_FRIEND
bool "Friend debug"
help
Use this option to enable Friend debug logs for the
Bluetooth Mesh functionality.
config BT_MESH_DEBUG_PROXY
bool "Proxy debug"
depends on BT_MESH_PROXY
help
Use this option to enable Proxy protocol debug logs.
endif # BT_MESH_DEBUG
endif # BT_MESH

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ACCESS_H_
#define _ACCESS_H_
#include "mesh_access.h"
#include "mesh_buf.h"
#include "net.h"
#if CONFIG_BT_MESH
/* bt_mesh_model.flags */
enum {
BT_MESH_MOD_BIND_PENDING = BIT(0),
BT_MESH_MOD_SUB_PENDING = BIT(1),
BT_MESH_MOD_PUB_PENDING = BIT(2),
};
void bt_mesh_elem_register(struct bt_mesh_elem *elem, u8_t count);
u8_t bt_mesh_elem_count(void);
/* Find local element based on unicast or group address */
struct bt_mesh_elem *bt_mesh_elem_find(u16_t addr);
struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem *elem,
u16_t company, u16_t id);
struct bt_mesh_model *bt_mesh_model_find(struct bt_mesh_elem *elem,
u16_t id);
u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr);
bool bt_mesh_fixed_group_match(u16_t addr);
void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod,
struct bt_mesh_elem *elem,
bool vnd, bool primary,
void *user_data),
void *user_data);
s32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod);
void bt_mesh_comp_provision(u16_t addr);
void bt_mesh_comp_unprovision(void);
u16_t bt_mesh_primary_addr(void);
struct bt_mesh_model *bt_mesh_model_get(bool vnd, u8_t elem_idx, u8_t mod_idx);
const struct bt_mesh_comp *bt_mesh_comp_get(void);
void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf);
int bt_mesh_comp_register(const struct bt_mesh_comp *comp);
#endif /* #if CONFIG_BT_MESH */
#endif /* #ifndef _ACCESS_H_ */

View File

@@ -0,0 +1,431 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/xtensa_api.h"
#include "freertos/FreeRTOSConfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
#include "osi/thread.h"
#include "mesh_util.h"
#include "mesh_buf.h"
#include "mesh.h"
#include "mesh_bearer_adapt.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_ADV)
#include "mesh_trace.h"
#include "adv.h"
#include "foundation.h"
#include "net.h"
#include "beacon.h"
#include "prov.h"
#include "proxy.h"
#include "mesh_hci.h"
#include "sdkconfig.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "provisioner_beacon.h"
#define BT_DATA_MESH_PROV 0x29 /* Mesh Provisioning PDU */
#define BT_DATA_MESH_MESSAGE 0x2a /* Mesh Networking PDU */
#define BT_DATA_MESH_BEACON 0x2b /* Mesh Beacon */
/* Window and Interval are equal for continuous scanning */
#define MESH_SCAN_INTERVAL 0x20//0x10 /*Change the scan interval to 20ms here just to reduce the packet loss rate */
#define MESH_SCAN_WINDOW 0x20//0x10 /*Change the scan window to 20ms here just to reduce the packet loss rate */
/* Convert from ms to 0.625ms units */
#define ADV_INT(_ms) ((_ms) * 8 / 5)
/* Pre-5.0 controllers enforce a minimum interval of 100ms
* whereas 5.0+ controllers can go down to 20ms.
*/
#define ADV_INT_DEFAULT K_MSEC(100)
#define ADV_INT_FAST K_MSEC(20)
/* TinyCrypt PRNG consumes a lot of stack space, so we need to have
* an increased call stack whenever it's used.
*/
#if defined(CONFIG_BT_HOST_CRYPTO)
#define ADV_STACK_SIZE 768
#else
#define ADV_STACK_SIZE 512
#endif
static xQueueHandle xBleMeshQueue = 0;
static const bt_addr_le_t *dev_addr;
static const u8_t adv_type[] = {
[BT_MESH_ADV_PROV] = BT_DATA_MESH_PROV,
[BT_MESH_ADV_DATA] = BT_DATA_MESH_MESSAGE,
[BT_MESH_ADV_BEACON] = BT_DATA_MESH_BEACON,
};
NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BT_MESH_ADV_BUF_COUNT + 3 * CONFIG_BT_MESH_PBA_SAME_TIME,
BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, NULL);
static struct bt_mesh_adv adv_pool[CONFIG_BT_MESH_ADV_BUF_COUNT + 3 * CONFIG_BT_MESH_PBA_SAME_TIME];
static struct bt_mesh_adv *adv_alloc(int id)
{
return &adv_pool[id];
}
static inline void adv_send_start(u16_t duration, int err,
const struct bt_mesh_send_cb *cb,
void *cb_data)
{
if (cb && cb->start) {
cb->start(duration, err, cb_data);
}
}
static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb,
void *cb_data)
{
if (cb && cb->end) {
cb->end(err, cb_data);
}
}
static inline int adv_send(struct net_buf *buf)
{
const s32_t adv_int_min = ((bt_dev.hci_version >= BT_HCI_VERSION_5_0) ?
ADV_INT_FAST : ADV_INT_DEFAULT);
const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb;
void *cb_data = BT_MESH_ADV(buf)->cb_data;
struct bt_le_adv_param param;
u16_t duration, adv_int;
struct bt_data ad;
int err;
adv_int = max(adv_int_min, BT_MESH_ADV(buf)->adv_int);
duration = (BT_MESH_ADV(buf)->count + 1) * (adv_int + 10);
BT_DBG("type %u len %u: %s", BT_MESH_ADV(buf)->type,
buf->len, bt_hex(buf->data, buf->len));
BT_DBG("count %u interval %ums duration %ums",
BT_MESH_ADV(buf)->count + 1, adv_int, duration);
ad.type = adv_type[BT_MESH_ADV(buf)->type];
ad.data_len = buf->len;
ad.data = buf->data;
param.options = 0;
param.interval_min = ADV_INT(adv_int);
param.interval_max = param.interval_min;
param.own_addr = NULL;
err = bt_le_adv_start(&param, &ad, 1, NULL, 0);
net_buf_unref(buf);
adv_send_start(duration, err, cb, cb_data);
if (err) {
BT_ERR("Advertising failed: err %d", err);
return err;
}
BT_DBG("Advertising started. Sleeping %u ms", duration);
k_sleep(duration);
err = bt_le_adv_stop();
adv_send_end(err, cb, cb_data);
if (err) {
BT_ERR("Stopping advertising failed: err %d", err);
/* If start adv successfully but stop failed, we think the data has been sent successfully */
return 0;
}
BT_DBG("Advertising stopped");
return 0;
}
/* Change by Espressif. The implementation of this function needs to be modified to
* FreeRTOS task implementation to use on ESP-IDF */
static void adv_thread(void *p)
{
BT_DBG("started");
int status;
struct net_buf **buf;
ble_mesh_msg_t msg = {0};
buf = (struct net_buf **)(&msg.arg);
while (1) {
*buf = NULL;
#if CONFIG_BT_MESH_NODE
if (IS_ENABLED(CONFIG_BT_MESH_PROXY)) {
xQueueReceive(xBleMeshQueue, &msg, K_NO_WAIT);
while (!(*buf)) {
s32_t timeout;
BT_DBG("========");
timeout = bt_mesh_proxy_adv_start();
BT_DBG("=========Proxy Advertising up to %d ms", timeout);
xQueueReceive(xBleMeshQueue, &msg, timeout);
bt_mesh_proxy_adv_stop();
}
} else {
xQueueReceive(xBleMeshQueue, &msg, (portTickType)portMAX_DELAY);
}
#else
xQueueReceive(xBleMeshQueue, &msg, (portTickType)portMAX_DELAY);
#endif
if (!(*buf)) {
continue;
}
/* busy == 0 means this was canceled */
if (BT_MESH_ADV(*buf)->busy) {
BT_MESH_ADV(*buf)->busy = 0;
/*TODO: Currently we check status of adv_send, which has changed the original
* code of Zephyr, we need to find a better way in the future
* */
status = adv_send(*buf);
if (status) {
status = xQueueSendToFront(xBleMeshQueue, &msg, K_NO_WAIT);
if (status) {
BT_ERR("adv_send, xQueueSendToFront failed, status=0x%x", status);
}
}
}
/* Give other threads a chance to run */
taskYIELD();
}
}
void bt_mesh_adv_update(void)
{
BT_DBG("%s", __func__);
ble_mesh_msg_t msg = {0};
msg.arg = NULL;
// Change by Espressif, should used the QueueSend in the ESP-IDF architecture.
ble_mesh_task_post(&msg, 0);
}
struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
bt_mesh_adv_alloc_t get_id,
enum bt_mesh_adv_type type,
u8_t xmit_count, u8_t xmit_int,
s32_t timeout)
{
struct bt_mesh_adv *adv;
struct net_buf *buf;
buf = net_buf_alloc(pool, timeout);
if (!buf) {
return NULL;
}
BT_DBG("%s, pool_id = %p, buf_count = %d, uinit_count = %d", __func__,
buf->pool_id, pool->buf_count, pool->uninit_count);
// adv = get_id(pool->buf_count - pool->uninit_count);
/* Change by Espressif. Use buf->index to get corresponding adv_pool */
adv = get_id(buf->index);
BT_MESH_ADV(buf) = adv;
memset(adv, 0, sizeof(*adv));
adv->type = type;
adv->count = xmit_count;
adv->adv_int = xmit_int;
return buf;
}
struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count,
u8_t xmit_int, s32_t timeout)
{
return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_alloc, type,
xmit_count, xmit_int, timeout);
}
void ble_mesh_task_post(ble_mesh_msg_t *msg, uint32_t timeout)
{
BT_DBG("%s", __func__);
if (xQueueSend(xBleMeshQueue, msg, timeout) != pdTRUE) {
BT_ERR("Ble Mesh Post failed\n");
return;
}
}
void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
void *cb_data)
{
ble_mesh_msg_t msg = {0};
struct net_buf *send_buf = NULL;
BT_DBG("type 0x%02x len %u: %s", BT_MESH_ADV(buf)->type, buf->len,
bt_hex(buf->data, buf->len));
BT_MESH_ADV(buf)->cb = cb;
BT_MESH_ADV(buf)->cb_data = cb_data;
BT_MESH_ADV(buf)->busy = 1;
send_buf = net_buf_ref(buf);
msg.arg = (void *)send_buf;
//net_buf_put(NULL, net_buf_ref(buf));
/* Change by Espressif. The ESP-IDF should used the QueueSend to sent the msg. */
ble_mesh_task_post(&msg, portMAX_DELAY);
/* Deleted the net_buf_put function, we don't used it in the ESP-IDF architecture */
//net_buf_put(NULL, net_buf_ref(buf));
}
const bt_addr_le_t *bt_mesh_pba_get_addr(void)
{
return dev_addr;
}
static void bt_mesh_scan_cb(const bt_addr_le_t *addr, s8_t rssi,
u8_t adv_type, struct net_buf_simple *buf)
{
#if CONFIG_BT_MESH_PROVISIONER && CONFIG_BT_MESH_PB_GATT
u16_t uuid = 0;
#endif
if (adv_type != BT_LE_ADV_NONCONN_IND && adv_type != BT_LE_ADV_IND) {
return;
}
BT_DBG("%s, len %u: %s", __func__, buf->len, bt_hex(buf->data, buf->len));
dev_addr = addr;
while (buf->len > 1) {
struct net_buf_simple_state state;
u8_t len, type;
len = net_buf_simple_pull_u8(buf);
/* Check for early termination */
if (len == 0) {
return;
}
if (len > buf->len || buf->len < 1) {
BT_WARN("AD malformed");
return;
}
net_buf_simple_save(buf, &state);
type = net_buf_simple_pull_u8(buf);
BT_DBG("%s, type = %x", __func__, type);
buf->len = len - 1;
#if 0
/* TODO: Check with BLE Mesh BQB test cases */
if ((type == BT_DATA_MESH_PROV || type == BT_DATA_MESH_MESSAGE ||
type == BT_DATA_MESH_BEACON) && (adv_type != BT_LE_ADV_NONCONN_IND)) {
BT_DBG("%s, ignore BLE Mesh packet (type 0x%02x) with adv_type 0x%02x",
__func__, type, adv_type);
return;
}
#endif
switch (type) {
case BT_DATA_MESH_MESSAGE:
bt_mesh_net_recv(buf, rssi, BT_MESH_NET_IF_ADV);
break;
#if CONFIG_BT_MESH_PB_ADV
case BT_DATA_MESH_PROV:
#if CONFIG_BT_MESH_NODE
if (!bt_mesh_is_provisioner_en()) {
bt_mesh_pb_adv_recv(buf);
}
#endif
#if CONFIG_BT_MESH_PROVISIONER
if (bt_mesh_is_provisioner_en()) {
provisioner_pb_adv_recv(buf);
}
#endif
break;
#endif /* CONFIG_BT_MESH_PB_ADV */
case BT_DATA_MESH_BEACON:
#if CONFIG_BT_MESH_NODE
if (!bt_mesh_is_provisioner_en()) {
bt_mesh_beacon_recv(buf);
}
#endif
#if CONFIG_BT_MESH_PROVISIONER
if (bt_mesh_is_provisioner_en()) {
provisioner_beacon_recv(buf);
}
#endif
break;
#if CONFIG_BT_MESH_PROVISIONER && CONFIG_BT_MESH_PB_GATT
case BT_DATA_FLAGS:
if (bt_mesh_is_provisioner_en()) {
if (!provisioner_flags_match(buf)) {
BT_DBG("Flags mismatch, ignore this adv pkt");
return;
}
}
break;
case BT_DATA_SERVICE_UUID:
if (bt_mesh_is_provisioner_en()) {
uuid = provisioner_srv_uuid_recv(buf);
if (!uuid) {
BT_DBG("Service UUID mismatch, ignore this adv pkt");
return;
}
}
break;
case BT_DATA_SERVICE_DATA:
if (bt_mesh_is_provisioner_en()) {
provisioner_srv_data_recv(buf, addr, uuid);
}
break;
#endif /* CONFIG_BT_MESH_PROVISIONER && CONFIG_BT_MESH_PB_GATT */
default:
break;
}
net_buf_simple_restore(buf, &state);
net_buf_simple_pull(buf, len);
}
return;
}
void bt_mesh_adv_init(void)
{
/* Change by Espressif, we should used the FreeRTOS create task method to use task */
xBleMeshQueue = xQueueCreate(150, sizeof(ble_mesh_msg_t));
xTaskCreatePinnedToCore(adv_thread, "BLE_Mesh_Adv_task", 2048, NULL,
configMAX_PRIORITIES - 7, NULL, TASK_PINNED_TO_CORE);
}
int bt_mesh_scan_enable(void)
{
struct bt_le_scan_param scan_param = {
.type = BT_HCI_LE_SCAN_PASSIVE,
.filter_dup = BT_HCI_LE_SCAN_FILTER_DUP_DISABLE,
.interval = MESH_SCAN_INTERVAL,
.window = MESH_SCAN_WINDOW
};
BT_DBG("%s", __func__);
return bt_le_scan_start(&scan_param, bt_mesh_scan_cb);
}
int bt_mesh_scan_disable(void)
{
BT_DBG("%s", __func__);
return bt_le_scan_stop();
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,82 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mesh_bearer_adapt.h"
/* Maximum advertising data payload for a single data type */
#define BT_MESH_ADV_DATA_SIZE 29
/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */
#define BT_MESH_ADV_USER_DATA_SIZE 4
#define BT_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
typedef struct ble_mesh_msg {
uint8_t sig; //event signal
uint8_t aid; //application id
uint8_t pid; //profile id
uint8_t act; //profile action, defined in seprerate header files
void *arg; //param for btc function or function param
} ble_mesh_msg_t;
enum bt_mesh_adv_type {
BT_MESH_ADV_PROV,
BT_MESH_ADV_DATA,
BT_MESH_ADV_BEACON,
};
typedef void (*bt_mesh_adv_func_t)(struct net_buf *buf, u16_t duration,
int err, void *user_data);
struct bt_mesh_adv {
const struct bt_mesh_send_cb *cb;
void *cb_data;
u8_t type: 2,
busy: 1;
u8_t count: 3,
adv_int: 5;
union {
/* Address, used e.g. for Friend Queue messages */
u16_t addr;
/* For transport layer segment sending */
struct {
u8_t attempts;
} seg;
};
};
typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id);
/* xmit_count: Number of retransmissions, i.e. 0 == 1 transmission */
struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit_count,
u8_t xmit_int, s32_t timeout);
struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
bt_mesh_adv_alloc_t get_id,
enum bt_mesh_adv_type type,
u8_t xmit_count, u8_t xmit_int,
s32_t timeout);
void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
void *cb_data);
const bt_addr_le_t *bt_mesh_pba_get_addr(void);
void bt_mesh_adv_update(void);
void bt_mesh_adv_init(void);
int bt_mesh_scan_enable(void);
int bt_mesh_scan_disable(void);
void ble_mesh_task_post(ble_mesh_msg_t *msg, uint32_t timeout);

View File

@@ -0,0 +1,217 @@
/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2018, Nordic Semiconductor ASA
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*
* Adapted for Zephyr by Carles Cufi (carles.cufi@nordicsemi.no)
* - Removed mbedtls_ prefixes
* - Reworked coding style
*/
#include <stdint.h>
#include <errno.h>
#include <base64.h>
static const u8_t base64_enc_map[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '+', '/'
};
static const u8_t base64_dec_map[128] = {
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 127, 127, 127, 127, 127
};
#define BASE64_SIZE_T_MAX ((size_t) -1) /* SIZE_T_MAX is not standard */
/*
* Encode a buffer into base64 format
*/
int base64_encode(u8_t *dst, size_t dlen, size_t *olen, const u8_t *src,
size_t slen)
{
size_t i, n;
int C1, C2, C3;
u8_t *p;
if (slen == 0) {
*olen = 0;
return 0;
}
n = slen / 3 + (slen % 3 != 0);
if (n > (BASE64_SIZE_T_MAX - 1) / 4) {
*olen = BASE64_SIZE_T_MAX;
return -ENOMEM;
}
n *= 4;
if ((dlen < n + 1) || (!dst)) {
*olen = n + 1;
return -ENOMEM;
}
n = (slen / 3) * 3;
for (i = 0, p = dst; i < n; i += 3) {
C1 = *src++;
C2 = *src++;
C3 = *src++;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
}
if (i < slen) {
C1 = *src++;
C2 = ((i + 1) < slen) ? *src++ : 0;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
if ((i + 1) < slen) {
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
} else {
*p++ = '=';
}
*p++ = '=';
}
*olen = p - dst;
*p = 0;
return 0;
}
/*
* Decode a base64-formatted buffer
*/
int base64_decode(u8_t *dst, size_t dlen, size_t *olen, const u8_t *src,
size_t slen)
{
size_t i, n;
u32_t j, x;
u8_t *p;
/* First pass: check for validity and get output length */
for (i = n = j = 0; i < slen; i++) {
/* Skip spaces before checking for EOL */
x = 0;
while (i < slen && src[i] == ' ') {
++i;
++x;
}
/* Spaces at end of buffer are OK */
if (i == slen) {
break;
}
if ((slen - i) >= 2 && src[i] == '\r' && src[i + 1] == '\n') {
continue;
}
if (src[i] == '\n') {
continue;
}
/* Space inside a line is an error */
if (x != 0) {
return -EINVAL;
}
if (src[i] == '=' && ++j > 2) {
return -EINVAL;
}
if (src[i] > 127 || base64_dec_map[src[i]] == 127) {
return -EINVAL;
}
if (base64_dec_map[src[i]] < 64 && j != 0) {
return -EINVAL;
}
n++;
}
if (n == 0) {
*olen = 0;
return 0;
}
/* The following expression is to calculate the following formula
* without risk of integer overflow in n:
* n = ( ( n * 6 ) + 7 ) >> 3;
*/
n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
n -= j;
if (dst == NULL || dlen < n) {
*olen = n;
return -ENOMEM;
}
for (j = 3, n = x = 0, p = dst; i > 0; i--, src++) {
if (*src == '\r' || *src == '\n' || *src == ' ') {
continue;
}
j -= (base64_dec_map[*src] == 64);
x = (x << 6) | (base64_dec_map[*src] & 0x3F);
if (++n == 4) {
n = 0;
if (j > 0) {
*p++ = (unsigned char)(x >> 16);
}
if (j > 1) {
*p++ = (unsigned char)(x >> 8);
}
if (j > 2) {
*p++ = (unsigned char)(x);
}
}
}
*olen = p - dst;
return 0;
}

View File

@@ -0,0 +1,402 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <string.h>
#include "mesh_util.h"
#include "mesh_buf.h"
#include "sdkconfig.h"
#include "mesh_main.h"
#if CONFIG_BT_MESH
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_BEACON)
#include "mesh_trace.h"
#include "adv.h"
#include "mesh.h"
#include "net.h"
#include "prov.h"
#include "crypto.h"
#include "beacon.h"
#include "foundation.h"
#include "provisioner_prov.h"
#if CONFIG_BT_MESH_NODE
#if defined(CONFIG_BT_MESH_FAST_PROV)
#define UNPROVISIONED_INTERVAL K_SECONDS(3)
#else
#define UNPROVISIONED_INTERVAL K_SECONDS(5)
#endif /* CONFIG_BT_MESH_FAST_PROV */
#define PROVISIONED_INTERVAL K_SECONDS(10)
#define BEACON_TYPE_UNPROVISIONED 0x00
#define BEACON_TYPE_SECURE 0x01
/* 3 transmissions, 20ms interval */
#define UNPROV_XMIT_COUNT 2
#define UNPROV_XMIT_INT 20
/* 1 transmission, 20ms interval */
#define PROV_XMIT_COUNT 0
#define PROV_XMIT_INT 20
static struct k_delayed_work beacon_timer;
static struct bt_mesh_subnet *cache_check(u8_t data[21])
{
int i;
for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
if (sub->net_idx == BT_MESH_KEY_UNUSED) {
continue;
}
if (!memcmp(sub->beacon_cache, data, 21)) {
return sub;
}
}
return NULL;
}
static void cache_add(u8_t data[21], struct bt_mesh_subnet *sub)
{
memcpy(sub->beacon_cache, data, 21);
}
static void beacon_complete(int err, void *user_data)
{
struct bt_mesh_subnet *sub = user_data;
BT_DBG("err %d", err);
sub->beacon_sent = k_uptime_get_32();
}
void bt_mesh_beacon_create(struct bt_mesh_subnet *sub,
struct net_buf_simple *buf)
{
u8_t flags = bt_mesh_net_flags(sub);
struct bt_mesh_subnet_keys *keys;
net_buf_simple_add_u8(buf, BEACON_TYPE_SECURE);
if (sub->kr_flag) {
keys = &sub->keys[1];
} else {
keys = &sub->keys[0];
}
net_buf_simple_add_u8(buf, flags);
/* Network ID */
net_buf_simple_add_mem(buf, keys->net_id, 8);
/* IV Index */
net_buf_simple_add_be32(buf, bt_mesh.iv_index);
net_buf_simple_add_mem(buf, sub->auth, 8);
BT_DBG("net_idx 0x%04x flags 0x%02x NetID %s", sub->net_idx,
flags, bt_hex(keys->net_id, 8));
BT_DBG("IV Index 0x%08x Auth %s", bt_mesh.iv_index,
bt_hex(sub->auth, 8));
}
/* If the interval has passed or is within 5 seconds from now send a beacon */
#define BEACON_THRESHOLD(sub) (K_SECONDS(10 * ((sub)->beacons_last + 1)) - K_SECONDS(5))
static int secure_beacon_send(void)
{
static const struct bt_mesh_send_cb send_cb = {
.end = beacon_complete,
};
u32_t now = k_uptime_get_32();
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
struct net_buf *buf;
u32_t time_diff;
if (sub->net_idx == BT_MESH_KEY_UNUSED) {
continue;
}
time_diff = now - sub->beacon_sent;
if (time_diff < K_SECONDS(600) &&
time_diff < BEACON_THRESHOLD(sub)) {
continue;
}
buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, PROV_XMIT_COUNT,
PROV_XMIT_INT, K_NO_WAIT);
if (!buf) {
BT_ERR("Unable to allocate beacon buffer");
return -ENOBUFS;
}
bt_mesh_beacon_create(sub, &buf->b);
bt_mesh_adv_send(buf, &send_cb, sub);
net_buf_unref(buf);
}
return 0;
}
static int unprovisioned_beacon_send(void)
{
#if defined(CONFIG_BT_MESH_PB_ADV)
struct net_buf *buf;
struct bt_mesh_adv *adv;
BT_DBG("%s", __func__);
buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, UNPROV_XMIT_COUNT,
UNPROV_XMIT_INT, K_NO_WAIT);
if (!buf) {
BT_ERR("Unable to allocate beacon buffer");
return -ENOBUFS;
}
// Change by Espressif, added the following code for the debug used.
adv = BT_MESH_ADV(buf);
BT_DBG("%s, adv->type = %d, adv->count = %d, adv->adv_int = %d", __func__,
adv->type, adv->count, adv->adv_int);
net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED);
net_buf_add_mem(buf, bt_mesh_prov_get_uuid(), 16);
/* OOB Info (2 bytes) + URI Hash (4 bytes) */
memset(net_buf_add(buf, 2 + 4), 0, 2 + 4);
bt_mesh_adv_send(buf, NULL, NULL);
net_buf_unref(buf);
#endif /* CONFIG_BT_MESH_PB_ADV */
return 0;
}
static void update_beacon_observation(void)
{
static bool first_half;
int i;
/* Observation period is 20 seconds, whereas the beacon timer
* runs every 10 seconds. We process what's happened during the
* window only after the second half.
*/
first_half = !first_half;
if (first_half) {
return;
}
for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
if (sub->net_idx == BT_MESH_KEY_UNUSED) {
continue;
}
sub->beacons_last = sub->beacons_cur;
sub->beacons_cur = 0;
}
}
static void beacon_send(struct k_work *work)
{
/* Don't send anything if there is an active provisioning link */
if (IS_ENABLED(CONFIG_BT_MESH_PROV) && bt_prov_active()) {
k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL);
return;
}
BT_DBG("%s", __func__);
if (bt_mesh_is_provisioned()) {
update_beacon_observation();
secure_beacon_send();
/* Only resubmit if beaconing is still enabled */
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED ||
bt_mesh.ivu_initiator) {
k_delayed_work_submit(&beacon_timer,
PROVISIONED_INTERVAL);
}
} else {
unprovisioned_beacon_send();
k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL);
}
}
static void secure_beacon_recv(struct net_buf_simple *buf)
{
u8_t *data, *net_id, *auth;
struct bt_mesh_subnet *sub;
u32_t iv_index;
bool new_key, kr_change, iv_change;
u8_t flags;
if (buf->len < 21) {
BT_ERR("Too short secure beacon (len %u)", buf->len);
return;
}
sub = cache_check(buf->data);
if (sub) {
/* We've seen this beacon before - just update the stats */
goto update_stats;
}
/* So we can add to the cache if auth matches */
data = buf->data;
flags = net_buf_simple_pull_u8(buf);
net_id = buf->data;
net_buf_simple_pull(buf, 8);
iv_index = net_buf_simple_pull_be32(buf);
auth = buf->data;
BT_DBG("flags 0x%02x id %s iv_index 0x%08x",
flags, bt_hex(net_id, 8), iv_index);
sub = bt_mesh_subnet_find(net_id, flags, iv_index, auth, &new_key);
if (!sub) {
BT_DBG("No subnet that matched beacon");
return;
}
if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !new_key) {
BT_WARN("Ignoring Phase 2 KR Update secured using old key");
return;
}
cache_add(data, sub);
/* If there is NetKey0, accept initiation only from it */
if (bt_mesh_subnet_get(BT_MESH_KEY_PRIMARY) &&
sub->net_idx != BT_MESH_KEY_PRIMARY) {
BT_WARN("Ignoring secure beacon on non-primary subnet");
goto update_stats;
}
BT_DBG("net_idx 0x%04x iv_index 0x%08x, current iv_index 0x%08x",
sub->net_idx, iv_index, bt_mesh.iv_index);
if (bt_mesh.ivu_initiator &&
bt_mesh.iv_update == BT_MESH_IV_UPDATE(flags)) {
bt_mesh_beacon_ivu_initiator(false);
}
iv_change = bt_mesh_net_iv_update(iv_index, BT_MESH_IV_UPDATE(flags));
kr_change = bt_mesh_kr_update(sub, BT_MESH_KEY_REFRESH(flags), new_key);
if (kr_change) {
bt_mesh_net_beacon_update(sub);
}
if (iv_change) {
/* Update all subnets */
bt_mesh_net_sec_update(NULL);
} else if (kr_change) {
/* Key Refresh without IV Update only impacts one subnet */
bt_mesh_net_sec_update(sub);
}
update_stats:
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED &&
sub->beacons_cur < 0xff) {
sub->beacons_cur++;
}
}
void bt_mesh_beacon_recv(struct net_buf_simple *buf)
{
u8_t type;
BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));
if (buf->len < 1) {
BT_ERR("Too short beacon");
return;
}
type = net_buf_simple_pull_u8(buf);
switch (type) {
case BEACON_TYPE_UNPROVISIONED:
BT_DBG("Ignoring unprovisioned device beacon");
break;
case BEACON_TYPE_SECURE:
secure_beacon_recv(buf);
break;
default:
BT_WARN("Unknown beacon type 0x%02x", type);
break;
}
}
void bt_mesh_beacon_init(void)
{
k_delayed_work_init(&beacon_timer, beacon_send);
}
void bt_mesh_beacon_ivu_initiator(bool enable)
{
bt_mesh.ivu_initiator = enable;
if (enable) {
k_work_submit(&beacon_timer.work);
} else if (bt_mesh_beacon_get() == BT_MESH_BEACON_DISABLED) {
k_delayed_work_cancel(&beacon_timer);
}
}
void bt_mesh_beacon_enable(void)
{
int i;
if (!bt_mesh_is_provisioned()) {
k_work_submit(&beacon_timer.work);
return;
}
for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
struct bt_mesh_subnet *sub = &bt_mesh.sub[i];
if (sub->net_idx == BT_MESH_KEY_UNUSED) {
continue;
}
sub->beacons_last = 0;
sub->beacons_cur = 0;
bt_mesh_net_beacon_update(sub);
}
k_work_submit(&beacon_timer.work);
}
void bt_mesh_beacon_disable(void)
{
if (!bt_mesh.ivu_initiator) {
k_delayed_work_cancel(&beacon_timer);
}
}
#endif /* CONFIG_BT_MESH_NODE */
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,19 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
void bt_mesh_beacon_enable(void);
void bt_mesh_beacon_disable(void);
void bt_mesh_beacon_ivu_initiator(bool enable);
void bt_mesh_beacon_recv(struct net_buf_simple *buf);
void bt_mesh_beacon_create(struct bt_mesh_subnet *sub,
struct net_buf_simple *buf);
void bt_mesh_beacon_init(void);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,880 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include "mesh_types.h"
#include "mesh_util.h"
#include "sdkconfig.h"
#include "mesh_buf.h"
#if CONFIG_BT_MESH
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_CRYPTO)
#include "mesh_trace.h"
#include "mesh.h"
#include "crypto.h"
#include "mesh_bearer_adapt.h"
#include "mesh_aes_encrypt.h"
#define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4)
#define APP_MIC_LEN(aszmic) ((aszmic) ? 8 : 4)
int bt_mesh_aes_cmac(const u8_t key[16], struct bt_mesh_sg *sg,
size_t sg_len, u8_t mac[16])
{
struct tc_aes_key_sched_struct sched;
struct tc_cmac_struct state;
if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) {
return -EIO;
}
for (; sg_len; sg_len--, sg++) {
if (tc_cmac_update(&state, sg->data,
sg->len) == TC_CRYPTO_FAIL) {
return -EIO;
}
}
if (tc_cmac_final(mac, &state) == TC_CRYPTO_FAIL) {
return -EIO;
}
return 0;
}
int bt_mesh_k1(const u8_t *ikm, size_t ikm_len, const u8_t salt[16],
const char *info, u8_t okm[16])
{
int err;
err = bt_mesh_aes_cmac_one(salt, ikm, ikm_len, okm);
if (err < 0) {
return err;
}
return bt_mesh_aes_cmac_one(okm, info, strlen(info), okm);
}
int bt_mesh_k2(const u8_t n[16], const u8_t *p, size_t p_len,
u8_t net_id[1], u8_t enc_key[16], u8_t priv_key[16])
{
struct bt_mesh_sg sg[3];
u8_t salt[16];
u8_t out[16];
u8_t t[16];
u8_t pad;
int err;
BT_DBG("n %s", bt_hex(n, 16));
BT_DBG("p %s", bt_hex(p, p_len));
err = bt_mesh_s1("smk2", salt);
if (err) {
return err;
}
err = bt_mesh_aes_cmac_one(salt, n, 16, t);
if (err) {
return err;
}
pad = 0x01;
sg[0].data = NULL;
sg[0].len = 0;
sg[1].data = p;
sg[1].len = p_len;
sg[2].data = &pad;
sg[2].len = sizeof(pad);
err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
if (err) {
return err;
}
net_id[0] = out[15] & 0x7f;
sg[0].data = out;
sg[0].len = sizeof(out);
pad = 0x02;
err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
if (err) {
return err;
}
memcpy(enc_key, out, 16);
pad = 0x03;
err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out);
if (err) {
return err;
}
memcpy(priv_key, out, 16);
BT_DBG("NID 0x%02x enc_key %s", net_id[0], bt_hex(enc_key, 16));
BT_DBG("priv_key %s", bt_hex(priv_key, 16));
return 0;
}
int bt_mesh_k3(const u8_t n[16], u8_t out[8])
{
u8_t id64[] = { 'i', 'd', '6', '4', 0x01 };
u8_t tmp[16];
u8_t t[16];
int err;
err = bt_mesh_s1("smk3", tmp);
if (err) {
return err;
}
err = bt_mesh_aes_cmac_one(tmp, n, 16, t);
if (err) {
return err;
}
err = bt_mesh_aes_cmac_one(t, id64, sizeof(id64), tmp);
if (err) {
return err;
}
memcpy(out, tmp + 8, 8);
return 0;
}
int bt_mesh_k4(const u8_t n[16], u8_t out[1])
{
u8_t id6[] = { 'i', 'd', '6', 0x01 };
u8_t tmp[16];
u8_t t[16];
int err;
err = bt_mesh_s1("smk4", tmp);
if (err) {
return err;
}
err = bt_mesh_aes_cmac_one(tmp, n, 16, t);
if (err) {
return err;
}
err = bt_mesh_aes_cmac_one(t, id6, sizeof(id6), tmp);
if (err) {
return err;
}
out[0] = tmp[15] & BIT_MASK(6);
return 0;
}
int bt_mesh_id128(const u8_t n[16], const char *s, u8_t out[16])
{
const char *id128 = "id128\x01";
u8_t salt[16];
int err;
err = bt_mesh_s1(s, salt);
if (err) {
return err;
}
return bt_mesh_k1(n, 16, salt, id128, out);
}
static int bt_mesh_ccm_decrypt(const u8_t key[16], u8_t nonce[13],
const u8_t *enc_msg, size_t msg_len,
const u8_t *aad, size_t aad_len,
u8_t *out_msg, size_t mic_size)
{
u8_t msg[16], pmsg[16], cmic[16], cmsg[16], Xn[16], mic[16];
u16_t last_blk, blk_cnt;
size_t i, j;
int err;
if (msg_len < 1 || aad_len >= 0xff00) {
return -EINVAL;
}
/* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */
pmsg[0] = 0x01;
memcpy(pmsg + 1, nonce, 13);
sys_put_be16(0x0000, pmsg + 14);
err = bt_encrypt_be(key, pmsg, cmic);
if (err) {
return err;
}
/* X_0 = e(AppKey, 0x09 || nonce || length) */
if (mic_size == sizeof(u64_t)) {
pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00);
} else {
pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00);
}
memcpy(pmsg + 1, nonce, 13);
sys_put_be16(msg_len, pmsg + 14);
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
/* If AAD is being used to authenticate, include it here */
if (aad_len) {
sys_put_be16(aad_len, pmsg);
for (i = 0; i < sizeof(u16_t); i++) {
pmsg[i] = Xn[i] ^ pmsg[i];
}
j = 0;
aad_len += sizeof(u16_t);
while (aad_len > 16) {
do {
pmsg[i] = Xn[i] ^ aad[j];
i++, j++;
} while (i < 16);
aad_len -= 16;
i = 0;
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
}
for (i = 0; i < aad_len; i++, j++) {
pmsg[i] = Xn[i] ^ aad[j];
}
for (i = aad_len; i < 16; i++) {
pmsg[i] = Xn[i];
}
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
}
last_blk = msg_len % 16;
blk_cnt = (msg_len + 15) / 16;
if (!last_blk) {
last_blk = 16;
}
for (j = 0; j < blk_cnt; j++) {
if (j + 1 == blk_cnt) {
/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
pmsg[0] = 0x01;
memcpy(pmsg + 1, nonce, 13);
sys_put_be16(j + 1, pmsg + 14);
err = bt_encrypt_be(key, pmsg, cmsg);
if (err) {
return err;
}
/* Encrypted = Payload[0-15] ^ C_1 */
for (i = 0; i < last_blk; i++) {
msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i];
}
memcpy(out_msg + (j * 16), msg, last_blk);
/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
for (i = 0; i < last_blk; i++) {
pmsg[i] = Xn[i] ^ msg[i];
}
for (i = last_blk; i < 16; i++) {
pmsg[i] = Xn[i] ^ 0x00;
}
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
/* MIC = C_mic ^ X_1 */
for (i = 0; i < sizeof(mic); i++) {
mic[i] = cmic[i] ^ Xn[i];
}
} else {
/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
pmsg[0] = 0x01;
memcpy(pmsg + 1, nonce, 13);
sys_put_be16(j + 1, pmsg + 14);
err = bt_encrypt_be(key, pmsg, cmsg);
if (err) {
return err;
}
/* Encrypted = Payload[0-15] ^ C_1 */
for (i = 0; i < 16; i++) {
msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i];
}
memcpy(out_msg + (j * 16), msg, 16);
/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
for (i = 0; i < 16; i++) {
pmsg[i] = Xn[i] ^ msg[i];
}
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
}
}
if (memcmp(mic, enc_msg + msg_len, mic_size)) {
return -EBADMSG;
}
return 0;
}
static int bt_mesh_ccm_encrypt(const u8_t key[16], u8_t nonce[13],
const u8_t *msg, size_t msg_len,
const u8_t *aad, size_t aad_len,
u8_t *out_msg, size_t mic_size)
{
u8_t pmsg[16], cmic[16], cmsg[16], mic[16], Xn[16];
u16_t blk_cnt, last_blk;
size_t i, j;
int err;
BT_DBG("key %s", bt_hex(key, 16));
BT_DBG("nonce %s", bt_hex(nonce, 13));
BT_DBG("msg (len %u) %s", msg_len, bt_hex(msg, msg_len));
BT_DBG("aad_len %u mic_size %u", aad_len, mic_size);
/* Unsupported AAD size */
if (aad_len >= 0xff00) {
return -EINVAL;
}
/* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */
pmsg[0] = 0x01;
memcpy(pmsg + 1, nonce, 13);
sys_put_be16(0x0000, pmsg + 14);
err = bt_encrypt_be(key, pmsg, cmic);
if (err) {
return err;
}
/* X_0 = e(AppKey, 0x09 || nonce || length) */
if (mic_size == sizeof(u64_t)) {
pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00);
} else {
pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00);
}
memcpy(pmsg + 1, nonce, 13);
sys_put_be16(msg_len, pmsg + 14);
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
/* If AAD is being used to authenticate, include it here */
if (aad_len) {
sys_put_be16(aad_len, pmsg);
for (i = 0; i < sizeof(u16_t); i++) {
pmsg[i] = Xn[i] ^ pmsg[i];
}
j = 0;
aad_len += sizeof(u16_t);
while (aad_len > 16) {
do {
pmsg[i] = Xn[i] ^ aad[j];
i++, j++;
} while (i < 16);
aad_len -= 16;
i = 0;
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
}
for (i = 0; i < aad_len; i++, j++) {
pmsg[i] = Xn[i] ^ aad[j];
}
for (i = aad_len; i < 16; i++) {
pmsg[i] = Xn[i];
}
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
}
last_blk = msg_len % 16;
blk_cnt = (msg_len + 15) / 16;
if (!last_blk) {
last_blk = 16;
}
for (j = 0; j < blk_cnt; j++) {
if (j + 1 == blk_cnt) {
/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
for (i = 0; i < last_blk; i++) {
pmsg[i] = Xn[i] ^ msg[(j * 16) + i];
}
for (i = last_blk; i < 16; i++) {
pmsg[i] = Xn[i] ^ 0x00;
}
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
/* MIC = C_mic ^ X_1 */
for (i = 0; i < sizeof(mic); i++) {
mic[i] = cmic[i] ^ Xn[i];
}
/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
pmsg[0] = 0x01;
memcpy(pmsg + 1, nonce, 13);
sys_put_be16(j + 1, pmsg + 14);
err = bt_encrypt_be(key, pmsg, cmsg);
if (err) {
return err;
}
/* Encrypted = Payload[0-15] ^ C_1 */
for (i = 0; i < last_blk; i++) {
out_msg[(j * 16) + i] =
msg[(j * 16) + i] ^ cmsg[i];
}
} else {
/* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */
for (i = 0; i < 16; i++) {
pmsg[i] = Xn[i] ^ msg[(j * 16) + i];
}
err = bt_encrypt_be(key, pmsg, Xn);
if (err) {
return err;
}
/* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */
pmsg[0] = 0x01;
memcpy(pmsg + 1, nonce, 13);
sys_put_be16(j + 1, pmsg + 14);
err = bt_encrypt_be(key, pmsg, cmsg);
if (err) {
return err;
}
/* Encrypted = Payload[0-15] ^ C_N */
for (i = 0; i < 16; i++) {
out_msg[(j * 16) + i] =
msg[(j * 16) + i] ^ cmsg[i];
}
}
}
memcpy(out_msg + msg_len, mic, mic_size);
return 0;
}
#if defined(CONFIG_BT_MESH_PROXY)
static void create_proxy_nonce(u8_t nonce[13], const u8_t *pdu,
u32_t iv_index)
{
/* Nonce Type */
nonce[0] = 0x03;
/* Pad */
nonce[1] = 0x00;
/* Sequence Number */
nonce[2] = pdu[2];
nonce[3] = pdu[3];
nonce[4] = pdu[4];
/* Source Address */
nonce[5] = pdu[5];
nonce[6] = pdu[6];
/* Pad */
nonce[7] = 0;
nonce[8] = 0;
/* IV Index */
sys_put_be32(iv_index, &nonce[9]);
}
#endif /* PROXY */
static void create_net_nonce(u8_t nonce[13], const u8_t *pdu,
u32_t iv_index)
{
/* Nonce Type */
nonce[0] = 0x00;
/* FRND + TTL */
nonce[1] = pdu[1];
/* Sequence Number */
nonce[2] = pdu[2];
nonce[3] = pdu[3];
nonce[4] = pdu[4];
/* Source Address */
nonce[5] = pdu[5];
nonce[6] = pdu[6];
/* Pad */
nonce[7] = 0;
nonce[8] = 0;
/* IV Index */
sys_put_be32(iv_index, &nonce[9]);
}
int bt_mesh_net_obfuscate(u8_t *pdu, u32_t iv_index,
const u8_t privacy_key[16])
{
u8_t priv_rand[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
u8_t tmp[16];
int err, i;
BT_DBG("IVIndex %u, PrivacyKey %s", iv_index, bt_hex(privacy_key, 16));
sys_put_be32(iv_index, &priv_rand[5]);
memcpy(&priv_rand[9], &pdu[7], 7);
BT_DBG("PrivacyRandom %s", bt_hex(priv_rand, 16));
err = bt_encrypt_be(privacy_key, priv_rand, tmp);
if (err) {
return err;
}
for (i = 0; i < 6; i++) {
pdu[1 + i] ^= tmp[i];
}
return 0;
}
int bt_mesh_net_encrypt(const u8_t key[16], struct net_buf_simple *buf,
u32_t iv_index, bool proxy)
{
u8_t mic_len = NET_MIC_LEN(buf->data);
u8_t nonce[13];
int err;
BT_DBG("IVIndex %u EncKey %s mic_len %u", iv_index, bt_hex(key, 16),
mic_len);
BT_DBG("PDU (len %u) %s", buf->len, bt_hex(buf->data, buf->len));
#if defined(CONFIG_BT_MESH_PROXY)
if (proxy) {
create_proxy_nonce(nonce, buf->data, iv_index);
} else {
create_net_nonce(nonce, buf->data, iv_index);
}
#else
create_net_nonce(nonce, buf->data, iv_index);
#endif
BT_DBG("Nonce %s", bt_hex(nonce, 13));
err = bt_mesh_ccm_encrypt(key, nonce, &buf->data[7], buf->len - 7,
NULL, 0, &buf->data[7], mic_len);
if (!err) {
net_buf_simple_add(buf, mic_len);
}
return err;
}
int bt_mesh_net_decrypt(const u8_t key[16], struct net_buf_simple *buf,
u32_t iv_index, bool proxy)
{
u8_t mic_len = NET_MIC_LEN(buf->data);
u8_t nonce[13];
BT_DBG("PDU (%u bytes) %s", buf->len, bt_hex(buf->data, buf->len));
BT_DBG("iv_index %u, key %s mic_len %u", iv_index, bt_hex(key, 16),
mic_len);
#if defined(CONFIG_BT_MESH_PROXY)
if (proxy) {
create_proxy_nonce(nonce, buf->data, iv_index);
} else {
create_net_nonce(nonce, buf->data, iv_index);
}
#else
create_net_nonce(nonce, buf->data, iv_index);
#endif
BT_DBG("Nonce %s", bt_hex(nonce, 13));
buf->len -= mic_len;
return bt_mesh_ccm_decrypt(key, nonce, &buf->data[7], buf->len - 7,
NULL, 0, &buf->data[7], mic_len);
}
static void create_app_nonce(u8_t nonce[13], bool dev_key, u8_t aszmic,
u16_t src, u16_t dst, u32_t seq_num,
u32_t iv_index)
{
if (dev_key) {
nonce[0] = 0x02;
} else {
nonce[0] = 0x01;
}
sys_put_be32((seq_num | ((u32_t)aszmic << 31)), &nonce[1]);
sys_put_be16(src, &nonce[5]);
sys_put_be16(dst, &nonce[7]);
sys_put_be32(iv_index, &nonce[9]);
}
int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic,
struct net_buf_simple *buf, const u8_t *ad,
u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index)
{
u8_t nonce[13];
int err;
BT_DBG("AppKey %s", bt_hex(key, 16));
BT_DBG("dev_key %u src 0x%04x dst 0x%04x", dev_key, src, dst);
BT_DBG("seq_num 0x%08x iv_index 0x%08x", seq_num, iv_index);
BT_DBG("Clear: %s", bt_hex(buf->data, buf->len));
create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index);
BT_DBG("Nonce %s", bt_hex(nonce, 13));
err = bt_mesh_ccm_encrypt(key, nonce, buf->data, buf->len, ad,
ad ? 16 : 0, buf->data, APP_MIC_LEN(aszmic));
if (!err) {
net_buf_simple_add(buf, APP_MIC_LEN(aszmic));
BT_DBG("Encr: %s", bt_hex(buf->data, buf->len));
}
return err;
}
int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic,
struct net_buf_simple *buf, struct net_buf_simple *out,
const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num,
u32_t iv_index)
{
u8_t nonce[13];
int err;
BT_DBG("EncData (len %u) %s", buf->len, bt_hex(buf->data, buf->len));
create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index);
BT_DBG("AppKey %s", bt_hex(key, 16));
BT_DBG("Nonce %s", bt_hex(nonce, 13));
err = bt_mesh_ccm_decrypt(key, nonce, buf->data, buf->len, ad,
ad ? 16 : 0, out->data, APP_MIC_LEN(aszmic));
if (!err) {
net_buf_simple_add(out, buf->len);
}
return err;
}
/* reversed, 8-bit, poly=0x07 */
static const u8_t crc_table[256] = {
0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
};
u8_t bt_mesh_fcs_calc(const u8_t *data, u8_t data_len)
{
u8_t fcs = 0xff;
while (data_len--) {
fcs = crc_table[fcs ^ *data++];
}
BT_DBG("fcs 0x%02x", 0xff - fcs);
return 0xff - fcs;
}
bool bt_mesh_fcs_check(struct net_buf_simple *buf, u8_t received_fcs)
{
const u8_t *data = buf->data;
u16_t data_len = buf->len;
u8_t fcs = 0xff;
while (data_len--) {
fcs = crc_table[fcs ^ *data++];
}
return crc_table[fcs ^ received_fcs] == 0xcf;
}
int bt_mesh_virtual_addr(const u8_t virtual_label[16], u16_t *addr)
{
u8_t salt[16];
u8_t tmp[16];
int err;
err = bt_mesh_s1("vtad", salt);
if (err) {
return err;
}
err = bt_mesh_aes_cmac_one(salt, virtual_label, 16, tmp);
if (err) {
return err;
}
*addr = (sys_get_be16(&tmp[14]) & 0x3fff) | 0x8000;
return 0;
}
int bt_mesh_prov_conf_salt(const u8_t conf_inputs[145], u8_t salt[16])
{
const u8_t conf_salt_key[16] = { 0 };
return bt_mesh_aes_cmac_one(conf_salt_key, conf_inputs, 145, salt);
}
int bt_mesh_prov_conf_key(const u8_t dhkey[32], const u8_t conf_salt[16],
u8_t conf_key[16])
{
return bt_mesh_k1(dhkey, 32, conf_salt, "prck", conf_key);
}
int bt_mesh_prov_conf(const u8_t conf_key[16], const u8_t rand[16],
const u8_t auth[16], u8_t conf[16])
{
struct bt_mesh_sg sg[] = { { rand, 16 }, { auth, 16 } };
BT_DBG("ConfirmationKey %s", bt_hex(conf_key, 16));
BT_DBG("RandomDevice %s", bt_hex(rand, 16));
BT_DBG("AuthValue %s", bt_hex(auth, 16));
return bt_mesh_aes_cmac(conf_key, sg, ARRAY_SIZE(sg), conf);
}
int bt_mesh_prov_decrypt(const u8_t key[16], u8_t nonce[13],
const u8_t data[25 + 8], u8_t out[25])
{
return bt_mesh_ccm_decrypt(key, nonce, data, 25, NULL, 0, out, 8);
}
#if CONFIG_BT_MESH_PROVISIONER
int bt_mesh_prov_encrypt(const u8_t key[16], u8_t nonce[13],
const u8_t data[25], u8_t out[33])
{
return bt_mesh_ccm_encrypt(key, nonce, data, 25, NULL, 0, out, 8);
}
#endif
int bt_mesh_beacon_auth(const u8_t beacon_key[16], u8_t flags,
const u8_t net_id[8], u32_t iv_index,
u8_t auth[8])
{
u8_t msg[13], tmp[16];
int err;
BT_DBG("BeaconKey %s", bt_hex(beacon_key, 16));
BT_DBG("NetId %s", bt_hex(net_id, 8));
BT_DBG("IV Index 0x%08x", iv_index);
msg[0] = flags;
memcpy(&msg[1], net_id, 8);
sys_put_be32(iv_index, &msg[9]);
BT_DBG("BeaconMsg %s", bt_hex(msg, sizeof(msg)));
err = bt_mesh_aes_cmac_one(beacon_key, msg, sizeof(msg), tmp);
if (!err) {
memcpy(auth, tmp, 8);
}
return err;
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,163 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mesh_types.h"
#include <string.h>
struct bt_mesh_sg {
const void *data;
size_t len;
};
int bt_mesh_aes_cmac(const u8_t key[16], struct bt_mesh_sg *sg,
size_t sg_len, u8_t mac[16]);
static inline int bt_mesh_aes_cmac_one(const u8_t key[16], const void *m,
size_t len, u8_t mac[16])
{
struct bt_mesh_sg sg = { m, len };
return bt_mesh_aes_cmac(key, &sg, 1, mac);
}
static inline bool bt_mesh_s1(const char *m, u8_t salt[16])
{
const u8_t zero[16] = { 0 };
return bt_mesh_aes_cmac_one(zero, m, strlen(m), salt);
}
int bt_mesh_k1(const u8_t *ikm, size_t ikm_len, const u8_t salt[16],
const char *info, u8_t okm[16]);
#define bt_mesh_k1_str(ikm, ikm_len, salt_str, info, okm) \
({ \
const u8_t salt[16] = salt_str; \
bt_mesh_k1(ikm, ikm_len, salt, info, okm); \
})
int bt_mesh_k2(const u8_t n[16], const u8_t *p, size_t p_len,
u8_t net_id[1], u8_t enc_key[16], u8_t priv_key[16]);
int bt_mesh_k3(const u8_t n[16], u8_t out[8]);
int bt_mesh_k4(const u8_t n[16], u8_t out[1]);
int bt_mesh_id128(const u8_t n[16], const char *s, u8_t out[16]);
static inline int bt_mesh_id_resolving_key(const u8_t net_key[16],
u8_t resolving_key[16])
{
return bt_mesh_k1_str(net_key, 16, "smbt", "smbi", resolving_key);
}
static inline int bt_mesh_identity_key(const u8_t net_key[16],
u8_t identity_key[16])
{
return bt_mesh_id128(net_key, "nkik", identity_key);
}
static inline int bt_mesh_beacon_key(const u8_t net_key[16],
u8_t beacon_key[16])
{
return bt_mesh_id128(net_key, "nkbk", beacon_key);
}
int bt_mesh_beacon_auth(const u8_t beacon_key[16], u8_t flags,
const u8_t net_id[16], u32_t iv_index,
u8_t auth[8]);
static inline int bt_mesh_app_id(const u8_t app_key[16], u8_t app_id[1])
{
return bt_mesh_k4(app_key, app_id);
}
static inline int bt_mesh_session_key(const u8_t dhkey[32],
const u8_t prov_salt[16],
u8_t session_key[16])
{
return bt_mesh_k1(dhkey, 32, prov_salt, "prsk", session_key);
}
static inline int bt_mesh_prov_nonce(const u8_t dhkey[32],
const u8_t prov_salt[16],
u8_t nonce[13])
{
u8_t tmp[16];
int err;
err = bt_mesh_k1(dhkey, 32, prov_salt, "prsn", tmp);
if (!err) {
memcpy(nonce, tmp + 3, 13);
}
return err;
}
static inline int bt_mesh_dev_key(const u8_t dhkey[32],
const u8_t prov_salt[16],
u8_t dev_key[16])
{
return bt_mesh_k1(dhkey, 32, prov_salt, "prdk", dev_key);
}
static inline int bt_mesh_prov_salt(const u8_t conf_salt[16],
const u8_t prov_rand[16],
const u8_t dev_rand[16],
u8_t prov_salt[16])
{
const u8_t prov_salt_key[16] = { 0 };
struct bt_mesh_sg sg[] = {
{ conf_salt, 16 },
{ prov_rand, 16 },
{ dev_rand, 16 },
};
return bt_mesh_aes_cmac(prov_salt_key, sg, ARRAY_SIZE(sg), prov_salt);
}
int bt_mesh_net_obfuscate(u8_t *pdu, u32_t iv_index,
const u8_t privacy_key[16]);
int bt_mesh_net_encrypt(const u8_t key[16], struct net_buf_simple *buf,
u32_t iv_index, bool proxy);
int bt_mesh_net_decrypt(const u8_t key[16], struct net_buf_simple *buf,
u32_t iv_index, bool proxy);
int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic,
struct net_buf_simple *buf, const u8_t *ad,
u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index);
int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic,
struct net_buf_simple *buf, struct net_buf_simple *out,
const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num,
u32_t iv_index);
u8_t bt_mesh_fcs_calc(const u8_t *data, u8_t data_len);
bool bt_mesh_fcs_check(struct net_buf_simple *buf, u8_t received_fcs);
int bt_mesh_virtual_addr(const u8_t virtual_label[16], u16_t *addr);
int bt_mesh_prov_conf_salt(const u8_t conf_inputs[145], u8_t salt[16]);
int bt_mesh_prov_conf_key(const u8_t dhkey[32], const u8_t conf_salt[16],
u8_t conf_key[16]);
int bt_mesh_prov_conf(const u8_t conf_key[16], const u8_t rand[16],
const u8_t auth[16], u8_t conf[16]);
int bt_mesh_prov_decrypt(const u8_t key[16], u8_t nonce[13],
const u8_t data[25 + 8], u8_t out[25]);
#if CONFIG_BT_MESH_PROVISIONER
int bt_mesh_prov_encrypt(const u8_t key[16], u8_t nonce[13],
const u8_t data[25], u8_t out[33]);
#endif

View File

@@ -0,0 +1,319 @@
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "dlist.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
static sys_dlist_t test_list;
struct container_node {
sys_dnode_t node;
int unused;
};
static struct container_node test_node_1;
static struct container_node test_node_2;
static struct container_node test_node_3;
static struct container_node test_node_4;
static inline bool verify_emptyness(sys_dlist_t *list)
{
sys_dnode_t *node;
sys_dnode_t *s_node;
struct container_node *cnode;
struct container_node *s_cnode;
int count;
if (!sys_dlist_is_empty(list)) {
return false;
}
if (sys_dlist_peek_head(list)) {
return false;
}
if (sys_dlist_peek_tail(list)) {
return false;
}
count = 0;
SYS_DLIST_FOR_EACH_NODE(list, node) {
count++;
}
if (count) {
return false;
}
SYS_DLIST_FOR_EACH_NODE_SAFE(list, node, s_node) {
count++;
}
if (count) {
return false;
}
count = 0;
SYS_DLIST_FOR_EACH_CONTAINER(list, cnode, node) {
count++;
}
if (count) {
return false;
}
count = 0;
SYS_DLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) {
count++;
}
if (count) {
return false;
}
return true;
}
static inline bool verify_content_amount(sys_dlist_t *list, int amount)
{
sys_dnode_t *node;
sys_dnode_t *s_node;
struct container_node *cnode;
struct container_node *s_cnode;
int count;
if (sys_dlist_is_empty(list)) {
return false;
}
if (!sys_dlist_peek_head(list)) {
return false;
}
if (!sys_dlist_peek_tail(list)) {
return false;
}
count = 0;
SYS_DLIST_FOR_EACH_NODE(list, node) {
count++;
}
if (count != amount) {
return false;
}
count = 0;
SYS_DLIST_FOR_EACH_NODE_SAFE(list, node, s_node) {
count++;
}
if (count != amount) {
return false;
}
count = 0;
SYS_DLIST_FOR_EACH_CONTAINER(list, cnode, node) {
count++;
}
if (count != amount) {
return false;
}
count = 0;
SYS_DLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) {
count++;
}
if (count != amount) {
return false;
}
return true;
}
static inline bool verify_tail_head(sys_dlist_t *list,
sys_dnode_t *head,
sys_dnode_t *tail,
bool same)
{
if (sys_dlist_peek_head(list) != head) {
return false;
}
if (sys_dlist_peek_tail(list) != tail) {
return false;
}
if (same) {
if (sys_dlist_peek_head(list) != sys_dlist_peek_tail(list)) {
return false;
}
} else {
if (sys_dlist_peek_head(list) == sys_dlist_peek_tail(list)) {
return false;
}
}
return true;
}
void dlist_test(void)
{
sys_dlist_init(&test_list);
//zassert_true((verify_emptyness(&test_list)), "test_list should be empty");
/* Appending node 1 */
sys_dlist_append(&test_list, &test_node_1.node);
//zassert_true((verify_content_amount(&test_list, 1)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_1.node,
// &test_node_1.node, true)),
// "test_list head/tail are wrong");
/* Finding and removing node 1 */
sys_dlist_remove(&test_node_1.node);
//zassert_true((verify_emptyness(&test_list)),
// "test_list should be empty");
/* Prepending node 1 */
sys_dlist_prepend(&test_list, &test_node_1.node);
//zassert_true((verify_content_amount(&test_list, 1)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_1.node,
// &test_node_1.node, true)),
// "test_list head/tail are wrong");
/* Removing node 1 */
sys_dlist_remove(&test_node_1.node);
//zassert_true((verify_emptyness(&test_list)),
// "test_list should be empty");
/* Appending node 1 */
sys_dlist_append(&test_list, &test_node_1.node);
/* Prepending node 2 */
sys_dlist_prepend(&test_list, &test_node_2.node);
//zassert_true((verify_content_amount(&test_list, 2)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_1.node, false)),
// "test_list head/tail are wrong");
/* Appending node 3 */
sys_dlist_append(&test_list, &test_node_3.node);
//zassert_true((verify_content_amount(&test_list, 3)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_3.node, false)),
// "test_list head/tail are wrong");
//zassert_true((sys_dlist_peek_next(&test_list, &test_node_2.node) ==
// &test_node_1.node),
// "test_list node links are wrong");
/* Inserting node 4 after node 2 */
sys_dlist_insert_after(&test_list, &test_node_2.node,
&test_node_4.node);
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_3.node, false)),
// "test_list head/tail are wrong");
//zassert_true((sys_dlist_peek_next(&test_list, &test_node_2.node) ==
// &test_node_4.node),
// "test_list node links are wrong");
/* Finding and removing node 1 */
sys_dlist_remove(&test_node_1.node);
//zassert_true((verify_content_amount(&test_list, 3)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_3.node, false)),
// "test_list head/tail are wrong");
/* Removing node 3 */
sys_dlist_remove(&test_node_3.node);
//zassert_true((verify_content_amount(&test_list, 2)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_4.node, false)),
// "test_list head/tail are wrong");
/* Removing node 4 */
sys_dlist_remove(&test_node_4.node);
//zassert_true((verify_content_amount(&test_list, 1)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_2.node, true)),
// "test_list head/tail are wrong");
/* Removing node 2 */
sys_dlist_remove(&test_node_2.node);
//zassert_true((verify_emptyness(&test_list)),
// "test_list should be empty");
/* test iterator from a node */
struct data_node {
sys_dnode_t node;
int data;
} data_node[6] = {
{ .data = 0 },
{ .data = 1 },
{ .data = 2 },
{ .data = 3 },
{ .data = 4 },
{ .data = 5 },
};
sys_dnode_t *node = NULL;
int ii;
sys_dlist_init(&test_list);
for (ii = 0; ii < 6; ii++) {
sys_dlist_append(&test_list, &data_node[ii].node);
}
ii = 0;
SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) {
ii++;
if (((struct data_node *)node)->data == 2) {
break;
}
}
//zassert_equal(ii, 3, "");
ii = 0;
SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) {
ii++;
if (((struct data_node *)node)->data == 3) {
break;
}
}
//zassert_equal(ii, 1, "");
ii = 0;
SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) {
ii++;
}
//zassert_equal(ii, 2, "");
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,496 @@
/*
* Copyright (c) 2013-2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Doubly-linked list implementation
*
* Doubly-linked list implementation using inline macros/functions.
* This API is not thread safe, and thus if a list is used across threads,
* calls to functions must be protected with synchronization primitives.
*
* The lists are expected to be initialized such that both the head and tail
* pointers point to the list itself. Initializing the lists in such a fashion
* simplifies the adding and removing of nodes to/from the list.
*/
#ifndef _misc_dlist__h_
#define _misc_dlist__h_
#include <stddef.h>
#include "mesh_util.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _dnode {
union {
struct _dnode *head; /* ptr to head of list (sys_dlist_t) */
struct _dnode *next; /* ptr to next node (sys_dnode_t) */
};
union {
struct _dnode *tail; /* ptr to tail of list (sys_dlist_t) */
struct _dnode *prev; /* ptr to previous node (sys_dnode_t) */
};
};
typedef struct _dnode sys_dlist_t;
typedef struct _dnode sys_dnode_t;
/**
* @brief Provide the primitive to iterate on a list
* Note: the loop is unsafe and thus __dn should not be removed
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_FOR_EACH_NODE(l, n) {
* <user code>
* }
*
* This and other SYS_DLIST_*() macros are not thread safe.
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __dn A sys_dnode_t pointer to peek each node of the list
*/
#define SYS_DLIST_FOR_EACH_NODE(__dl, __dn) \
for (__dn = sys_dlist_peek_head(__dl); __dn; \
__dn = sys_dlist_peek_next(__dl, __dn))
/**
* @brief Provide the primitive to iterate on a list, from a node in the list
* Note: the loop is unsafe and thus __dn should not be removed
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_ITERATE_FROM_NODE(l, n) {
* <user code>
* }
*
* Like SYS_DLIST_FOR_EACH_NODE(), but __dn already contains a node in the list
* where to start searching for the next entry from. If NULL, it starts from
* the head.
*
* This and other SYS_DLIST_*() macros are not thread safe.
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __dn A sys_dnode_t pointer to peek each node of the list;
* it contains the starting node, or NULL to start from the head
*/
#define SYS_DLIST_ITERATE_FROM_NODE(__dl, __dn) \
for (__dn = __dn ? sys_dlist_peek_next_no_check(__dl, __dn) \
: sys_dlist_peek_head(__dl); \
__dn; \
__dn = sys_dlist_peek_next(__dl, __dn))
/**
* @brief Provide the primitive to safely iterate on a list
* Note: __dn can be removed, it will not break the loop.
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_FOR_EACH_NODE_SAFE(l, n, s) {
* <user code>
* }
*
* This and other SYS_DLIST_*() macros are not thread safe.
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __dn A sys_dnode_t pointer to peek each node of the list
* @param __dns A sys_dnode_t pointer for the loop to run safely
*/
#define SYS_DLIST_FOR_EACH_NODE_SAFE(__dl, __dn, __dns) \
for (__dn = sys_dlist_peek_head(__dl), \
__dns = sys_dlist_peek_next(__dl, __dn); \
__dn; __dn = __dns, \
__dns = sys_dlist_peek_next(__dl, __dn))
/*
* @brief Provide the primitive to resolve the container of a list node
* Note: it is safe to use with NULL pointer nodes
*
* @param __dn A pointer on a sys_dnode_t to get its container
* @param __cn Container struct type pointer
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_CONTAINER(__dn, __cn, __n) \
(__dn ? CONTAINER_OF(__dn, __typeof__(*__cn), __n) : NULL)
/*
* @brief Provide the primitive to peek container of the list head
*
* @param __dl A pointer on a sys_dlist_t to peek
* @param __cn Container struct type pointer
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n) \
SYS_DLIST_CONTAINER(sys_dlist_peek_head(__dl), __cn, __n)
/*
* @brief Provide the primitive to peek the next container
*
* @param __dl A pointer on a sys_dlist_t to peek
* @param __cn Container struct type pointer
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n) \
((__cn) ? SYS_DLIST_CONTAINER(sys_dlist_peek_next(__dl, &(__cn->__n)), \
__cn, __n) : NULL)
/**
* @brief Provide the primitive to iterate on a list under a container
* Note: the loop is unsafe and thus __cn should not be detached
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_FOR_EACH_CONTAINER(l, c, n) {
* <user code>
* }
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __cn A pointer to peek each entry of the list
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_FOR_EACH_CONTAINER(__dl, __cn, __n) \
for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n); __cn; \
__cn = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
/**
* @brief Provide the primitive to safely iterate on a list under a container
* Note: __cn can be detached, it will not break the loop.
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_FOR_EACH_CONTAINER_SAFE(l, c, cn, n) {
* <user code>
* }
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __cn A pointer to peek each entry of the list
* @param __cns A pointer for the loop to run safely
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_FOR_EACH_CONTAINER_SAFE(__dl, __cn, __cns, __n) \
for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n), \
__cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n); __cn; \
__cn = __cns, \
__cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
/**
* @brief initialize list
*
* @param list the doubly-linked list
*
* @return N/A
*/
static inline void sys_dlist_init(sys_dlist_t *list)
{
list->head = (sys_dnode_t *)list;
list->tail = (sys_dnode_t *)list;
}
#define SYS_DLIST_STATIC_INIT(ptr_to_list) {{(ptr_to_list)}, {(ptr_to_list)}}
/**
* @brief check if a node is the list's head
*
* @param list the doubly-linked list to operate on
* @param node the node to check
*
* @return 1 if node is the head, 0 otherwise
*/
static inline int sys_dlist_is_head(sys_dlist_t *list, sys_dnode_t *node)
{
return list->head == node;
}
/**
* @brief check if a node is the list's tail
*
* @param list the doubly-linked list to operate on
* @param node the node to check
*
* @return 1 if node is the tail, 0 otherwise
*/
static inline int sys_dlist_is_tail(sys_dlist_t *list, sys_dnode_t *node)
{
return list->tail == node;
}
/**
* @brief check if the list is empty
*
* @param list the doubly-linked list to operate on
*
* @return 1 if empty, 0 otherwise
*/
static inline int sys_dlist_is_empty(sys_dlist_t *list)
{
return list->head == list;
}
/**
* @brief check if more than one node present
*
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
*
* @return 1 if multiple nodes, 0 otherwise
*/
static inline int sys_dlist_has_multiple_nodes(sys_dlist_t *list)
{
return list->head != list->tail;
}
/**
* @brief get a reference to the head item in the list
*
* @param list the doubly-linked list to operate on
*
* @return a pointer to the head element, NULL if list is empty
*/
static inline sys_dnode_t *sys_dlist_peek_head(sys_dlist_t *list)
{
return sys_dlist_is_empty(list) ? NULL : list->head;
}
/**
* @brief get a reference to the head item in the list
*
* The list must be known to be non-empty.
*
* @param list the doubly-linked list to operate on
*
* @return a pointer to the head element
*/
static inline sys_dnode_t *sys_dlist_peek_head_not_empty(sys_dlist_t *list)
{
return list->head;
}
/**
* @brief get a reference to the next item in the list, node is not NULL
*
* Faster than sys_dlist_peek_next() if node is known not to be NULL.
*
* @param list the doubly-linked list to operate on
* @param node the node from which to get the next element in the list
*
* @return a pointer to the next element from a node, NULL if node is the tail
*/
static inline sys_dnode_t *sys_dlist_peek_next_no_check(sys_dlist_t *list,
sys_dnode_t *node)
{
return (node == list->tail) ? NULL : node->next;
}
/**
* @brief get a reference to the next item in the list
*
* @param list the doubly-linked list to operate on
* @param node the node from which to get the next element in the list
*
* @return a pointer to the next element from a node, NULL if node is the tail
* or NULL (when node comes from reading the head of an empty list).
*/
static inline sys_dnode_t *sys_dlist_peek_next(sys_dlist_t *list,
sys_dnode_t *node)
{
return node ? sys_dlist_peek_next_no_check(list, node) : NULL;
}
/**
* @brief get a reference to the tail item in the list
*
* @param list the doubly-linked list to operate on
*
* @return a pointer to the tail element, NULL if list is empty
*/
static inline sys_dnode_t *sys_dlist_peek_tail(sys_dlist_t *list)
{
return sys_dlist_is_empty(list) ? NULL : list->tail;
}
/**
* @brief add node to tail of list
*
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param node the element to append
*
* @return N/A
*/
static inline void sys_dlist_append(sys_dlist_t *list, sys_dnode_t *node)
{
node->next = list;
node->prev = list->tail;
list->tail->next = node;
list->tail = node;
}
/**
* @brief add node to head of list
*
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param node the element to append
*
* @return N/A
*/
static inline void sys_dlist_prepend(sys_dlist_t *list, sys_dnode_t *node)
{
node->next = list->head;
node->prev = list;
list->head->prev = node;
list->head = node;
}
/**
* @brief insert node after a node
*
* Insert a node after a specified node in a list.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param insert_point the insert point in the list: if NULL, insert at head
* @param node the element to append
*
* @return N/A
*/
static inline void sys_dlist_insert_after(sys_dlist_t *list,
sys_dnode_t *insert_point, sys_dnode_t *node)
{
if (!insert_point) {
sys_dlist_prepend(list, node);
} else {
node->next = insert_point->next;
node->prev = insert_point;
insert_point->next->prev = node;
insert_point->next = node;
}
}
/**
* @brief insert node before a node
*
* Insert a node before a specified node in a list.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param insert_point the insert point in the list: if NULL, insert at tail
* @param node the element to insert
*
* @return N/A
*/
static inline void sys_dlist_insert_before(sys_dlist_t *list,
sys_dnode_t *insert_point, sys_dnode_t *node)
{
if (!insert_point) {
sys_dlist_append(list, node);
} else {
node->prev = insert_point->prev;
node->next = insert_point;
insert_point->prev->next = node;
insert_point->prev = node;
}
}
/**
* @brief insert node at position
*
* Insert a node in a location depending on a external condition. The cond()
* function checks if the node is to be inserted _before_ the current node
* against which it is checked.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param node the element to insert
* @param cond a function that determines if the current node is the correct
* insert point
* @param data parameter to cond()
*
* @return N/A
*/
static inline void sys_dlist_insert_at(sys_dlist_t *list, sys_dnode_t *node,
int (*cond)(sys_dnode_t *, void *), void *data)
{
if (sys_dlist_is_empty(list)) {
sys_dlist_append(list, node);
} else {
sys_dnode_t *pos = sys_dlist_peek_head(list);
while (pos && !cond(pos, data)) {
pos = sys_dlist_peek_next(list, pos);
}
sys_dlist_insert_before(list, pos, node);
}
}
/**
* @brief remove a specific node from a list
*
* The list is implicit from the node. The node must be part of a list.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param node the node to remove
*
* @return N/A
*/
static inline void sys_dlist_remove(sys_dnode_t *node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
}
/**
* @brief get the first node in a list
*
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
*
* @return the first node in the list, NULL if list is empty
*/
static inline sys_dnode_t *sys_dlist_get(sys_dlist_t *list)
{
sys_dnode_t *node;
if (sys_dlist_is_empty(list)) {
return NULL;
}
node = list->head;
sys_dlist_remove(node);
return node;
}
#ifdef __cplusplus
}
#endif
#endif /* _misc_dlist__h_ */

View File

@@ -0,0 +1,165 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _FOUNDATION_H_
#define _FOUNDATION_H_
#include "mesh_access.h"
#include "net.h"
#define OP_APP_KEY_ADD BT_MESH_MODEL_OP_1(0x00)
#define OP_APP_KEY_UPDATE BT_MESH_MODEL_OP_1(0x01)
#define OP_DEV_COMP_DATA_STATUS BT_MESH_MODEL_OP_1(0x02)
#define OP_MOD_PUB_SET BT_MESH_MODEL_OP_1(0x03)
#define OP_HEALTH_CURRENT_STATUS BT_MESH_MODEL_OP_1(0x04)
#define OP_HEALTH_FAULT_STATUS BT_MESH_MODEL_OP_1(0x05)
#define OP_HEARTBEAT_PUB_STATUS BT_MESH_MODEL_OP_1(0x06)
#define OP_APP_KEY_DEL BT_MESH_MODEL_OP_2(0x80, 0x00)
#define OP_APP_KEY_GET BT_MESH_MODEL_OP_2(0x80, 0x01)
#define OP_APP_KEY_LIST BT_MESH_MODEL_OP_2(0x80, 0x02)
#define OP_APP_KEY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x03)
#define OP_ATTENTION_GET BT_MESH_MODEL_OP_2(0x80, 0x04)
#define OP_ATTENTION_SET BT_MESH_MODEL_OP_2(0x80, 0x05)
#define OP_ATTENTION_SET_UNREL BT_MESH_MODEL_OP_2(0x80, 0x06)
#define OP_ATTENTION_STATUS BT_MESH_MODEL_OP_2(0x80, 0x07)
#define OP_DEV_COMP_DATA_GET BT_MESH_MODEL_OP_2(0x80, 0x08)
#define OP_BEACON_GET BT_MESH_MODEL_OP_2(0x80, 0x09)
#define OP_BEACON_SET BT_MESH_MODEL_OP_2(0x80, 0x0a)
#define OP_BEACON_STATUS BT_MESH_MODEL_OP_2(0x80, 0x0b)
#define OP_DEFAULT_TTL_GET BT_MESH_MODEL_OP_2(0x80, 0x0c)
#define OP_DEFAULT_TTL_SET BT_MESH_MODEL_OP_2(0x80, 0x0d)
#define OP_DEFAULT_TTL_STATUS BT_MESH_MODEL_OP_2(0x80, 0x0e)
#define OP_FRIEND_GET BT_MESH_MODEL_OP_2(0x80, 0x0f)
#define OP_FRIEND_SET BT_MESH_MODEL_OP_2(0x80, 0x10)
#define OP_FRIEND_STATUS BT_MESH_MODEL_OP_2(0x80, 0x11)
#define OP_GATT_PROXY_GET BT_MESH_MODEL_OP_2(0x80, 0x12)
#define OP_GATT_PROXY_SET BT_MESH_MODEL_OP_2(0x80, 0x13)
#define OP_GATT_PROXY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x14)
#define OP_KRP_GET BT_MESH_MODEL_OP_2(0x80, 0x15)
#define OP_KRP_SET BT_MESH_MODEL_OP_2(0x80, 0x16)
#define OP_KRP_STATUS BT_MESH_MODEL_OP_2(0x80, 0x17)
#define OP_MOD_PUB_GET BT_MESH_MODEL_OP_2(0x80, 0x18)
#define OP_MOD_PUB_STATUS BT_MESH_MODEL_OP_2(0x80, 0x19)
#define OP_MOD_PUB_VA_SET BT_MESH_MODEL_OP_2(0x80, 0x1a)
#define OP_MOD_SUB_ADD BT_MESH_MODEL_OP_2(0x80, 0x1b)
#define OP_MOD_SUB_DEL BT_MESH_MODEL_OP_2(0x80, 0x1c)
#define OP_MOD_SUB_DEL_ALL BT_MESH_MODEL_OP_2(0x80, 0x1d)
#define OP_MOD_SUB_OVERWRITE BT_MESH_MODEL_OP_2(0x80, 0x1e)
#define OP_MOD_SUB_STATUS BT_MESH_MODEL_OP_2(0x80, 0x1f)
#define OP_MOD_SUB_VA_ADD BT_MESH_MODEL_OP_2(0x80, 0x20)
#define OP_MOD_SUB_VA_DEL BT_MESH_MODEL_OP_2(0x80, 0x21)
#define OP_MOD_SUB_VA_OVERWRITE BT_MESH_MODEL_OP_2(0x80, 0x22)
#define OP_NET_TRANSMIT_GET BT_MESH_MODEL_OP_2(0x80, 0x23)
#define OP_NET_TRANSMIT_SET BT_MESH_MODEL_OP_2(0x80, 0x24)
#define OP_NET_TRANSMIT_STATUS BT_MESH_MODEL_OP_2(0x80, 0x25)
#define OP_RELAY_GET BT_MESH_MODEL_OP_2(0x80, 0x26)
#define OP_RELAY_SET BT_MESH_MODEL_OP_2(0x80, 0x27)
#define OP_RELAY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x28)
#define OP_MOD_SUB_GET BT_MESH_MODEL_OP_2(0x80, 0x29)
#define OP_MOD_SUB_LIST BT_MESH_MODEL_OP_2(0x80, 0x2a)
#define OP_MOD_SUB_GET_VND BT_MESH_MODEL_OP_2(0x80, 0x2b)
#define OP_MOD_SUB_LIST_VND BT_MESH_MODEL_OP_2(0x80, 0x2c)
#define OP_LPN_TIMEOUT_GET BT_MESH_MODEL_OP_2(0x80, 0x2d)
#define OP_LPN_TIMEOUT_STATUS BT_MESH_MODEL_OP_2(0x80, 0x2e)
#define OP_HEALTH_FAULT_CLEAR BT_MESH_MODEL_OP_2(0x80, 0x2f)
#define OP_HEALTH_FAULT_CLEAR_UNREL BT_MESH_MODEL_OP_2(0x80, 0x30)
#define OP_HEALTH_FAULT_GET BT_MESH_MODEL_OP_2(0x80, 0x31)
#define OP_HEALTH_FAULT_TEST BT_MESH_MODEL_OP_2(0x80, 0x32)
#define OP_HEALTH_FAULT_TEST_UNREL BT_MESH_MODEL_OP_2(0x80, 0x33)
#define OP_HEALTH_PERIOD_GET BT_MESH_MODEL_OP_2(0x80, 0x34)
#define OP_HEALTH_PERIOD_SET BT_MESH_MODEL_OP_2(0x80, 0x35)
#define OP_HEALTH_PERIOD_SET_UNREL BT_MESH_MODEL_OP_2(0x80, 0x36)
#define OP_HEALTH_PERIOD_STATUS BT_MESH_MODEL_OP_2(0x80, 0x37)
#define OP_HEARTBEAT_PUB_GET BT_MESH_MODEL_OP_2(0x80, 0x38)
#define OP_HEARTBEAT_PUB_SET BT_MESH_MODEL_OP_2(0x80, 0x39)
#define OP_HEARTBEAT_SUB_GET BT_MESH_MODEL_OP_2(0x80, 0x3a)
#define OP_HEARTBEAT_SUB_SET BT_MESH_MODEL_OP_2(0x80, 0x3b)
#define OP_HEARTBEAT_SUB_STATUS BT_MESH_MODEL_OP_2(0x80, 0x3c)
#define OP_MOD_APP_BIND BT_MESH_MODEL_OP_2(0x80, 0x3d)
#define OP_MOD_APP_STATUS BT_MESH_MODEL_OP_2(0x80, 0x3e)
#define OP_MOD_APP_UNBIND BT_MESH_MODEL_OP_2(0x80, 0x3f)
#define OP_NET_KEY_ADD BT_MESH_MODEL_OP_2(0x80, 0x40)
#define OP_NET_KEY_DEL BT_MESH_MODEL_OP_2(0x80, 0x41)
#define OP_NET_KEY_GET BT_MESH_MODEL_OP_2(0x80, 0x42)
#define OP_NET_KEY_LIST BT_MESH_MODEL_OP_2(0x80, 0x43)
#define OP_NET_KEY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x44)
#define OP_NET_KEY_UPDATE BT_MESH_MODEL_OP_2(0x80, 0x45)
#define OP_NODE_IDENTITY_GET BT_MESH_MODEL_OP_2(0x80, 0x46)
#define OP_NODE_IDENTITY_SET BT_MESH_MODEL_OP_2(0x80, 0x47)
#define OP_NODE_IDENTITY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x48)
#define OP_NODE_RESET BT_MESH_MODEL_OP_2(0x80, 0x49)
#define OP_NODE_RESET_STATUS BT_MESH_MODEL_OP_2(0x80, 0x4a)
#define OP_SIG_MOD_APP_GET BT_MESH_MODEL_OP_2(0x80, 0x4b)
#define OP_SIG_MOD_APP_LIST BT_MESH_MODEL_OP_2(0x80, 0x4c)
#define OP_VND_MOD_APP_GET BT_MESH_MODEL_OP_2(0x80, 0x4d)
#define OP_VND_MOD_APP_LIST BT_MESH_MODEL_OP_2(0x80, 0x4e)
#define STATUS_SUCCESS 0x00
#define STATUS_INVALID_ADDRESS 0x01
#define STATUS_INVALID_MODEL 0x02
#define STATUS_INVALID_APPKEY 0x03
#define STATUS_INVALID_NETKEY 0x04
#define STATUS_INSUFF_RESOURCES 0x05
#define STATUS_IDX_ALREADY_STORED 0x06
#define STATUS_NVAL_PUB_PARAM 0x07
#define STATUS_NOT_SUB_MOD 0x08
#define STATUS_STORAGE_FAIL 0x09
#define STATUS_FEAT_NOT_SUPP 0x0a
#define STATUS_CANNOT_UPDATE 0x0b
#define STATUS_CANNOT_REMOVE 0x0c
#define STATUS_CANNOT_BIND 0x0d
#define STATUS_TEMP_STATE_CHG_FAIL 0x0e
#define STATUS_CANNOT_SET 0x0f
#define STATUS_UNSPECIFIED 0x10
#define STATUS_INVALID_BINDING 0x11
int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary);
int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary);
void bt_mesh_cfg_reset(void);
void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat);
void bt_mesh_attention(struct bt_mesh_model *model, u8_t time);
u8_t *bt_mesh_label_uuid_get(u16_t addr);
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void);
struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void);
u8_t bt_mesh_net_transmit_get(void);
u8_t bt_mesh_relay_get(void);
u8_t bt_mesh_friend_get(void);
u8_t bt_mesh_relay_retransmit_get(void);
u8_t bt_mesh_beacon_get(void);
u8_t bt_mesh_gatt_proxy_get(void);
u8_t bt_mesh_default_ttl_get(void);
void bt_mesh_subnet_del(struct bt_mesh_subnet *sub);
struct bt_mesh_app_key *bt_mesh_app_key_alloc(u16_t app_idx);
void bt_mesh_app_key_del(struct bt_mesh_app_key *key);
static inline void key_idx_pack(struct net_buf_simple *buf,
u16_t idx1, u16_t idx2)
{
net_buf_simple_add_le16(buf, idx1 | ((idx2 & 0x00f) << 12));
net_buf_simple_add_u8(buf, idx2 >> 4);
}
static inline void key_idx_unpack(struct net_buf_simple *buf,
u16_t *idx1, u16_t *idx2)
{
*idx1 = sys_get_le16(&buf->data[0]) & 0xfff;
*idx2 = sys_get_le16(&buf->data[1]) >> 4;
net_buf_simple_pull(buf, 3);
}
#endif /* #ifndef _FOUNDATION_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,44 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
enum bt_mesh_friend_pdu_type {
BT_MESH_FRIEND_PDU_SINGLE,
BT_MESH_FRIEND_PDU_PARTIAL,
BT_MESH_FRIEND_PDU_COMPLETE,
};
bool bt_mesh_friend_match(u16_t net_idx, u16_t addr);
struct bt_mesh_friend *bt_mesh_friend_find(u16_t net_idx, u16_t lpn_addr,
bool valid, bool established);
void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx,
enum bt_mesh_friend_pdu_type type,
u64_t *seq_auth, struct net_buf_simple *sbuf);
bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx,
enum bt_mesh_friend_pdu_type type,
u64_t *seq_auth, struct net_buf_simple *sbuf);
void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src,
u16_t dst, u64_t *seq_auth);
void bt_mesh_friend_sec_update(u16_t net_idx);
void bt_mesh_friend_clear_net_idx(u16_t net_idx);
int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf);
int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf);
int bt_mesh_friend_clear(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf);
int bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf);
int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf);
int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf);
int bt_mesh_friend_init(void);

View File

@@ -0,0 +1,466 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include "mesh_types.h"
#include "mesh_util.h"
#include "sdkconfig.h"
#include "osi/allocator.h"
#if CONFIG_BT_MESH
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_MODEL)
#include "mesh_trace.h"
#include "health_cli.h"
#include "foundation.h"
#include "common.h"
#include "btc_ble_mesh_health.h"
s32_t health_msg_timeout;
static bt_mesh_health_client_t *health_cli;
static const bt_mesh_client_op_pair_t health_op_pair[] = {
{ OP_HEALTH_FAULT_GET, OP_HEALTH_FAULT_STATUS },
{ OP_HEALTH_FAULT_CLEAR, OP_HEALTH_FAULT_STATUS },
{ OP_HEALTH_FAULT_TEST, OP_HEALTH_FAULT_STATUS },
{ OP_HEALTH_PERIOD_GET, OP_HEALTH_PERIOD_STATUS },
{ OP_HEALTH_PERIOD_SET, OP_HEALTH_PERIOD_STATUS },
{ OP_ATTENTION_GET, OP_ATTENTION_STATUS },
{ OP_ATTENTION_SET, OP_ATTENTION_STATUS },
};
static void timeout_handler(struct k_work *work)
{
bt_mesh_health_client_t *client = NULL;
health_internal_data_t *internal = NULL;
bt_mesh_client_node_t *node = NULL;
BT_WARN("Receive health status message timeout");
node = CONTAINER_OF(work, bt_mesh_client_node_t, timer.work);
if (!node || !node->ctx.model) {
BT_ERR("%s: node parameter is NULL", __func__);
return;
}
client = (bt_mesh_health_client_t *)node->ctx.model->user_data;
if (!client) {
BT_ERR("%s: model user_data is NULL", __func__);
return;
}
internal = (health_internal_data_t *)client->internal_data;
if (!internal) {
BT_ERR("%s: internal_data is NULL", __func__);
return;
}
bt_mesh_callback_health_status_to_btc(node->opcode, 0x03, node->ctx.model,
&node->ctx, NULL, 0);
bt_mesh_client_free_node(&internal->queue, node);
return;
}
static void health_client_cancel(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
void *status, size_t len)
{
health_internal_data_t *data = NULL;
bt_mesh_client_node_t *node = NULL;
struct net_buf_simple buf = {0};
u8_t evt_type = 0xFF;
if (!model || !ctx || !status || !len) {
BT_ERR("%s: invalid parameter", __func__);
return;
}
data = (health_internal_data_t *)health_cli->internal_data;
if (!data) {
BT_ERR("%s: health client internal_data is NULL", __func__);
return;
}
/* If it is a publish message, sent to the user directly. */
buf.data = (u8_t *)status;
buf.len = (u16_t)len;
node = bt_mesh_is_model_message_publish(model, ctx, &buf, true);
if (!node) {
BT_DBG("Unexpected health status message 0x%x", ctx->recv_op);
} else {
switch (node->opcode) {
case OP_HEALTH_FAULT_GET:
case OP_HEALTH_PERIOD_GET:
case OP_ATTENTION_GET:
evt_type = 0x00;
break;
case OP_HEALTH_FAULT_CLEAR:
case OP_HEALTH_FAULT_TEST:
case OP_HEALTH_PERIOD_SET:
case OP_ATTENTION_SET:
evt_type = 0x01;
break;
default:
break;
}
bt_mesh_callback_health_status_to_btc(node->opcode, evt_type, model,
ctx, (const u8_t *)status, len);
// Don't forget to release the node at the end.
bt_mesh_client_free_node(&data->queue, node);
}
switch (ctx->recv_op) {
case OP_HEALTH_FAULT_STATUS: {
struct bt_mesh_health_fault_status *val;
val = (struct bt_mesh_health_fault_status *)status;
bt_mesh_free_buf(val->fault_array);
break;
}
default:
break;
}
}
static void health_fault_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_fault_status status = {0};
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
status.test_id = net_buf_simple_pull_u8(buf);
status.cid = net_buf_simple_pull_le16(buf);
status.fault_array = bt_mesh_alloc_buf(buf->len);
if (!status.fault_array) {
BT_ERR("%s: allocate memory for fault_array fail", __func__);
return;
}
net_buf_simple_init(status.fault_array, 0);
net_buf_simple_add_mem(status.fault_array, buf->data, buf->len);
health_client_cancel(model, ctx, &status, sizeof(struct bt_mesh_health_fault_status));
}
static void health_current_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
bt_mesh_client_node_t *node = NULL;
u8_t test_id;
u16_t cid;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
/* Health current status is a publish message, sent to the user directly. */
if (!(node = bt_mesh_is_model_message_publish(model, ctx, buf, true))) {
return;
}
test_id = net_buf_simple_pull_u8(buf);
cid = net_buf_simple_pull_le16(buf);
BT_DBG("Test ID 0x%02x Company ID 0x%04x Fault Count %u",
test_id, cid, buf->len);
}
static void health_period_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
u8_t status = 0;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
status = net_buf_simple_pull_u8(buf);
health_client_cancel(model, ctx, &status, sizeof(u8_t));
}
static void health_attention_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
u8_t status = 0;
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
ctx->net_idx, ctx->app_idx, ctx->addr, buf->len,
bt_hex(buf->data, buf->len));
status = net_buf_simple_pull_u8(buf);
health_client_cancel(model, ctx, &status, sizeof(u8_t));
}
const struct bt_mesh_model_op bt_mesh_health_cli_op[] = {
{ OP_HEALTH_FAULT_STATUS, 3, health_fault_status },
{ OP_HEALTH_CURRENT_STATUS, 3, health_current_status },
{ OP_HEALTH_PERIOD_STATUS, 1, health_period_status },
{ OP_ATTENTION_STATUS, 1, health_attention_status },
BT_MESH_MODEL_OP_END,
};
int bt_mesh_health_attention_get(struct bt_mesh_msg_ctx *ctx)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 0 + 4);
int err;
if (!ctx || !ctx->addr) {
return -EINVAL;
}
bt_mesh_model_msg_init(msg, OP_ATTENTION_GET);
err = bt_mesh_client_send_msg(health_cli->model, OP_ATTENTION_GET, ctx,
msg, timeout_handler, health_msg_timeout,
true, NULL, NULL);
if (err) {
BT_ERR("%s: send failed (err %d)", __func__, err);
}
return err;
}
int bt_mesh_health_attention_set(struct bt_mesh_msg_ctx *ctx,
u8_t attention, bool need_ack)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);
u32_t opcode;
int err;
if (!ctx || !ctx->addr) {
return -EINVAL;
}
if (need_ack) {
opcode = OP_ATTENTION_SET;
} else {
opcode = OP_ATTENTION_SET_UNREL;
}
bt_mesh_model_msg_init(msg, opcode);
net_buf_simple_add_u8(msg, attention);
err = bt_mesh_client_send_msg(health_cli->model, opcode, ctx, msg,
timeout_handler, health_msg_timeout,
need_ack, NULL, NULL);
if (err) {
BT_ERR("%s: send failed (err %d)", __func__, err);
}
return err;
}
int bt_mesh_health_period_get(struct bt_mesh_msg_ctx *ctx)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 0 + 4);
int err;
if (!ctx || !ctx->addr) {
return -EINVAL;
}
bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_GET);
err = bt_mesh_client_send_msg(health_cli->model, OP_HEALTH_PERIOD_GET,
ctx, msg, timeout_handler, health_msg_timeout,
true, NULL, NULL);
if (err) {
BT_ERR("%s: send failed (err %d)", __func__, err);
}
return err;
}
int bt_mesh_health_period_set(struct bt_mesh_msg_ctx *ctx,
u8_t divisor, bool need_ack)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);
u32_t opcode;
int err;
if (!ctx || !ctx->addr) {
return -EINVAL;
}
if (need_ack) {
opcode = OP_HEALTH_PERIOD_SET;
} else {
opcode = OP_HEALTH_PERIOD_SET_UNREL;
}
bt_mesh_model_msg_init(msg, opcode);
net_buf_simple_add_u8(msg, divisor);
err = bt_mesh_client_send_msg(health_cli->model, opcode, ctx, msg,
timeout_handler, health_msg_timeout,
need_ack, NULL, NULL);
if (err) {
BT_ERR("%s: send failed (err %d)", __func__, err);
}
return err;
}
int bt_mesh_health_fault_test(struct bt_mesh_msg_ctx *ctx,
u16_t cid, u8_t test_id, bool need_ack)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 3 + 4);
u32_t opcode;
int err;
if (!ctx || !ctx->addr) {
return -EINVAL;
}
if (need_ack) {
opcode = OP_HEALTH_FAULT_TEST;
} else {
opcode = OP_HEALTH_FAULT_TEST_UNREL;
}
bt_mesh_model_msg_init(msg, opcode);
net_buf_simple_add_u8(msg, test_id);
net_buf_simple_add_le16(msg, cid);
err = bt_mesh_client_send_msg(health_cli->model, opcode, ctx, msg,
timeout_handler, health_msg_timeout,
need_ack, NULL, NULL);
if (err) {
BT_ERR("%s: send failed (err %d)", __func__, err);
}
return err;
}
int bt_mesh_health_fault_clear(struct bt_mesh_msg_ctx *ctx,
u16_t cid, bool need_ack)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 2 + 4);
u32_t opcode;
int err;
if (!ctx || !ctx->addr) {
return -EINVAL;
}
if (need_ack) {
opcode = OP_HEALTH_FAULT_CLEAR;
} else {
opcode = OP_HEALTH_FAULT_CLEAR_UNREL;
}
bt_mesh_model_msg_init(msg, opcode);
net_buf_simple_add_le16(msg, cid);
err = bt_mesh_client_send_msg(health_cli->model, opcode, ctx, msg,
timeout_handler, health_msg_timeout,
need_ack, NULL, NULL);
if (err) {
BT_ERR("%s: send failed (err %d)", __func__, err);
}
return err;
}
int bt_mesh_health_fault_get(struct bt_mesh_msg_ctx *ctx, u16_t cid)
{
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 2 + 4);
int err;
if (!ctx || !ctx->addr) {
return -EINVAL;
}
bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_GET);
net_buf_simple_add_le16(msg, cid);
err = bt_mesh_client_send_msg(health_cli->model, OP_HEALTH_FAULT_GET, ctx,
msg, timeout_handler, health_msg_timeout,
true, NULL, NULL);
if (err) {
BT_ERR("%s: send failed (err %d)", __func__, err);
}
return err;
}
s32_t bt_mesh_health_cli_timeout_get(void)
{
return health_msg_timeout;
}
void bt_mesh_health_cli_timeout_set(s32_t timeout)
{
health_msg_timeout = timeout;
}
int bt_mesh_health_cli_set(struct bt_mesh_model *model)
{
if (!model || !model->user_data) {
BT_ERR("No Health Client context for given model");
return -EINVAL;
}
health_cli = model->user_data;
return 0;
}
int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary)
{
bt_mesh_health_client_t *client = NULL;
health_internal_data_t *internal = NULL;
BT_DBG("primary %u", primary);
if (!model) {
BT_ERR("Health Client model is NULL");
return -EINVAL;
}
client = (bt_mesh_health_client_t *)model->user_data;
if (!client) {
BT_ERR("No Health Client context provided");
return -EINVAL;
}
/* TODO: call osi_free() when deinit function is invoked*/
internal = osi_calloc(sizeof(health_internal_data_t));
if (!internal) {
BT_ERR("Allocate memory for Health Client internal data fail");
return -ENOMEM;
}
sys_slist_init(&internal->queue);
client->model = model;
client->op_pair_size = ARRAY_SIZE(health_op_pair);
client->op_pair = health_op_pair;
client->internal_data = internal;
/* Set the default health client pointer */
if (!health_cli) {
health_cli = client;
}
return 0;
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,512 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include "mesh_types.h"
#include "mesh_util.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_MODEL)
#include "mesh_trace.h"
#include "health_srv.h"
#include "mesh.h"
#include "adv.h"
#include "net.h"
#include "transport.h"
#include "access.h"
#include "foundation.h"
#include "common.h"
#define HEALTH_TEST_STANDARD 0x00
/* Maximum message length is 384 in BLE Mesh. Here for health fault status,
* due to 1 octet opcode and 4 octets TransMIC, 379 octets can be used to
* store health fault status.
*/
#define HEALTH_FAULT_MAX_LEN 379
/* Health Server context of the primary element */
struct bt_mesh_health_srv *health_srv;
static void health_get_registered(struct bt_mesh_model *mod,
u16_t company_id,
struct net_buf_simple *msg)
{
struct bt_mesh_health_srv *srv = mod->user_data;
u8_t *test_id;
BT_DBG("Company ID 0x%04x", company_id);
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return;
}
bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_STATUS);
test_id = net_buf_simple_add(msg, 1);
net_buf_simple_add_le16(msg, company_id);
if (srv->cb && srv->cb->fault_get_reg) {
u8_t fault_count = net_buf_simple_tailroom(msg) - 4;
int err;
err = srv->cb->fault_get_reg(mod, company_id, test_id,
net_buf_simple_tail(msg),
&fault_count);
if (err) {
BT_ERR("Failed to get faults (err %d)", err);
*test_id = HEALTH_TEST_STANDARD;
} else {
net_buf_simple_add(msg, fault_count);
}
} else {
BT_WARN("No callback for getting faults");
*test_id = HEALTH_TEST_STANDARD;
}
}
static size_t health_get_current(struct bt_mesh_model *mod,
struct net_buf_simple *msg)
{
struct bt_mesh_health_srv *srv = mod->user_data;
const struct bt_mesh_comp *comp;
u8_t *test_id, *company_ptr;
u16_t company_id;
u8_t fault_count;
int err;
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return 0;
}
bt_mesh_model_msg_init(msg, OP_HEALTH_CURRENT_STATUS);
test_id = net_buf_simple_add(msg, 1);
company_ptr = net_buf_simple_add(msg, sizeof(company_id));
comp = bt_mesh_comp_get();
if (srv->cb && srv->cb->fault_get_cur) {
fault_count = net_buf_simple_tailroom(msg);
err = srv->cb->fault_get_cur(mod, test_id, &company_id,
net_buf_simple_tail(msg),
&fault_count);
if (err) {
BT_ERR("Failed to get faults (err %d)", err);
sys_put_le16(comp->cid, company_ptr);
*test_id = HEALTH_TEST_STANDARD;
fault_count = 0;
} else {
sys_put_le16(company_id, company_ptr);
net_buf_simple_add(msg, fault_count);
}
} else {
BT_WARN("No callback for getting faults");
sys_put_le16(comp->cid, company_ptr);
*test_id = HEALTH_TEST_STANDARD;
fault_count = 0;
}
return fault_count;
}
static void health_fault_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct net_buf_simple *sdu = NULL;
u16_t company_id;
company_id = net_buf_simple_pull_le16(buf);
BT_DBG("company_id 0x%04x", company_id);
sdu = bt_mesh_alloc_buf(min(BT_MESH_TX_SDU_MAX, HEALTH_FAULT_MAX_LEN));
if (!sdu) {
BT_ERR("%s, Failed to allocate memory", __func__);
return;
}
health_get_registered(model, company_id, sdu);
if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) {
BT_ERR("Unable to send Health Current Status response");
}
bt_mesh_free_buf(sdu);
return;
}
static void health_fault_clear_unrel(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_srv *srv = model->user_data;
u16_t company_id;
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return;
}
company_id = net_buf_simple_pull_le16(buf);
BT_DBG("company_id 0x%04x", company_id);
if (srv->cb && srv->cb->fault_clear) {
srv->cb->fault_clear(model, company_id);
}
}
static void health_fault_clear(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_srv *srv = model->user_data;
struct net_buf_simple *sdu = NULL;
u16_t company_id;
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return;
}
company_id = net_buf_simple_pull_le16(buf);
BT_DBG("company_id 0x%04x", company_id);
if (srv->cb && srv->cb->fault_clear) {
srv->cb->fault_clear(model, company_id);
}
sdu = bt_mesh_alloc_buf(min(BT_MESH_TX_SDU_MAX, HEALTH_FAULT_MAX_LEN));
if (!sdu) {
BT_ERR("%s, Failed to allocate memory", __func__);
return;
}
health_get_registered(model, company_id, sdu);
if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) {
BT_ERR("Unable to send Health Current Status response");
}
bt_mesh_free_buf(sdu);
return;
}
static void health_fault_test_unrel(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_srv *srv = model->user_data;
u16_t company_id;
u8_t test_id;
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return;
}
test_id = net_buf_simple_pull_u8(buf);
company_id = net_buf_simple_pull_le16(buf);
BT_DBG("test 0x%02x company 0x%04x", test_id, company_id);
if (srv->cb && srv->cb->fault_test) {
srv->cb->fault_test(model, test_id, company_id);
}
}
static void health_fault_test(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_health_srv *srv = model->user_data;
struct net_buf_simple *sdu = NULL;
u16_t company_id;
u8_t test_id;
BT_DBG("%s", __func__);
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return;
}
test_id = net_buf_simple_pull_u8(buf);
company_id = net_buf_simple_pull_le16(buf);
BT_DBG("test 0x%02x company 0x%04x", test_id, company_id);
if (srv->cb && srv->cb->fault_test) {
int err;
err = srv->cb->fault_test(model, test_id, company_id);
if (err) {
BT_WARN("Running fault test failed with err %d", err);
return;
}
}
sdu = bt_mesh_alloc_buf(min(BT_MESH_TX_SDU_MAX, HEALTH_FAULT_MAX_LEN));
if (!sdu) {
BT_ERR("%s, Failed to allocate memory", __func__);
return;
}
health_get_registered(model, company_id, sdu);
if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) {
BT_ERR("Unable to send Health Current Status response");
}
bt_mesh_free_buf(sdu);
return;
}
static void send_attention_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx)
{
/* Needed size: opcode (2 bytes) + msg + MIC */
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);
struct bt_mesh_health_srv *srv = model->user_data;
u8_t time;
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return;
}
time = k_delayed_work_remaining_get(&srv->attn_timer) / 1000;
BT_DBG("%u second%s", time, (time == 1) ? "" : "s");
bt_mesh_model_msg_init(msg, OP_ATTENTION_STATUS);
net_buf_simple_add_u8(msg, time);
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
BT_ERR("Unable to send Attention Status");
}
}
static void attention_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
BT_DBG("%s", __func__);
send_attention_status(model, ctx);
}
static void attention_set_unrel(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
u8_t time;
time = net_buf_simple_pull_u8(buf);
BT_DBG("%u second%s", time, (time == 1) ? "" : "s");
bt_mesh_attention(model, time);
}
static void attention_set(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
BT_DBG("%s", __func__);
attention_set_unrel(model, ctx, buf);
send_attention_status(model, ctx);
}
static void send_health_period_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx)
{
/* Needed size: opcode (2 bytes) + msg + MIC */
struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 1 + 4);
bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_STATUS);
net_buf_simple_add_u8(msg, model->pub->period_div);
if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) {
BT_ERR("Unable to send Health Period Status");
}
}
static void health_period_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
BT_DBG("%s", __func__);
send_health_period_status(model, ctx);
}
static void health_period_set_unrel(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
u8_t period;
period = net_buf_simple_pull_u8(buf);
if (period > 15) {
BT_WARN("Prohibited period value %u", period);
return;
}
BT_DBG("period %u", period);
model->pub->period_div = period;
}
static void health_period_set(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
BT_DBG("%s", __func__);
health_period_set_unrel(model, ctx, buf);
send_health_period_status(model, ctx);
}
const struct bt_mesh_model_op bt_mesh_health_srv_op[] = {
{ OP_HEALTH_FAULT_GET, 2, health_fault_get },
{ OP_HEALTH_FAULT_CLEAR, 2, health_fault_clear },
{ OP_HEALTH_FAULT_CLEAR_UNREL, 2, health_fault_clear_unrel },
{ OP_HEALTH_FAULT_TEST, 3, health_fault_test },
{ OP_HEALTH_FAULT_TEST_UNREL, 3, health_fault_test_unrel },
{ OP_HEALTH_PERIOD_GET, 0, health_period_get },
{ OP_HEALTH_PERIOD_SET, 1, health_period_set },
{ OP_HEALTH_PERIOD_SET_UNREL, 1, health_period_set_unrel },
{ OP_ATTENTION_GET, 0, attention_get },
{ OP_ATTENTION_SET, 1, attention_set },
{ OP_ATTENTION_SET_UNREL, 1, attention_set_unrel },
BT_MESH_MODEL_OP_END,
};
static int health_pub_update(struct bt_mesh_model *mod)
{
struct bt_mesh_model_pub *pub = mod->pub;
size_t count;
BT_DBG("%s", __func__);
count = health_get_current(mod, pub->msg);
if (!count) {
pub->period_div = 0;
}
return 0;
}
int bt_mesh_fault_update(struct bt_mesh_elem *elem)
{
struct bt_mesh_model *mod;
mod = bt_mesh_model_find(elem, BT_MESH_MODEL_ID_HEALTH_SRV);
if (!mod) {
return -EINVAL;
}
return bt_mesh_model_publish(mod);
}
static void attention_off(struct k_work *work)
{
struct bt_mesh_health_srv *srv = CONTAINER_OF(work,
struct bt_mesh_health_srv,
attn_timer.work);
BT_DBG("%s", __func__);
if (!srv) {
BT_ERR("%s, No Health Server context provided", __func__);
return;
}
if (srv->cb && srv->cb->attn_off) {
srv->cb->attn_off(srv->model);
}
}
int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary)
{
struct bt_mesh_health_srv *srv = model->user_data;
if (!srv) {
if (!primary) {
return 0;
}
BT_ERR("%s, No Health Server context provided", __func__);
return -EINVAL;
}
if (!model->pub) {
BT_ERR("%s, Health Server has no publication support", __func__);
return -EINVAL;
}
model->pub->update = health_pub_update;
k_delayed_work_init(&srv->attn_timer, attention_off);
srv->model = model;
if (primary) {
health_srv = srv;
}
return 0;
}
void bt_mesh_attention(struct bt_mesh_model *model, u8_t time)
{
struct bt_mesh_health_srv *srv;
if (!model) {
srv = health_srv;
if (!srv) {
BT_WARN("%s, No Health Server context provided", __func__);
return;
}
model = srv->model;
} else {
srv = model->user_data;
if (!srv) {
BT_WARN("%s, No Health Server context provided", __func__);
return;
}
}
if (time) {
if (srv->cb && srv->cb->attn_on) {
srv->cb->attn_on(model);
}
k_delayed_work_submit(&srv->attn_timer, time * 1000);
} else {
k_delayed_work_cancel(&srv->attn_timer);
if (srv->cb && srv->cb->attn_off) {
srv->cb->attn_off(model);
}
}
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,79 @@
/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2018, Nordic Semiconductor ASA
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*
* Adapted for Zephyr by Carles Cufi (carles.cufi@nordicsemi.no)
* - Removed mbedtls_ prefixes
* - Reworked coding style
*/
#ifndef __BASE64_H__
#define __BASE64_H__
#include <stddef.h>
#include "mesh_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Encode a buffer into base64 format
*
* @param dst destination buffer
* @param dlen size of the destination buffer
* @param olen number of bytes written
* @param src source buffer
* @param slen amount of data to be encoded
*
* @return 0 if successful, or -ENOMEM if the buffer is too small.
* *olen is always updated to reflect the amount
* of data that has (or would have) been written.
* If that length cannot be represented, then no data is
* written to the buffer and *olen is set to the maximum
* length representable as a size_t.
*
* @note Call this function with dlen = 0 to obtain the
* required buffer size in *olen
*/
int base64_encode(u8_t *dst, size_t dlen, size_t *olen, const u8_t *src,
size_t slen);
/**
* @brief Decode a base64-formatted buffer
*
* @param dst destination buffer (can be NULL for checking size)
* @param dlen size of the destination buffer
* @param olen number of bytes written
* @param src source buffer
* @param slen amount of data to be decoded
*
* @return 0 if successful, -ENOMEM, or -EINVAL if the input data is
* not correct. *olen is always updated to reflect the amount
* of data that has (or would have) been written.
*
* @note Call this function with *dst = NULL or dlen = 0 to obtain
* the required buffer size in *olen
*/
int base64_decode(u8_t *dst, size_t dlen, size_t *olen, const u8_t *src,
size_t slen);
#ifdef __cplusplus
}
#endif
#endif /* __BASE64_H__ */

View File

@@ -0,0 +1,297 @@
/** @file
* @brief Bluetooth Mesh Configuration Client Model APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_MESH_CFG_CLI_H
#define __BT_MESH_CFG_CLI_H
#include "mesh_access.h"
#include "mesh_kernel.h"
#include "bt_mesh_client_common.h"
/**
* @brief Bluetooth Mesh
* @defgroup bt_mesh_cfg_cli Bluetooth Mesh Configuration Client Model
* @ingroup bt_mesh
* @{
*/
/* Config client model common structure */
typedef bt_mesh_client_common_t bt_mesh_config_client_t;
typedef bt_mesh_internal_data_t config_internal_data_t;
extern const struct bt_mesh_model_op bt_mesh_cfg_cli_op[];
#define BT_MESH_MODEL_CFG_CLI(cli_data) \
BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_CLI, \
bt_mesh_cfg_cli_op, NULL, cli_data)
int bt_mesh_cfg_comp_data_get(struct bt_mesh_msg_ctx *ctx, u8_t page);
int bt_mesh_cfg_beacon_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_cfg_beacon_set(struct bt_mesh_msg_ctx *ctx, u8_t val);
int bt_mesh_cfg_ttl_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_cfg_ttl_set(struct bt_mesh_msg_ctx *ctx, u8_t val);
int bt_mesh_cfg_friend_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_cfg_friend_set(struct bt_mesh_msg_ctx *ctx, u8_t val);
int bt_mesh_cfg_gatt_proxy_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_cfg_gatt_proxy_set(struct bt_mesh_msg_ctx *ctx, u8_t val);
int bt_mesh_cfg_relay_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_cfg_relay_set(struct bt_mesh_msg_ctx *ctx, u8_t new_relay, u8_t new_transmit);
int bt_mesh_cfg_net_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx,
const u8_t net_key[16]);
int bt_mesh_cfg_app_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx,
u16_t key_app_idx, const u8_t app_key[16]);
int bt_mesh_cfg_mod_app_bind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t mod_app_idx, u16_t mod_id, u16_t cid);
struct bt_mesh_cfg_mod_pub {
u16_t addr;
u16_t app_idx;
bool cred_flag;
u8_t ttl;
u8_t period;
u8_t transmit;
};
int bt_mesh_cfg_mod_pub_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t mod_id, u16_t cid);
int bt_mesh_cfg_mod_pub_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t mod_id, u16_t cid,
struct bt_mesh_cfg_mod_pub *pub);
int bt_mesh_cfg_mod_sub_add(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t sub_addr, u16_t mod_id, u16_t cid);
int bt_mesh_cfg_mod_sub_del(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t sub_addr, u16_t mod_id, u16_t cid);
int bt_mesh_cfg_mod_sub_overwrite(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t sub_addr, u16_t mod_id, u16_t cid);
int bt_mesh_cfg_mod_sub_va_add(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
const u8_t label[16], u16_t mod_id, u16_t cid);
int bt_mesh_cfg_mod_sub_va_del(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
const u8_t label[16], u16_t mod_id, u16_t cid);
int bt_mesh_cfg_mod_sub_va_overwrite(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
const u8_t label[16], u16_t mod_id, u16_t cid);
struct bt_mesh_cfg_hb_sub {
u16_t src;
u16_t dst;
u8_t period;
};
int bt_mesh_cfg_hb_sub_set(struct bt_mesh_msg_ctx *ctx,
struct bt_mesh_cfg_hb_sub *sub);
int bt_mesh_cfg_hb_sub_get(struct bt_mesh_msg_ctx *ctx);
struct bt_mesh_cfg_hb_pub {
u16_t dst;
u8_t count;
u8_t period;
u8_t ttl;
u16_t feat;
u16_t net_idx;
};
int bt_mesh_cfg_hb_pub_set(struct bt_mesh_msg_ctx *ctx,
const struct bt_mesh_cfg_hb_pub *pub);
int bt_mesh_cfg_hb_pub_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_cfg_node_reset(struct bt_mesh_msg_ctx *ctx);
s32_t bt_mesh_cfg_cli_timeout_get(void);
void bt_mesh_cfg_cli_timeout_set(s32_t timeout);
/* Configuration Client Status Message Context */
struct bt_mesh_cfg_comp_data_status {
u8_t page;
struct net_buf_simple *comp_data;
};
struct bt_mesh_cfg_relay_status {
u8_t relay;
u8_t retransmit;
};
struct bt_mesh_cfg_netkey_status {
u8_t status;
u16_t net_idx;
};
struct bt_mesh_cfg_appkey_status {
u8_t status;
u16_t net_idx;
u16_t app_idx;
};
struct bt_mesh_cfg_mod_app_status {
u8_t status;
u16_t elem_addr;
u16_t app_idx;
u16_t cid;
u16_t mod_id;
};
struct bt_mesh_cfg_mod_pub_status {
u8_t status;
u16_t elem_addr;
u16_t addr;
u16_t app_idx;
bool cred_flag;
u8_t ttl;
u8_t period;
u8_t transmit;
u16_t cid;
u16_t mod_id;
};
struct bt_mesh_cfg_mod_sub_status {
u8_t status;
u16_t elem_addr;
u16_t sub_addr;
u16_t cid;
u16_t mod_id;
};
struct bt_mesh_cfg_hb_sub_status {
u8_t status;
u16_t src;
u16_t dst;
u8_t period;
u8_t count;
u8_t min;
u8_t max;
};
struct bt_mesh_cfg_hb_pub_status {
u8_t status;
u16_t dst;
u8_t count;
u8_t period;
u8_t ttl;
u16_t feat;
u16_t net_idx;
};
struct bt_mesh_cfg_mod_sub_list {
u8_t status;
u16_t elem_addr;
u16_t cid;
u16_t mod_id;
struct net_buf_simple *addr;
};
struct bt_mesh_cfg_net_key_list {
struct net_buf_simple *net_idx;
};
struct bt_mesh_cfg_app_key_list {
u8_t status;
u16_t net_idx;
struct net_buf_simple *app_idx;
};
struct bt_mesh_cfg_node_id_status {
u8_t status;
u16_t net_idx;
u8_t identity;
};
struct bt_mesh_cfg_mod_app_list {
u8_t status;
u16_t elem_addr;
u16_t cid;
u16_t mod_id;
struct net_buf_simple *app_idx;
};
struct bt_mesh_cfg_key_refresh_status {
u8_t status;
u16_t net_idx;
u8_t phase;
};
struct bt_mesh_cfg_lpn_pollto_status {
u16_t lpn_addr;
s32_t timeout;
};
int bt_mesh_cfg_mod_pub_va_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t mod_id, u16_t cid, const u8_t label[16],
struct bt_mesh_cfg_mod_pub *pub);
int bt_mesh_cfg_mod_sub_del_all(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t mod_id, u16_t cid);
int bt_mesh_cfg_mod_sub_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id);
int bt_mesh_cfg_mod_sub_get_vnd(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t mod_id, u16_t cid);
int bt_mesh_cfg_net_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx,
const u8_t net_key[16]);
int bt_mesh_cfg_net_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx);
int bt_mesh_cfg_net_key_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_cfg_app_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx,
u16_t app_idx, const u8_t app_key[16]);
int bt_mesh_cfg_app_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u16_t app_idx);
int bt_mesh_cfg_app_key_get(struct bt_mesh_msg_ctx *ctx, u16_t net_idx);
int bt_mesh_cfg_node_identity_get(struct bt_mesh_msg_ctx *ctx, u16_t net_idx);
int bt_mesh_cfg_node_identity_set(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u8_t identity);
int bt_mesh_cfg_mod_app_unbind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t app_idx, u16_t mod_id, u16_t cid);
int bt_mesh_cfg_mod_app_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id);
int bt_mesh_cfg_mod_app_get_vnd(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
u16_t mod_id, u16_t cid);
int bt_mesh_cfg_kr_phase_get(struct bt_mesh_msg_ctx *ctx, u16_t net_idx);
int bt_mesh_cfg_kr_phase_set(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u8_t transition);
int bt_mesh_cfg_lpn_timeout_get(struct bt_mesh_msg_ctx *ctx, u16_t lpn_addr);
int bt_mesh_cfg_net_transmit_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_cfg_net_transmit_set(struct bt_mesh_msg_ctx *ctx, u8_t transmit);
/**
* @}
*/
#endif /* __BT_MESH_CFG_CLI_H */

View File

@@ -0,0 +1,72 @@
/** @file
* @brief Bluetooth Mesh Configuration Server Model APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_MESH_CFG_SRV_H
#define __BT_MESH_CFG_SRV_H
#include "mesh_access.h"
#include "mesh_kernel.h"
/**
* @brief Bluetooth Mesh
* @defgroup bt_mesh_cfg_srv Bluetooth Mesh Configuration Server Model
* @ingroup bt_mesh
* @{
*/
/** Mesh Configuration Server Model Context */
struct bt_mesh_cfg_srv {
struct bt_mesh_model *model;
u8_t net_transmit; /* Network Transmit state */
u8_t relay; /* Relay Mode state */
u8_t relay_retransmit; /* Relay Retransmit state */
u8_t beacon; /* Secure Network Beacon state */
u8_t gatt_proxy; /* GATT Proxy state */
u8_t frnd; /* Friend state */
u8_t default_ttl; /* Default TTL */
/* Heartbeat Publication */
struct bt_mesh_hb_pub {
struct k_delayed_work timer;
u16_t dst;
u16_t count;
u8_t period;
u8_t ttl;
u16_t feat;
u16_t net_idx;
} hb_pub;
/* Heartbeat Subscription */
struct bt_mesh_hb_sub {
s64_t expiry;
u16_t src;
u16_t dst;
u16_t count;
u8_t min_hops;
u8_t max_hops;
/* Optional subscription tracking function */
void (*func)(u8_t hops, u16_t feat);
} hb_sub;
};
extern const struct bt_mesh_model_op bt_mesh_cfg_srv_op[];
#define BT_MESH_MODEL_CFG_SRV(srv_data) \
BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_SRV, \
bt_mesh_cfg_srv_op, NULL, srv_data)
/**
* @}
*/
#endif /* __BT_MESH_CFG_SRV_H */

View File

@@ -0,0 +1,495 @@
/*
* Copyright (c) 2013-2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Doubly-linked list implementation
*
* Doubly-linked list implementation using inline macros/functions.
* This API is not thread safe, and thus if a list is used across threads,
* calls to functions must be protected with synchronization primitives.
*
* The lists are expected to be initialized such that both the head and tail
* pointers point to the list itself. Initializing the lists in such a fashion
* simplifies the adding and removing of nodes to/from the list.
*/
#ifndef _misc_dlist__h_
#define _misc_dlist__h_
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
struct _dnode {
union {
struct _dnode *head; /* ptr to head of list (sys_dlist_t) */
struct _dnode *next; /* ptr to next node (sys_dnode_t) */
};
union {
struct _dnode *tail; /* ptr to tail of list (sys_dlist_t) */
struct _dnode *prev; /* ptr to previous node (sys_dnode_t) */
};
};
typedef struct _dnode sys_dlist_t;
typedef struct _dnode sys_dnode_t;
/**
* @brief Provide the primitive to iterate on a list
* Note: the loop is unsafe and thus __dn should not be removed
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_FOR_EACH_NODE(l, n) {
* <user code>
* }
*
* This and other SYS_DLIST_*() macros are not thread safe.
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __dn A sys_dnode_t pointer to peek each node of the list
*/
#define SYS_DLIST_FOR_EACH_NODE(__dl, __dn) \
for (__dn = sys_dlist_peek_head(__dl); __dn; \
__dn = sys_dlist_peek_next(__dl, __dn))
/**
* @brief Provide the primitive to iterate on a list, from a node in the list
* Note: the loop is unsafe and thus __dn should not be removed
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_ITERATE_FROM_NODE(l, n) {
* <user code>
* }
*
* Like SYS_DLIST_FOR_EACH_NODE(), but __dn already contains a node in the list
* where to start searching for the next entry from. If NULL, it starts from
* the head.
*
* This and other SYS_DLIST_*() macros are not thread safe.
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __dn A sys_dnode_t pointer to peek each node of the list;
* it contains the starting node, or NULL to start from the head
*/
#define SYS_DLIST_ITERATE_FROM_NODE(__dl, __dn) \
for (__dn = __dn ? sys_dlist_peek_next_no_check(__dl, __dn) \
: sys_dlist_peek_head(__dl); \
__dn; \
__dn = sys_dlist_peek_next(__dl, __dn))
/**
* @brief Provide the primitive to safely iterate on a list
* Note: __dn can be removed, it will not break the loop.
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_FOR_EACH_NODE_SAFE(l, n, s) {
* <user code>
* }
*
* This and other SYS_DLIST_*() macros are not thread safe.
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __dn A sys_dnode_t pointer to peek each node of the list
* @param __dns A sys_dnode_t pointer for the loop to run safely
*/
#define SYS_DLIST_FOR_EACH_NODE_SAFE(__dl, __dn, __dns) \
for (__dn = sys_dlist_peek_head(__dl), \
__dns = sys_dlist_peek_next(__dl, __dn); \
__dn; __dn = __dns, \
__dns = sys_dlist_peek_next(__dl, __dn))
/*
* @brief Provide the primitive to resolve the container of a list node
* Note: it is safe to use with NULL pointer nodes
*
* @param __dn A pointer on a sys_dnode_t to get its container
* @param __cn Container struct type pointer
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_CONTAINER(__dn, __cn, __n) \
(__dn ? CONTAINER_OF(__dn, __typeof__(*__cn), __n) : NULL)
/*
* @brief Provide the primitive to peek container of the list head
*
* @param __dl A pointer on a sys_dlist_t to peek
* @param __cn Container struct type pointer
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n) \
SYS_DLIST_CONTAINER(sys_dlist_peek_head(__dl), __cn, __n)
/*
* @brief Provide the primitive to peek the next container
*
* @param __dl A pointer on a sys_dlist_t to peek
* @param __cn Container struct type pointer
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n) \
((__cn) ? SYS_DLIST_CONTAINER(sys_dlist_peek_next(__dl, &(__cn->__n)), \
__cn, __n) : NULL)
/**
* @brief Provide the primitive to iterate on a list under a container
* Note: the loop is unsafe and thus __cn should not be detached
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_FOR_EACH_CONTAINER(l, c, n) {
* <user code>
* }
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __cn A pointer to peek each entry of the list
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_FOR_EACH_CONTAINER(__dl, __cn, __n) \
for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n); __cn; \
__cn = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
/**
* @brief Provide the primitive to safely iterate on a list under a container
* Note: __cn can be detached, it will not break the loop.
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_DLIST_FOR_EACH_CONTAINER_SAFE(l, c, cn, n) {
* <user code>
* }
*
* @param __dl A pointer on a sys_dlist_t to iterate on
* @param __cn A pointer to peek each entry of the list
* @param __cns A pointer for the loop to run safely
* @param __n The field name of sys_dnode_t within the container struct
*/
#define SYS_DLIST_FOR_EACH_CONTAINER_SAFE(__dl, __cn, __cns, __n) \
for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n), \
__cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n); __cn; \
__cn = __cns, \
__cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
/**
* @brief initialize list
*
* @param list the doubly-linked list
*
* @return N/A
*/
static inline void sys_dlist_init(sys_dlist_t *list)
{
list->head = (sys_dnode_t *)list;
list->tail = (sys_dnode_t *)list;
}
#define SYS_DLIST_STATIC_INIT(ptr_to_list) {{(ptr_to_list)}, {(ptr_to_list)}}
/**
* @brief check if a node is the list's head
*
* @param list the doubly-linked list to operate on
* @param node the node to check
*
* @return 1 if node is the head, 0 otherwise
*/
static inline int sys_dlist_is_head(sys_dlist_t *list, sys_dnode_t *node)
{
return list->head == node;
}
/**
* @brief check if a node is the list's tail
*
* @param list the doubly-linked list to operate on
* @param node the node to check
*
* @return 1 if node is the tail, 0 otherwise
*/
static inline int sys_dlist_is_tail(sys_dlist_t *list, sys_dnode_t *node)
{
return list->tail == node;
}
/**
* @brief check if the list is empty
*
* @param list the doubly-linked list to operate on
*
* @return 1 if empty, 0 otherwise
*/
static inline int sys_dlist_is_empty(sys_dlist_t *list)
{
return list->head == list;
}
/**
* @brief check if more than one node present
*
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
*
* @return 1 if multiple nodes, 0 otherwise
*/
static inline int sys_dlist_has_multiple_nodes(sys_dlist_t *list)
{
return list->head != list->tail;
}
/**
* @brief get a reference to the head item in the list
*
* @param list the doubly-linked list to operate on
*
* @return a pointer to the head element, NULL if list is empty
*/
static inline sys_dnode_t *sys_dlist_peek_head(sys_dlist_t *list)
{
return sys_dlist_is_empty(list) ? NULL : list->head;
}
/**
* @brief get a reference to the head item in the list
*
* The list must be known to be non-empty.
*
* @param list the doubly-linked list to operate on
*
* @return a pointer to the head element
*/
static inline sys_dnode_t *sys_dlist_peek_head_not_empty(sys_dlist_t *list)
{
return list->head;
}
/**
* @brief get a reference to the next item in the list, node is not NULL
*
* Faster than sys_dlist_peek_next() if node is known not to be NULL.
*
* @param list the doubly-linked list to operate on
* @param node the node from which to get the next element in the list
*
* @return a pointer to the next element from a node, NULL if node is the tail
*/
static inline sys_dnode_t *sys_dlist_peek_next_no_check(sys_dlist_t *list,
sys_dnode_t *node)
{
return (node == list->tail) ? NULL : node->next;
}
/**
* @brief get a reference to the next item in the list
*
* @param list the doubly-linked list to operate on
* @param node the node from which to get the next element in the list
*
* @return a pointer to the next element from a node, NULL if node is the tail
* or NULL (when node comes from reading the head of an empty list).
*/
static inline sys_dnode_t *sys_dlist_peek_next(sys_dlist_t *list,
sys_dnode_t *node)
{
return node ? sys_dlist_peek_next_no_check(list, node) : NULL;
}
/**
* @brief get a reference to the tail item in the list
*
* @param list the doubly-linked list to operate on
*
* @return a pointer to the tail element, NULL if list is empty
*/
static inline sys_dnode_t *sys_dlist_peek_tail(sys_dlist_t *list)
{
return sys_dlist_is_empty(list) ? NULL : list->tail;
}
/**
* @brief add node to tail of list
*
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param node the element to append
*
* @return N/A
*/
static inline void sys_dlist_append(sys_dlist_t *list, sys_dnode_t *node)
{
node->next = list;
node->prev = list->tail;
list->tail->next = node;
list->tail = node;
}
/**
* @brief add node to head of list
*
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param node the element to append
*
* @return N/A
*/
static inline void sys_dlist_prepend(sys_dlist_t *list, sys_dnode_t *node)
{
node->next = list->head;
node->prev = list;
list->head->prev = node;
list->head = node;
}
/**
* @brief insert node after a node
*
* Insert a node after a specified node in a list.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param insert_point the insert point in the list: if NULL, insert at head
* @param node the element to append
*
* @return N/A
*/
static inline void sys_dlist_insert_after(sys_dlist_t *list,
sys_dnode_t *insert_point, sys_dnode_t *node)
{
if (!insert_point) {
sys_dlist_prepend(list, node);
} else {
node->next = insert_point->next;
node->prev = insert_point;
insert_point->next->prev = node;
insert_point->next = node;
}
}
/**
* @brief insert node before a node
*
* Insert a node before a specified node in a list.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param insert_point the insert point in the list: if NULL, insert at tail
* @param node the element to insert
*
* @return N/A
*/
static inline void sys_dlist_insert_before(sys_dlist_t *list,
sys_dnode_t *insert_point, sys_dnode_t *node)
{
if (!insert_point) {
sys_dlist_append(list, node);
} else {
node->prev = insert_point->prev;
node->next = insert_point;
insert_point->prev->next = node;
insert_point->prev = node;
}
}
/**
* @brief insert node at position
*
* Insert a node in a location depending on a external condition. The cond()
* function checks if the node is to be inserted _before_ the current node
* against which it is checked.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
* @param node the element to insert
* @param cond a function that determines if the current node is the correct
* insert point
* @param data parameter to cond()
*
* @return N/A
*/
static inline void sys_dlist_insert_at(sys_dlist_t *list, sys_dnode_t *node,
int (*cond)(sys_dnode_t *, void *), void *data)
{
if (sys_dlist_is_empty(list)) {
sys_dlist_append(list, node);
} else {
sys_dnode_t *pos = sys_dlist_peek_head(list);
while (pos && !cond(pos, data)) {
pos = sys_dlist_peek_next(list, pos);
}
sys_dlist_insert_before(list, pos, node);
}
}
/**
* @brief remove a specific node from a list
*
* The list is implicit from the node. The node must be part of a list.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param node the node to remove
*
* @return N/A
*/
static inline void sys_dlist_remove(sys_dnode_t *node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
}
/**
* @brief get the first node in a list
*
* This and other sys_dlist_*() functions are not thread safe.
*
* @param list the doubly-linked list to operate on
*
* @return the first node in the list, NULL if list is empty
*/
static inline sys_dnode_t *sys_dlist_get(sys_dlist_t *list)
{
sys_dnode_t *node;
if (sys_dlist_is_empty(list)) {
return NULL;
}
node = list->head;
sys_dlist_remove(node);
return node;
}
#ifdef __cplusplus
}
#endif
#endif /* _misc_dlist__h_ */

View File

@@ -0,0 +1,78 @@
/** @file
* @brief Bluetooth Mesh Health Client Model APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_MESH_HEALTH_CLI_H
#define __BT_MESH_HEALTH_CLI_H
#include "mesh_access.h"
#include "mesh_kernel.h"
#include "bt_mesh_client_common.h"
/**
* @brief Bluetooth Mesh
* @defgroup bt_mesh_health_cli Bluetooth Mesh Health Client Model
* @ingroup bt_mesh
* @{
*/
/* Health client model common structure */
typedef bt_mesh_client_common_t bt_mesh_health_client_t;
typedef bt_mesh_internal_data_t health_internal_data_t;
typedef bt_mesh_internal_data_t health_client_internal_data_t;
extern const struct bt_mesh_model_op bt_mesh_health_cli_op[];
#define BT_MESH_MODEL_HEALTH_CLI(cli_data) \
BT_MESH_MODEL(BT_MESH_MODEL_ID_HEALTH_CLI, \
bt_mesh_health_cli_op, NULL, cli_data)
int bt_mesh_health_cli_set(struct bt_mesh_model *model);
int bt_mesh_health_fault_get(struct bt_mesh_msg_ctx *ctx, u16_t cid);
int bt_mesh_health_fault_clear(struct bt_mesh_msg_ctx *ctx, u16_t cid,
bool need_ack);
int bt_mesh_health_fault_test(struct bt_mesh_msg_ctx *ctx,
u16_t cid, u8_t test_id, bool need_ack);
int bt_mesh_health_period_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_health_period_set(struct bt_mesh_msg_ctx *ctx,
u8_t divisor, bool need_ack);
int bt_mesh_health_attention_get(struct bt_mesh_msg_ctx *ctx);
int bt_mesh_health_attention_set(struct bt_mesh_msg_ctx *ctx,
u8_t attention, bool need_ack);
s32_t bt_mesh_health_cli_timeout_get(void);
void bt_mesh_health_cli_timeout_set(s32_t timeout);
/* Health Client Status Message Context */
struct bt_mesh_health_current_status {
u8_t test_id;
u16_t cid;
struct net_buf_simple *fault_array;
};
struct bt_mesh_health_fault_status {
u8_t test_id;
u16_t cid;
struct net_buf_simple *fault_array;
};
/**
* @}
*/
#endif /* __BT_MESH_HEALTH_CLI_H */

View File

@@ -0,0 +1,94 @@
/** @file
* @brief Bluetooth Mesh Health Server Model APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_MESH_HEALTH_SRV_H
#define __BT_MESH_HEALTH_SRV_H
#include "mesh_access.h"
#include "mesh_kernel.h"
/**
* @brief Bluetooth Mesh Health Server Model
* @defgroup bt_mesh_health_srv Bluetooth Mesh Health Server Model
* @ingroup bt_mesh
* @{
*/
struct bt_mesh_health_srv_cb {
/* Fetch current faults */
int (*fault_get_cur)(struct bt_mesh_model *model, u8_t *test_id,
u16_t *company_id, u8_t *faults,
u8_t *fault_count);
/* Fetch registered faults */
int (*fault_get_reg)(struct bt_mesh_model *model, u16_t company_id,
u8_t *test_id, u8_t *faults,
u8_t *fault_count);
/* Clear registered faults */
int (*fault_clear)(struct bt_mesh_model *model, u16_t company_id);
/* Run a specific test */
int (*fault_test)(struct bt_mesh_model *model, u8_t test_id,
u16_t company_id);
/* Attention on */
void (*attn_on)(struct bt_mesh_model *model);
/* Attention off */
void (*attn_off)(struct bt_mesh_model *model);
};
/** @def BT_MESH_HEALTH_FAULT_MSG
*
* A helper to define a health fault message.
*
* @param max_faults Maximum number of faults the element can have.
*
* @return a New net_buf_simple of the needed size.
*/
#define BT_MESH_HEALTH_FAULT_MSG(max_faults) \
NET_BUF_SIMPLE(1 + 3 + (max_faults))
/** Mesh Health Server Model Context */
struct bt_mesh_health_srv {
struct bt_mesh_model *model;
/* Optional callback struct */
const struct bt_mesh_health_srv_cb *cb;
/* Attention Timer state */
struct k_delayed_work attn_timer;
};
int bt_mesh_fault_update(struct bt_mesh_elem *elem);
extern const struct bt_mesh_model_op bt_mesh_health_srv_op[];
/** @def BT_MESH_MODEL_HEALTH_SRV
*
* Define a new health server model. Note that this API needs to be
* repeated for each element which the application wants to have a
* health server model on. Each instance also needs a unique
* bt_mesh_health_srv and bt_mesh_model_pub context.
*
* @param srv Pointer to a unique struct bt_mesh_health_srv.
* @param pub Pointer to a unique struct bt_mesh_model_pub.
*
* @return New mesh model instance.
*/
#define BT_MESH_MODEL_HEALTH_SRV(srv, pub) \
BT_MESH_MODEL(BT_MESH_MODEL_ID_HEALTH_SRV, \
bt_mesh_health_srv_op, pub, srv)
/**
* @}
*/
#endif /* __BT_MESH_HEALTH_SRV_H */

View File

@@ -0,0 +1,449 @@
/** @file
* @brief Bluetooth Mesh Access Layer APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include "mesh_types.h"
#include "mesh_util.h"
#include "mesh_buf.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
#ifndef __BT_MESH_ACCESS_H
#define __BT_MESH_ACCESS_H
/**
* @brief Bluetooth Mesh Access Layer
* @defgroup bt_mesh_access Bluetooth Mesh Access Layer
* @ingroup bt_mesh
* @{
*/
#define BT_MESH_ADDR_UNASSIGNED 0x0000
#define BT_MESH_ADDR_ALL_NODES 0xffff
#define BT_MESH_ADDR_PROXIES 0xfffc
#define BT_MESH_ADDR_FRIENDS 0xfffd
#define BT_MESH_ADDR_RELAYS 0xfffe
#define BT_MESH_KEY_UNUSED 0xffff
#define BT_MESH_KEY_DEV 0xfffe
/** Helper to define a mesh element within an array.
*
* In case the element has no SIG or Vendor models the helper
* macro BT_MESH_MODEL_NONE can be given instead.
*
* @param _loc Location Descriptor.
* @param _mods Array of models.
* @param _vnd_mods Array of vendor models.
*/
#define BT_MESH_ELEM(_loc, _mods, _vnd_mods) \
{ \
.loc = (_loc), \
.model_count = ARRAY_SIZE(_mods), \
.models = (_mods), \
.vnd_model_count = ARRAY_SIZE(_vnd_mods), \
.vnd_models = (_vnd_mods), \
}
/** Abstraction that describes a Mesh Element */
struct bt_mesh_elem {
/* Unicast Address. Set at runtime during provisioning. */
u16_t addr;
/* Location Descriptor (GATT Bluetooth Namespace Descriptors) */
const u16_t loc;
const u8_t model_count;
const u8_t vnd_model_count;
struct bt_mesh_model *const models;
struct bt_mesh_model *const vnd_models;
};
/* Foundation Models */
#define BT_MESH_MODEL_ID_CFG_SRV 0x0000
#define BT_MESH_MODEL_ID_CFG_CLI 0x0001
#define BT_MESH_MODEL_ID_HEALTH_SRV 0x0002
#define BT_MESH_MODEL_ID_HEALTH_CLI 0x0003
/* Models from the Mesh Model Specification */
#define BT_MESH_MODEL_ID_GEN_ONOFF_SRV 0x1000
#define BT_MESH_MODEL_ID_GEN_ONOFF_CLI 0x1001
#define BT_MESH_MODEL_ID_GEN_LEVEL_SRV 0x1002
#define BT_MESH_MODEL_ID_GEN_LEVEL_CLI 0x1003
#define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV 0x1004
#define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI 0x1005
#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV 0x1006
#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV 0x1007
#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI 0x1008
#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV 0x1009
#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV 0x100a
#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI 0x100b
#define BT_MESH_MODEL_ID_GEN_BATTERY_SRV 0x100c
#define BT_MESH_MODEL_ID_GEN_BATTERY_CLI 0x100d
#define BT_MESH_MODEL_ID_GEN_LOCATION_SRV 0x100e
#define BT_MESH_MODEL_ID_GEN_LOCATION_SETUPSRV 0x100f
#define BT_MESH_MODEL_ID_GEN_LOCATION_CLI 0x1010
#define BT_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV 0x1011
#define BT_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV 0x1012
#define BT_MESH_MODEL_ID_GEN_USER_PROP_SRV 0x1013
#define BT_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV 0x1014
#define BT_MESH_MODEL_ID_GEN_PROP_CLI 0x1015
#define BT_MESH_MODEL_ID_SENSOR_SRV 0x1100
#define BT_MESH_MODEL_ID_SENSOR_SETUP_SRV 0x1101
#define BT_MESH_MODEL_ID_SENSOR_CLI 0x1102
#define BT_MESH_MODEL_ID_TIME_SRV 0x1200
#define BT_MESH_MODEL_ID_TIME_SETUP_SRV 0x1201
#define BT_MESH_MODEL_ID_TIME_CLI 0x1202
#define BT_MESH_MODEL_ID_SCENE_SRV 0x1203
#define BT_MESH_MODEL_ID_SCENE_SETUP_SRV 0x1204
#define BT_MESH_MODEL_ID_SCENE_CLI 0x1205
#define BT_MESH_MODEL_ID_SCHEDULER_SRV 0x1206
#define BT_MESH_MODEL_ID_SCHEDULER_SETUP_SRV 0x1207
#define BT_MESH_MODEL_ID_SCHEDULER_CLI 0x1208
#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV 0x1300
#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV 0x1301
#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI 0x1302
#define BT_MESH_MODEL_ID_LIGHT_CTL_SRV 0x1303
#define BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV 0x1304
#define BT_MESH_MODEL_ID_LIGHT_CTL_CLI 0x1305
#define BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV 0x1306
#define BT_MESH_MODEL_ID_LIGHT_HSL_SRV 0x1307
#define BT_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV 0x1308
#define BT_MESH_MODEL_ID_LIGHT_HSL_CLI 0x1309
#define BT_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV 0x130a
#define BT_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV 0x130b
#define BT_MESH_MODEL_ID_LIGHT_XYL_SRV 0x130c
#define BT_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV 0x130d
#define BT_MESH_MODEL_ID_LIGHT_XYL_CLI 0x130e
#define BT_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f
#define BT_MESH_MODEL_ID_LIGHT_LC_SETUPSRV 0x1310
#define BT_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311
/** Message sending context. */
struct bt_mesh_msg_ctx {
/** NetKey Index of the subnet to send the message on. */
u16_t net_idx;
/** AppKey Index to encrypt the message with. */
u16_t app_idx;
/** Remote address. */
u16_t addr;
/** Received TTL value. Not used for sending. */
u8_t recv_ttl: 7;
/** Force sending reliably by using segment acknowledgement */
u8_t send_rel: 1;
/** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */
u8_t send_ttl;
/** Change by Espressif, opcode of a received message.
* Not used for sending message. */
u32_t recv_op;
/** Change by Espressif, destination address of a received
* message. Not used for sending message. */
u16_t recv_dst;
/** Change by Espressif, model corresponds to the message */
struct bt_mesh_model *model;
/** Change by Espressif, if the message is sent by a server
* model. Not used for receiving message. */
bool srv_send;
};
struct bt_mesh_model_op {
/* OpCode encoded using the BT_MESH_MODEL_OP_* macros */
const u32_t opcode;
/* Minimum required message length */
const size_t min_len;
/* Message handler for the opcode */
void (*const func)(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
};
#define BT_MESH_MODEL_OP_1(b0) (b0)
#define BT_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1))
#define BT_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid))
#define BT_MESH_MODEL_OP_END { 0, 0, NULL }
#define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \
{ BT_MESH_MODEL_OP_END })
/** Helper to define an empty model array */
#define BT_MESH_MODEL_NONE ((struct bt_mesh_model []){})
#define BT_MESH_MODEL(_id, _op, _pub, _user_data) \
{ \
.id = (_id), \
.op = _op, \
.keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] = \
BT_MESH_KEY_UNUSED }, \
.pub = _pub, \
.groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] = \
BT_MESH_ADDR_UNASSIGNED }, \
.user_data = _user_data, \
}
#define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \
{ \
.vnd.company = (_company), \
.vnd.id = (_id), \
.op = _op, \
.pub = _pub, \
.keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] = \
BT_MESH_KEY_UNUSED }, \
.groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] = \
BT_MESH_ADDR_UNASSIGNED }, \
.user_data = _user_data, \
}
/** @def BT_MESH_TRANSMIT
*
* @brief Encode transmission count & interval steps.
*
* @param count Number of retransmissions (first transmission is excluded).
* @param int_ms Interval steps in milliseconds. Must be greater than 0
* and a multiple of 10.
*
* @return Mesh transmit value that can be used e.g. for the default
* values of the configuration model data.
*/
#define BT_MESH_TRANSMIT(count, int_ms) ((count) | (((int_ms / 10) - 1) << 3))
/** @def BT_MESH_TRANSMIT_COUNT
*
* @brief Decode transmit count from a transmit value.
*
* @param transmit Encoded transmit count & interval value.
*
* @return Transmission count (actual transmissions is N + 1).
*/
#define BT_MESH_TRANSMIT_COUNT(transmit) (((transmit) & (u8_t)BIT_MASK(3)))
/** @def BT_MESH_TRANSMIT_INT
*
* @brief Decode transmit interval from a transmit value.
*
* @param transmit Encoded transmit count & interval value.
*
* @return Transmission interval in milliseconds.
*/
#define BT_MESH_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 10)
/** @def BT_MESH_PUB_TRANSMIT
*
* @brief Encode Publish Retransmit count & interval steps.
*
* @param count Number of retransmissions (first transmission is excluded).
* @param int_ms Interval steps in milliseconds. Must be greater than 0
* and a multiple of 50.
*
* @return Mesh transmit value that can be used e.g. for the default
* values of the configuration model data.
*/
#define BT_MESH_PUB_TRANSMIT(count, int_ms) BT_MESH_TRANSMIT(count, \
(int_ms) / 5)
/** @def BT_MESH_PUB_TRANSMIT_COUNT
*
* @brief Decode Pubhlish Retransmit count from a given value.
*
* @param transmit Encoded Publish Retransmit count & interval value.
*
* @return Retransmission count (actual transmissions is N + 1).
*/
#define BT_MESH_PUB_TRANSMIT_COUNT(transmit) BT_MESH_TRANSMIT_COUNT(transmit)
/** @def BT_MESH_PUB_TRANSMIT_INT
*
* @brief Decode Publish Retransmit interval from a given value.
*
* @param transmit Encoded Publish Retransmit count & interval value.
*
* @return Transmission interval in milliseconds.
*/
#define BT_MESH_PUB_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 50)
/** Model publication context. */
struct bt_mesh_model_pub {
/** The model the context belongs to. Initialized by the stack. */
struct bt_mesh_model *mod;
u16_t addr; /**< Publish Address. */
u16_t key; /**< Publish AppKey Index. */
u8_t ttl; /**< Publish Time to Live. */
u8_t retransmit; /**< Retransmit Count & Interval Steps. */
u8_t period; /**< Publish Period. */
u8_t period_div: 4, /**< Divisor for the Period. */
cred: 1, /**< Friendship Credentials Flag. */
count: 3; /**< Retransmissions left. */
u32_t period_start; /**< Start of the current period. */
/** @brief Publication buffer, containing the publication message.
*
* The application is expected to initialize this with
* a valid net_buf_simple pointer, with the help of e.g.
* the NET_BUF_SIMPLE() macro. The publication buffer must
* contain a valid publication message before calling the
* bt_mesh_model_publish() API or after the publication's
* @ref bt_mesh_model_pub.update callback has been called
* and returned success. The buffer must be created outside
* of function context, i.e. it must not be on the stack.
* This is most conveniently acheived by creating it inline
* when declaring the publication context:
*
* static struct bt_mesh_model_pub my_pub = {
* .msg = NET_BUF_SIMPLE(size),
* };
*/
struct net_buf_simple *msg;
/** @brief Callback for updating the publication buffer.
*
* When set to NULL, the model is assumed not to support
* periodic publishing. When set to non-NULL the callback
* will be called periodically and is expected to update
* @ref bt_mesh_model_pub.msg with a valid publication
* message.
*
* @param mod The Model the Publication Context belogs to.
*
* @return Zero on success or (negative) error code otherwise.
*/
int (*update)(struct bt_mesh_model *mod);
/* Change by Espressif, role of the device going to publish messages */
u8_t dev_role;
/** Publish Period Timer. Only for stack-internal use. */
struct k_delayed_work timer;
};
/** @def BT_MESH_MODEL_PUB_DEFINE
*
* Define a model publication context.
*
* @param _name Variable name given to the context.
* @param _update Optional message update callback (may be NULL).
* @param _msg_len Length of the publication message.
*/
#define BT_MESH_MODEL_PUB_DEFINE(_name, _update, _msg_len) \
NET_BUF_SIMPLE_DEFINE_STATIC(bt_mesh_pub_msg_##_name, _msg_len); \
static struct bt_mesh_model_pub _name = { \
.update = _update, \
.msg = &bt_mesh_pub_msg_##_name, \
}
/** Abstraction that describes a Mesh Model instance */
struct bt_mesh_model {
union {
const u16_t id;
struct {
u16_t company;
u16_t id;
} vnd;
};
/* The Element this Model belongs to */
struct bt_mesh_elem *elem;
/* Model Publication */
struct bt_mesh_model_pub *const pub;
/* AppKey List */
u16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT];
/* Subscription List (group or virtual addresses) */
u16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
const struct bt_mesh_model_op *const op;
/* Model-specific user data */
void *user_data;
/* Internal information, mainly for persistent storage */
u8_t element_idx; /* Belongs to Nth element */
u8_t model_idx; /* Is the Nth model in the element */
u16_t flags; /* Information about what has changed */
};
struct bt_mesh_send_cb {
void (*start)(u16_t duration, int err, void *cb_data);
void (*end)(int err, void *cb_data);
};
void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode);
/** Special TTL value to request using configured default TTL */
#define BT_MESH_TTL_DEFAULT 0xff
/** Maximum allowed TTL value */
#define BT_MESH_TTL_MAX 0x7f
/**
* @brief Send an Access Layer message.
*
* @param model Mesh (client) Model that the message belongs to.
* @param ctx Message context, includes keys, TTL, etc.
* @param msg Access Layer payload (the actual message to be sent).
* @param cb Optional "message sent" callback.
* @param cb_data User data to be passed to the callback.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_model_send(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *msg,
const struct bt_mesh_send_cb *cb,
void *cb_data);
/**
* @brief Send a model publication message.
*
* Before calling this function, the user needs to ensure that the model
* publication message (@ref bt_mesh_model_pub.msg) contains a valid
* message to be sent. Note that this API is only to be used for
* non-period publishing. For periodic publishing the app only needs
* to make sure that @ref bt_mesh_model_pub.msg contains a valid message
* whenever the @ref bt_mesh_model_pub.update callback is called.
*
* @param model Mesh (client) Model that's publishing the message.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_model_publish(struct bt_mesh_model *model);
/** Node Composition */
struct bt_mesh_comp {
u16_t cid;
u16_t pid;
u16_t vid;
size_t elem_count;
struct bt_mesh_elem *elem;
};
/**
* @}
*/
#endif /* __BT_MESH_ACCESS_H */
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,172 @@
/* aes.h - TinyCrypt interface to an AES-128 implementation */
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief -- Interface to an AES-128 implementation.
*
* Overview: AES-128 is a NIST approved block cipher specified in
* FIPS 197. Block ciphers are deterministic algorithms that
* perform a transformation specified by a symmetric key in fixed-
* length data sets, also called blocks.
*
* Security: AES-128 provides approximately 128 bits of security.
*
* Usage: 1) call tc_aes128_set_encrypt/decrypt_key to set the key.
*
* 2) call tc_aes_encrypt/decrypt to process the data.
*/
#ifndef __TC_AES_H__
#define __TC_AES_H__
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define Nb (4) /* number of columns (32-bit words) comprising the state */
#define Nk (4) /* number of 32-bit words comprising the key */
#define Nr (10) /* number of rounds */
#define TC_AES_BLOCK_SIZE (Nb*Nk)
#define TC_AES_KEY_SIZE (Nb*Nk)
#define TC_CRYPTO_SUCCESS 1
#define TC_CRYPTO_FAIL 0
#define TC_ZERO_BYTE 0x00
/* padding for last message block */
#define TC_CMAC_PADDING 0x80
typedef struct tc_aes_key_sched_struct {
unsigned int words[Nb * (Nr + 1)];
} *TCAesKeySched_t;
/* struct tc_cmac_struct represents the state of a CMAC computation */
typedef struct tc_cmac_struct {
/* initialization vector */
uint8_t iv[TC_AES_BLOCK_SIZE];
/* used if message length is a multiple of block_size bytes */
uint8_t K1[TC_AES_BLOCK_SIZE];
/* used if message length isn't a multiple block_size bytes */
uint8_t K2[TC_AES_BLOCK_SIZE];
/* where to put bytes that didn't fill a block */
uint8_t leftover[TC_AES_BLOCK_SIZE];
/* identifies the encryption key */
unsigned int keyid;
/* next available leftover location */
unsigned int leftover_offset;
/* AES key schedule */
TCAesKeySched_t sched;
/* calls to tc_cmac_update left before re-key */
uint64_t countdown;
} *TCCmacState_t;
/**
* @brief Set AES-128 encryption key
* Uses key k to initialize s
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL
* @note This implementation skips the additional steps required for keys
* larger than 128 bits, and must not be used for AES-192 or
* AES-256 key schedule -- see FIPS 197 for details
* @param s IN/OUT -- initialized struct tc_aes_key_sched_struct
* @param k IN -- points to the AES key
*/
int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k);
/**
* @brief AES-128 Encryption procedure
* Encrypts contents of in buffer into out buffer under key;
* schedule s
* @note Assumes s was initialized by aes_set_encrypt_key;
* out and in point to 16 byte buffers
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: out == NULL or in == NULL or s == NULL
* @param out IN/OUT -- buffer to receive ciphertext block
* @param in IN -- a plaintext block to encrypt
* @param s IN -- initialized AES key schedule
*/
int tc_aes_encrypt(uint8_t *out, const uint8_t *in,
const TCAesKeySched_t s);
/**
* @brief Set the AES-128 decryption key
* Uses key k to initialize s
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL
* @note This is the implementation of the straightforward inverse cipher
* using the cipher documented in FIPS-197 figure 12, not the
* equivalent inverse cipher presented in Figure 15
* @warning This routine skips the additional steps required for keys larger
* than 128, and must not be used for AES-192 or AES-256 key
* schedule -- see FIPS 197 for details
* @param s IN/OUT -- initialized struct tc_aes_key_sched_struct
* @param k IN -- points to the AES key
*/
int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k);
/**
* @brief AES-128 Encryption procedure
* Decrypts in buffer into out buffer under key schedule s
* @return returns TC_CRYPTO_SUCCESS (1)
* returns TC_CRYPTO_FAIL (0) if: out is NULL or in is NULL or s is NULL
* @note Assumes s was initialized by aes_set_encrypt_key
* out and in point to 16 byte buffers
* @param out IN/OUT -- buffer to receive ciphertext block
* @param in IN -- a plaintext block to encrypt
* @param s IN -- initialized AES key schedule
*/
int tc_aes_decrypt(uint8_t *out, const uint8_t *in,
const TCAesKeySched_t s);
int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched);
void gf_double(uint8_t *out, uint8_t *in);
int tc_cmac_init(TCCmacState_t s);
int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length);
int tc_cmac_final(uint8_t *tag, TCCmacState_t s);
int tc_cmac_erase(TCCmacState_t s);
#ifdef __cplusplus
}
#endif
#endif /* __TC_AES_H__ */

View File

@@ -0,0 +1,420 @@
/* atomic operations */
/*
* Copyright (c) 1997-2015, Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ATOMIC_H__
#define __ATOMIC_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef int atomic_t;
typedef atomic_t atomic_val_t;
/**
* @defgroup atomic_apis Atomic Services APIs
* @ingroup kernel_apis
* @{
*/
/**
* @brief Atomic compare-and-set.
*
* This routine performs an atomic compare-and-set on @a target. If the current
* value of @a target equals @a old_value, @a target is set to @a new_value.
* If the current value of @a target does not equal @a old_value, @a target
* is left unchanged.
*
* @param target Address of atomic variable.
* @param old_value Original value to compare against.
* @param new_value New value to store.
* @return 1 if @a new_value is written, 0 otherwise.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline int atomic_cas(atomic_t *target, atomic_val_t old_value,
atomic_val_t new_value)
{
return __atomic_compare_exchange_n(target, &old_value, new_value,
0, __ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
}
#else
extern int atomic_cas(atomic_t *target, atomic_val_t old_value,
atomic_val_t new_value);
#endif
/**
*
* @brief Atomic addition.
*
* This routine performs an atomic addition on @a target.
*
* @param target Address of atomic variable.
* @param value Value to add.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value)
{
return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST);
}
#else
extern atomic_val_t atomic_add(atomic_t *target, atomic_val_t value);
#endif
/**
*
* @brief Atomic subtraction.
*
* This routine performs an atomic subtraction on @a target.
*
* @param target Address of atomic variable.
* @param value Value to subtract.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value)
{
return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST);
}
#else
extern atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value);
#endif
/**
*
* @brief Atomic increment.
*
* This routine performs an atomic increment by 1 on @a target.
*
* @param target Address of atomic variable.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_inc(atomic_t *target)
{
return atomic_add(target, 1);
}
#else
extern atomic_val_t atomic_inc(atomic_t *target);
#endif
/**
*
* @brief Atomic decrement.
*
* This routine performs an atomic decrement by 1 on @a target.
*
* @param target Address of atomic variable.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_dec(atomic_t *target)
{
return atomic_sub(target, 1);
}
#else
extern atomic_val_t atomic_dec(atomic_t *target);
#endif
/**
*
* @brief Atomic get.
*
* This routine performs an atomic read on @a target.
*
* @param target Address of atomic variable.
*
* @return Value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_get(const atomic_t *target)
{
return __atomic_load_n(target, __ATOMIC_SEQ_CST);
}
#else
extern atomic_val_t atomic_get(const atomic_t *target);
#endif
/**
*
* @brief Atomic get-and-set.
*
* This routine atomically sets @a target to @a value and returns
* the previous value of @a target.
*
* @param target Address of atomic variable.
* @param value Value to write to @a target.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value)
{
/* This builtin, as described by Intel, is not a traditional
* test-and-set operation, but rather an atomic exchange operation. It
* writes value into *ptr, and returns the previous contents of *ptr.
*/
return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST);
}
#else
extern atomic_val_t atomic_set(atomic_t *target, atomic_val_t value);
#endif
/**
*
* @brief Atomic clear.
*
* This routine atomically sets @a target to zero and returns its previous
* value. (Hence, it is equivalent to atomic_set(target, 0).)
*
* @param target Address of atomic variable.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_clear(atomic_t *target)
{
return atomic_set(target, 0);
}
#else
extern atomic_val_t atomic_clear(atomic_t *target);
#endif
/**
*
* @brief Atomic bitwise inclusive OR.
*
* This routine atomically sets @a target to the bitwise inclusive OR of
* @a target and @a value.
*
* @param target Address of atomic variable.
* @param value Value to OR.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value)
{
return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST);
}
#else
extern atomic_val_t atomic_or(atomic_t *target, atomic_val_t value);
#endif
/**
*
* @brief Atomic bitwise exclusive OR (XOR).
*
* This routine atomically sets @a target to the bitwise exclusive OR (XOR) of
* @a target and @a value.
*
* @param target Address of atomic variable.
* @param value Value to XOR
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value)
{
return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST);
}
#else
extern atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value);
#endif
/**
*
* @brief Atomic bitwise AND.
*
* This routine atomically sets @a target to the bitwise AND of @a target
* and @a value.
*
* @param target Address of atomic variable.
* @param value Value to AND.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value)
{
return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST);
}
#else
extern atomic_val_t atomic_and(atomic_t *target, atomic_val_t value);
#endif
/**
*
* @brief Atomic bitwise NAND.
*
* This routine atomically sets @a target to the bitwise NAND of @a target
* and @a value. (This operation is equivalent to target = ~(target & value).)
*
* @param target Address of atomic variable.
* @param value Value to NAND.
*
* @return Previous value of @a target.
*/
#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
static inline atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value)
{
return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST);
}
#else
extern atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value);
#endif
/**
* @brief Initialize an atomic variable.
*
* This macro can be used to initialize an atomic variable. For example,
* @code atomic_t my_var = ATOMIC_INIT(75); @endcode
*
* @param i Value to assign to atomic variable.
*/
#define ATOMIC_INIT(i) (i)
/**
* @cond INTERNAL_HIDDEN
*/
#define ATOMIC_BITS (sizeof(atomic_val_t) * 8)
#define ATOMIC_MASK(bit) (1 << ((bit) & (ATOMIC_BITS - 1)))
#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS))
/**
* INTERNAL_HIDDEN @endcond
*/
/**
* @brief Define an array of atomic variables.
*
* This macro defines an array of atomic variables containing at least
* @a num_bits bits.
*
* @note
* If used from file scope, the bits of the array are initialized to zero;
* if used from within a function, the bits are left uninitialized.
*
* @param name Name of array of atomic variables.
* @param num_bits Number of bits needed.
*/
#define ATOMIC_DEFINE(name, num_bits) \
atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS]
/**
* @brief Atomically test a bit.
*
* This routine tests whether bit number @a bit of @a target is set or not.
* The target may be a single atomic variable or an array of them.
*
* @param target Address of atomic variable or array.
* @param bit Bit number (starting from 0).
*
* @return 1 if the bit was set, 0 if it wasn't.
*/
static inline int atomic_test_bit(const atomic_t *target, int bit)
{
atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit));
return (1 & (val >> (bit & (ATOMIC_BITS - 1))));
}
/**
* @brief Atomically test and clear a bit.
*
* Atomically clear bit number @a bit of @a target and return its old value.
* The target may be a single atomic variable or an array of them.
*
* @param target Address of atomic variable or array.
* @param bit Bit number (starting from 0).
*
* @return 1 if the bit was set, 0 if it wasn't.
*/
static inline int atomic_test_and_clear_bit(atomic_t *target, int bit)
{
atomic_val_t mask = ATOMIC_MASK(bit);
atomic_val_t old;
old = atomic_and(ATOMIC_ELEM(target, bit), ~mask);
return (old & mask) != 0;
}
/**
* @brief Atomically set a bit.
*
* Atomically set bit number @a bit of @a target and return its old value.
* The target may be a single atomic variable or an array of them.
*
* @param target Address of atomic variable or array.
* @param bit Bit number (starting from 0).
*
* @return 1 if the bit was set, 0 if it wasn't.
*/
static inline int atomic_test_and_set_bit(atomic_t *target, int bit)
{
atomic_val_t mask = ATOMIC_MASK(bit);
atomic_val_t old;
old = atomic_or(ATOMIC_ELEM(target, bit), mask);
return (old & mask) != 0;
}
/**
* @brief Atomically clear a bit.
*
* Atomically clear bit number @a bit of @a target.
* The target may be a single atomic variable or an array of them.
*
* @param target Address of atomic variable or array.
* @param bit Bit number (starting from 0).
*
* @return N/A
*/
static inline void atomic_clear_bit(atomic_t *target, int bit)
{
atomic_val_t mask = ATOMIC_MASK(bit);
atomic_and(ATOMIC_ELEM(target, bit), ~mask);
}
/**
* @brief Atomically set a bit.
*
* Atomically set bit number @a bit of @a target.
* The target may be a single atomic variable or an array of them.
*
* @param target Address of atomic variable or array.
* @param bit Bit number (starting from 0).
*
* @return N/A
*/
static inline void atomic_set_bit(atomic_t *target, int bit)
{
atomic_val_t mask = ATOMIC_MASK(bit);
atomic_or(ATOMIC_ELEM(target, bit), mask);
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __ATOMIC_H__ */

View File

@@ -0,0 +1,836 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
* Copyright (c) 2015-2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _MESH_BEARER_ADRPT_H_
#define _MESH_BEARER_ADRPT_H_
#include <string.h>
#include "mesh_types.h"
#include "mesh_buf.h"
#include "mesh_bt_uuid.h"
/* Advertising types */
#define BT_LE_ADV_IND 0x00
#define BT_LE_ADV_DIRECT_IND 0x01
#define BT_LE_ADV_SCAN_IND 0x02
#define BT_LE_ADV_NONCONN_IND 0x03
#define BT_LE_ADV_DIRECT_IND_LOW_DUTY 0x04
/* Needed in advertising reports when getting info about */
#define BT_LE_ADV_SCAN_RSP 0x04
#define BT_HCI_LE_SCAN_PASSIVE 0x00
#define BT_HCI_LE_SCAN_ACTIVE 0x01
#define BT_HCI_LE_SCAN_DISABLE 0x00
#define BT_HCI_LE_SCAN_ENABLE 0x01
#define BT_HCI_LE_SCAN_FILTER_DUP_DISABLE 0x00
#define BT_HCI_LE_SCAN_FILTER_DUP_ENABLE 0x01
/* Error codes for Error response PDU */
#define BT_ATT_ERR_INVALID_HANDLE 0x01
#define BT_ATT_ERR_READ_NOT_PERMITTED 0x02
#define BT_ATT_ERR_WRITE_NOT_PERMITTED 0x03
#define BT_ATT_ERR_INVALID_PDU 0x04
#define BT_ATT_ERR_AUTHENTICATION 0x05
#define BT_ATT_ERR_NOT_SUPPORTED 0x06
#define BT_ATT_ERR_INVALID_OFFSET 0x07
#define BT_ATT_ERR_AUTHORIZATION 0x08
#define BT_ATT_ERR_PREPARE_QUEUE_FULL 0x09
#define BT_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0a
#define BT_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0b
#define BT_ATT_ERR_ENCRYPTION_KEY_SIZE 0x0c
#define BT_ATT_ERR_INVALID_ATTRIBUTE_LEN 0x0d
#define BT_ATT_ERR_UNLIKELY 0x0e
#define BT_ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f
#define BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10
#define BT_ATT_ERR_INSUFFICIENT_RESOURCES 0x11
/* Common Profile Error Codes (from CSS) */
#define BT_ATT_ERR_WRITE_REQ_REJECTED 0xfc
#define BT_ATT_ERR_CCC_IMPROPER_CONF 0xfd
#define BT_ATT_ERR_PROCEDURE_IN_PROGRESS 0xfe
#define BT_ATT_ERR_OUT_OF_RANGE 0xff
/* EIR/AD data type definitions */
#define BT_DATA_FLAGS 0x01 /* AD flags */
#define BT_DATA_UUID16_SOME 0x02 /* 16-bit UUID, more available */
#define BT_DATA_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
#define BT_DATA_UUID32_SOME 0x04 /* 32-bit UUID, more available */
#define BT_DATA_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
#define BT_DATA_UUID128_SOME 0x06 /* 128-bit UUID, more available */
#define BT_DATA_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
#define BT_DATA_NAME_SHORTENED 0x08 /* Shortened name */
#define BT_DATA_NAME_COMPLETE 0x09 /* Complete name */
#define BT_DATA_TX_POWER 0x0a /* Tx Power */
#define BT_DATA_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */
#define BT_DATA_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */
#define BT_DATA_SVC_DATA16 0x16 /* Service data, 16-bit UUID */
#define BT_DATA_GAP_APPEARANCE 0x19 /* GAP appearance */
#define BT_DATA_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */
#define BT_DATA_SVC_DATA32 0x20 /* Service data, 32-bit UUID */
#define BT_DATA_SVC_DATA128 0x21 /* Service data, 128-bit UUID */
#define BT_DATA_MESH_PROV 0x29 /* Mesh Provisioning PDU */
#define BT_DATA_MESH_MESSAGE 0x2a /* Mesh Networking PDU */
#define BT_DATA_MESH_BEACON 0x2b /* Mesh Beacon */
#define BT_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */
#define BT_LE_AD_LIMITED 0x01 /* Limited Discoverable */
#define BT_LE_AD_GENERAL 0x02 /* General Discoverable */
#define BT_LE_AD_NO_BREDR 0x04 /* BR/EDR not supported */
/* Client Characteristic Configuration Values */
/** @def BT_GATT_CCC_NOTIFY
* @brief Client Characteristic Configuration Notification.
*
* If set, changes to Characteristic Value shall be notified.
*/
#define BT_GATT_CCC_NOTIFY 0x0001
/** @def BT_GATT_CCC_INDICATE
* @brief Client Characteristic Configuration Indication.
*
* If set, changes to Characteristic Value shall be indicated.
*/
#define BT_GATT_CCC_INDICATE 0x0002
/** @def BT_GATT_ERR
* @brief Construct error return value for attribute read and write callbacks.
*
* @param _att_err ATT error code
*
* @return Appropriate error code for the attribute callbacks.
*
*/
#define BT_GATT_ERR(_att_err) (-(_att_err))
enum {
BT_GATT_ITER_STOP = 0,
BT_GATT_ITER_CONTINUE,
};
/* GATT attribute permission bit field values */
enum {
/** No operations supported, e.g. for notify-only */
BT_GATT_PERM_NONE = 0,
/** Attribute read permission. */
BT_GATT_PERM_READ = BIT(0),
/** Attribute write permission. */
BT_GATT_PERM_WRITE = BIT(1),
/** Attribute read permission with encryption.
*
* If set, requires encryption for read access.
*/
BT_GATT_PERM_READ_ENCRYPT = BIT(2),
/** Attribute write permission with encryption.
*
* If set, requires encryption for write access.
*/
BT_GATT_PERM_WRITE_ENCRYPT = BIT(3),
/** Attribute read permission with authentication.
*
* If set, requires encryption using authenticated link-key for read
* access.
*/
BT_GATT_PERM_READ_AUTHEN = BIT(4),
/** Attribute write permission with authentication.
*
* If set, requires encryption using authenticated link-key for write
* access.
*/
BT_GATT_PERM_WRITE_AUTHEN = BIT(5),
/** Attribute prepare write permission.
*
* If set, allows prepare writes with use of BT_GATT_WRITE_FLAG_PREPARE
* passed to write callback.
*/
BT_GATT_PERM_PREPARE_WRITE = BIT(6),
};
/** Advertising options */
enum {
/** Convenience value when no options are specified. */
BT_LE_ADV_OPT_NONE = 0,
/** Advertise as connectable. Type of advertising is determined by
* providing SCAN_RSP data and/or enabling local privacy support.
*/
BT_LE_ADV_OPT_CONNECTABLE = BIT(0),
/** Don't try to resume connectable advertising after a connection.
* This option is only meaningful when used together with
* BT_LE_ADV_OPT_CONNECTABLE. If set the advertising will be stopped
* when bt_le_adv_stop() is called or when an incoming (slave)
* connection happens. If this option is not set the stack will
* take care of keeping advertising enabled even as connections
* occur.
*/
BT_LE_ADV_OPT_ONE_TIME = BIT(1),
};
/* Defined GAP timers */
#define BT_GAP_SCAN_FAST_INTERVAL 0x0060 /* 60 ms */
#define BT_GAP_SCAN_FAST_WINDOW 0x0030 /* 30 ms */
#define BT_GAP_SCAN_SLOW_INTERVAL_1 0x0800 /* 1.28 s */
#define BT_GAP_SCAN_SLOW_WINDOW_1 0x0012 /* 11.25 ms */
#define BT_GAP_SCAN_SLOW_INTERVAL_2 0x1000 /* 2.56 s */
#define BT_GAP_SCAN_SLOW_WINDOW_2 0x0012 /* 11.25 ms */
#define BT_GAP_ADV_FAST_INT_MIN_0 0x0020 /* 20 ms */
#define BT_GAP_ADV_FAST_INT_MAX_0 0x0020 /* 20 ms */
#define BT_GAP_ADV_FAST_INT_MIN_1 0x0030 /* 30 ms */
#define BT_GAP_ADV_FAST_INT_MAX_1 0x0060 /* 60 ms */
#define BT_GAP_ADV_FAST_INT_MIN_2 0x00a0 /* 100 ms */
#define BT_GAP_ADV_FAST_INT_MAX_2 0x00f0 /* 150 ms */
#define BT_GAP_ADV_SLOW_INT_MIN 0x0320 //0x0640 /* 1 s */
#define BT_GAP_ADV_SLOW_INT_MAX 0x0320 //0x0780 /* 1.2 s */
#define BT_GAP_INIT_CONN_INT_MIN 0x0018 /* 30 ms */
#define BT_GAP_INIT_CONN_INT_MAX 0x0028 /* 50 ms */
/* Characteristic Properties Bit field values */
/** @def BT_GATT_CHRC_BROADCAST
* @brief Characteristic broadcast property.
*
* If set, permits broadcasts of the Characteristic Value using Server
* Characteristic Configuration Descriptor.
*/
#define BT_GATT_CHRC_BROADCAST 0x01
/** @def BT_GATT_CHRC_READ
* @brief Characteristic read property.
*
* If set, permits reads of the Characteristic Value.
*/
#define BT_GATT_CHRC_READ 0x02
/** @def BT_GATT_CHRC_WRITE_WITHOUT_RESP
* @brief Characteristic write without response property.
*
* If set, permits write of the Characteristic Value without response.
*/
#define BT_GATT_CHRC_WRITE_WITHOUT_RESP 0x04
/** @def BT_GATT_CHRC_WRITE
* @brief Characteristic write with response property.
*
* If set, permits write of the Characteristic Value with response.
*/
#define BT_GATT_CHRC_WRITE 0x08
/** @def BT_GATT_CHRC_NOTIFY
* @brief Characteristic notify property.
*
* If set, permits notifications of a Characteristic Value without
* acknowledgment.
*/
#define BT_GATT_CHRC_NOTIFY 0x10
/** @def BT_GATT_CHRC_INDICATE
* @brief Characteristic indicate property.
*
* If set, permits indications of a Characteristic Value with acknowledgment.
*/
#define BT_GATT_CHRC_INDICATE 0x20
/** @def BT_GATT_CHRC_AUTH
* @brief Characteristic Authenticated Signed Writes property.
*
* If set, permits signed writes to the Characteristic Value.
*/
#define BT_GATT_CHRC_AUTH 0x40
/** @def BT_GATT_CHRC_EXT_PROP
* @brief Characteristic Extended Properties property.
*
* If set, additional characteristic properties are defined in the
* Characteristic Extended Properties Descriptor.
*/
#define BT_GATT_CHRC_EXT_PROP 0x80
/** @brief Characteristic Attribute Value. */
struct bt_gatt_chrc {
/** Characteristic UUID. */
const struct bt_uuid *uuid;
/** Characteristic properties. */
u8_t properties;
};
/** @brief GATT Service structure */
struct bt_gatt_service {
/** Service Attributes */
struct bt_gatt_attr *attrs;
/** Service Attribute count */
u16_t attr_count;
sys_snode_t node;
};
/*
* Copyright (c) 2015 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
typedef enum __packed {
BT_CONN_DISCONNECTED,
BT_CONN_CONNECT_SCAN,
BT_CONN_CONNECT,
BT_CONN_CONNECTED,
BT_CONN_DISCONNECT,
} bt_conn_state_t;
/** Security level. */
typedef enum __packed {
/** Only for BR/EDR special cases, like SDP */
BT_SECURITY_NONE,
/** No encryption and no authentication. */
BT_SECURITY_LOW,
/** Encryption and no authentication (no MITM). */
BT_SECURITY_MEDIUM,
/** Encryption and authentication (MITM). */
BT_SECURITY_HIGH,
/** Authenticated Secure Connections */
BT_SECURITY_FIPS,
} bt_security_t;
struct ecb_param {
u8_t key[16];
u8_t clear_text[16];
u8_t cipher_text[16];
} __packed;
typedef struct {
u8_t val[6];
} bt_addr_t;
typedef struct {
u8_t type;
bt_addr_t a;
} bt_addr_le_t;
/** Description of different data types that can be encoded into
* advertising data. Used to form arrays that are passed to the
* bt_le_adv_start() function.
*/
struct bt_data {
u8_t type;
u8_t data_len;
const u8_t *data;
};
/** @brief Helper to declare elements of bt_data arrays
*
* This macro is mainly for creating an array of struct bt_data
* elements which is then passed to bt_le_adv_start().
*
* @param _type Type of advertising data field
* @param _data Pointer to the data field payload
* @param _data_len Number of bytes behind the _data pointer
*/
#define BT_DATA(_type, _data, _data_len) \
{ \
.type = (_type), \
.data_len = (_data_len), \
.data = (const u8_t *)(_data), \
}
/** @brief Helper to declare elements of bt_data arrays
*
* This macro is mainly for creating an array of struct bt_data
* elements which is then passed to bt_le_adv_start().
*
* @param _type Type of advertising data field
* @param _bytes Variable number of single-byte parameters
*/
#define BT_DATA_BYTES(_type, _bytes...) \
BT_DATA(_type, ((u8_t []) { _bytes }), \
sizeof((u8_t []) { _bytes }))
/** LE Advertising Parameters. */
struct bt_le_adv_param {
/** Bit-field of advertising options */
u8_t options;
/** Minimum Advertising Interval (N * 0.625) */
u16_t interval_min;
/** Maximum Advertising Interval (N * 0.625) */
u16_t interval_max;
/** Optional predefined (random) own address. Currently
* the only permitted use of this is for NRPA with
* non-connectable advertising.
*/
const bt_addr_t *own_addr;
};
/** LE scan parameters */
struct bt_le_scan_param {
/** Scan type (BT_HCI_LE_SCAN_ACTIVE or BT_HCI_LE_SCAN_PASSIVE) */
u8_t type;
/** Duplicate filtering (BT_HCI_LE_SCAN_FILTER_DUP_ENABLE or
* BT_HCI_LE_SCAN_FILTER_DUP_DISABLE)
*/
u8_t filter_dup;
/** Scan interval (N * 0.625 ms) */
u16_t interval;
/** Scan window (N * 0.625 ms) */
u16_t window;
};
/** Connection parameters for LE connections */
struct bt_le_conn_param {
u16_t interval_min;
u16_t interval_max;
u16_t latency;
u16_t timeout;
};
struct bt_conn {
u16_t handle;
u8_t type;
u8_t role;
/* Connection error or reason for disconnect */
u8_t err;
bt_conn_state_t state;
u16_t rx_len;
struct net_buf *rx;
/* Sent but not acknowledged TX packets */
sys_slist_t tx_pending;
/* Acknowledged but not yet notified TX packets */
struct k_fifo tx_notify;
/* Queue for outgoing ACL data */
struct k_fifo tx_queue;
/* Active L2CAP channels */
sys_slist_t channels;
atomic_t ref;
};
/** @typedef bt_le_scan_cb_t
* @brief Callback type for reporting LE scan results.
*
* A function of this type is given to the bt_le_scan_start() function
* and will be called for any discovered LE device.
*
* @param addr Advertiser LE address and type.
* @param rssi Strength of advertiser signal.
* @param adv_type Type of advertising response from advertiser.
* @param data Buffer containing advertiser data.
*/
typedef void bt_le_scan_cb_t(const bt_addr_le_t *addr, s8_t rssi,
u8_t adv_type, struct net_buf_simple *buf);
/* @typedef bt_dh_key_cb_t
* @brief Callback type for DH Key calculation.
*
* Used to notify of the calculated DH Key.
*
* @param key The DH Key, or NULL in case of failure.
*/
typedef void (*bt_dh_key_cb_t)(const u8_t key[32]);
/** @typedef bt_gatt_attr_func_t
* @brief Attribute iterator callback.
*
* @param attr Attribute found.
* @param user_data Data given.
*
* @return BT_GATT_ITER_CONTINUE if should continue to the next attribute
* or BT_GATT_ITER_STOP to stop.
*/
typedef u8_t (*bt_gatt_attr_func_t)(const struct bt_gatt_attr *attr,
void *user_data);
/** @brief Connection callback structure.
*
* This structure is used for tracking the state of a connection.
* It is registered with the help of the bt_mesh_gatts_conn_cb_register() API.
* It's permissible to register multiple instances of this @ref bt_conn_cb
* type, in case different modules of an application are interested in
* tracking the connection state. If a callback is not of interest for
* an instance, it may be set to NULL and will as a consequence not be
* used for that instance.
*/
struct bt_conn_cb {
/** @brief A new connection has been established.
*
* This callback notifies the application of a new connection.
* In case the err parameter is non-zero it means that the
* connection establishment failed.
*
* @param conn New connection object.
* @param err HCI error. Zero for success, non-zero otherwise.
*/
void (*connected)(struct bt_conn *conn, u8_t err);
/** @brief A connection has been disconnected.
*
* This callback notifies the application that a connection
* has been disconnected.
*
* @param conn Connection object.
* @param reason HCI reason for the disconnection.
*/
void (*disconnected)(struct bt_conn *conn, u8_t reason);
/** @brief LE connection parameter update request.
*
* This callback notifies the application that a remote device
* is requesting to update the connection parameters. The
* application accepts the parameters by returning true, or
* rejects them by returning false. Before accepting, the
* application may also adjust the parameters to better suit
* its needs.
*
* It is recommended for an application to have just one of these
* callbacks for simplicity. However, if an application registers
* multiple it needs to manage the potentially different
* requirements for each callback. Each callback gets the
* parameters as returned by previous callbacks, i.e. they are not
* necessarily the same ones as the remote originally sent.
*
* @param conn Connection object.
* @param param Proposed connection parameters.
*
* @return true to accept the parameters, or false to reject them.
*/
bool (*le_param_req)(struct bt_conn *conn,
struct bt_le_conn_param *param);
/** @brief The parameters for an LE connection have been updated.
*
* This callback notifies the application that the connection
* parameters for an LE connection have been updated.
*
* @param conn Connection object.
* @param interval Connection interval.
* @param latency Connection latency.
* @param timeout Connection supervision timeout.
*/
void (*le_param_updated)(struct bt_conn *conn, u16_t interval,
u16_t latency, u16_t timeout);
#if defined(CONFIG_BT_SMP)
/** @brief Remote Identity Address has been resolved.
*
* This callback notifies the application that a remote
* Identity Address has been resolved
*
* @param conn Connection object.
* @param rpa Resolvable Private Address.
* @param identity Identity Address.
*/
void (*identity_resolved)(struct bt_conn *conn,
const bt_addr_le_t *rpa,
const bt_addr_le_t *identity);
#endif /* CONFIG_BT_SMP */
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
/** @brief The security level of a connection has changed.
*
* This callback notifies the application that the security level
* of a connection has changed.
*
* @param conn Connection object.
* @param level New security level of the connection.
*/
void (*security_changed)(struct bt_conn *conn, bt_security_t level);
#endif /* defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR) */
struct bt_conn_cb *_next;
};
#if CONFIG_BT_MESH_PROVISIONER
struct bt_prov_conn_cb {
void (*connected)(const u8_t addr[6], struct bt_conn *conn, int id);
void (*disconnected)(struct bt_conn *conn, u8_t reason);
ssize_t (*prov_write_descr)(struct bt_conn *conn, u8_t *addr);
ssize_t (*prov_notify)(struct bt_conn *conn, u8_t *data, u16_t len);
ssize_t (*proxy_write_descr)(struct bt_conn *conn);
ssize_t (*proxy_notify)(struct bt_conn *conn, u8_t *data, u16_t len);
bool (*le_param_req)(struct bt_conn *conn, struct bt_le_conn_param *param);
void (*le_param_updated)(struct bt_conn *conn, u16_t interval,
u16_t latency, u16_t timeout);
#if defined(CONFIG_BT_SMP)
void (*identity_resolved)(struct bt_conn *conn,
const bt_addr_le_t *rpa,
const bt_addr_le_t *identity);
#endif /* CONFIG_BT_SMP */
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
void (*security_changed)(struct bt_conn *conn, bt_security_t level);
#endif /* defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR) */
struct bt_conn_cb *_next;
};
#endif /* CONFIG_BT_MESH_PROVISIONER */
/** @brief GATT Attribute structure. */
struct bt_gatt_attr {
/** Attribute UUID */
const struct bt_uuid *uuid;
/** Attribute read callback
*
* @param conn The connection that is requesting to read
* @param attr The attribute that's being read
* @param buf Buffer to place the read result in
* @param len Length of data to read
* @param offset Offset to start reading from
*
* @return Number fo bytes read, or in case of an error
* BT_GATT_ERR() with a specific ATT error code.
*/
ssize_t (*read)(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
void *buf, u16_t len,
u16_t offset);
/** Attribute write callback
*
* @param conn The connection that is requesting to write
* @param attr The attribute that's being written
* @param buf Buffer with the data to write
* @param len Number of bytes in the buffer
* @param offset Offset to start writing from
* @param flags Flags (BT_GATT_WRITE_*)
*
* @return Number of bytes written, or in case of an error
* BT_GATT_ERR() with a specific ATT error code.
*/
ssize_t (*write)(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
const void *buf, u16_t len,
u16_t offset, u8_t flags);
/** Attribute user data */
void *user_data;
/** Attribute handle */
u16_t handle;
/** Attribute permissions */
u8_t perm;
};
/** @def BT_GATT_PRIMARY_SERVICE
* @brief Primary Service Declaration Macro.
*
* Helper macro to declare a primary service attribute.
*
* @param _service Service attribute value.
*/
#define BT_GATT_PRIMARY_SERVICE(_service) \
{ \
.uuid = BT_UUID_GATT_PRIMARY, \
.perm = BT_GATT_PERM_READ, \
.read = bt_mesh_gatts_attr_read_service, \
.user_data = _service, \
}
/** @def BT_GATT_SECONDARY_SERVICE
* @brief Secondary Service Declaration Macro.
*
* Helper macro to declare a secondary service attribute.
*
* @param _service Service attribute value.
*/
#define BT_GATT_SECONDARY_SERVICE(_service) \
{ \
.uuid = BT_UUID_GATT_SECONDARY, \
.perm = BT_GATT_PERM_READ, \
.read = bt_mesh_gatts_attr_read_service, \
.user_data = _service, \
}
/** @def BT_GATT_INCLUDE_SERVICE
* @brief Include Service Declaration Macro.
*
* Helper macro to declare database internal include service attribute.
*
* @param _service_incl the first service attribute of service to include
*/
#define BT_GATT_INCLUDE_SERVICE(_service_incl) \
{ \
.uuid = BT_UUID_GATT_INCLUDE, \
.perm = BT_GATT_PERM_READ, \
.read = bt_mesh_gatts_attr_read_included, \
.user_data = _service_incl, \
}
/** @def BT_GATT_CHARACTERISTIC
* @brief Characteristic Declaration Macro.
*
* Helper macro to declare a characteristic attribute.
*
* @param _uuid Characteristic attribute uuid.
* @param _props Characteristic attribute properties.
*/
#define BT_GATT_CHARACTERISTIC(_uuid, _props) \
{ \
.uuid = BT_UUID_GATT_CHRC, \
.perm = BT_GATT_PERM_READ, \
.read = bt_mesh_gatts_attr_read_chrc, \
.user_data = (&(struct bt_gatt_chrc) { .uuid = _uuid, \
.properties = _props, }),\
}
/** @def BT_GATT_DESCRIPTOR
* @brief Descriptor Declaration Macro.
*
* Helper macro to declare a descriptor attribute.
*
* @param _uuid Descriptor attribute uuid.
* @param _perm Descriptor attribute access permissions.
* @param _read Descriptor attribute read callback.
* @param _write Descriptor attribute write callback.
* @param _value Descriptor attribute value.
*/
#define BT_GATT_DESCRIPTOR(_uuid, _perm, _read, _write, _value) \
{ \
.uuid = _uuid, \
.perm = _perm, \
.read = _read, \
.write = _write, \
.user_data = _value, \
}
/** @def BT_GATT_SERVICE
* @brief Service Structure Declaration Macro.
*
* Helper macro to declare a service structure.
*
* @param _attrs Service attributes.
*/
#define BT_GATT_SERVICE(_attrs) \
{ \
.attrs = _attrs, \
.attr_count = ARRAY_SIZE(_attrs), \
}
/* @brief Container for public key callback */
struct bt_pub_key_cb {
/** @brief Callback type for Public Key generation.
*
* Used to notify of the local public key or that the local key is not
* available (either because of a failure to read it or because it is
* being regenerated).
*
* @param key The local public key, or NULL in case of no key.
*/
void (*func)(const u8_t key[64]);
struct bt_pub_key_cb *_next;
};
int bt_le_adv_start(const struct bt_le_adv_param *param,
const struct bt_data *ad, size_t ad_len,
const struct bt_data *sd, size_t sd_len);
int bt_le_adv_stop(void);
int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb);
int bt_le_scan_stop(void);
void bt_mesh_gatts_conn_cb_register(struct bt_conn_cb *cb);
int bt_mesh_gatts_disconnect(struct bt_conn *conn, u8_t reason);
int bt_mesh_gatts_service_register(struct bt_gatt_service *svc);
int bt_mesh_gatts_service_unregister(struct bt_gatt_service *svc);
ssize_t bt_mesh_gatts_attr_read_included(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
void *buf, u16_t len, u16_t offset);
ssize_t bt_mesh_gatts_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, u16_t buf_len, u16_t offset,
const void *value, u16_t value_len);
ssize_t bt_mesh_gatts_attr_read_service(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
void *buf, u16_t len, u16_t offset);
ssize_t bt_mesh_gatts_attr_read_chrc(struct bt_conn *conn,
const struct bt_gatt_attr *attr, void *buf,
u16_t len, u16_t offset);
int bt_mesh_gatts_notify(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *data, u16_t len);
u16_t bt_mesh_gatt_get_mtu(struct bt_conn *conn);
/** APIs added by Espressif */
int bt_mesh_gatts_service_stop(struct bt_gatt_service *svc);
int bt_mesh_gatts_service_start(struct bt_gatt_service *svc);
#if CONFIG_BT_MESH_PROVISIONER
void bt_mesh_gattc_conn_cb_register(struct bt_prov_conn_cb *cb);
u16_t bt_mesh_gattc_get_service_uuid(struct bt_conn *conn);
int bt_mesh_gattc_conn_create(const bt_addr_le_t *addr, u16_t service_uuid);
void bt_gattc_conn_close(struct bt_conn *conn);
void bt_mesh_gattc_exchange_mtu(u8_t index);
u16_t bt_mesh_gattc_get_mtu_info(struct bt_conn *conn);
int bt_mesh_gattc_write_no_rsp(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *data, u16_t len);
void bt_mesh_gattc_disconnect(struct bt_conn *conn);
#endif /* CONFIG_BT_MESH_PROVISIONER */
struct bt_conn *bt_mesh_conn_ref(struct bt_conn *conn);
void bt_mesh_conn_unref(struct bt_conn *conn);
void bt_mesh_gatt_init(void);
void bt_mesh_adapt_init(void);
int bt_mesh_rand(void *buf, size_t len);
void bt_mesh_set_private_key(const u8_t pri_key[32]);
const u8_t *bt_mesh_pub_key_get(void);
bool bt_mesh_check_public_key(const uint8_t key[64]);
int bt_mesh_dh_key_gen(const u8_t remote_pk[64], bt_dh_key_cb_t cb);
int bt_encrypt_le(const u8_t key[16], const u8_t plaintext[16],
u8_t enc_data[16]);
int bt_encrypt_be(const u8_t key[16], const u8_t plaintext[16],
u8_t enc_data[16]);
#endif /* #ifndef __MESH_BEARER_ADRPT_H__ */

View File

@@ -0,0 +1,580 @@
/** @file
* @brief Bluetooth UUID handling
*/
/*
* Copyright (c) 2015-2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_UUID_H
#define __BT_UUID_H
/**
* @brief UUIDs
* @defgroup bt_uuid UUIDs
* @ingroup bluetooth
* @{
*/
#include "mesh_util.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Bluetooth UUID types */
enum {
BT_UUID_TYPE_16,
BT_UUID_TYPE_32,
BT_UUID_TYPE_128,
};
/** @brief This is a 'tentative' type and should be used as a pointer only */
struct bt_uuid {
u8_t type;
};
struct bt_uuid_16 {
struct bt_uuid uuid;
u16_t val;
};
struct bt_uuid_32 {
struct bt_uuid uuid;
u32_t val;
};
struct bt_uuid_128 {
struct bt_uuid uuid;
u8_t val[16];
};
#define BT_UUID_INIT_16(value) \
{ \
.uuid.type = BT_UUID_TYPE_16, \
.val = (value), \
}
#define BT_UUID_INIT_32(value) \
{ \
.uuid.type = BT_UUID_TYPE_32, \
.val = (value), \
}
#define BT_UUID_INIT_128(value...) \
{ \
.uuid.type = BT_UUID_TYPE_128, \
.val = { value }, \
}
#define BT_UUID_DECLARE_16(value) \
((struct bt_uuid *) (&(struct bt_uuid_16) BT_UUID_INIT_16(value)))
#define BT_UUID_DECLARE_32(value) \
((struct bt_uuid *) (&(struct bt_uuid_32) BT_UUID_INIT_32(value)))
#define BT_UUID_DECLARE_128(value...) \
((struct bt_uuid *) (&(struct bt_uuid_128) BT_UUID_INIT_128(value)))
#define BT_UUID_16(__u) CONTAINER_OF(__u, struct bt_uuid_16, uuid)
#define BT_UUID_32(__u) CONTAINER_OF(__u, struct bt_uuid_32, uuid)
#define BT_UUID_128(__u) CONTAINER_OF(__u, struct bt_uuid_128, uuid)
/** @def BT_UUID_GAP
* @brief Generic Access
*/
#define BT_UUID_GAP BT_UUID_DECLARE_16(0x1800)
#define BT_UUID_GAP_VAL 0x1800
/** @def BT_UUID_GATT
* @brief Generic Attribute
*/
#define BT_UUID_GATT BT_UUID_DECLARE_16(0x1801)
#define BT_UUID_GATT_VAL 0x1801
/** @def BT_UUID_CTS
* @brief Current Time Service
*/
#define BT_UUID_CTS BT_UUID_DECLARE_16(0x1805)
#define BT_UUID_CTS_VAL 0x1805
/** @def BT_UUID_DIS
* @brief Device Information Service
*/
#define BT_UUID_DIS BT_UUID_DECLARE_16(0x180a)
#define BT_UUID_DIS_VAL 0x180a
/** @def BT_UUID_HRS
* @brief Heart Rate Service
*/
#define BT_UUID_HRS BT_UUID_DECLARE_16(0x180d)
#define BT_UUID_HRS_VAL 0x180d
/** @def BT_UUID_BAS
* @brief Battery Service
*/
#define BT_UUID_BAS BT_UUID_DECLARE_16(0x180f)
#define BT_UUID_BAS_VAL 0x180f
/** @def BT_UUID_HIDS
* @brief HID Service
*/
#define BT_UUID_HIDS BT_UUID_DECLARE_16(0x1812)
#define BT_UUID_HIDS_VAL 0x1812
/** @def BT_UUID_CSC
* @brief Cycling Speed and Cadence Service
*/
#define BT_UUID_CSC BT_UUID_DECLARE_16(0x1816)
#define BT_UUID_CSC_VAL 0x1816
/** @def BT_UUID_ESS
* @brief Environmental Sensing Service
*/
#define BT_UUID_ESS BT_UUID_DECLARE_16(0x181a)
#define BT_UUID_ESS_VAL 0x181a
/** @def BT_UUID_IPSS
* @brief IP Support Service
*/
#define BT_UUID_IPSS BT_UUID_DECLARE_16(0x1820)
#define BT_UUID_IPSS_VAL 0x1820
/** @def BT_UUID_MESH_PROV
* @brief Mesh Provisioning Service
*/
#define BT_UUID_MESH_PROV BT_UUID_DECLARE_16(0x1827)
#define BT_UUID_MESH_PROV_VAL 0x1827
/** @def BT_UUID_MESH_PROXY
* @brief Mesh Proxy Service
*/
#define BT_UUID_MESH_PROXY BT_UUID_DECLARE_16(0x1828)
#define BT_UUID_MESH_PROXY_VAL 0x1828
/** @def BT_UUID_GATT_PRIMARY
* @brief GATT Primary Service
*/
#define BT_UUID_GATT_PRIMARY BT_UUID_DECLARE_16(0x2800)
#define BT_UUID_GATT_PRIMARY_VAL 0x2800
/** @def BT_UUID_GATT_SECONDARY
* @brief GATT Secondary Service
*/
#define BT_UUID_GATT_SECONDARY BT_UUID_DECLARE_16(0x2801)
#define BT_UUID_GATT_SECONDARY_VAL 0x2801
/** @def BT_UUID_GATT_INCLUDE
* @brief GATT Include Service
*/
#define BT_UUID_GATT_INCLUDE BT_UUID_DECLARE_16(0x2802)
#define BT_UUID_GATT_INCLUDE_VAL 0x2802
/** @def BT_UUID_GATT_CHRC
* @brief GATT Characteristic
*/
#define BT_UUID_GATT_CHRC BT_UUID_DECLARE_16(0x2803)
#define BT_UUID_GATT_CHRC_VAL 0x2803
/** @def BT_UUID_GATT_CEP
* @brief GATT Characteristic Extended Properties
*/
#define BT_UUID_GATT_CEP BT_UUID_DECLARE_16(0x2900)
#define BT_UUID_GATT_CEP_VAL 0x2900
/** @def BT_UUID_GATT_CUD
* @brief GATT Characteristic User Description
*/
#define BT_UUID_GATT_CUD BT_UUID_DECLARE_16(0x2901)
#define BT_UUID_GATT_CUD_VAL 0x2901
/** @def BT_UUID_GATT_CCC
* @brief GATT Client Characteristic Configuration
*/
#define BT_UUID_GATT_CCC BT_UUID_DECLARE_16(0x2902)
#define BT_UUID_GATT_CCC_VAL 0x2902
/** @def BT_UUID_GATT_SCC
* @brief GATT Server Characteristic Configuration
*/
#define BT_UUID_GATT_SCC BT_UUID_DECLARE_16(0x2903)
#define BT_UUID_GATT_SCC_VAL 0x2903
/** @def BT_UUID_GATT_CPF
* @brief GATT Characteristic Presentation Format
*/
#define BT_UUID_GATT_CPF BT_UUID_DECLARE_16(0x2904)
#define BT_UUID_GATT_CPF_VAL 0x2904
/** @def BT_UUID_VALID_RANGE
* @brief Valid Range Descriptor
*/
#define BT_UUID_VALID_RANGE BT_UUID_DECLARE_16(0x2906)
#define BT_UUID_VALID_RANGE_VAL 0x2906
/** @def BT_UUID_HIDS_EXT_REPORT
* @brief HID External Report Descriptor
*/
#define BT_UUID_HIDS_EXT_REPORT BT_UUID_DECLARE_16(0x2907)
#define BT_UUID_HIDS_EXT_REPORT_VAL 0x2907
/** @def BT_UUID_HIDS_REPORT_REF
* @brief HID Report Reference Descriptor
*/
#define BT_UUID_HIDS_REPORT_REF BT_UUID_DECLARE_16(0x2908)
#define BT_UUID_HIDS_REPORT_REF_VAL 0x2908
/** @def BT_UUID_ES_CONFIGURATION
* @brief Environmental Sensing Configuration Descriptor
*/
#define BT_UUID_ES_CONFIGURATION BT_UUID_DECLARE_16(0x290b)
#define BT_UUID_ES_CONFIGURATION_VAL 0x290b
/** @def BT_UUID_ES_MEASUREMENT
* @brief Environmental Sensing Measurement Descriptor
*/
#define BT_UUID_ES_MEASUREMENT BT_UUID_DECLARE_16(0x290c)
#define BT_UUID_ES_MEASUREMENT_VAL 0x290c
/** @def BT_UUID_ES_TRIGGER_SETTING
* @brief Environmental Sensing Trigger Setting Descriptor
*/
#define BT_UUID_ES_TRIGGER_SETTING BT_UUID_DECLARE_16(0x290d)
#define BT_UUID_ES_TRIGGER_SETTING_VAL 0x290d
/** @def BT_UUID_GAP_DEVICE_NAME
* @brief GAP Characteristic Device Name
*/
#define BT_UUID_GAP_DEVICE_NAME BT_UUID_DECLARE_16(0x2a00)
#define BT_UUID_GAP_DEVICE_NAME_VAL 0x2a00
/** @def BT_UUID_GAP_APPEARANCE
* @brief GAP Characteristic Appearance
*/
#define BT_UUID_GAP_APPEARANCE BT_UUID_DECLARE_16(0x2a01)
#define BT_UUID_GAP_APPEARANCE_VAL 0x2a01
/** @def BT_UUID_GAP_PPCP
* @brief GAP Characteristic Peripheral Preferred Connection Parameters
*/
#define BT_UUID_GAP_PPCP BT_UUID_DECLARE_16(0x2a04)
#define BT_UUID_GAP_PPCP_VAL 0x2a04
/** @def BT_UUID_GATT_SC
* @brief GATT Characteristic Service Changed
*/
#define BT_UUID_GATT_SC BT_UUID_DECLARE_16(0x2a05)
#define BT_UUID_GATT_SC_VAL 0x2a05
/** @def BT_UUID_BAS_BATTERY_LEVEL
* @brief BAS Characteristic Battery Level
*/
#define BT_UUID_BAS_BATTERY_LEVEL BT_UUID_DECLARE_16(0x2a19)
#define BT_UUID_BAS_BATTERY_LEVEL_VAL 0x2a19
/** @def BT_UUID_DIS_SYSTEM_ID
* @brief DIS Characteristic System ID
*/
#define BT_UUID_DIS_SYSTEM_ID BT_UUID_DECLARE_16(0x2a23)
#define BT_UUID_DIS_SYSTEM_ID_VAL 0x2a23
/** @def BT_UUID_DIS_MODEL_NUMBER
* @brief DIS Characteristic Model Number String
*/
#define BT_UUID_DIS_MODEL_NUMBER BT_UUID_DECLARE_16(0x2a24)
#define BT_UUID_DIS_MODEL_NUMBER_VAL 0x2a24
/** @def BT_UUID_DIS_SERIAL_NUMBER
* @brief DIS Characteristic Serial Number String
*/
#define BT_UUID_DIS_SERIAL_NUMBER BT_UUID_DECLARE_16(0x2a25)
#define BT_UUID_DIS_SERIAL_NUMBER_VAL 0x2a25
/** @def BT_UUID_DIS_FIRMWARE_REVISION
* @brief DIS Characteristic Firmware Revision String
*/
#define BT_UUID_DIS_FIRMWARE_REVISION BT_UUID_DECLARE_16(0x2a26)
#define BT_UUID_DIS_FIRMWARE_REVISION_VAL 0x2a26
/** @def BT_UUID_DIS_HARDWARE_REVISION
* @brief DIS Characteristic Hardware Revision String
*/
#define BT_UUID_DIS_HARDWARE_REVISION BT_UUID_DECLARE_16(0x2a27)
#define BT_UUID_DIS_HARDWARE_REVISION_VAL 0x2a27
/** @def BT_UUID_DIS_SOFTWARE_REVISION
* @brief DIS Characteristic Software Revision String
*/
#define BT_UUID_DIS_SOFTWARE_REVISION BT_UUID_DECLARE_16(0x2a28)
#define BT_UUID_DIS_SOFTWARE_REVISION_VAL 0x2a28
/** @def BT_UUID_DIS_MANUFACTURER_NAME
* @brief DIS Characteristic Manufacturer Name String
*/
#define BT_UUID_DIS_MANUFACTURER_NAME BT_UUID_DECLARE_16(0x2a29)
#define BT_UUID_DIS_MANUFACTURER_NAME_VAL 0x2a29
/** @def BT_UUID_DIS_PNP_ID
* @brief DIS Characteristic PnP ID
*/
#define BT_UUID_DIS_PNP_ID BT_UUID_DECLARE_16(0x2a50)
#define BT_UUID_DIS_PNP_ID_VAL 0x2a50
/** @def BT_UUID_CTS_CURRENT_TIME
* @brief CTS Characteristic Current Time
*/
#define BT_UUID_CTS_CURRENT_TIME BT_UUID_DECLARE_16(0x2a2b)
#define BT_UUID_CTS_CURRENT_TIME_VAL 0x2a2b
/** @def BT_UUID_MAGN_DECLINATION
* @brief Magnetic Declination Characteristic
*/
#define BT_UUID_MAGN_DECLINATION BT_UUID_DECLARE_16(0x2a2c)
#define BT_UUID_MAGN_DECLINATION_VAL 0x2a2c
/** @def BT_UUID_HRS_MEASUREMENT
* @brief HRS Characteristic Measurement Interval
*/
#define BT_UUID_HRS_MEASUREMENT BT_UUID_DECLARE_16(0x2a37)
#define BT_UUID_HRS_MEASUREMENT_VAL 0x2a37
/** @def BT_UUID_HRS_BODY_SENSOR
* @brief HRS Characteristic Body Sensor Location
*/
#define BT_UUID_HRS_BODY_SENSOR BT_UUID_DECLARE_16(0x2a38)
#define BT_UUID_HRS_BODY_SENSOR_VAL 0x2a38
/** @def BT_UUID_HRS_CONTROL_POINT
* @brief HRS Characteristic Control Point
*/
#define BT_UUID_HRS_CONTROL_POINT BT_UUID_DECLARE_16(0x2a39)
#define BT_UUID_HRS_CONTROL_POINT_VAL 0x2a39
/** @def BT_UUID_HIDS_INFO
* @brief HID Information Characteristic
*/
#define BT_UUID_HIDS_INFO BT_UUID_DECLARE_16(0x2a4a)
#define BT_UUID_HIDS_INFO_VAL 0x2a4a
/** @def BT_UUID_HIDS_REPORT_MAP
* @brief HID Report Map Characteristic
*/
#define BT_UUID_HIDS_REPORT_MAP BT_UUID_DECLARE_16(0x2a4b)
#define BT_UUID_HIDS_REPORT_MAP_VAL 0x2a4b
/** @def BT_UUID_HIDS_CTRL_POINT
* @brief HID Control Point Characteristic
*/
#define BT_UUID_HIDS_CTRL_POINT BT_UUID_DECLARE_16(0x2a4c)
#define BT_UUID_HIDS_CTRL_POINT_VAL 0x2a4c
/** @def BT_UUID_HIDS_REPORT
* @brief HID Report Characteristic
*/
#define BT_UUID_HIDS_REPORT BT_UUID_DECLARE_16(0x2a4d)
#define BT_UUID_HIDS_REPORT_VAL 0x2a4d
/** @def BT_UUID_CSC_MEASUREMENT
* @brief CSC Measurement Characteristic
*/
#define BT_UUID_CSC_MEASUREMENT BT_UUID_DECLARE_16(0x2a5b)
#define BT_UUID_CSC_MEASUREMENT_VAL 0x2a5b
/** @def BT_UUID_CSC_FEATURE
* @brief CSC Feature Characteristic
*/
#define BT_UUID_CSC_FEATURE BT_UUID_DECLARE_16(0x2a5c)
#define BT_UUID_CSC_FEATURE_VAL 0x2a5c
/** @def BT_UUID_SENSOR_LOCATION
* @brief Sensor Location Characteristic
*/
#define BT_UUID_SENSOR_LOCATION BT_UUID_DECLARE_16(0x2a5d)
#define BT_UUID_SENSOR_LOCATION_VAL 0x2a5d
/** @def BT_UUID_SC_CONTROL_POINT
* @brief SC Control Point Characteristic
*/
#define BT_UUID_SC_CONTROL_POINT BT_UUID_DECLARE_16(0x2a55)
#define BT_UUID_SC_CONTROL_POINT_VAl 0x2a55
/** @def BT_UUID_ELEVATION
* @brief Elevation Characteristic
*/
#define BT_UUID_ELEVATION BT_UUID_DECLARE_16(0x2a6c)
#define BT_UUID_ELEVATION_VAL 0x2a6c
/** @def BT_UUID_PRESSURE
* @brief Pressure Characteristic
*/
#define BT_UUID_PRESSURE BT_UUID_DECLARE_16(0x2a6d)
#define BT_UUID_PRESSURE_VAL 0x2a6d
/** @def BT_UUID_TEMPERATURE
* @brief Temperature Characteristic
*/
#define BT_UUID_TEMPERATURE BT_UUID_DECLARE_16(0x2a6e)
#define BT_UUID_TEMPERATURE_VAL 0x2a6e
/** @def BT_UUID_HUMIDITY
* @brief Humidity Characteristic
*/
#define BT_UUID_HUMIDITY BT_UUID_DECLARE_16(0x2a6f)
#define BT_UUID_HUMIDITY_VAL 0x2a6f
/** @def BT_UUID_TRUE_WIND_SPEED
* @brief True Wind Speed Characteristic
*/
#define BT_UUID_TRUE_WIND_SPEED BT_UUID_DECLARE_16(0x2a70)
#define BT_UUID_TRUE_WIND_SPEED_VAL 0x2a70
/** @def BT_UUID_TRUE_WIND_DIR
* @brief True Wind Direction Characteristic
*/
#define BT_UUID_TRUE_WIND_DIR BT_UUID_DECLARE_16(0x2a71)
#define BT_UUID_TRUE_WIND_DIR_VAL 0x2a71
/** @def BT_UUID_APPARENT_WIND_SPEED
* @brief Apparent Wind Speed Characteristic
*/
#define BT_UUID_APPARENT_WIND_SPEED BT_UUID_DECLARE_16(0x2a72)
#define BT_UUID_APPARENT_WIND_SPEED_VAL 0x2a72
/** @def BT_UUID_APPARENT_WIND_DIR
* @brief Apparent Wind Direction Characteristic
*/
#define BT_UUID_APPARENT_WIND_DIR BT_UUID_DECLARE_16(0x2a73)
#define BT_UUID_APPARENT_WIND_DIR_VAL 0x2a73
/** @def BT_UUID_GUST_FACTOR
* @brief Gust Factor Characteristic
*/
#define BT_UUID_GUST_FACTOR BT_UUID_DECLARE_16(0x2a74)
#define BT_UUID_GUST_FACTOR_VAL 0x2a74
/** @def BT_UUID_POLLEN_CONCENTRATION
* @brief Pollen Concentration Characteristic
*/
#define BT_UUID_POLLEN_CONCENTRATION BT_UUID_DECLARE_16(0x2a75)
#define BT_UUID_POLLEN_CONCENTRATION_VAL 0x2a75
/** @def BT_UUID_UV_INDEX
* @brief UV Index Characteristic
*/
#define BT_UUID_UV_INDEX BT_UUID_DECLARE_16(0x2a76)
#define BT_UUID_UV_INDEX_VAL 0x2a76
/** @def BT_UUID_IRRADIANCE
* @brief Irradiance Characteristic
*/
#define BT_UUID_IRRADIANCE BT_UUID_DECLARE_16(0x2a77)
#define BT_UUID_IRRADIANCE_VAL 0x2a77
/** @def BT_UUID_RAINFALL
* @brief Rainfall Characteristic
*/
#define BT_UUID_RAINFALL BT_UUID_DECLARE_16(0x2a78)
#define BT_UUID_RAINFALL_VAL 0x2a78
/** @def BT_UUID_WIND_CHILL
* @brief Wind Chill Characteristic
*/
#define BT_UUID_WIND_CHILL BT_UUID_DECLARE_16(0x2a79)
#define BT_UUID_WIND_CHILL_VAL 0x2a79
/** @def BT_UUID_HEAT_INDEX
* @brief Heat Index Characteristic
*/
#define BT_UUID_HEAT_INDEX BT_UUID_DECLARE_16(0x2a7a)
#define BT_UUID_HEAT_INDEX_VAL 0x2a7a
/** @def BT_UUID_DEW_POINT
* @brief Dew Point Characteristic
*/
#define BT_UUID_DEW_POINT BT_UUID_DECLARE_16(0x2a7b)
#define BT_UUID_DEW_POINT_VAL 0x2a7b
/** @def BT_UUID_DESC_VALUE_CHANGED
* @brief Descriptor Value Changed Characteristic
*/
#define BT_UUID_DESC_VALUE_CHANGED BT_UUID_DECLARE_16(0x2a7d)
#define BT_UUID_DESC_VALUE_CHANGED_VAL 0x2a7d
/** @def BT_UUID_MAGN_FLUX_DENSITY_2D
* @brief Magnetic Flux Density - 2D Characteristic
*/
#define BT_UUID_MAGN_FLUX_DENSITY_2D BT_UUID_DECLARE_16(0x2aa0)
#define BT_UUID_MAGN_FLUX_DENSITY_2D_VAL 0x2aa0
/** @def BT_UUID_MAGN_FLUX_DENSITY_3D
* @brief Magnetic Flux Density - 3D Characteristic
*/
#define BT_UUID_MAGN_FLUX_DENSITY_3D BT_UUID_DECLARE_16(0x2aa1)
#define BT_UUID_MAGN_FLUX_DENSITY_3D_VAL 0x2aa1
/** @def BT_UUID_BAR_PRESSURE_TREND
* @brief Barometric Pressure Trend Characteristic
*/
#define BT_UUID_BAR_PRESSURE_TREND BT_UUID_DECLARE_16(0x2aa3)
#define BT_UUID_BAR_PRESSURE_TREND_VAL 0x2aa3
/** @def BT_UUID_MESH_PROV_DATA_IN
* @brief Mesh Provisioning Data In
*/
#define BT_UUID_MESH_PROV_DATA_IN BT_UUID_DECLARE_16(0x2adb)
#define BT_UUID_MESH_PROV_DATA_IN_VAL 0x2adb
/** @def BT_UUID_MESH_PROV_DATA_OUT
* @brief Mesh Provisioning Data Out
*/
#define BT_UUID_MESH_PROV_DATA_OUT BT_UUID_DECLARE_16(0x2adc)
#define BT_UUID_MESH_PROV_DATA_OUT_VAL 0x2adc
/** @def BT_UUID_MESH_PROXY_DATA_IN
* @brief Mesh Proxy Data In
*/
#define BT_UUID_MESH_PROXY_DATA_IN BT_UUID_DECLARE_16(0x2add)
#define BT_UUID_MESH_PROXY_DATA_IN_VAL 0x2add
/** @def BT_UUID_MESH_PROXY_DATA_OUT
* @brief Mesh Proxy Data Out
*/
#define BT_UUID_MESH_PROXY_DATA_OUT BT_UUID_DECLARE_16(0x2ade)
#define BT_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade
/*
* Protocol UUIDs
*/
#define BT_UUID_SDP BT_UUID_DECLARE_16(0x0001)
#define BT_UUID_SDP_VAL 0x0001
#define BT_UUID_UDP BT_UUID_DECLARE_16(0x0002)
#define BT_UUID_UDP_VAL 0x0002
#define BT_UUID_RFCOMM BT_UUID_DECLARE_16(0x0003)
#define BT_UUID_RFCOMM_VAL 0x0003
#define BT_UUID_TCP BT_UUID_DECLARE_16(0x0004)
#define BT_UUID_TCP_VAL 0x0004
#define BT_UUID_TCS_BIN BT_UUID_DECLARE_16(0x0005)
#define BT_UUID_TCS_BIN_VAL 0x0005
#define BT_UUID_TCS_AT BT_UUID_DECLARE_16(0x0006)
#define BT_UUID_TCS_AT_VAL 0x0006
#define BT_UUID_ATT BT_UUID_DECLARE_16(0x0007)
#define BT_UUID_ATT_VAL 0x0007
#define BT_UUID_OBEX BT_UUID_DECLARE_16(0x0008)
#define BT_UUID_OBEX_VAL 0x0008
#define BT_UUID_IP BT_UUID_DECLARE_16(0x0009)
#define BT_UUID_IP_VAL 0x0009
#define BT_UUID_FTP BT_UUID_DECLARE_16(0x000a)
#define BT_UUID_FTP_VAL 0x000a
#define BT_UUID_HTTP BT_UUID_DECLARE_16(0x000c)
#define BT_UUID_HTTP_VAL 0x000c
#define BT_UUID_BNEP BT_UUID_DECLARE_16(0x000f)
#define BT_UUID_BNEP_VAL 0x000f
#define BT_UUID_UPNP BT_UUID_DECLARE_16(0x0010)
#define BT_UUID_UPNP_VAL 0x0010
#define BT_UUID_HIDP BT_UUID_DECLARE_16(0x0011)
#define BT_UUID_HIDP_VAL 0x0011
#define BT_UUID_HCRP_CTRL BT_UUID_DECLARE_16(0x0012)
#define BT_UUID_HCRP_CTRL_VAL 0x0012
#define BT_UUID_HCRP_DATA BT_UUID_DECLARE_16(0x0014)
#define BT_UUID_HCRP_DATA_VAL 0x0014
#define BT_UUID_HCRP_NOTE BT_UUID_DECLARE_16(0x0016)
#define BT_UUID_HCRP_NOTE_VAL 0x0016
#define BT_UUID_AVCTP BT_UUID_DECLARE_16(0x0017)
#define BT_UUID_AVCTP_VAL 0x0017
#define BT_UUID_AVDTP BT_UUID_DECLARE_16(0x0019)
#define BT_UUID_AVDTP_VAL 0x0019
#define BT_UUID_CMTP BT_UUID_DECLARE_16(0x001b)
#define BT_UUID_CMTP_VAL 0x001b
#define BT_UUID_UDI BT_UUID_DECLARE_16(0x001d)
#define BT_UUID_UDI_VAL 0x001d
#define BT_UUID_MCAP_CTRL BT_UUID_DECLARE_16(0x001e)
#define BT_UUID_MCAP_CTRL_VAL 0x001e
#define BT_UUID_MCAP_DATA BT_UUID_DECLARE_16(0x001f)
#define BT_UUID_MCAP_DATA_VAL 0x001f
#define BT_UUID_L2CAP BT_UUID_DECLARE_16(0x0100)
#define BT_UUID_L2CAP_VAL 0x0100
/** @brief Compare Bluetooth UUIDs.
*
* Compares 2 Bluetooth UUIDs, if the types are different both UUIDs are
* first converted to 128 bits format before comparing.
*
* @param u1 First Bluetooth UUID to compare
* @param u2 Second Bluetooth UUID to compare
*
* @return negative value if @a u1 < @a u2, 0 if @a u1 == @a u2, else positive
*/
int bt_uuid_cmp(const struct bt_uuid *u1, const struct bt_uuid *u2);
#if defined(CONFIG_BT_DEBUG)
/** @brief Convert Bluetooth UUID to string.
*
* Converts Bluetooth UUID to string. UUID has to be in 16 bits or 128 bits
* format.
*
* @param uuid Bluetooth UUID
* @param str pointer where to put converted string
* @param len length of str
*
* @return N/A
*/
void bt_uuid_to_str(const struct bt_uuid *uuid, char *str, size_t len);
/** @brief Convert Bluetooth UUID to string in place.
*
* Converts Bluetooth UUID to string in place. UUID has to be in 16 bits or
* 128 bits format.
*
* @param uuid Bluetooth UUID
*
* @return String representation of the UUID given
*/
const char *bt_uuid_str(const struct bt_uuid *uuid);
#else
static inline void bt_uuid_to_str(const struct bt_uuid *uuid, char *str,
size_t len)
{
if (len > 0) {
str[0] = '\0';
}
}
static inline const char *bt_uuid_str(const struct bt_uuid *uuid)
{
return "";
}
#endif /* CONFIG_BT_DEBUG */
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* __BT_UUID_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,239 @@
/*
* Copyright (c) 2015-2016 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __MESH_HCI_H
#define __MESH_HCI_H
#include "mesh_kernel.h"
#include "mesh_bearer_adapt.h"
#include "mesh_atomic.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Porting form zephyr/subsys/bluetooth/host/hci_core.h */
#if defined(CONFIG_BT_BREDR)
#define LMP_FEAT_PAGES_COUNT 3
#else
#define LMP_FEAT_PAGES_COUNT 1
#endif
/* bt_dev flags: the flags defined here represent BT controller state */
enum {
BT_DEV_ENABLE,
BT_DEV_READY,
BT_DEV_ID_STATIC_RANDOM,
BT_DEV_HAS_PUB_KEY,
BT_DEV_PUB_KEY_BUSY,
BT_DEV_ADVERTISING,
BT_DEV_KEEP_ADVERTISING,
BT_DEV_SCANNING,
BT_DEV_EXPLICIT_SCAN,
BT_DEV_ACTIVE_SCAN,
BT_DEV_SCAN_FILTER_DUP,
BT_DEV_RPA_VALID,
BT_DEV_ID_PENDING,
#if defined(CONFIG_BT_BREDR)
BT_DEV_ISCAN,
BT_DEV_PSCAN,
BT_DEV_INQUIRY,
#endif /* CONFIG_BT_BREDR */
/* Total number of flags - must be at the end of the enum */
BT_DEV_NUM_FLAGS,
};
struct bt_dev_le {
/* LE features */
u8_t features[8];
/* LE states */
u64_t states;
#if defined(CONFIG_BT_CONN)
/* Controller buffer information */
u16_t mtu;
struct k_sem pkts;
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_SMP)
/* Size of the the controller resolving list */
u8_t rl_size;
/* Number of entries in the resolving list. rl_entries > rl_size
* means that host-side resolving is used.
*/
u8_t rl_entries;
#endif /* CONFIG_BT_SMP */
};
#if defined(CONFIG_BT_BREDR)
struct bt_dev_br {
/* Max controller's acceptable ACL packet length */
u16_t mtu;
struct k_sem pkts;
u16_t esco_pkt_type;
};
#endif
/* The theoretical max for these is 8 and 64, but there's no point
* in allocating the full memory if we only support a small subset.
* These values must be updated whenever the host implementation is
* extended beyond the current values.
*/
#define BT_DEV_VS_FEAT_MAX 1
#define BT_DEV_VS_CMDS_MAX 2
/* State tracking for the local Bluetooth controller */
struct bt_dev {
/* Local Identity Address */
bt_addr_le_t id_addr;
/* Current local Random Address */
bt_addr_le_t random_addr;
/* Controller version & manufacturer information */
u8_t hci_version;
u8_t lmp_version;
u16_t hci_revision;
u16_t lmp_subversion;
u16_t manufacturer;
/* LMP features (pages 0, 1, 2) */
u8_t features[LMP_FEAT_PAGES_COUNT][8];
/* Supported commands */
u8_t supported_commands[64];
#if defined(CONFIG_BT_HCI_VS_EXT)
/* Vendor HCI support */
u8_t vs_features[BT_DEV_VS_FEAT_MAX];
u8_t vs_commands[BT_DEV_VS_CMDS_MAX];
#endif
#if 0
struct k_work init;
#endif /* if 0 */
ATOMIC_DEFINE(flags, BT_DEV_NUM_FLAGS);
/* LE controller specific features */
struct bt_dev_le le;
#if defined(CONFIG_BT_BREDR)
/* BR/EDR controller specific features */
struct bt_dev_br br;
#endif
#if 0
/* Number of commands controller can accept */
struct k_sem ncmd_sem;
/* Last sent HCI command */
struct net_buf *sent_cmd;
#endif /* if 0 */
#if !defined(CONFIG_BT_RECV_IS_RX_THREAD)
/* Queue for incoming HCI events & ACL data */
struct k_fifo rx_queue;
#endif
#if 0
/* Queue for high priority HCI events which may unlock waiters
* in other threads. Such events include Number of Completed
* Packets, as well as the Command Complete/Status events.
*/
struct k_fifo rx_prio_queue;
/* Queue for outgoing HCI commands */
struct k_fifo cmd_tx_queue;
/* Registered HCI driver */
const struct bt_hci_driver *drv;
#endif /* #if 0 */
#if defined(CONFIG_BT_PRIVACY)
/* Local Identity Resolving Key */
u8_t irk[16];
/* Work used for RPA rotation */
struct k_delayed_work rpa_update;
#endif
};
/* Added by Espressif */
extern struct bt_dev bt_dev;
void mesh_hci_init(void);
/*Porting from zephyr/subsys/bluetooth/host/hci_core.h */
/* HCI version from Assigned Numbers */
#define BT_HCI_VERSION_1_0B 0
#define BT_HCI_VERSION_1_1 1
#define BT_HCI_VERSION_1_2 2
#define BT_HCI_VERSION_2_0 3
#define BT_HCI_VERSION_2_1 4
#define BT_HCI_VERSION_3_0 5
#define BT_HCI_VERSION_4_0 6
#define BT_HCI_VERSION_4_1 7
#define BT_HCI_VERSION_4_2 8
#define BT_HCI_VERSION_5_0 9
/* OpCode Group Fields */
#define BT_OGF_LINK_CTRL 0x01
#define BT_OGF_BASEBAND 0x03
#define BT_OGF_INFO 0x04
#define BT_OGF_STATUS 0x05
#define BT_OGF_LE 0x08
#define BT_OGF_VS 0x3f
/* Construct OpCode from OGF and OCF */
#define BT_OP(ogf, ocf) ((ocf) | ((ogf) << 10))
/* Obtain OGF from OpCode */
#define BT_OGF(opcode) (((opcode) >> 10) & BIT_MASK(6))
/* Obtain OCF from OpCode */
#define BT_OCF(opcode) ((opcode) & BIT_MASK(10))
#define BT_HCI_OP_LE_SET_ADV_PARAM BT_OP(BT_OGF_LE, 0x0006)
struct bt_hci_cp_le_set_adv_param {
u16_t min_interval;
u16_t max_interval;
u8_t type;
u8_t own_addr_type;
bt_addr_le_t direct_addr;
u8_t channel_map;
u8_t filter_policy;
} __packed;
#define BT_HCI_OP_LE_SET_ADV_DATA BT_OP(BT_OGF_LE, 0x0008)
struct bt_hci_cp_le_set_adv_data {
u8_t len;
u8_t data[31];
} __packed;
#define BT_HCI_OP_LE_SET_SCAN_RSP_DATA BT_OP(BT_OGF_LE, 0x0009)
struct bt_hci_cp_le_set_scan_rsp_data {
u8_t len;
u8_t data[31];
} __packed;
#ifdef __cplusplus
}
#endif
#endif /* __MESH_HCI_H */

View File

@@ -0,0 +1,472 @@
/*
* Copyright (c) 2016, Wind River Systems, Inc.
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _MESH_KERNEL_
#define _MESH_KERNEL_
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "../../../bluedroid/osi/include/osi/mutex.h"
#include "mesh_types.h"
#include "mesh_slist.h"
#include "dlist.h"
#include "mesh_atomic.h"
typedef int atomic_t;
typedef atomic_t atomic_val_t;
/* number of nsec per usec */
#define NSEC_PER_USEC 1000
/* number of microseconds per millisecond */
#define USEC_PER_MSEC 1000
/* number of milliseconds per second */
#define MSEC_PER_SEC 1000
/* number of microseconds per second */
#define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC))
/* number of nanoseconds per second */
#define NSEC_PER_SEC ((NSEC_PER_USEC) * (USEC_PER_MSEC) * (MSEC_PER_SEC))
#define ATOMIC_MASK(bit) (1 << ((bit) & (ATOMIC_BITS - 1)))
#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS))
/* timeout is not in use */
#define _INACTIVE (-1)
/**
* @} end defgroup stack_apis
*/
struct k_work;
/**
* @typedef k_work_handler_t
* @brief Work item handler function type.
*
* A work item's handler function is executed by a workqueue's thread
* when the work item is processed by the workqueue.
*
* @param work Address of the work item.
*
* @return N/A
*/
typedef void (*k_work_handler_t)(struct k_work *work);
typedef sys_dlist_t _wait_q_t;
struct k_work {
void *_reserved; /* Used by k_queue implementation. */
k_work_handler_t handler;
atomic_t flags[1];
int index;
};
#define _K_WORK_INITIALIZER(work_handler) \
{ \
._reserved = NULL, \
.handler = work_handler, \
.flags = { 0 } \
}
struct _timeout;
typedef void (*_timeout_func_t)(struct _timeout *t);
struct _timeout {
sys_dnode_t node;
//struct k_thread *thread;
sys_dlist_t *wait_q;
s32_t delta_ticks_from_prev;
_timeout_func_t func;
};
/**
* @brief Define an array of atomic variables.
*
* This macro defines an array of atomic variables containing at least
* @a num_bits bits.
*
* @note
* If used from file scope, the bits of the array are initialized to zero;
* if used from within a function, the bits are left uninitialized.
*
* @param name Name of array of atomic variables.
* @param num_bits Number of bits needed.
*/
#define ATOMIC_DEFINE(name, num_bits) \
atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS]
/**
* @brief Generate null timeout delay.
*
* This macro generates a timeout delay that that instructs a kernel API
* not to wait if the requested operation cannot be performed immediately.
*
* @return Timeout delay value.
*/
#define K_NO_WAIT 0
/**
* @brief Generate timeout delay from milliseconds.
*
* This macro generates a timeout delay that that instructs a kernel API
* to wait up to @a ms milliseconds to perform the requested operation.
*
* @param ms Duration in milliseconds.
*
* @return Timeout delay value.
*/
#define K_MSEC(ms) (ms)
/**
* @brief Generate timeout delay from seconds.
*
* This macro generates a timeout delay that that instructs a kernel API
* to wait up to @a s seconds to perform the requested operation.
*
* @param s Duration in seconds.
*
* @return Timeout delay value.
*/
#define K_SECONDS(s) K_MSEC((s) * MSEC_PER_SEC)
/**
* @brief Generate timeout delay from minutes.
*
* This macro generates a timeout delay that that instructs a kernel API
* to wait up to @a m minutes to perform the requested operation.
*
* @param m Duration in minutes.
*
* @return Timeout delay value.
*/
#define K_MINUTES(m) K_SECONDS((m) * 60)
/**
* @brief Generate timeout delay from hours.
*
* This macro generates a timeout delay that that instructs a kernel API
* to wait up to @a h hours to perform the requested operation.
*
* @param h Duration in hours.
*
* @return Timeout delay value.
*/
#define K_HOURS(h) K_MINUTES((h) * 60)
/**
* @brief Generate infinite timeout delay.
*
* This macro generates a timeout delay that that instructs a kernel API
* to wait as long as necessary to perform the requested operation.
*
* @return Timeout delay value.
*/
#define K_FOREVER (-1)
/**
* @brief Get system uptime (32-bit version).
*
* This routine returns the lower 32-bits of the elapsed time since the system
* booted, in milliseconds.
*
* This routine can be more efficient than k_uptime_get(), as it reduces the
* need for interrupt locking and 64-bit math. However, the 32-bit result
* cannot hold a system uptime time larger than approximately 50 days, so the
* caller must handle possible rollovers.
*
* @return Current uptime.
*/
u32_t k_uptime_get_32(void);
struct k_sem {
osi_mutex_t mutex;
};
struct k_queue {
sys_slist_t data_q;
union {
_wait_q_t wait_q;
// TODO: The following not used now, delete it temporarily.
//_POLL_EVENT;
};
// TODO: The following not used now, delete it temporarily.
//_OBJECT_TRACING_NEXT_PTR(k_queue);
};
struct k_work_q {
struct k_queue queue;
};
/**
* @cond INTERNAL_HIDDEN
*/
struct k_fifo {
struct k_queue _queue;
};
struct k_lifo {
struct k_queue _queue;
};
struct k_delayed_work {
struct k_work work;
struct _timeout timeout;
struct k_work_q *work_q;
};
#define _K_QUEUE_INITIALIZER(obj) \
{ \
.wait_q = SYS_DLIST_STATIC_INIT(&obj.wait_q), \
.data_q = SYS_SLIST_STATIC_INIT(&obj.data_q), \
}
#define _K_FIFO_INITIALIZER(obj) \
{ \
._queue = _K_QUEUE_INITIALIZER(obj._queue) \
}
#define _K_LIFO_INITIALIZER(obj) \
{ \
._queue = _K_QUEUE_INITIALIZER(obj._queue) \
}
/**
* @brief Statically define and initialize a fifo.
*
* The fifo can be accessed outside the module where it is defined using:
*
* @code extern struct k_fifo <name>; @endcode
*
* @param name Name of the fifo.
*/
#define K_FIFO_DEFINE(name) \
struct k_fifo name \
__in_section(_k_queue, static, name) = \
_K_FIFO_INITIALIZER(name)
/* initialize the timeouts part of k_thread when enabled in the kernel */
static inline void _init_timeout(struct _timeout *t, _timeout_func_t func)
{
/*
* Must be initialized here and when dequeueing a timeout so that code
* not dealing with timeouts does not have to handle this, such as when
* waiting forever on a semaphore.
*/
t->delta_ticks_from_prev = _INACTIVE;
/*
* Must be initialized here so that k_wakeup can
* verify the thread is not on a wait queue before aborting a timeout.
*/
t->wait_q = NULL;
/*
* Function must be initialized before being potentially called.
*/
t->func = func;
/*
* These are initialized when enqueing on the timeout queue:
*
* thread->timeout.node.next
* thread->timeout.node.prev
*/
}
unsigned int irq_lock(void);
void irq_unlock(unsigned int key);
void mesh_k_init(void);
/**
* @brief Submit a delayed work item to the system workqueue.
*
* This routine schedules work item @a work to be processed by the system
* workqueue after a delay of @a delay milliseconds. The routine initiates
* an asynchronous countdown for the work item and then returns to the caller.
* Only when the countdown completes is the work item actually submitted to
* the workqueue and becomes pending.
*
* Submitting a previously submitted delayed work item that is still
* counting down cancels the existing submission and restarts the countdown
* using the new delay. If the work item is currently pending on the
* workqueue's queue because the countdown has completed it is too late to
* resubmit the item, and resubmission fails without impacting the work item.
* If the work item has already been processed, or is currently being processed,
* its work is considered complete and the work item can be resubmitted.
*
* @warning
* Work items submitted to the system workqueue should avoid using handlers
* that block or yield since this may prevent the system workqueue from
* processing other work items in a timely manner.
*
* @note Can be called by ISRs.
*
* @param work Address of delayed work item.
* @param delay Delay before submitting the work item (in milliseconds).
*
* @retval 0 Work item countdown started.
* @retval -EINPROGRESS Work item is already pending.
* @retval -EINVAL Work item is being processed or has completed its work.
* @retval -EADDRINUSE Work item is pending on a different workqueue.
*/
int k_delayed_work_submit(struct k_delayed_work *work,
s32_t delay);
/**
* @brief Get time remaining before a delayed work gets scheduled.
*
* This routine computes the (approximate) time remaining before a
* delayed work gets executed. If the delayed work is not waiting to be
* scheduled, it returns zero.
*
* @param work Delayed work item.
*
* @return Remaining time (in milliseconds).
*/
s32_t k_delayed_work_remaining_get(struct k_delayed_work *work);
/**
* @brief Submit a work item to the system workqueue.
*
* This routine submits work item @a work to be processed by the system
* workqueue. If the work item is already pending in the workqueue's queue
* as a result of an earlier submission, this routine has no effect on the
* work item. If the work item has already been processed, or is currently
* being processed, its work is considered complete and the work item can be
* resubmitted.
*
* @warning
* Work items submitted to the system workqueue should avoid using handlers
* that block or yield since this may prevent the system workqueue from
* processing other work items in a timely manner.
*
* @note Can be called by ISRs.
*
* @param work Address of work item.
*
* @return N/A
*/
static inline void k_work_submit(struct k_work *work)
{
// TODO:
if (work != NULL) {
work->handler(work);
}
return;
//k_work_submit_to_queue(&k_sys_work_q, work);
}
/**
* @brief Initialize a work item.
*
* This routine initializes a workqueue work item, prior to its first use.
*
* @param work Address of work item.
* @param handler Function to invoke each time work item is processed.
*
* @return N/A
*/
static inline void k_work_init(struct k_work *work, k_work_handler_t handler)
{
work->handler = handler;
}
int k_delayed_work_cancel(struct k_delayed_work *work);
int k_delayed_work_free(struct k_delayed_work *work);
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler);
/**
* @brief Get system uptime.
*
* This routine returns the elapsed time since the system booted,
* in milliseconds.
*
* @return Current uptime.
*/
s64_t k_uptime_get(void);
/**
* @brief Put the current thread to sleep.
*
* This routine puts the current thread to sleep for @a duration
* milliseconds.
*
* @param duration Number of milliseconds to sleep.
*
* @return N/A
*/
void k_sleep(s32_t duration);
/**
* @brief Give a semaphore.
*
* This routine gives @a sem, unless the semaphore is already at its maximum
* permitted count.
*
* @note Can be called by ISRs.
*
* @param sem Address of the semaphore.
*
* @return N/A
*/
void k_sem_give(struct k_sem *sem);
/**
* @brief Initialize a semaphore.
*
* This routine initializes a semaphore object, prior to its first use.
*
* @param sem Address of the semaphore.
* @param initial_count Initial semaphore count.
* @param limit Maximum permitted semaphore count.
*
* @return N/A
*/
void k_sem_init(struct k_sem *sem, unsigned int initial_count,
unsigned int limit);
/**
* @brief Take a semaphore.
*
* This routine takes @a sem.
*
* @note Can be called by ISRs, but @a timeout must be set to K_NO_WAIT.
*
* @param sem Address of the semaphore.
* @param timeout Waiting period to take the semaphore (in milliseconds),
* or one of the special values K_NO_WAIT and K_FOREVER.
*
* @note When porting code from the nanokernel legacy API to the new API, be
* careful with the return value of this function. The return value is the
* reverse of the one of nano_sem_take family of APIs: 0 means success, and
* non-zero means failure, while the nano_sem_take family returns 1 for success
* and 0 for failure.
*
* @retval 0 Semaphore taken.
* @retval -EBUSY Returned without waiting.
* @retval -EAGAIN Waiting period timed out.
*/
int k_sem_take(struct k_sem *sem, s32_t timeout);
#endif /* #ifndef _MESH_KERNEL_ */

View File

@@ -0,0 +1,534 @@
/** @file
* @brief Bluetooth Mesh Profile APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_MESH_MAIN_H
#define __BT_MESH_MAIN_H
#include "mesh_util.h"
#include "mesh_access.h"
#if CONFIG_BT_MESH
/**
* @brief Bluetooth Mesh Provisioning
* @defgroup bt_mesh_prov Bluetooth Mesh Provisioning
* @ingroup bt_mesh
* @{
*/
typedef enum {
BT_MESH_NO_OUTPUT = 0,
BT_MESH_BLINK = BIT(0),
BT_MESH_BEEP = BIT(1),
BT_MESH_VIBRATE = BIT(2),
BT_MESH_DISPLAY_NUMBER = BIT(3),
BT_MESH_DISPLAY_STRING = BIT(4),
} bt_mesh_output_action_t;
typedef enum {
BT_MESH_NO_INPUT = 0,
BT_MESH_PUSH = BIT(0),
BT_MESH_TWIST = BIT(1),
BT_MESH_ENTER_NUMBER = BIT(2),
BT_MESH_ENTER_STRING = BIT(3),
} bt_mesh_input_action_t;
typedef enum {
BT_MESH_PROV_ADV = BIT(0),
BT_MESH_PROV_GATT = BIT(1),
} bt_mesh_prov_bearer_t;
/** Provisioning properties & capabilities. */
struct bt_mesh_prov {
#if CONFIG_BT_MESH_NODE
/** The UUID that's used when advertising as unprovisioned */
const u8_t *uuid;
/** Flag indicates whether unprovisioned devices support OOB public key */
bool oob_pub_key;
/** @brief Set device OOB public key.
*
* This callback notifies the application to
* set OOB public key & private key pair.
*/
void (*oob_pub_key_cb)(void);
/** Static OOB value */
const u8_t *static_val;
/** Static OOB value length */
u8_t static_val_len;
/** Maximum size of Output OOB supported */
u8_t output_size;
/** Supported Output OOB Actions */
u16_t output_actions;
/* Maximum size of Input OOB supported */
u8_t input_size;
/** Supported Input OOB Actions */
u16_t input_actions;
/** @brief Output of a number is requested.
*
* This callback notifies the application to
* output the given number using the given action.
*
* @param act Action for outputting the number.
* @param num Number to be out-put.
*
* @return Zero on success or negative error code otherwise
*/
int (*output_number)(bt_mesh_output_action_t act, u32_t num);
/** @brief Output of a string is requested.
*
* This callback notifies the application to
* display the given string to the user.
*
* @param str String to be displayed.
*
* @return Zero on success or negative error code otherwise
*/
int (*output_string)(const char *str);
/** @brief Input is requested.
*
* This callback notifies the application to request
* input from the user using the given action. The
* requested input will either be a string or a number, and
* the application needs to consequently call the
* bt_mesh_input_string() or bt_mesh_input_number() functions
* once the data has been acquired from the user.
*
* @param act Action for inputting data.
* @param num Maximum size of the in-put data.
*
* @return Zero on success or negative error code otherwise
*/
int (*input)(bt_mesh_input_action_t act, u8_t size);
/** @brief Provisioning link has been opened.
*
* This callback notifies the application that a provisioning
* link has been opened on the given provisioning bearer.
*
* @param bearer Provisioning bearer.
*/
void (*link_open)(bt_mesh_prov_bearer_t bearer);
/** @brief Provisioning link has been closed.
*
* This callback notifies the application that a provisioning
* link has been closed on the given provisioning bearer.
*
* @param bearer Provisioning bearer.
*/
void (*link_close)(bt_mesh_prov_bearer_t bearer);
/** @brief Provisioning is complete.
*
* This callback notifies the application that provisioning has
* been successfully completed, and that the local node has been
* assigned the specified NetKeyIndex and primary element address.
*
* @param net_idx NetKeyIndex given during provisioning.
* @param addr Primary element address.
* @param flags Key Refresh & IV Update flags
* @param iv_index IV Index.
*/
void (*complete)(u16_t net_idx, u16_t addr, u8_t flags, u32_t iv_index);
/** @brief Node has been reset.
*
* This callback notifies the application that the local node
* has been reset and needs to be reprovisioned. The node will
* not automatically advertise as unprovisioned, rather the
* bt_mesh_prov_enable() API needs to be called to enable
* unprovisioned advertising on one or more provisioning bearers.
*/
void (*reset)(void);
#endif /* CONFIG_BT_MESH_NODE */
#if CONFIG_BT_MESH_PROVISIONER
/* Provisioner device uuid */
const u8_t *prov_uuid;
/*
* Primary element address of the provisioner.
* No need to initialize it for fast provisioning.
*/
const u16_t prov_unicast_addr;
/*
* Starting unicast address going to assigned.
* No need to initialize it for fast provisioning.
*/
u16_t prov_start_address;
/* Attention timer contained in Provisioning Invite */
u8_t prov_attention;
/* Provisioner provisioning Algorithm */
u8_t prov_algorithm;
/* Provisioner public key oob */
u8_t prov_pub_key_oob;
/** @brief Input is requested.
*
* This callback notifies the application that it should
* read device's public key with OOB
*
* @param link_idx: The provisioning link index
*
* @return Zero on success or negative error code otherwise
*/
int (*prov_pub_key_oob_cb)(u8_t link_idx);
/* Provisioner static oob value */
u8_t *prov_static_oob_val;
/* Provisioner static oob value length */
u8_t prov_static_oob_len;
/** @brief Provisioner input a number read from device output
*
* This callback notifies the application that it should
* input the number given by the device.
*
* @param method: The OOB authentication method
* @param act: The output action of the device
* @param size: The output size of the device
* @param link_idx: The provisioning link index
*
* @return Zero on success or negative error code otherwise
*/
int (*prov_input_num)(u8_t method, bt_mesh_output_action_t act, u8_t size, u8_t link_idx);
/** @brief Provisioner output a number to the device
*
* This callback notifies the application that it should
* output the number to the device.
*
* @param method: The OOB authentication method
* @param act: The input action of the device
* @param data: The input number/string of the device
* @param size: The input size of the device
* @param link_idx: The provisioning link index
*
* @return Zero on success or negative error code otherwise
*/
int (*prov_output_num)(u8_t method, bt_mesh_input_action_t act, void *data, u8_t size, u8_t link_idx);
/*
* Key refresh and IV update flag.
* No need to initialize it for fast provisioning.
*/
u8_t flags;
/*
* IV index. No need to initialize it for fast provisioning.
*/
u32_t iv_index;
/** @brief Provisioner has opened a provisioning link.
*
* This callback notifies the application that a provisioning
* link has been opened on the given provisioning bearer.
*
* @param bearer Provisioning bearer.
*/
void (*prov_link_open)(bt_mesh_prov_bearer_t bearer);
/** @brief Provisioner has closed a provisioning link.
*
* This callback notifies the application that a provisioning
* link has been closed on the given provisioning bearer.
*
* @param bearer Provisioning bearer.
* @param reason Provisioning link close reason(disconnect reason)
* 0xFF: disconnect due to provisioner_pb_gatt_disable()
*/
void (*prov_link_close)(bt_mesh_prov_bearer_t bearer, u8_t reason);
/** @brief Provision one device is complete.
*
* This callback notifies the application that provisioner has
* successfully provisioned a device, and the node has been assigned
* the specified NetKeyIndex and primary element address.
*
* @param node_idx Node index within the node(provisioned device) queue.
* @param device_uuid Provisioned device uuid pointer.
* @param unicast_addr Provisioned device assigned unicast address.
* @param element_num Provisioned device element number.
* @param netkey_idx Provisioned device assigned netkey index.
*/
void (*prov_complete)(int node_idx, const u8_t device_uuid[16],
u16_t unicast_addr, u8_t element_num,
u16_t netkey_idx);
#endif /* CONFIG_BT_MESH_PROVISIONER */
};
/** @brief Provide provisioning input OOB string.
*
* This is intended to be called after the bt_mesh_prov input callback
* has been called with BT_MESH_ENTER_STRING as the action.
*
* @param str String.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_input_string(const char *str);
/** @brief Provide provisioning input OOB number.
*
* This is intended to be called after the bt_mesh_prov input callback
* has been called with BT_MESH_ENTER_NUMBER as the action.
*
* @param num Number.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_input_number(u32_t num);
/** @brief Enable specific provisioning bearers
*
* Enable one or more provisioning bearers.
*
* @param Bit-wise OR of provisioning bearers.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers);
/** @brief Disable specific provisioning bearers
*
* Disable one or more provisioning bearers.
*
* @param Bit-wise OR of provisioning bearers.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers);
/** @brief Indicate whether provisioner is enabled
*
* @return true - enabled, false - disabled.
*/
bool bt_mesh_is_provisioner_en(void);
/* The following API is for fast provisioning */
#if CONFIG_BT_MESH_FAST_PROV
/** @brief Change the device action
*
* @param[IN] action: role of device to be set
* 0x01 - enter, 0x02 - suspend, 0x03 - exit
*
* @return status
*/
u8_t bt_mesh_set_fast_prov_action(u8_t action);
#endif /* CONFIG_BT_MESH_FAST_PROV */
#if CONFIG_BT_MESH_PROVISIONER
/** @brief Provide provisioning input OOB string.
*
* This is intended to be called after the bt_mesh_prov input callback
* has been called with BT_MESH_ENTER_STRING as the action.
*
* @param str String.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_prov_input_string(const char *str);
/** @brief Provide provisioning input OOB number.
*
* This is intended to be called after the bt_mesh_prov input callback
* has been called with BT_MESH_ENTER_NUMBER as the action.
*
* @param num Number.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_prov_input_number(u32_t num);
/** @brief Enable specific provisioning bearers
*
* Enable one or more provisioning bearers.
*
* @param bearers Bit-wise OR of provisioning bearers.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers);
/** @brief Disable specific provisioning bearers
*
* Disable one or more provisioning bearers.
*
* @param bearers Bit-wise OR of provisioning bearers.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers);
#endif /* CONFIG_BT_MESH_PROVISIONER */
/**
* @}
*/
/**
* @brief Bluetooth Mesh
* @defgroup bt_mesh Bluetooth Mesh
* @ingroup bluetooth
* @{
*/
/* Primary Network Key index */
#define BT_MESH_NET_PRIMARY 0x000
#define BT_MESH_RELAY_DISABLED 0x00
#define BT_MESH_RELAY_ENABLED 0x01
#define BT_MESH_RELAY_NOT_SUPPORTED 0x02
#define BT_MESH_BEACON_DISABLED 0x00
#define BT_MESH_BEACON_ENABLED 0x01
#define BT_MESH_GATT_PROXY_DISABLED 0x00
#define BT_MESH_GATT_PROXY_ENABLED 0x01
#define BT_MESH_GATT_PROXY_NOT_SUPPORTED 0x02
#define BT_MESH_FRIEND_DISABLED 0x00
#define BT_MESH_FRIEND_ENABLED 0x01
#define BT_MESH_FRIEND_NOT_SUPPORTED 0x02
#define BT_MESH_NODE_IDENTITY_STOPPED 0x00
#define BT_MESH_NODE_IDENTITY_RUNNING 0x01
#define BT_MESH_NODE_IDENTITY_NOT_SUPPORTED 0x02
/* Features */
#define BT_MESH_FEAT_RELAY BIT(0)
#define BT_MESH_FEAT_PROXY BIT(1)
#define BT_MESH_FEAT_FRIEND BIT(2)
#define BT_MESH_FEAT_LOW_POWER BIT(3)
#define BT_MESH_FEAT_SUPPORTED (BT_MESH_FEAT_RELAY | \
BT_MESH_FEAT_PROXY | \
BT_MESH_FEAT_FRIEND | \
BT_MESH_FEAT_LOW_POWER)
/** @brief Initialize Mesh support
*
* After calling this API, the node will not automatically advertise as
* unprovisioned, rather the bt_mesh_prov_enable() API needs to be called
* to enable unprovisioned advertising on one or more provisioning bearers.
*
* @param prov Node provisioning information.
* @param comp Node Composition.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_init(const struct bt_mesh_prov *prov,
const struct bt_mesh_comp *comp);
/** @brief Reset the state of the local Mesh node.
*
* Resets the state of the node, which means that it needs to be
* reprovisioned to become an active node in a Mesh network again.
*
* After calling this API, the node will not automatically advertise as
* unprovisioned, rather the bt_mesh_prov_enable() API needs to be called
* to enable unprovisioned advertising on one or more provisioning bearers.
*
*/
void bt_mesh_reset(void);
/** @brief Provision the local Mesh Node.
*
* This API should normally not be used directly by the application. The
* only exception is for testing purposes where manual provisioning is
* desired without an actual external provisioner.
*
* @param net_key Network Key
* @param net_idx Network Key Index
* @param flags Provisioning Flags
* @param iv_index IV Index
* @param seq Sequence Number (0 if newly provisioned).
* @param addr Primary element address
* @param dev_key Device Key
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
u8_t flags, u32_t iv_index, u32_t seq,
u16_t addr, const u8_t dev_key[16]);
/** @brief Toggle the IV Update test mode
*
* This API is only available if the IV Update test mode has been enabled
* in Kconfig. It is needed for passing most of the IV Update qualification
* test cases.
*
* @param enable true to enable IV Update test mode, false to disable it.
*/
void bt_mesh_iv_update_test(bool enable);
/** @brief Toggle the IV Update state
*
* This API is only available if the IV Update test mode has been enabled
* in Kconfig. It is needed for passing most of the IV Update qualification
* test cases.
*
* @return true if IV Update In Progress state was entered, false otherwise.
*/
bool bt_mesh_iv_update(void);
/** @brief Toggle the Low Power feature of the local device
*
* Enables or disables the Low Power feature of the local device. This is
* exposed as a run-time feature, since the device might want to change
* this e.g. based on being plugged into a stable power source or running
* from a battery power source.
*
* @param enable true to enable LPN functionality, false to disable it.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_lpn_set(bool enable);
/** @brief Send out a Friend Poll message.
*
* Send a Friend Poll message to the Friend of this node. If there is no
* established Friendship the function will return an error.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_lpn_poll(void);
/** @brief Register a callback for Friendship changes.
*
* Registers a callback that will be called whenever Friendship gets
* established or is lost.
*
* @param cb Function to call when the Friendship status changes.
*/
void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established));
/**
* @}
*/
#endif /* __BT_MESH_MAIN_H */
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,470 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Single-linked list implementation
*
* Single-linked list implementation using inline macros/functions.
* This API is not thread safe, and thus if a list is used across threads,
* calls to functions must be protected with synchronization primitives.
*/
#ifndef __SLIST_H__
#define __SLIST_H__
#include <stddef.h>
#include <stdbool.h>
#include "mesh_util.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _snode {
struct _snode *next;
};
typedef struct _snode sys_snode_t;
struct _slist {
sys_snode_t *head;
sys_snode_t *tail;
};
typedef struct _slist sys_slist_t;
/**
* @brief Provide the primitive to iterate on a list
* Note: the loop is unsafe and thus __sn should not be removed
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_SLIST_FOR_EACH_NODE(l, n) {
* <user code>
* }
*
* This and other SYS_SLIST_*() macros are not thread safe.
*
* @param __sl A pointer on a sys_slist_t to iterate on
* @param __sn A sys_snode_t pointer to peek each node of the list
*/
#define SYS_SLIST_FOR_EACH_NODE(__sl, __sn) \
for (__sn = sys_slist_peek_head(__sl); __sn; \
__sn = sys_slist_peek_next(__sn))
/**
* @brief Provide the primitive to iterate on a list, from a node in the list
* Note: the loop is unsafe and thus __sn should not be removed
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_SLIST_ITERATE_FROM_NODE(l, n) {
* <user code>
* }
*
* Like SYS_SLIST_FOR_EACH_NODE(), but __dn already contains a node in the list
* where to start searching for the next entry from. If NULL, it starts from
* the head.
*
* This and other SYS_SLIST_*() macros are not thread safe.
*
* @param __sl A pointer on a sys_slist_t to iterate on
* @param __sn A sys_snode_t pointer to peek each node of the list
* it contains the starting node, or NULL to start from the head
*/
#define SYS_SLIST_ITERATE_FROM_NODE(__sl, __sn) \
for (__sn = __sn ? sys_slist_peek_next_no_check(__sn) \
: sys_slist_peek_head(__sl); \
__sn; \
__sn = sys_slist_peek_next(__sn))
/**
* @brief Provide the primitive to safely iterate on a list
* Note: __sn can be removed, it will not break the loop.
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_SLIST_FOR_EACH_NODE_SAFE(l, n, s) {
* <user code>
* }
*
* This and other SYS_SLIST_*() macros are not thread safe.
*
* @param __sl A pointer on a sys_slist_t to iterate on
* @param __sn A sys_snode_t pointer to peek each node of the list
* @param __sns A sys_snode_t pointer for the loop to run safely
*/
#define SYS_SLIST_FOR_EACH_NODE_SAFE(__sl, __sn, __sns) \
for (__sn = sys_slist_peek_head(__sl), \
__sns = sys_slist_peek_next(__sn); \
__sn; __sn = __sns, \
__sns = sys_slist_peek_next(__sn))
/*
* @brief Provide the primitive to resolve the container of a list node
* Note: it is safe to use with NULL pointer nodes
*
* @param __ln A pointer on a sys_node_t to get its container
* @param __cn Container struct type pointer
* @param __n The field name of sys_node_t within the container struct
*/
#define SYS_SLIST_CONTAINER(__ln, __cn, __n) \
((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
/*
* @brief Provide the primitive to peek container of the list head
*
* @param __sl A pointer on a sys_slist_t to peek
* @param __cn Container struct type pointer
* @param __n The field name of sys_node_t within the container struct
*/
#define SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n) \
SYS_SLIST_CONTAINER(sys_slist_peek_head(__sl), __cn, __n)
/*
* @brief Provide the primitive to peek container of the list tail
*
* @param __sl A pointer on a sys_slist_t to peek
* @param __cn Container struct type pointer
* @param __n The field name of sys_node_t within the container struct
*/
#define SYS_SLIST_PEEK_TAIL_CONTAINER(__sl, __cn, __n) \
SYS_SLIST_CONTAINER(sys_slist_peek_tail(__sl), __cn, __n)
/*
* @brief Provide the primitive to peek the next container
*
* @param __cn Container struct type pointer
* @param __n The field name of sys_node_t within the container struct
*/
#define SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n) \
((__cn) ? SYS_SLIST_CONTAINER(sys_slist_peek_next(&((__cn)->__n)), \
__cn, __n) : NULL)
/**
* @brief Provide the primitive to iterate on a list under a container
* Note: the loop is unsafe and thus __cn should not be detached
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_SLIST_FOR_EACH_CONTAINER(l, c, n) {
* <user code>
* }
*
* @param __sl A pointer on a sys_slist_t to iterate on
* @param __cn A pointer to peek each entry of the list
* @param __n The field name of sys_node_t within the container struct
*/
#define SYS_SLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \
for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n); __cn; \
__cn = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n))
/**
* @brief Provide the primitive to safely iterate on a list under a container
* Note: __cn can be detached, it will not break the loop.
*
* User _MUST_ add the loop statement curly braces enclosing its own code:
*
* SYS_SLIST_FOR_EACH_NODE_SAFE(l, c, cn, n) {
* <user code>
* }
*
* @param __sl A pointer on a sys_slist_t to iterate on
* @param __cn A pointer to peek each entry of the list
* @param __cns A pointer for the loop to run safely
* @param __n The field name of sys_node_t within the container struct
*/
#define SYS_SLIST_FOR_EACH_CONTAINER_SAFE(__sl, __cn, __cns, __n) \
for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n), \
__cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n); __cn; \
__cn = __cns, __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n))
/**
* @brief Initialize a list
*
* @param list A pointer on the list to initialize
*/
static inline void sys_slist_init(sys_slist_t *list)
{
list->head = NULL;
list->tail = NULL;
}
#define SYS_SLIST_STATIC_INIT(ptr_to_list) {NULL, NULL}
/**
* @brief Test if the given list is empty
*
* @param list A pointer on the list to test
*
* @return a boolean, true if it's empty, false otherwise
*/
static inline bool sys_slist_is_empty(sys_slist_t *list)
{
return (!list->head);
}
/**
* @brief Peek the first node from the list
*
* @param list A point on the list to peek the first node from
*
* @return A pointer on the first node of the list (or NULL if none)
*/
static inline sys_snode_t *sys_slist_peek_head(sys_slist_t *list)
{
return list->head;
}
/**
* @brief Peek the last node from the list
*
* @param list A point on the list to peek the last node from
*
* @return A pointer on the last node of the list (or NULL if none)
*/
static inline sys_snode_t *sys_slist_peek_tail(sys_slist_t *list)
{
return list->tail;
}
/**
* @brief Peek the next node from current node, node is not NULL
*
* Faster then sys_slist_peek_next() if node is known not to be NULL.
*
* @param node A pointer on the node where to peek the next node
*
* @return a pointer on the next node (or NULL if none)
*/
static inline sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node)
{
return node->next;
}
/**
* @brief Peek the next node from current node
*
* @param node A pointer on the node where to peek the next node
*
* @return a pointer on the next node (or NULL if none)
*/
static inline sys_snode_t *sys_slist_peek_next(sys_snode_t *node)
{
return node ? sys_slist_peek_next_no_check(node) : NULL;
}
/**
* @brief Prepend a node to the given list
*
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
* @param node A pointer on the node to prepend
*/
static inline void sys_slist_prepend(sys_slist_t *list,
sys_snode_t *node)
{
node->next = list->head;
list->head = node;
if (!list->tail) {
list->tail = list->head;
}
}
/**
* @brief Append a node to the given list
*
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
* @param node A pointer on the node to append
*/
static inline void sys_slist_append(sys_slist_t *list,
sys_snode_t *node)
{
node->next = NULL;
if (!list->tail) {
list->tail = node;
list->head = node;
} else {
list->tail->next = node;
list->tail = node;
}
}
/**
* @brief Append a list to the given list
*
* Append a singly-linked, NULL-terminated list consisting of nodes containing
* the pointer to the next node as the first element of a node, to @a list.
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
* @param head A pointer to the first element of the list to append
* @param tail A pointer to the last element of the list to append
*/
static inline void sys_slist_append_list(sys_slist_t *list,
void *head, void *tail)
{
if (!list->tail) {
list->head = (sys_snode_t *)head;
list->tail = (sys_snode_t *)tail;
} else {
list->tail->next = (sys_snode_t *)head;
list->tail = (sys_snode_t *)tail;
}
}
/**
* @brief merge two slists, appending the second one to the first
*
* When the operation is completed, the appending list is empty.
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
* @param list_to_append A pointer to the list to append.
*/
static inline void sys_slist_merge_slist(sys_slist_t *list,
sys_slist_t *list_to_append)
{
sys_slist_append_list(list, list_to_append->head,
list_to_append->tail);
sys_slist_init(list_to_append);
}
/**
* @brief Insert a node to the given list
*
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
* @param prev A pointer on the previous node
* @param node A pointer on the node to insert
*/
static inline void sys_slist_insert(sys_slist_t *list,
sys_snode_t *prev,
sys_snode_t *node)
{
if (!prev) {
sys_slist_prepend(list, node);
} else if (!prev->next) {
sys_slist_append(list, node);
} else {
node->next = prev->next;
prev->next = node;
}
}
/**
* @brief Fetch and remove the first node of the given list
*
* List must be known to be non-empty.
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
*
* @return A pointer to the first node of the list
*/
static inline sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list)
{
sys_snode_t *node = list->head;
list->head = node->next;
if (list->tail == node) {
list->tail = list->head;
}
return node;
}
/**
* @brief Fetch and remove the first node of the given list
*
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
*
* @return A pointer to the first node of the list (or NULL if empty)
*/
static inline sys_snode_t *sys_slist_get(sys_slist_t *list)
{
return sys_slist_is_empty(list) ? NULL : sys_slist_get_not_empty(list);
}
/**
* @brief Remove a node
*
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
* @param prev_node A pointer on the previous node
* (can be NULL, which means the node is the list's head)
* @param node A pointer on the node to remove
*/
static inline void sys_slist_remove(sys_slist_t *list,
sys_snode_t *prev_node,
sys_snode_t *node)
{
if (!prev_node) {
list->head = node->next;
/* Was node also the tail? */
if (list->tail == node) {
list->tail = list->head;
}
} else {
prev_node->next = node->next;
/* Was node the tail? */
if (list->tail == node) {
list->tail = prev_node;
}
}
node->next = NULL;
}
/**
* @brief Find and remove a node from a list
*
* This and other sys_slist_*() functions are not thread safe.
*
* @param list A pointer on the list to affect
* @param node A pointer on the node to remove from the list
*
* @return true if node was removed
*/
static inline bool sys_slist_find_and_remove(sys_slist_t *list,
sys_snode_t *node)
{
sys_snode_t *prev = NULL;
sys_snode_t *test;
SYS_SLIST_FOR_EACH_NODE(list, test) {
if (test == node) {
sys_slist_remove(list, prev, node);
return true;
}
prev = test;
}
return false;
}
#ifdef __cplusplus
}
#endif
#endif /* __SLIST_H__ */

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
* Copyright (c) 2015-2016 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_log.h"
#include "sdkconfig.h"
/* Define common tracing for all */
#ifndef LOG_LEVEL_ERROR
#define LOG_LEVEL_ERROR 1
#endif /* LOG_LEVEL_ERROR */
#ifndef LOG_LEVEL_WARN
#define LOG_LEVEL_WARN 2
#endif /* LOG_LEVEL_WARN */
#ifndef LOG_LEVEL_INFO
#define LOG_LEVEL_INFO 3
#endif /* LOG_LEVEL_INFO */
#ifndef LOG_LEVEL_DEBUG
#define LOG_LEVEL_DEBUG 4
#endif /* LOG_LEVEL_DEBUG */
#ifndef LOG_LEVEL_VERBOSE
#define LOG_LEVEL_VERBOSE 5
#endif /*LOG_LEVEL_VERBOSE */
#ifdef CONFIG_BT_MESH_STACK_INITIAL_TRACE_LEVEL
#define MESH_LOG_LEVEL CONFIG_BT_MESH_STACK_INITIAL_TRACE_LEVEL
#else
#define MESH_LOG_LEVEL LOG_LEVEL_WARN
#endif
#ifdef CONFIG_BT_MESH_NET_BUF_TRACE_LEVEL
#define NET_BUF_LOG_LEVEL CONFIG_BT_MESH_NET_BUF_TRACE_LEVEL
#else
#define NET_BUF_LOG_LEVEL LOG_LEVEL_WARN
#endif
#define MESH_TRACE_TAG "BLE_MESH"
#if (LOG_LOCAL_LEVEL >= 4)
#define BT_MESH_LOG_LOCAL_LEVEL_MAPPING (LOG_LOCAL_LEVEL + 1)
#else
#define BT_MESH_LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif /* MAX(a, b) */
#define BT_MESH_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_LOG_LEVEL, BT_MESH_LOG_LOCAL_LEVEL_MAPPING) >= LOG_LEVEL_##LEVEL)
#define BT_MESH_PRINT_E(tag, format, ...) {esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define BT_MESH_PRINT_W(tag, format, ...) {esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define BT_MESH_PRINT_I(tag, format, ...) {esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define BT_MESH_PRINT_D(tag, format, ...) {esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define BT_MESH_PRINT_V(tag, format, ...) {esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#ifndef __ASSERT_NO_MSG
#define __ASSERT_NO_MSG(x) do { if (!(x)) BT_MESH_PRINT_E(MESH_TRACE_TAG, "bt mesh error %s %u\n", __FILE__, __LINE__); } while (0)
#endif
#if !CONFIG_BT_MESH_NO_LOG
#define BT_ERR(fmt, args...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_ERROR) && BT_MESH_LOG_LEVEL_CHECK(MESH, ERROR)) BT_MESH_PRINT_E(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define BT_WARN(fmt, args...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_WARN) && BT_MESH_LOG_LEVEL_CHECK(MESH, WARN)) BT_MESH_PRINT_W(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define BT_INFO(fmt, args...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_INFO) && BT_MESH_LOG_LEVEL_CHECK(MESH, INFO)) BT_MESH_PRINT_I(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define BT_DBG(fmt, args...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_DEBUG) && BT_MESH_LOG_LEVEL_CHECK(MESH, DEBUG)) BT_MESH_PRINT_D(MESH_TRACE_TAG, fmt, ## args);} while(0)
#else /* #if !CONFIG_BT_STACK_NO_LOG */
#define BT_ERR(fmt, args...)
#define BT_WARN(fmt, args...)
#define BT_INFO(fmt, args...)
#define BT_DBG(fmt, args...)
#endif /* #if !CONFIG_BT_STACK_NO_LOG */
#if defined(CONFIG_NET_BUF_LOG) && (!CONFIG_BT_MESH_NO_LOG)
#define NET_BUF_DBG(fmt, ...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_ERROR) && BT_MESH_LOG_LEVEL_CHECK(NET_BUF, DEBUG)) BT_MESH_PRINT_D(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_ERR(fmt, ...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_ERROR) && BT_MESH_LOG_LEVEL_CHECK(NET_BUF, ERROR)) BT_MESH_PRINT_E(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_WARN(fmt, ...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_ERROR) && BT_MESH_LOG_LEVEL_CHECK(NET_BUF, WARN)) BT_MESH_PRINT_W(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_INFO(fmt, ...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_ERROR) && BT_MESH_LOG_LEVEL_CHECK(NET_BUF, INFO)) BT_MESH_PRINT_I(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_ASSERT(cond) do { if (!(cond)) { \
NET_BUF_ERR("assert: '" #cond "' failed"); \
} } while (0)
#else
#define NET_BUF_DBG(fmt, ...)
#define NET_BUF_ERR(fmt, ...)
#define NET_BUF_WARN(fmt, ...)
#define NET_BUF_INFO(fmt, ...)
#define NET_BUF_ASSERT(cond)
#endif /* CONFIG_NET_BUF_LOG */
#if defined(CONFIG_NET_BUF_SIMPLE_LOG) && (!CONFIG_BT_MESH_NO_LOG)
#define NET_BUF_SIMPLE_DBG(fmt, ...) do {if (MESH_LOG_LEVEL >= LOG_LEVEL_DEBUG) esp_log_write(ESP_LOG_ERROR, MESH_TRACE_TAG, LOG_FORMAT(D, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__);} while(0)
#define NET_BUF_SIMPLE_ERR(fmt, ...) do {if (MESH_LOG_LEVEL >= LOG_LEVEL_ERROR) esp_log_write(ESP_LOG_ERROR, MESH_TRACE_TAG, LOG_FORMAT(E, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__);} while(0)
#define NET_BUF_SIMPLE_WARN(fmt, ...) do {if (MESH_LOG_LEVEL >= LOG_LEVEL_WARN) esp_log_write(ESP_LOG_ERROR, MESH_TRACE_TAG, LOG_FORMAT(W, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__);} while(0)
#define NET_BUF_SIMPLE_INFO(fmt, ...) do {if (MESH_LOG_LEVEL >= LOG_LEVEL_INFO) esp_log_write(ESP_LOG_ERROR, MESH_TRACE_TAG, LOG_FORMAT(I, format), esp_log_timestamp(), "BT_LOG", ##__VA_ARGS__);} while(0)
#define NET_BUF_SIMPLE_ASSERT(cond) assert(cond != NULL)
#else /* CONFIG_NET_BUF_SIMPLE_LOG */
#define NET_BUF_SIMPLE_DBG(fmt, ...)
#define NET_BUF_SIMPLE_ERR(fmt, ...)
#define NET_BUF_SIMPLE_WARN(fmt, ...)
#define NET_BUF_SIMPLE_INFO(fmt, ...)
#define NET_BUF_SIMPLE_ASSERT(cond)
#endif /* CONFIG_NET_BUF_SIMPLE_LOG */
#define printk ets_printf

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2017 Linaro Limited
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __Z_TYPES_H__
#define __Z_TYPES_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef signed char s8_t;
typedef signed short s16_t;
typedef signed int s32_t;
typedef signed long long s64_t;
typedef unsigned char u8_t;
typedef unsigned short u16_t;
typedef unsigned int u32_t;
typedef unsigned long long u64_t;
typedef int atomic_t;
#ifndef bool
#define bool int8_t
#define false 0 ///< XOS definition of 'false'
#define true 1 ///< XOS definition of 'true'
#endif
#ifdef __cplusplus
}
#endif
#endif /* __Z_TYPES_H__ */

View File

@@ -0,0 +1,629 @@
/*
* Copyright (c) 2011-2014, Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Misc utilities
*
* Misc utilities usable by the kernel and application code.
*/
#ifndef _UTIL__H_
#define _UTIL__H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ASMLANGUAGE
#include <stddef.h>
#include "mesh_types.h"
#include "mesh_trace.h"
#include "soc/soc.h"
/* Helper to pass a int as a pointer or vice-versa.
* Those are available for 32 bits architectures:
*/
#define POINTER_TO_UINT(x) ((u32_t) (x))
#define UINT_TO_POINTER(x) ((void *) (x))
#define POINTER_TO_INT(x) ((s32_t) (x))
#define INT_TO_POINTER(x) ((void *) (x))
/* Evaluates to 0 if cond is true-ish; compile error otherwise */
#define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
/* Evaluates to 0 if array is an array; compile error if not array (e.g.
* pointer)
*/
#define IS_ARRAY(array) \
ZERO_OR_COMPILE_ERROR( \
!__builtin_types_compatible_p(__typeof__(array), \
__typeof__(&(array)[0])))
/* Evaluates to number of elements in an array; compile error if not
* an array (e.g. pointer)
*/
#define ARRAY_SIZE(array) \
((unsigned long) (IS_ARRAY(array) + \
(sizeof(array) / sizeof((array)[0]))))
/* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if
* "array" argument is not an array (e.g. "ptr" and "array" mixed up)
*/
#define PART_OF_ARRAY(array, ptr) \
((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)]))
#define CONTAINER_OF(ptr, type, field) \
((type *)(((char *)(ptr)) - offsetof(type, field)))
/* round "x" up/down to next multiple of "align" (which must be a power of 2) */
#define ROUND_UP(x, align) \
(((unsigned long)(x) + ((unsigned long)align - 1)) & \
~((unsigned long)align - 1))
#define ROUND_DOWN(x, align) ((unsigned long)(x) & ~((unsigned long)align - 1))
#define ceiling_fraction(numerator, divider) \
(((numerator) + ((divider) - 1)) / (divider))
/* Internal helpers only used by the sys_* APIs further below */
#define __bswap_16(x) ((u16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
#define __bswap_32(x) ((u32_t) ((((x) >> 24) & 0xff) | \
(((x) >> 8) & 0xff00) | \
(((x) & 0xff00) << 8) | \
(((x) & 0xff) << 24)))
#define __bswap_64(x) ((u64_t) ((((x) >> 56) & 0xff) | \
(((x) >> 40) & 0xff00) | \
(((x) >> 24) & 0xff0000) | \
(((x) >> 8) & 0xff000000) | \
(((x) & 0xff000000) << 8) | \
(((x) & 0xff0000) << 24) | \
(((x) & 0xff00) << 40) | \
(((x) & 0xff) << 56)))
#define sys_le16_to_cpu(val) (val)
#define sys_cpu_to_le16(val) (val)
#define sys_be16_to_cpu(val) __bswap_16(val)
#define sys_cpu_to_be16(val) __bswap_16(val)
#define sys_le32_to_cpu(val) (val)
#define sys_cpu_to_le32(val) (val)
#define sys_le64_to_cpu(val) (val)
#define sys_cpu_to_le64(val) (val)
#define sys_be32_to_cpu(val) __bswap_32(val)
#define sys_cpu_to_be32(val) __bswap_32(val)
#define sys_be64_to_cpu(val) __bswap_64(val)
#define sys_cpu_to_be64(val) __bswap_64(val)
#ifdef INLINED
#define INLINE inline
#else
#define INLINE
#endif
#define NOINIT
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
static inline int is_power_of_two(unsigned int x)
{
return (x != 0) && !(x & (x - 1));
}
static inline s64_t arithmetic_shift_right(s64_t value, u8_t shift)
{
s64_t sign_ext;
if (shift == 0) {
return value;
}
/* extract sign bit */
sign_ext = (value >> 63) & 1;
/* make all bits of sign_ext be the same as the value's sign bit */
sign_ext = -sign_ext;
/* shift value and fill opened bit positions with sign bit */
return (value >> shift) | (sign_ext << (64 - shift));
}
#endif /* !_ASMLANGUAGE */
/* KB, MB, GB */
#define KB(x) ((x) << 10)
#define MB(x) (KB(x) << 10)
#define GB(x) (MB(x) << 10)
/* KHZ, MHZ */
#define KHZ(x) ((x) * 1000)
#define MHZ(x) (KHZ(x) * 1000)
#ifndef BIT
#define BIT(n) (1UL << (n))
#endif
#define BIT_MASK(n) (BIT(n) - 1)
/**
* @brief Check for macro definition in compiler-visible expressions
*
* This trick was pioneered in Linux as the config_enabled() macro.
* The madness has the effect of taking a macro value that may be
* defined to "1" (e.g. CONFIG_MYFEATURE), or may not be defined at
* all and turning it into a literal expression that can be used at
* "runtime". That is, it works similarly to
* "defined(CONFIG_MYFEATURE)" does except that it is an expansion
* that can exist in a standard expression and be seen by the compiler
* and optimizer. Thus much ifdef usage can be replaced with cleaner
* expressions like:
*
* if (IS_ENABLED(CONFIG_MYFEATURE))
* myfeature_enable();
*
* INTERNAL
* First pass just to expand any existing macros, we need the macro
* value to be e.g. a literal "1" at expansion time in the next macro,
* not "(1)", etc... Standard recursive expansion does not work.
*/
#define IS_ENABLED(config_macro) _IS_ENABLED1(config_macro)
/* Now stick on a "_XXXX" prefix, it will now be "_XXXX1" if config_macro
* is "1", or just "_XXXX" if it's undefined.
* ENABLED: _IS_ENABLED2(_XXXX1)
* DISABLED _IS_ENABLED2(_XXXX)
*/
#define _IS_ENABLED1(config_macro) _IS_ENABLED2(_XXXX##config_macro)
/* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string
* with a trailing comma), so it has the effect of making this a
* two-argument tuple to the preprocessor only in the case where the
* value is defined to "1"
* ENABLED: _YYYY, <--- note comma!
* DISABLED: _XXXX
*/
#define _XXXX1 _YYYY,
/* Then we append an extra argument to fool the gcc preprocessor into
* accepting it as a varargs macro.
* arg1 arg2 arg3
* ENABLED: _IS_ENABLED3(_YYYY, 1, 0)
* DISABLED _IS_ENABLED3(_XXXX 1, 0)
*/
#define _IS_ENABLED2(one_or_two_args) _IS_ENABLED3(one_or_two_args 1, 0)
/* And our second argument is thus now cooked to be 1 in the case
* where the value is defined to 1, and 0 if not:
*/
#define _IS_ENABLED3(ignore_this, val, ...) val
/**
* Macros for doing code-generation with the preprocessor.
*
* Generally it is better to generate code with the preprocessor than
* to copy-paste code or to generate code with the build system /
* python script's etc.
*
* http://stackoverflow.com/a/12540675
*/
#define UTIL_EMPTY(...)
#define UTIL_DEFER(...) __VA_ARGS__ UTIL_EMPTY()
#define UTIL_OBSTRUCT(...) __VA_ARGS__ UTIL_DEFER(UTIL_EMPTY)()
#define UTIL_EXPAND(...) __VA_ARGS__
#define UTIL_EVAL(...) UTIL_EVAL1(UTIL_EVAL1(UTIL_EVAL1(__VA_ARGS__)))
#define UTIL_EVAL1(...) UTIL_EVAL2(UTIL_EVAL2(UTIL_EVAL2(__VA_ARGS__)))
#define UTIL_EVAL2(...) UTIL_EVAL3(UTIL_EVAL3(UTIL_EVAL3(__VA_ARGS__)))
#define UTIL_EVAL3(...) UTIL_EVAL4(UTIL_EVAL4(UTIL_EVAL4(__VA_ARGS__)))
#define UTIL_EVAL4(...) UTIL_EVAL5(UTIL_EVAL5(UTIL_EVAL5(__VA_ARGS__)))
#define UTIL_EVAL5(...) __VA_ARGS__
#define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__)
#define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
#define UTIL_INC(x) UTIL_PRIMITIVE_CAT(UTIL_INC_, x)
#define UTIL_INC_0 1
#define UTIL_INC_1 2
#define UTIL_INC_2 3
#define UTIL_INC_3 4
#define UTIL_INC_4 5
#define UTIL_INC_5 6
#define UTIL_INC_6 7
#define UTIL_INC_7 8
#define UTIL_INC_8 9
#define UTIL_INC_9 10
#define UTIL_INC_10 11
#define UTIL_INC_11 12
#define UTIL_INC_12 13
#define UTIL_INC_13 14
#define UTIL_INC_14 15
#define UTIL_INC_15 16
#define UTIL_INC_16 17
#define UTIL_INC_17 18
#define UTIL_INC_18 19
#define UTIL_INC_19 19
#define UTIL_DEC(x) UTIL_PRIMITIVE_CAT(UTIL_DEC_, x)
#define UTIL_DEC_0 0
#define UTIL_DEC_1 0
#define UTIL_DEC_2 1
#define UTIL_DEC_3 2
#define UTIL_DEC_4 3
#define UTIL_DEC_5 4
#define UTIL_DEC_6 5
#define UTIL_DEC_7 6
#define UTIL_DEC_8 7
#define UTIL_DEC_9 8
#define UTIL_DEC_10 9
#define UTIL_DEC_11 10
#define UTIL_DEC_12 11
#define UTIL_DEC_13 12
#define UTIL_DEC_14 13
#define UTIL_DEC_15 14
#define UTIL_DEC_16 15
#define UTIL_DEC_17 16
#define UTIL_DEC_18 17
#define UTIL_DEC_19 18
#define UTIL_CHECK_N(x, n, ...) n
#define UTIL_CHECK(...) UTIL_CHECK_N(__VA_ARGS__, 0,)
#define UTIL_NOT(x) UTIL_CHECK(UTIL_PRIMITIVE_CAT(UTIL_NOT_, x))
#define UTIL_NOT_0 ~, 1,
#define UTIL_COMPL(b) UTIL_PRIMITIVE_CAT(UTIL_COMPL_, b)
#define UTIL_COMPL_0 1
#define UTIL_COMPL_1 0
#define UTIL_BOOL(x) UTIL_COMPL(UTIL_NOT(x))
#define UTIL_IIF(c) UTIL_PRIMITIVE_CAT(UTIL_IIF_, c)
#define UTIL_IIF_0(t, ...) __VA_ARGS__
#define UTIL_IIF_1(t, ...) t
#define UTIL_IF(c) UTIL_IIF(UTIL_BOOL(c))
#define UTIL_EAT(...)
#define UTIL_EXPAND(...) __VA_ARGS__
#define UTIL_WHEN(c) UTIL_IF(c)(UTIL_EXPAND, UTIL_EAT)
#define UTIL_REPEAT(count, macro, ...) \
UTIL_WHEN(count) \
( \
UTIL_OBSTRUCT(UTIL_REPEAT_INDIRECT) () \
( \
UTIL_DEC(count), macro, __VA_ARGS__ \
) \
UTIL_OBSTRUCT(macro) \
( \
UTIL_DEC(count), __VA_ARGS__ \
) \
)
#define UTIL_REPEAT_INDIRECT() UTIL_REPEAT
#define _STRINGIFY(x) #x
#define STRINGIFY(s) _STRINGIFY(s)
/* ESP Toolchain doesn't support section */
#define ___in_section(a, b, c)
#define __in_section(a, b, c) ___in_section(a, b, c)
#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__)
/* ESP Toolchain doesn't support section */
#define __noinit
#define popcount(x) __builtin_popcount(x)
/**
*
* @brief find most significant bit set in a 32-bit word
*
* This routine finds the first bit set starting from the most significant bit
* in the argument passed in and returns the index of that bit. Bits are
* numbered starting at 1 from the least significant bit. A return value of
* zero indicates that the value passed is zero.
*
* @return most significant bit set, 0 if @a op is 0
*/
#if defined(__GNUC__)
static inline unsigned int find_msb_set(u32_t op)
{
if (!op) {
return 0;
}
return 32 - __builtin_clz(op);
}
#endif
/**
*
* @brief find least significant bit set in a 32-bit word
*
* This routine finds the first bit set starting from the least significant bit
* in the argument passed in and returns the index of that bit. Bits are
* numbered starting at 1 from the least significant bit. A return value of
* zero indicates that the value passed is zero.
*
* @return least significant bit set, 0 if @a op is 0
*/
#if defined(__GNUC__)
static inline unsigned int find_lsb_set(u32_t op)
{
return __builtin_ffs(op);
}
#endif
#define __ASSERT(test, fmt, ...) \
do { \
if (!(test)) { \
printk("ASSERTION FAIL [%s] @ %s:%d:\n\t", \
_STRINGIFY(test), \
__FILE__, \
__LINE__); \
printk(fmt, ##__VA_ARGS__); \
for (;;) \
; /* spin thread */ \
} \
} while ((0))
/**
* Generates a sequence of code.
* Useful for generating code like;
*
* NRF_PWM0, NRF_PWM1, NRF_PWM2,
*
* @arg LEN: The length of the sequence. Must be defined and less than
* 20.
*
* @arg F(i, F_ARG): A macro function that accepts two arguments.
* F is called repeatedly, the first argument
* is the index in the sequence, and the second argument is the third
* argument given to UTIL_LISTIFY.
*
* Example:
*
* \#define FOO(i, _) NRF_PWM ## i ,
* { UTIL_LISTIFY(PWM_COUNT, FOO) }
* // The above two lines will generate the below:
* { NRF_PWM0 , NRF_PWM1 , }
*
* @note Calling UTIL_LISTIFY with undefined arguments has undefined
* behaviour.
*/
#define UTIL_LISTIFY(LEN, F, F_ARG) UTIL_EVAL(UTIL_REPEAT(LEN, F, F_ARG))
/**
* @brief Put a 16-bit integer as big-endian to arbitrary location.
*
* Put a 16-bit integer, originally in host endianness, to a
* potentially unaligned memory location in big-endian format.
*
* @param val 16-bit integer in host endianness.
* @param dst Destination memory address to store the result.
*/
static inline void sys_put_be16(u16_t val, u8_t dst[2])
{
dst[0] = val >> 8;
dst[1] = val;
}
/**
* @brief Put a 32-bit integer as big-endian to arbitrary location.
*
* Put a 32-bit integer, originally in host endianness, to a
* potentially unaligned memory location in big-endian format.
*
* @param val 32-bit integer in host endianness.
* @param dst Destination memory address to store the result.
*/
static inline void sys_put_be32(u32_t val, u8_t dst[4])
{
sys_put_be16(val >> 16, dst);
sys_put_be16(val, &dst[2]);
}
/**
* @brief Put a 16-bit integer as little-endian to arbitrary location.
*
* Put a 16-bit integer, originally in host endianness, to a
* potentially unaligned memory location in little-endian format.
*
* @param val 16-bit integer in host endianness.
* @param dst Destination memory address to store the result.
*/
static inline void sys_put_le16(u16_t val, u8_t dst[2])
{
dst[0] = val;
dst[1] = val >> 8;
}
/**
* @brief Put a 32-bit integer as little-endian to arbitrary location.
*
* Put a 32-bit integer, originally in host endianness, to a
* potentially unaligned memory location in little-endian format.
*
* @param val 32-bit integer in host endianness.
* @param dst Destination memory address to store the result.
*/
static inline void sys_put_le32(u32_t val, u8_t dst[4])
{
sys_put_le16(val, dst);
sys_put_le16(val >> 16, &dst[2]);
}
/**
* @brief Put a 64-bit integer as little-endian to arbitrary location.
*
* Put a 64-bit integer, originally in host endianness, to a
* potentially unaligned memory location in little-endian format.
*
* @param val 64-bit integer in host endianness.
* @param dst Destination memory address to store the result.
*/
static inline void sys_put_le64(u64_t val, u8_t dst[8])
{
sys_put_le32(val, dst);
sys_put_le32(val >> 32, &dst[4]);
}
/**
* @brief Get a 16-bit integer stored in big-endian format.
*
* Get a 16-bit integer, stored in big-endian format in a potentially
* unaligned memory location, and convert it to the host endianness.
*
* @param src Location of the big-endian 16-bit integer to get.
*
* @return 16-bit integer in host endianness.
*/
static inline u16_t sys_get_be16(const u8_t src[2])
{
return ((u16_t)src[0] << 8) | src[1];
}
/**
* @brief Get a 32-bit integer stored in big-endian format.
*
* Get a 32-bit integer, stored in big-endian format in a potentially
* unaligned memory location, and convert it to the host endianness.
*
* @param src Location of the big-endian 32-bit integer to get.
*
* @return 32-bit integer in host endianness.
*/
static inline u32_t sys_get_be32(const u8_t src[4])
{
return ((u32_t)sys_get_be16(&src[0]) << 16) | sys_get_be16(&src[2]);
}
/**
* @brief Get a 16-bit integer stored in little-endian format.
*
* Get a 16-bit integer, stored in little-endian format in a potentially
* unaligned memory location, and convert it to the host endianness.
*
* @param src Location of the little-endian 16-bit integer to get.
*
* @return 16-bit integer in host endianness.
*/
static inline u16_t sys_get_le16(const u8_t src[2])
{
return ((u16_t)src[1] << 8) | src[0];
}
/**
* @brief Get a 32-bit integer stored in little-endian format.
*
* Get a 32-bit integer, stored in little-endian format in a potentially
* unaligned memory location, and convert it to the host endianness.
*
* @param src Location of the little-endian 32-bit integer to get.
*
* @return 32-bit integer in host endianness.
*/
static inline u32_t sys_get_le32(const u8_t src[4])
{
return ((u32_t)sys_get_le16(&src[2]) << 16) | sys_get_le16(&src[0]);
}
/**
* @brief Get a 64-bit integer stored in little-endian format.
*
* Get a 64-bit integer, stored in little-endian format in a potentially
* unaligned memory location, and convert it to the host endianness.
*
* @param src Location of the little-endian 64-bit integer to get.
*
* @return 64-bit integer in host endianness.
*/
static inline u64_t sys_get_le64(const u8_t src[8])
{
return ((u64_t)sys_get_le32(&src[4]) << 32) | sys_get_le32(&src[0]);
}
const char *bt_hex(const void *buf, size_t len);
void mem_rcopy(u8_t *dst, u8_t const *src, u16_t len);
void _set(void *to, uint8_t val, unsigned int len);
unsigned int _copy(uint8_t *to, unsigned int to_len,
const uint8_t *from, unsigned int from_len);
void _set(void *to, uint8_t val, unsigned int len);
uint8_t _double_byte(uint8_t a);
int _compare(const uint8_t *a, const uint8_t *b, size_t size);
/**
* @brief Swap one buffer content into another
*
* Copy the content of src buffer into dst buffer in reversed order,
* i.e.: src[n] will be put in dst[end-n]
* Where n is an index and 'end' the last index in both arrays.
* The 2 memory pointers must be pointing to different areas, and have
* a minimum size of given length.
*
* @param dst A valid pointer on a memory area where to copy the data in
* @param src A valid pointer on a memory area where to copy the data from
* @param length Size of both dst and src memory areas
*/
static inline void sys_memcpy_swap(void *dst, const void *src, size_t length)
{
__ASSERT(((src < dst && (src + length) <= dst) ||
(src > dst && (dst + length) <= src)),
"Source and destination buffers must not overlap");
src += length - 1;
for (; length > 0; length--) {
*((u8_t *)dst++) = *((u8_t *)src--);
}
}
/**
* @brief Swap buffer content
*
* In-place memory swap, where final content will be reversed.
* I.e.: buf[n] will be put in buf[end-n]
* Where n is an index and 'end' the last index of buf.
*
* @param buf A valid pointer on a memory area to swap
* @param length Size of buf memory area
*/
static inline void sys_mem_swap(void *buf, size_t length)
{
size_t i;
for (i = 0; i < (length / 2); i++) {
u8_t tmp = ((u8_t *)buf)[i];
((u8_t *)buf)[i] = ((u8_t *)buf)[length - 1 - i];
((u8_t *)buf)[length - 1 - i] = tmp;
}
}
#ifdef __cplusplus
}
#endif
#endif /* _UTIL__H_ */

View File

@@ -0,0 +1,37 @@
/** @file
* @brief Bluetooth Mesh Proxy APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_MESH_PROXY_H
#define __BT_MESH_PROXY_H
#include <stddef.h>
/**
* @brief Bluetooth Mesh Proxy
* @defgroup bt_mesh_proxy Bluetooth Mesh Proxy
* @ingroup bt_mesh
* @{
*/
/**
* @brief Enable advertising with Node Identity.
*
* This API requires that GATT Proxy support has been enabled. Once called
* each subnet will start advertising using Node Identity for the next
* 60 seconds.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_proxy_identity_enable(void);
/**
* @}
*/
#endif /* __BT_MESH_PROXY_H */

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _SETTINGS_H_
#define _SETTINGS_H_
#include "sdkconfig.h"
#include "net.h"
#include "mesh_access.h"
#include "mesh_bearer_adapt.h"
struct bt_settings_handler {
const char *name;
int (*set)(int argc, char **argv, char *val);
int (*commit)(void);
int (*export)(int (*func)(const char *name, char *val));
};
#define BT_SETTINGS_DEFINE(_name, _set, _commit, _export) \
const struct bt_settings_handler _name __aligned(4) \
__in_section(_bt_settings, static, _name) = { \
.name = STRINGIFY(_name), \
.set = _set, \
.commit = _commit, \
.export = _export, \
}
/* Max settings key length (with all components) */
#define BT_SETTINGS_KEY_MAX 36
/* Base64-encoded string buffer size of in_size bytes */
#define BT_SETTINGS_SIZE(in_size) ((((((in_size) - 1) / 3) * 4) + 4) + 1)
/* Helpers for keys containing a bdaddr */
void bt_settings_encode_key(char *path, size_t path_size, const char *subsys,
bt_addr_le_t *addr, const char *key);
int bt_settings_decode_key(char *key, bt_addr_le_t *addr);
void bt_mesh_store_net(void);
void bt_mesh_store_iv(void);
void bt_mesh_store_seq(void);
void bt_mesh_store_rpl(struct bt_mesh_rpl *rpl);
void bt_mesh_store_subnet(struct bt_mesh_subnet *sub);
void bt_mesh_store_app_key(struct bt_mesh_app_key *key);
void bt_mesh_store_hb_pub(void);
void bt_mesh_store_cfg(void);
void bt_mesh_store_mod_bind(struct bt_mesh_model *mod);
void bt_mesh_store_mod_sub(struct bt_mesh_model *mod);
void bt_mesh_store_mod_pub(struct bt_mesh_model *mod);
void bt_mesh_clear_net(void);
void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub);
void bt_mesh_clear_app_key(struct bt_mesh_app_key *key);
void bt_mesh_clear_rpl(void);
int bt_mesh_settings_init(void);
#endif /* _SETTINGS_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf);
int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf);
int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf);
int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf);
static inline bool bt_mesh_lpn_established(void)
{
#if defined(CONFIG_BT_MESH_LOW_POWER)
return bt_mesh.lpn.established;
#else
return false;
#endif
}
static inline bool bt_mesh_lpn_match(u16_t addr)
{
#if defined(CONFIG_BT_MESH_LOW_POWER)
if (bt_mesh_lpn_established()) {
return (addr == bt_mesh.lpn.frnd);
}
#endif
return false;
}
static inline bool bt_mesh_lpn_waiting_update(void)
{
#if defined(CONFIG_BT_MESH_LOW_POWER)
return (bt_mesh.lpn.state == BT_MESH_LPN_WAIT_UPDATE);
#else
return false;
#endif
}
static inline bool bt_mesh_lpn_timer(void)
{
#if defined(CONFIG_BT_MESH_LPN_AUTO)
return (bt_mesh.lpn.state == BT_MESH_LPN_TIMER);
#else
return false;
#endif
}
void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx);
void bt_mesh_lpn_group_add(u16_t group);
void bt_mesh_lpn_group_del(u16_t *groups, size_t group_count);
void bt_mesh_lpn_disable(bool force);
int bt_mesh_lpn_init(void);

View File

@@ -0,0 +1,19 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#define BT_MESH_KEY_PRIMARY 0x0000
#define BT_MESH_KEY_ANY 0xffff
#define BT_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000)
#define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00)
#define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000)
#define BT_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb)
struct bt_mesh_net;
bool bt_mesh_is_provisioned(void);

View File

@@ -0,0 +1,415 @@
/* aes_encrypt.c - TinyCrypt implementation of AES encryption procedure */
/*
* Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "mesh_aes_encrypt.h"
#include "mesh_util.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
/* max number of calls until change the key (2^48).*/
const static uint64_t MAX_CALLS = ((uint64_t)1 << 48);
/*
* gf_wrap -- In our implementation, GF(2^128) is represented as a 16 byte
* array with byte 0 the most significant and byte 15 the least significant.
* High bit carry reduction is based on the primitive polynomial
*
* X^128 + X^7 + X^2 + X + 1,
*
* which leads to the reduction formula X^128 = X^7 + X^2 + X + 1. Indeed,
* since 0 = (X^128 + X^7 + X^2 + 1) mod (X^128 + X^7 + X^2 + X + 1) and since
* addition of polynomials with coefficients in Z/Z(2) is just XOR, we can
* add X^128 to both sides to get
*
* X^128 = (X^7 + X^2 + X + 1) mod (X^128 + X^7 + X^2 + X + 1)
*
* and the coefficients of the polynomial on the right hand side form the
* string 1000 0111 = 0x87, which is the value of gf_wrap.
*
* This gets used in the following way. Doubling in GF(2^128) is just a left
* shift by 1 bit, except when the most significant bit is 1. In the latter
* case, the relation X^128 = X^7 + X^2 + X + 1 says that the high order bit
* that overflows beyond 128 bits can be replaced by addition of
* X^7 + X^2 + X + 1 <--> 0x87 to the low order 128 bits. Since addition
* in GF(2^128) is represented by XOR, we therefore only have to XOR 0x87
* into the low order byte after a left shift when the starting high order
* bit is 1.
*/
const unsigned char gf_wrap = 0x87;
static const uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16
};
static inline unsigned int rotword(unsigned int a)
{
return (((a) >> 24) | ((a) << 8));
}
#define subbyte(a, o)(sbox[((a) >> (o))&0xff] << (o))
#define subword(a)(subbyte(a, 24)|subbyte(a, 16)|subbyte(a, 8)|subbyte(a, 0))
int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k)
{
const unsigned int rconst[11] = {
0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000
};
unsigned int i;
unsigned int t;
if (s == (TCAesKeySched_t) 0) {
return TC_CRYPTO_FAIL;
} else if (k == (const uint8_t *) 0) {
return TC_CRYPTO_FAIL;
}
for (i = 0; i < Nk; ++i) {
s->words[i] = (k[Nb * i] << 24) | (k[Nb * i + 1] << 16) |
(k[Nb * i + 2] << 8) | (k[Nb * i + 3]);
}
for (; i < (Nb * (Nr + 1)); ++i) {
t = s->words[i - 1];
if ((i % Nk) == 0) {
t = subword(rotword(t)) ^ rconst[i / Nk];
}
s->words[i] = s->words[i - Nk] ^ t;
}
return TC_CRYPTO_SUCCESS;
}
static inline void add_round_key(uint8_t *s, const unsigned int *k)
{
s[0] ^= (uint8_t)(k[0] >> 24); s[1] ^= (uint8_t)(k[0] >> 16);
s[2] ^= (uint8_t)(k[0] >> 8); s[3] ^= (uint8_t)(k[0]);
s[4] ^= (uint8_t)(k[1] >> 24); s[5] ^= (uint8_t)(k[1] >> 16);
s[6] ^= (uint8_t)(k[1] >> 8); s[7] ^= (uint8_t)(k[1]);
s[8] ^= (uint8_t)(k[2] >> 24); s[9] ^= (uint8_t)(k[2] >> 16);
s[10] ^= (uint8_t)(k[2] >> 8); s[11] ^= (uint8_t)(k[2]);
s[12] ^= (uint8_t)(k[3] >> 24); s[13] ^= (uint8_t)(k[3] >> 16);
s[14] ^= (uint8_t)(k[3] >> 8); s[15] ^= (uint8_t)(k[3]);
}
static inline void sub_bytes(uint8_t *s)
{
unsigned int i;
for (i = 0; i < (Nb * Nk); ++i) {
s[i] = sbox[s[i]];
}
}
#define triple(a)(_double_byte(a)^(a))
static inline void mult_row_column(uint8_t *out, const uint8_t *in)
{
out[0] = _double_byte(in[0]) ^ triple(in[1]) ^ in[2] ^ in[3];
out[1] = in[0] ^ _double_byte(in[1]) ^ triple(in[2]) ^ in[3];
out[2] = in[0] ^ in[1] ^ _double_byte(in[2]) ^ triple(in[3]);
out[3] = triple(in[0]) ^ in[1] ^ in[2] ^ _double_byte(in[3]);
}
static inline void mix_columns(uint8_t *s)
{
uint8_t t[Nb * Nk];
mult_row_column(t, s);
mult_row_column(&t[Nb], s + Nb);
mult_row_column(&t[2 * Nb], s + (2 * Nb));
mult_row_column(&t[3 * Nb], s + (3 * Nb));
(void) _copy(s, sizeof(t), t, sizeof(t));
}
/*
* This shift_rows also implements the matrix flip required for mix_columns, but
* performs it here to reduce the number of memory operations.
*/
static inline void shift_rows(uint8_t *s)
{
uint8_t t[Nb * Nk];
t[0] = s[0]; t[1] = s[5]; t[2] = s[10]; t[3] = s[15];
t[4] = s[4]; t[5] = s[9]; t[6] = s[14]; t[7] = s[3];
t[8] = s[8]; t[9] = s[13]; t[10] = s[2]; t[11] = s[7];
t[12] = s[12]; t[13] = s[1]; t[14] = s[6]; t[15] = s[11];
(void) _copy(s, sizeof(t), t, sizeof(t));
}
int tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s)
{
uint8_t state[Nk * Nb];
unsigned int i;
if (out == (uint8_t *) 0) {
return TC_CRYPTO_FAIL;
} else if (in == (const uint8_t *) 0) {
return TC_CRYPTO_FAIL;
} else if (s == (TCAesKeySched_t) 0) {
return TC_CRYPTO_FAIL;
}
(void)_copy(state, sizeof(state), in, sizeof(state));
add_round_key(state, s->words);
for (i = 0; i < (Nr - 1); ++i) {
sub_bytes(state);
shift_rows(state);
mix_columns(state);
add_round_key(state, s->words + Nb * (i + 1));
}
sub_bytes(state);
shift_rows(state);
add_round_key(state, s->words + Nb * (i + 1));
(void)_copy(out, sizeof(state), state, sizeof(state));
/* zeroing out the state buffer */
_set(state, TC_ZERO_BYTE, sizeof(state));
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched)
{
/* input sanity check: */
if (s == (TCCmacState_t) 0 ||
key == (const uint8_t *) 0) {
return TC_CRYPTO_FAIL;
}
/* put s into a known state */
_set(s, 0, sizeof(*s));
s->sched = sched;
/* configure the encryption key used by the underlying block cipher */
tc_aes128_set_encrypt_key(s->sched, key);
/* compute s->K1 and s->K2 from s->iv using s->keyid */
_set(s->iv, 0, TC_AES_BLOCK_SIZE);
tc_aes_encrypt(s->iv, s->iv, s->sched);
gf_double (s->K1, s->iv);
gf_double (s->K2, s->K1);
/* reset s->iv to 0 in case someone wants to compute now */
tc_cmac_init(s);
return TC_CRYPTO_SUCCESS;
}
/*
* assumes: out != NULL and points to a GF(2^n) value to receive the
* doubled value;
* in != NULL and points to a 16 byte GF(2^n) value
* to double;
* the in and out buffers do not overlap.
* effects: doubles the GF(2^n) value pointed to by "in" and places
* the result in the GF(2^n) value pointed to by "out."
*/
void gf_double(uint8_t *out, uint8_t *in)
{
/* start with low order byte */
uint8_t *x = in + (TC_AES_BLOCK_SIZE - 1);
/* if msb == 1, we need to add the gf_wrap value, otherwise add 0 */
uint8_t carry = (in[0] >> 7) ? gf_wrap : 0;
out += (TC_AES_BLOCK_SIZE - 1);
for (;;) {
*out-- = (*x << 1) ^ carry;
if (x == in) {
break;
}
carry = *x-- >> 7;
}
}
int tc_cmac_init(TCCmacState_t s)
{
/* input sanity check: */
if (s == (TCCmacState_t) 0) {
return TC_CRYPTO_FAIL;
}
/* CMAC starts with an all zero initialization vector */
_set(s->iv, 0, TC_AES_BLOCK_SIZE);
/* and the leftover buffer is empty */
_set(s->leftover, 0, TC_AES_BLOCK_SIZE);
s->leftover_offset = 0;
/* Set countdown to max number of calls allowed before re-keying: */
s->countdown = MAX_CALLS;
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length)
{
unsigned int i;
/* input sanity check: */
if (s == (TCCmacState_t) 0) {
return TC_CRYPTO_FAIL;
}
if (data_length == 0) {
return TC_CRYPTO_SUCCESS;
}
if (data == (const uint8_t *) 0) {
return TC_CRYPTO_FAIL;
}
if (s->countdown == 0) {
return TC_CRYPTO_FAIL;
}
s->countdown--;
if (s->leftover_offset > 0) {
/* last data added to s didn't end on a TC_AES_BLOCK_SIZE byte boundary */
size_t remaining_space = TC_AES_BLOCK_SIZE - s->leftover_offset;
if (data_length < remaining_space) {
/* still not enough data to encrypt this time either */
_copy(&s->leftover[s->leftover_offset], data_length, data, data_length);
s->leftover_offset += data_length;
return TC_CRYPTO_SUCCESS;
}
/* leftover block is now full; encrypt it first */
_copy(&s->leftover[s->leftover_offset],
remaining_space,
data,
remaining_space);
data_length -= remaining_space;
data += remaining_space;
s->leftover_offset = 0;
for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
s->iv[i] ^= s->leftover[i];
}
tc_aes_encrypt(s->iv, s->iv, s->sched);
}
/* CBC encrypt each (except the last) of the data blocks */
while (data_length > TC_AES_BLOCK_SIZE) {
for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
s->iv[i] ^= data[i];
}
tc_aes_encrypt(s->iv, s->iv, s->sched);
data += TC_AES_BLOCK_SIZE;
data_length -= TC_AES_BLOCK_SIZE;
}
if (data_length > 0) {
/* save leftover data for next time */
_copy(s->leftover, data_length, data, data_length);
s->leftover_offset = data_length;
}
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_final(uint8_t *tag, TCCmacState_t s)
{
uint8_t *k;
unsigned int i;
/* input sanity check: */
if (tag == (uint8_t *) 0 ||
s == (TCCmacState_t) 0) {
return TC_CRYPTO_FAIL;
}
if (s->leftover_offset == TC_AES_BLOCK_SIZE) {
/* the last message block is a full-sized block */
k = (uint8_t *) s->K1;
} else {
/* the final message block is not a full-sized block */
size_t remaining = TC_AES_BLOCK_SIZE - s->leftover_offset;
_set(&s->leftover[s->leftover_offset], 0, remaining);
s->leftover[s->leftover_offset] = TC_CMAC_PADDING;
k = (uint8_t *) s->K2;
}
for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) {
s->iv[i] ^= s->leftover[i] ^ k[i];
}
tc_aes_encrypt(tag, s->iv, s->sched);
/* erasing state: */
tc_cmac_erase(s);
return TC_CRYPTO_SUCCESS;
}
int tc_cmac_erase(TCCmacState_t s)
{
if (s == (TCCmacState_t) 0) {
return TC_CRYPTO_FAIL;
}
/* destroy the current state */
_set(s, 0, sizeof(*s));
return TC_CRYPTO_SUCCESS;
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,180 @@
/**
* @brief Atomically set a bit.
*
* Atomically set bit number @a bit of @a target.
* The target may be a single atomic variable or an array of them.
*
* @param target Address of atomic variable or array.
* @param bit Bit number (starting from 0).
*
* @return N/A
*/
/*
* Copyright (c) 2016 Intel Corporation
* Copyright (c) 2011-2014 Wind River Systems, Inc.
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mesh_atomic.h"
#include "mesh_kernel.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
/**
*
* @brief Atomic get primitive
*
* @param target memory location to read from
*
* This routine provides the atomic get primitive to atomically read
* a value from <target>. It simply does an ordinary load. Note that <target>
* is expected to be aligned to a 4-byte boundary.
*
* @return The value read from <target>
*/
atomic_val_t atomic_get(const atomic_t *target)
{
return *target;
}
/**
*
* @brief Atomic get-and-set primitive
*
* This routine provides the atomic set operator. The <value> is atomically
* written at <target> and the previous value at <target> is returned.
*
* @param target the memory location to write to
* @param value the value to write
*
* @return The previous value from <target>
*/
atomic_val_t atomic_set(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
key = irq_lock();
ret = *target;
*target = value;
irq_unlock(key);
return ret;
}
/**
*
* @brief Atomic bitwise inclusive OR primitive
*
* This routine provides the atomic bitwise inclusive OR operator. The <value>
* is atomically bitwise OR'ed with the value at <target>, placing the result
* at <target>, and the previous value at <target> is returned.
*
* @param target the memory location to be modified
* @param value the value to OR
*
* @return The previous value from <target>
*/
atomic_val_t atomic_or(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
key = irq_lock();
ret = *target;
*target |= value;
irq_unlock(key);
return ret;
}
/**
*
* @brief Atomic bitwise AND primitive
*
* This routine provides the atomic bitwise AND operator. The <value> is
* atomically bitwise AND'ed with the value at <target>, placing the result
* at <target>, and the previous value at <target> is returned.
*
* @param target the memory location to be modified
* @param value the value to AND
*
* @return The previous value from <target>
*/
atomic_val_t atomic_and(atomic_t *target, atomic_val_t value)
{
unsigned int key;
atomic_val_t ret;
key = irq_lock();
ret = *target;
*target &= value;
irq_unlock(key);
return ret;
}
/**
*
* @brief Atomic decrement primitive
*
* @param target memory location to decrement
*
* This routine provides the atomic decrement operator. The value at <target>
* is atomically decremented by 1, and the old value from <target> is returned.
*
* @return The value from <target> prior to the decrement
*/
atomic_val_t atomic_dec(atomic_t *target)
{
unsigned int key;
atomic_val_t ret;
key = irq_lock();
ret = *target;
(*target)--;
irq_unlock(key);
return ret;
}
/**
*
* @brief Atomic increment primitive
*
* @param target memory location to increment
*
* This routine provides the atomic increment operator. The value at <target>
* is atomically incremented by 1, and the old value from <target> is returned.
*
* @return The value from <target> before the increment
*/
atomic_val_t atomic_inc(atomic_t *target)
{
unsigned int key;
atomic_val_t ret;
key = irq_lock();
ret = *target;
(*target)++;
irq_unlock(key);
return ret;
}
#endif /* #if CONFIG_BT_MESH */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,528 @@
/*
* Copyright (c) 2015 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "mesh_buf.h"
#include "mesh_trace.h"
#include "esp_bt_defs.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
/* Helpers to access the storage array, since we don't have access to its
* type at this point anymore.
*/
#define BUF_SIZE(pool) (sizeof(struct net_buf) + \
ROUND_UP(pool->buf_size, 4) + \
ROUND_UP(pool->user_data_size, 4))
#define UNINIT_BUF(pool, n) (struct net_buf *)(((u8_t *)(pool->__bufs)) + \
((n) * BUF_SIZE(pool)))
/* Linker-defined symbol bound to the static pool structs */
struct net_buf_pool *net_buf_pool_get(int id)
{
return (struct net_buf_pool *)id;
}
//static int pool_id(struct net_buf_pool *pool)
//{
// BT_DBG("%s, the pool id = %p", __func__, pool);
// return (int)&pool[pool->buf_count - pool->uninit_count - 1];
//}
static inline struct net_buf *pool_get_uninit(struct net_buf_pool *pool,
u16_t uninit_count)
{
struct net_buf *buf;
buf = UNINIT_BUF(pool, pool->buf_count - uninit_count);
buf->pool_id = pool;
buf->size = pool->buf_size;
BT_DBG("%s, pool_id = %p, uninit_count = %d, pool->buf_count = %d, buf = %p, buf->size = %d, pool = %p",
__func__, buf->pool_id, uninit_count, pool->buf_count, buf, buf->size, pool);
return buf;
}
void *net_buf_simple_add(struct net_buf_simple *buf, size_t len)
{
u8_t *tail = net_buf_simple_tail(buf);
NET_BUF_SIMPLE_DBG("buf %p len %u", buf, len);
NET_BUF_SIMPLE_ASSERT(net_buf_simple_tailroom(buf) >= len);
buf->len += len;
return tail;
}
void *net_buf_simple_add_mem(struct net_buf_simple *buf, const void *mem,
size_t len)
{
NET_BUF_SIMPLE_DBG("buf %p len %u", buf, len);
return memcpy(net_buf_simple_add(buf, len), mem, len);
}
u8_t *net_buf_simple_add_u8(struct net_buf_simple *buf, u8_t val)
{
u8_t *u8;
NET_BUF_SIMPLE_DBG("buf %p val 0x%02x", buf, val);
u8 = net_buf_simple_add(buf, 1);
*u8 = val;
return u8;
}
void net_buf_simple_add_le16(struct net_buf_simple *buf, u16_t val)
{
NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
val = sys_cpu_to_le16(val);
memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val));
}
void net_buf_simple_add_be16(struct net_buf_simple *buf, u16_t val)
{
NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
val = sys_cpu_to_be16(val);
memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val));
}
void net_buf_simple_add_le32(struct net_buf_simple *buf, u32_t val)
{
NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
val = sys_cpu_to_le32(val);
memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val));
}
void net_buf_simple_add_be32(struct net_buf_simple *buf, u32_t val)
{
NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
val = sys_cpu_to_be32(val);
memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val));
}
void *net_buf_simple_push(struct net_buf_simple *buf, size_t len)
{
NET_BUF_SIMPLE_DBG("buf %p len %u", buf, len);
NET_BUF_SIMPLE_ASSERT(net_buf_simple_headroom(buf) >= len);
buf->data -= len;
buf->len += len;
return buf->data;
}
void net_buf_simple_push_le16(struct net_buf_simple *buf, u16_t val)
{
NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
val = sys_cpu_to_le16(val);
memcpy(net_buf_simple_push(buf, sizeof(val)), &val, sizeof(val));
}
void net_buf_simple_push_be16(struct net_buf_simple *buf, u16_t val)
{
NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val);
val = sys_cpu_to_be16(val);
memcpy(net_buf_simple_push(buf, sizeof(val)), &val, sizeof(val));
}
void net_buf_simple_push_u8(struct net_buf_simple *buf, u8_t val)
{
u8_t *data = net_buf_simple_push(buf, 1);
*data = val;
}
void *net_buf_simple_pull(struct net_buf_simple *buf, size_t len)
{
NET_BUF_SIMPLE_DBG("buf %p len %u", buf, len);
NET_BUF_SIMPLE_ASSERT(buf->len >= len);
buf->len -= len;
return buf->data += len;
}
u8_t net_buf_simple_pull_u8(struct net_buf_simple *buf)
{
u8_t val;
val = buf->data[0];
net_buf_simple_pull(buf, 1);
return val;
}
u16_t net_buf_simple_pull_le16(struct net_buf_simple *buf)
{
u16_t val;
val = UNALIGNED_GET((u16_t *)buf->data);
net_buf_simple_pull(buf, sizeof(val));
return sys_le16_to_cpu(val);
}
u16_t net_buf_simple_pull_be16(struct net_buf_simple *buf)
{
u16_t val;
val = UNALIGNED_GET((u16_t *)buf->data);
net_buf_simple_pull(buf, sizeof(val));
return sys_be16_to_cpu(val);
}
u32_t net_buf_simple_pull_le32(struct net_buf_simple *buf)
{
u32_t val;
val = UNALIGNED_GET((u32_t *)buf->data);
net_buf_simple_pull(buf, sizeof(val));
return sys_le32_to_cpu(val);
}
u32_t net_buf_simple_pull_be32(struct net_buf_simple *buf)
{
u32_t val;
val = UNALIGNED_GET((u32_t *)buf->data);
net_buf_simple_pull(buf, sizeof(val));
return sys_be32_to_cpu(val);
}
size_t net_buf_simple_headroom(struct net_buf_simple *buf)
{
return buf->data - buf->__buf;
}
size_t net_buf_simple_tailroom(struct net_buf_simple *buf)
{
return buf->size - net_buf_simple_headroom(buf) - buf->len;
}
void net_buf_reset(struct net_buf *buf)
{
NET_BUF_ASSERT(buf->flags == 0);
NET_BUF_ASSERT(buf->frags == NULL);
buf->len = 0;
buf->data = buf->__buf;
}
void net_buf_reserve(struct net_buf *buf, size_t reserve)
{
NET_BUF_ASSERT(buf);
NET_BUF_ASSERT(buf->len == 0);
NET_BUF_DBG("buf %p reserve %u", buf, reserve);
buf->data = buf->__buf + reserve;
}
void net_buf_slist_put(sys_slist_t *list, struct net_buf *buf)
{
struct net_buf *tail;
unsigned int key;
NET_BUF_ASSERT(list);
NET_BUF_ASSERT(buf);
for (tail = buf; tail->frags; tail = tail->frags) {
tail->flags |= NET_BUF_FRAGS;
}
key = irq_lock();
sys_slist_append_list(list, &buf->node, &tail->node);
irq_unlock(key);
}
struct net_buf *net_buf_slist_get(sys_slist_t *list)
{
struct net_buf *buf, *frag;
unsigned int key;
NET_BUF_ASSERT(list);
key = irq_lock();
buf = (void *)sys_slist_get(list);
irq_unlock(key);
if (!buf) {
return NULL;
}
/* Get any fragments belonging to this buffer */
for (frag = buf; (frag->flags & NET_BUF_FRAGS); frag = frag->frags) {
key = irq_lock();
frag->frags = (void *)sys_slist_get(list);
irq_unlock(key);
NET_BUF_ASSERT(frag->frags);
/* The fragments flag is only for list-internal usage */
frag->flags &= ~NET_BUF_FRAGS;
}
/* Mark the end of the fragment list */
frag->frags = NULL;
return buf;
}
void net_buf_put(struct k_fifo *fifo, struct net_buf *buf)
{
struct net_buf *tail;
//NET_BUF_ASSERT(fifo);
//NET_BUF_ASSERT(buf);
//ble_mesh_msg_t msg = {0};
//ble_mesh_task_post(ble_mesh_msg_t *msg, 0);
for (tail = buf; tail->frags; tail = tail->frags) {
tail->flags |= NET_BUF_FRAGS;
}
//k_fifo_put_list(fifo, buf, tail);
}
struct net_buf *net_buf_ref(struct net_buf *buf)
{
NET_BUF_ASSERT(buf);
NET_BUF_DBG("buf %p (old) ref %u pool_id %p",
buf, buf->ref, buf->pool_id);
buf->ref++;
return buf;
}
struct net_buf *net_buf_clone(struct net_buf *buf, s32_t timeout)
{
struct net_buf_pool *pool;
struct net_buf *clone;
NET_BUF_ASSERT(buf);
pool = buf->pool_id;//net_buf_pool_get(buf->pool_id);
clone = net_buf_alloc(pool, timeout);
if (!clone) {
return NULL;
}
net_buf_reserve(clone, net_buf_headroom(buf));
/* TODO: Add reference to the original buffer instead of copying it. */
memcpy(net_buf_add(clone, buf->len), buf->data, buf->len);
return clone;
}
struct net_buf *net_buf_frag_last(struct net_buf *buf)
{
NET_BUF_ASSERT(buf);
while (buf->frags) {
buf = buf->frags;
}
return buf;
}
void net_buf_frag_insert(struct net_buf *parent, struct net_buf *frag)
{
NET_BUF_ASSERT(parent);
NET_BUF_ASSERT(frag);
if (parent->frags) {
net_buf_frag_last(frag)->frags = parent->frags;
}
/* Take ownership of the fragment reference */
parent->frags = frag;
}
#if defined(CONFIG_NET_BUF_LOG)
struct net_buf *net_buf_frag_del_debug(struct net_buf *parent,
struct net_buf *frag,
const char *func, int line)
#else
struct net_buf *net_buf_frag_del(struct net_buf *parent, struct net_buf *frag)
#endif
{
struct net_buf *next_frag;
NET_BUF_ASSERT(frag);
if (parent) {
NET_BUF_ASSERT(parent->frags);
NET_BUF_ASSERT(parent->frags == frag);
parent->frags = frag->frags;
}
next_frag = frag->frags;
frag->frags = NULL;
#if defined(CONFIG_NET_BUF_LOG)
net_buf_unref_debug(frag, func, line);
#else
net_buf_unref(frag);
#endif
return next_frag;
}
#if defined(CONFIG_NET_BUF_LOG)
void net_buf_unref_debug(struct net_buf *buf, const char *func, int line)
#else
void net_buf_unref(struct net_buf *buf)
#endif
{
NET_BUF_ASSERT(buf);
while (buf) {
struct net_buf *frags = buf->frags;
struct net_buf_pool *pool;
#if defined(CONFIG_NET_BUF_LOG)
if (!buf->ref) {
NET_BUF_ERR("%s():%d: buf %p double free", func, line,
buf);
return;
}
#endif
NET_BUF_DBG("buf %p ref %u pool_id %p frags %p", buf, buf->ref,
buf->pool_id, buf->frags);
/* Change by Espressif. Add !buf->ref to avoid minus 0 */
if (!buf->ref || --buf->ref > 0) {
return;
}
buf->frags = NULL;
pool = buf->pool_id;//net_buf_pool_get(buf->pool_id);
pool->uninit_count++;
#if defined(CONFIG_NET_BUF_POOL_USAGE)
pool->avail_count++;
BT_DBG("%s, pool->avail_count = %d, pool->uninit_count = %d", __func__,
pool->avail_count, pool->uninit_count);
NET_BUF_ASSERT(pool->avail_count <= pool->buf_count);
#endif
if (pool->destroy) {
pool->destroy(buf);
} else {
net_buf_destroy(buf);
}
buf = frags;
}
}
#if defined(CONFIG_NET_BUF_LOG)
struct net_buf *net_buf_alloc_debug(struct net_buf_pool *pool, s32_t timeout,
const char *func, int line)
#else
struct net_buf *net_buf_alloc(struct net_buf_pool *pool, s32_t timeout)
#endif
{
struct net_buf *buf = NULL;
unsigned int key;
int i;
NET_BUF_ASSERT(pool);
NET_BUF_DBG("%s():%d: pool %p timeout %d", func, line, pool, timeout);
BT_DBG("%s, pool = %p , pool->uninit_count= %d, buf_count = %d", __func__,
pool, pool->uninit_count, pool->buf_count);
/* We need to lock interrupts temporarily to prevent race conditions
* when accessing pool->uninit_count.
*/
key = irq_lock();
/* If there are uninitialized buffers we're guaranteed to succeed
* with the allocation one way or another.
*/
if (pool->uninit_count) {
/* Change by Espressif. Use buf when buf->ref is 0 */
for (i = pool->buf_count; i > 0; i--) {
buf = pool_get_uninit(pool, i);
if (!buf->ref) {
goto success;
}
}
// u16_t uninit_count;
/* If this is not the first access to the pool, we can
* be opportunistic and try to fetch a previously used
* buffer from the LIFO with K_NO_WAIT.
*/
//if (pool->uninit_count < pool->buf_count) {
// buf = &pool->__bufs[pool->buf_count - pool->uninit_count];
//if (buf) {
// irq_unlock(key);
// goto success;
//}
//}
// uninit_count = pool->uninit_count--;
// irq_unlock(key);
// buf = pool_get_uninit(pool, uninit_count);
// goto success;
}
irq_unlock(key);
if (!buf) {
BT_ERR("%s():Failed to get free buffer", __func__);
}
return buf;
success:
NET_BUF_DBG("allocated buf %p", buf);
irq_unlock(key);
buf->ref = 1;
buf->index = pool->buf_count - i;
buf->flags = 0;
buf->frags = NULL;
net_buf_reset(buf);
pool->uninit_count--;
#if defined(CONFIG_NET_BUF_POOL_USAGE)
pool->avail_count--;
NET_BUF_ASSERT(pool->avail_count >= 0);
#endif
return buf;
}
int net_buf_id(struct net_buf *buf)
{
struct net_buf_pool *pool = buf->pool_id;//net_buf_pool_get(buf->pool_id);
u8_t *pool_start = (u8_t *)pool->__bufs;
u8_t *buf_ptr = (u8_t *)buf;
return (buf_ptr - pool_start) / BUF_SIZE(pool);
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
* Copyright (c) 2015-2016 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mesh_hci.h"
#include "stack/bt_types.h"
#include "device/controller.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
struct bt_dev bt_dev;
void mesh_hci_init(void)
{
const uint8_t *features = controller_get_interface()->get_features_ble()->as_array;
if (features != NULL) {
// We just copy the ble feature here, we don't care the classic bt feature in the ble mesh system.
memcpy(bt_dev.features[0], features, 8);
}
/**TODO: We support 20ms non-connectable adv interval, but not hci 5.0, so we need to add another flag
* to indicate if we support 20ms adv interval
* */
#ifdef CONFIG_HCI_5_0_VERSION
bt_dev.hci_version = BT_HCI_VERSION_5_0;
#else
bt_dev.hci_version = controller_get_interface()->get_bt_version()->hci_version;
#endif
bt_dev.lmp_version = controller_get_interface()->get_bt_version()->lmp_version;
bt_dev.hci_revision = controller_get_interface()->get_bt_version()->hci_revision;
bt_dev.lmp_subversion = controller_get_interface()->get_bt_version()->lmp_subversion;
bt_dev.manufacturer = controller_get_interface()->get_bt_version()->manufacturer;
// Still to copy the features to the ble features struct.
memcpy(bt_dev.le.features, features, 8);
const uint8_t *p = controller_get_interface()->get_ble_supported_states();
uint64_t states_fh = 0, states_sh = 0;
// We don't have the STREAM_TO_UINT64 macro, so we should used stream to u32 two times add then put them together.
STREAM_TO_UINT32(states_fh, p);
STREAM_TO_UINT32(states_sh, p);
bt_dev.le.states = (states_sh << 32) | states_fh;
#if defined(CONFIG_BT_CONN)
bt_dev.le.mtu = controller_get_interface()->get_acl_data_size_ble();
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_SMP)
bt_dev.le.rl_size = controller_get_interface()->get_ble_resolving_list_max_size();
#endif /* #if defined(CONFIG_BT_SMP) */
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,239 @@
/*
* Copyright (c) 2016 Intel Corporation
* Copyright (c) 2016 Wind River Systems, Inc.
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa/xtruntime.h>
#include <errno.h>
#include "mesh_kernel.h"
#include "esp_timer.h"
#include "osi/hash_map.h"
#include "osi/alarm.h"
#include "common/bt_trace.h"
#include "common/bt_defs.h"
#include "osi/hash_functions.h"
#include "mesh_trace.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
#include "provisioner_prov.h"
static osi_mutex_t ble_mesh_alarm_lock;
static osi_mutex_t mesh_irq_lock;
static hash_map_t *ble_mesh_alarm_hash_map;
static const size_t BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BT_MESH_PBA_SAME_TIME + \
CONFIG_BT_MESH_PBG_SAME_TIME;
typedef struct alarm_t {
/* timer id point to here */
esp_timer_handle_t alarm_hdl;
osi_alarm_callback_t cb;
void *cb_data;
int64_t deadline_us;
} osi_alarm_t;
static void ble_mesh_alarm_cb(void *data)
{
assert(data != NULL);
struct k_delayed_work *work = (struct k_delayed_work *)data;
work->work.handler(&work->work);
return;
}
unsigned int irq_lock(void)
{
#if defined(CONFIG_BT_MESH_IRQ_LOCK) && CONFIG_BT_MESH_IRQ_LOCK
unsigned int key = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
return key;
#else /* !CONFIG_BT_MESH_IRQ_LOCK */
/* Change by Espressif. In BLE Mesh, in order to improve the real-time
* requirements of bt controller, we use task lock to replace IRQ lock.
*/
osi_mutex_lock(&mesh_irq_lock, OSI_MUTEX_MAX_TIMEOUT);
return 0;
#endif /*#if (CONFIG_BT_MESH_IRQ_LOCK) */
}
void irq_unlock(unsigned int key)
{
#if defined(CONFIG_BT_MESH_IRQ_LOCK) && CONFIG_BT_MESH_IRQ_LOCK
XTOS_RESTORE_INTLEVEL(key);
#else /* !CONFIG_BT_MESH_IRQ_LOCK */
osi_mutex_unlock(&mesh_irq_lock);
#endif /*#if (CONFIG_BT_MESH_IRQ_LOCK) && CONFIG_BT_MESH_IRQ_LOCK */
}
s64_t k_uptime_get(void)
{
/** k_uptime_get_32 is in in milliseconds,
* but esp_timer_get_time is in microseconds
*/
return (esp_timer_get_time() / 1000);
}
u32_t k_uptime_get_32(void)
{
/** k_uptime_get_32 is in in milliseconds,
* but esp_timer_get_time is in microseconds
*/
return (u32_t)(esp_timer_get_time() / 1000);
}
void k_sleep(s32_t duration)
{
vTaskDelay(duration / portTICK_PERIOD_MS);
return;
}
void mesh_k_init(void)
{
osi_mutex_new(&ble_mesh_alarm_lock);
osi_mutex_new(&mesh_irq_lock);
ble_mesh_alarm_hash_map = hash_map_new(BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE,
hash_function_pointer, NULL, (data_free_fn)osi_alarm_free, NULL);
assert(ble_mesh_alarm_hash_map != NULL);
}
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
{
assert(work != NULL && ble_mesh_alarm_hash_map != NULL);
k_work_init(&work->work, handler);
_init_timeout(&work->timeout, NULL);
work->work_q = NULL;
osi_alarm_t *alarm = NULL;
// Get the alarm for the timer list entry.
osi_mutex_lock(&ble_mesh_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
if (!hash_map_has_key(ble_mesh_alarm_hash_map, (void *)work)) {
alarm = osi_alarm_new("ble_mesh", ble_mesh_alarm_cb, (void *)work, 0);
if (alarm == NULL) {
LOG_ERROR("%s, Unable to create alarm", __func__);
return;
}
if (!hash_map_set(ble_mesh_alarm_hash_map, work, (void *)alarm)) {
LOG_ERROR("%s Unable to add the work timer to the mesh alarm hash map.", __func__);
}
}
osi_mutex_unlock(&ble_mesh_alarm_lock);
alarm = hash_map_get(ble_mesh_alarm_hash_map, work);
if (alarm == NULL) {
LOG_WARN("%s, Unable to find expected alarm in hash map", __func__);
return;
}
// Just init the work timer only, don't start it.
osi_alarm_cancel(alarm);
return;
}
int k_delayed_work_submit(struct k_delayed_work *work,
s32_t delay)
{
assert(work != NULL);
osi_alarm_t *alarm = hash_map_get(ble_mesh_alarm_hash_map, (void *)work);
if (alarm == NULL) {
LOG_WARN("%s, Unable to find expected alarm in hash map", __func__);
return -EINVAL;
}
// Cancel the alarm first, before start the alarm.
osi_alarm_cancel(alarm);
osi_alarm_set(alarm, delay);
return 0;
}
int k_delayed_work_cancel(struct k_delayed_work *work)
{
assert(work != NULL);
// Check if the work have been store in the ble_mesh timer list or not.
osi_alarm_t *alarm = hash_map_get(ble_mesh_alarm_hash_map, (void *)work);
if (alarm == NULL) {
LOG_WARN("%s, Unable to find expected alarm in hash map", __func__);
return -EINVAL;
}
osi_alarm_cancel(alarm);
alarm->deadline_us = 0;
return 0;
}
int k_delayed_work_free(struct k_delayed_work *work)
{
assert(work != NULL);
// Get the alarm for the timer list entry.
osi_alarm_t *alarm = hash_map_get(ble_mesh_alarm_hash_map, work);
if (alarm == NULL) {
LOG_WARN("%s Unable to find expected alarm in hash map", __func__);
return -EINVAL;
}
hash_map_erase(ble_mesh_alarm_hash_map, work);
return 0;
}
s32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
{
assert(work != NULL);
osi_alarm_t *alarm = hash_map_get(ble_mesh_alarm_hash_map, (void *)work);
if (alarm == NULL) {
LOG_WARN("%s Unable to find expected alarm in hash map", __func__);
return 0;
}
if (!alarm->deadline_us) {
return 0;
}
s32_t remain_time = 0;
int64_t now = esp_timer_get_time();
if ((alarm->deadline_us - now) < 0x1FFFFFFFFFF) {
remain_time = (alarm->deadline_us - now) / 1000;
} else {
return 0;
}
return remain_time;
}
void k_sem_give(struct k_sem *sem)
{
assert(sem != NULL);
osi_mutex_unlock(sem->mutex);
return;
}
void k_sem_init(struct k_sem *sem, unsigned int initial_count,
unsigned int limit)
{
assert(sem != NULL);
UNUSED(initial_count);
UNUSED(limit);
sem->mutex = xSemaphoreCreateBinary();
if (sem->mutex == NULL) {
LOG_WARN("%s, the mutex alloc fail", __func__);
return;
}
return;
}
int k_sem_take(struct k_sem *sem, s32_t timeout)
{
assert(sem != NULL);
return osi_mutex_lock(sem->mutex, timeout);
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,449 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include "mesh_buf.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG)
#include "mesh_trace.h"
#include "mesh_main.h"
#include "adv.h"
#include "prov.h"
#include "net.h"
#include "beacon.h"
#include "lpn.h"
#include "friend.h"
#include "transport.h"
#include "access.h"
#include "foundation.h"
#include "proxy.h"
#include "mesh.h"
#include "mesh_hci.h"
#include "settings.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "provisioner_main.h"
static volatile bool provisioner_en;
#define ACTION_ENTER 0x01
#define ACTION_SUSPEND 0x02
#define ACTION_EXIT 0x03
#if CONFIG_BT_MESH_NODE
int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
u8_t flags, u32_t iv_index, u32_t seq,
u16_t addr, const u8_t dev_key[16])
{
int err;
BT_DBG("Primary Element: 0x%04x", addr);
BT_DBG("net_idx 0x%04x flags 0x%02x iv_index 0x%04x",
net_idx, flags, iv_index);
BT_DBG("Device key: %s", bt_hex(dev_key, 16));
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
bt_mesh_proxy_prov_disable();
}
err = bt_mesh_net_create(net_idx, flags, net_key, iv_index);
if (err) {
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
bt_mesh_proxy_prov_enable();
}
return err;
}
bt_mesh.seq = seq;
bt_mesh_comp_provision(addr);
memcpy(bt_mesh.dev_key, dev_key, 16);
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
bt_mesh_beacon_enable();
} else {
bt_mesh_beacon_disable();
}
if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS)) {
BT_DBG("Storing network information persistently");
bt_mesh_store_net();
bt_mesh_store_subnet(&bt_mesh.sub[0]);
bt_mesh_store_iv();
}
BT_DBG("%s, gatt_proxy = %d", __func__, bt_mesh_gatt_proxy_get());
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) &&
bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) {
bt_mesh_proxy_gatt_enable();
bt_mesh_adv_update();
}
/* Add this to avoid "already active status" for bt_mesh_scan_enable() */
bt_mesh_scan_disable();
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
bt_mesh_lpn_init();
} else {
bt_mesh_scan_enable();
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
bt_mesh_friend_init();
}
if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
bt_mesh_prov_complete(net_idx, addr, flags, iv_index);
}
return 0;
}
void bt_mesh_reset(void)
{
if (!bt_mesh.valid) {
BT_WARN("%s: not provisioned", __func__);
return;
}
bt_mesh_comp_unprovision();
bt_mesh.iv_index = 0;
bt_mesh.seq = 0;
bt_mesh.iv_update = 0;
bt_mesh.pending_update = 0;
bt_mesh.valid = 0;
bt_mesh.last_update = 0;
bt_mesh.ivu_initiator = 0;
k_delayed_work_cancel(&bt_mesh.ivu_complete);
bt_mesh_cfg_reset();
bt_mesh_rx_reset();
bt_mesh_tx_reset();
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
bt_mesh_lpn_disable(true);
}
if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
bt_mesh_friend_clear_net_idx(BT_MESH_KEY_ANY);
}
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
bt_mesh_proxy_gatt_disable();
}
#if defined(CONFIG_BT_MESH_SETTINGS)
if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS)) {
bt_mesh_clear_net();
}
#endif
memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl));
bt_mesh_scan_disable();
bt_mesh_beacon_disable();
if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
bt_mesh_prov_reset();
}
}
bool bt_mesh_is_provisioned(void)
{
return bt_mesh.valid; // Previous is "bool provisioned"
}
int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
{
if (bt_mesh_is_provisioned()) {
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) &&
(bearers & BT_MESH_PROV_ADV)) {
/* Make sure the scanning is for provisioning invitations */
bt_mesh_scan_enable();
/* Enable unprovisioned beacon sending */
bt_mesh_beacon_enable();
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
(bearers & BT_MESH_PROV_GATT)) {
bt_mesh_proxy_prov_enable();
bt_mesh_adv_update();
}
provisioner_en = false;
return 0;
}
int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)
{
if (bt_mesh_is_provisioned()) {
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) &&
(bearers & BT_MESH_PROV_ADV)) {
bt_mesh_beacon_disable();
bt_mesh_scan_disable();
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
(bearers & BT_MESH_PROV_GATT)) {
bt_mesh_proxy_prov_disable();
bt_mesh_adv_update();
}
return 0;
}
#endif /* CONFIG_BT_MESH_NODE */
bool bt_mesh_is_provisioner_en(void)
{
return provisioner_en;
}
#if CONFIG_BT_MESH_PROVISIONER
int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)
{
int err;
if (bt_mesh_is_provisioner_en()) {
BT_ERR("Provisioner already enabled");
return -EALREADY;
}
err = provisioner_upper_init();
if (err) {
BT_ERR("%s: provisioner_upper_init fail", __func__);
return err;
}
if ((IS_ENABLED(CONFIG_BT_MESH_PB_ADV) &&
(bearers & BT_MESH_PROV_ADV)) ||
(IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
(bearers & BT_MESH_PROV_GATT))) {
bt_mesh_scan_enable();
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
(bearers & BT_MESH_PROV_GATT)) {
provisioner_pb_gatt_enable();
}
provisioner_en = true;
return 0;
}
int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers)
{
if (!bt_mesh_is_provisioner_en()) {
BT_ERR("Provisioner already disabled");
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
(bearers & BT_MESH_PROV_GATT)) {
provisioner_pb_gatt_disable();
}
if ((IS_ENABLED(CONFIG_BT_MESH_PB_ADV) &&
(bearers & BT_MESH_PROV_ADV)) &&
(IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
(bearers & BT_MESH_PROV_GATT))) {
bt_mesh_scan_disable();
}
provisioner_en = false;
return 0;
}
#endif /* CONFIG_BT_MESH_PROVISIONER */
/* The following API is for fast provisioning */
#if CONFIG_BT_MESH_FAST_PROV
u8_t bt_mesh_set_fast_prov_action(u8_t action)
{
if (!action || action > ACTION_EXIT) {
return 0x01;
}
if ((!provisioner_en && (action == ACTION_SUSPEND || action == ACTION_EXIT)) ||
(provisioner_en && (action == ACTION_ENTER))) {
BT_WARN("%s: action is already done", __func__);
return 0x0;
}
if (action == ACTION_ENTER) {
#if 0
/* If the device is provisioned using PB-GATT and connected to
* the phone with proxy service, proxy_gatt shall not be disabled
* here. The node needs to send some status messages to the phone
* while it is connected.
*/
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
bt_mesh_proxy_gatt_disable();
}
#endif
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
bt_mesh_beacon_disable();
}
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
provisioner_pb_gatt_enable();
}
provisioner_set_fast_prov_flag(true);
provisioner_en = true;
} else {
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
provisioner_pb_gatt_disable();
}
if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
bt_mesh_beacon_enable();
}
#if 0
/* Mesh Proxy GATT will be re-enabled on application layer */
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) &&
bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) {
bt_mesh_proxy_gatt_enable();
bt_mesh_adv_update();
}
#endif
provisioner_set_fast_prov_flag(false);
provisioner_en = false;
if (action == ACTION_EXIT) {
provisioner_upper_reset_all_nodes();
provisioner_prov_reset_all_nodes();
}
}
return 0x0;
}
#endif /* CONFIG_BT_MESH_FAST_PROV */
int bt_mesh_init(const struct bt_mesh_prov *prov,
const struct bt_mesh_comp *comp)
{
int err;
//err = bt_mesh_test();
//if (err) {
// return err;
//}
// The mesh kernel should be initialized first.
mesh_k_init();
mesh_hci_init();
bt_mesh_adapt_init();
err = bt_mesh_comp_register(comp);
if (err) {
return err;
}
/** GATT is initialised here in order to register services later */
bt_mesh_gatt_init();
/** Register service in the init function,
* then start it according to bt_mesh_proxy_gatt_enable
*/
#if CONFIG_BT_MESH_NODE
extern struct bt_gatt_service proxy_svc;
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
bt_mesh_gatts_service_register(&proxy_svc);
}
/** Register service in the init function,
* then start it according to bt_mesh_proxy_prov_enable
*/
extern struct bt_gatt_service prov_svc;
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
bt_mesh_gatts_service_register(&prov_svc);
}
#endif
if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
#if CONFIG_BT_MESH_NODE
err = bt_mesh_prov_init(prov);
if (err) {
return err;
}
#endif
#if CONFIG_BT_MESH_PROVISIONER
err = provisioner_prov_init(prov);
if (err) {
return err;
}
#endif
}
bt_mesh_net_init();
bt_mesh_trans_init();
#if CONFIG_BT_MESH_NODE
/* Changed by Espressif, add random delay (0 ~ 3s) */
#if defined(CONFIG_BT_MESH_FAST_PROV)
u32_t delay = 0;
bt_mesh_rand(&delay, sizeof(u32_t));
vTaskDelay((delay % 3000) / portTICK_PERIOD_MS);
#endif
bt_mesh_beacon_init();
#endif
bt_mesh_adv_init();
if (IS_ENABLED(CONFIG_BT_MESH_PROXY)) {
#if CONFIG_BT_MESH_NODE
bt_mesh_proxy_init();
#endif
#if CONFIG_BT_MESH_PROVISIONER
provisioner_proxy_init();
#endif
}
#if !CONFIG_BT_MESH_NODE && CONFIG_BT_MESH_PROVISIONER
/* If node & provisioner are both enabled and the
* device starts as a node, it must finish provisioning */
err = provisioner_upper_init();
if (err) {
return err;
}
#endif
#if defined(CONFIG_BT_MESH_SETTINGS)
if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS)) {
bt_mesh_settings_init();
}
#endif
return 0;
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,317 @@
/*
* Copyright (c) 2016 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "mesh_slist.h"
#include "sdkconfig.h"
#if CONFIG_BT_MESH
static sys_slist_t test_list;
struct container_node {
sys_snode_t node;
int unused;
};
static struct container_node test_node_1;
static struct container_node test_node_2;
static struct container_node test_node_3;
static struct container_node test_node_4;
static inline bool verify_emptyness(sys_slist_t *list)
{
sys_snode_t *node;
sys_snode_t *s_node;
struct container_node *cnode;
struct container_node *s_cnode;
int count;
if (!sys_slist_is_empty(list)) {
return false;
}
if (sys_slist_peek_head(list)) {
return false;
}
if (sys_slist_peek_tail(list)) {
return false;
}
count = 0;
SYS_SLIST_FOR_EACH_NODE(list, node) {
count++;
}
if (count) {
return false;
}
SYS_SLIST_FOR_EACH_NODE_SAFE(list, node, s_node) {
count++;
}
if (count) {
return false;
}
count = 0;
SYS_SLIST_FOR_EACH_CONTAINER(list, cnode, node) {
count++;
}
if (count) {
return false;
}
count = 0;
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) {
count++;
}
if (count) {
return false;
}
return true;
}
static inline bool verify_content_amount(sys_slist_t *list, int amount)
{
sys_snode_t *node;
sys_snode_t *s_node;
struct container_node *cnode;
struct container_node *s_cnode;
int count;
if (sys_slist_is_empty(list)) {
return false;
}
if (!sys_slist_peek_head(list)) {
return false;
}
if (!sys_slist_peek_tail(list)) {
return false;
}
count = 0;
SYS_SLIST_FOR_EACH_NODE(list, node) {
count++;
}
if (count != amount) {
return false;
}
count = 0;
SYS_SLIST_FOR_EACH_NODE_SAFE(list, node, s_node) {
count++;
}
if (count != amount) {
return false;
}
count = 0;
SYS_SLIST_FOR_EACH_CONTAINER(list, cnode, node) {
count++;
}
if (count != amount) {
return false;
}
count = 0;
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) {
count++;
}
if (count != amount) {
return false;
}
return true;
}
static inline bool verify_tail_head(sys_slist_t *list,
sys_snode_t *head,
sys_snode_t *tail,
bool same)
{
if (sys_slist_peek_head(list) != head) {
return false;
}
if (sys_slist_peek_tail(list) != tail) {
return false;
}
if (same) {
if (sys_slist_peek_head(list) != sys_slist_peek_tail(list)) {
return false;
}
} else {
if (sys_slist_peek_head(list) == sys_slist_peek_tail(list)) {
return false;
}
}
return true;
}
void slist_test(void)
{
sys_slist_init(&test_list);
//zassert_true((verify_emptyness(&test_list)), "test_list should be empty");
/* Appending node 1 */
sys_slist_append(&test_list, &test_node_1.node);
//zassert_true((verify_content_amount(&test_list, 1)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_1.node,
// &test_node_1.node, true)),
// "test_list head/tail are wrong");
/* Finding and removing node 1 */
sys_slist_find_and_remove(&test_list, &test_node_1.node);
//zassert_true((verify_emptyness(&test_list)),
// "test_list should be empty");
/* Prepending node 1 */
sys_slist_prepend(&test_list, &test_node_1.node);
//zassert_true((verify_content_amount(&test_list, 1)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_1.node,
// &test_node_1.node, true)),
// "test_list head/tail are wrong");
/* Removing node 1 */
sys_slist_remove(&test_list, NULL, &test_node_1.node);
//zassert_true((verify_emptyness(&test_list)),
// "test_list should be empty");
/* Appending node 1 */
sys_slist_append(&test_list, &test_node_1.node);
/* Prepending node 2 */
sys_slist_prepend(&test_list, &test_node_2.node);
//zassert_true((verify_content_amount(&test_list, 2)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_1.node, false)),
// "test_list head/tail are wrong");
/* Appending node 3 */
sys_slist_append(&test_list, &test_node_3.node);
//zassert_true((verify_content_amount(&test_list, 3)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_3.node, false)),
// "test_list head/tail are wrong");
//zassert_true((sys_slist_peek_next(&test_node_2.node) ==
// &test_node_1.node),
// "test_list node links are wrong");
/* Inserting node 4 after node 2 */
sys_slist_insert(&test_list, &test_node_2.node, &test_node_4.node);
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_3.node, false)),
// "test_list head/tail are wrong");
//zassert_true((sys_slist_peek_next(&test_node_2.node) ==
// &test_node_4.node),
// "test_list node links are wrong");
/* Finding and removing node 1 */
sys_slist_find_and_remove(&test_list, &test_node_1.node);
//zassert_true((verify_content_amount(&test_list, 3)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_3.node, false)),
// "test_list head/tail are wrong");
/* Removing node 3 */
sys_slist_remove(&test_list, &test_node_4.node, &test_node_3.node);
//zassert_true((verify_content_amount(&test_list, 2)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_4.node, false)),
// "test_list head/tail are wrong");
/* Removing node 4 */
sys_slist_remove(&test_list, &test_node_2.node, &test_node_4.node);
//zassert_true((verify_content_amount(&test_list, 1)),
// "test_list has wrong content");
//zassert_true((verify_tail_head(&test_list, &test_node_2.node,
// &test_node_2.node, true)),
// "test_list head/tail are wrong");
/* Removing node 2 */
sys_slist_remove(&test_list, NULL, &test_node_2.node);
//zassert_true((verify_emptyness(&test_list)),
// "test_list should be empty");
/* test iterator from a node */
struct data_node {
sys_snode_t node;
int data;
} data_node[6] = {
{ .data = 0 },
{ .data = 1 },
{ .data = 2 },
{ .data = 3 },
{ .data = 4 },
{ .data = 5 },
};
sys_snode_t *node = NULL;
int ii;
sys_slist_init(&test_list);
for (ii = 0; ii < 6; ii++) {
sys_slist_append(&test_list, &data_node[ii].node);
}
ii = 0;
SYS_SLIST_ITERATE_FROM_NODE(&test_list, node) {
ii++;
if (((struct data_node *)node)->data == 2) {
break;
}
}
//zassert_equal(ii, 3, "");
ii = 0;
SYS_SLIST_ITERATE_FROM_NODE(&test_list, node) {
ii++;
if (((struct data_node *)node)->data == 3) {
break;
}
}
//zassert_equal(ii, 1, "");
ii = 0;
SYS_SLIST_ITERATE_FROM_NODE(&test_list, node) {
ii++;
}
//zassert_equal(ii, 2, "");
}
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
* Copyright (c) 2015-2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "sdkconfig.h"
#if CONFIG_BT_MESH
#include "mesh_util.h"
#include "mesh_kernel.h"
#include "mesh_aes_encrypt.h"
#define MASK_TWENTY_SEVEN 0x1b
const char *bt_hex(const void *buf, size_t len)
{
static const char hex[] = "0123456789abcdef";
static char hexbufs[4][129];
static u8_t curbuf;
const u8_t *b = buf;
unsigned int mask;
char *str;
int i;
mask = irq_lock();
str = hexbufs[curbuf++];
curbuf %= ARRAY_SIZE(hexbufs);
irq_unlock(mask);
len = min(len, (sizeof(hexbufs[0]) - 1) / 2);
for (i = 0; i < len; i++) {
str[i * 2] = hex[b[i] >> 4];
str[i * 2 + 1] = hex[b[i] & 0xf];
}
str[i * 2] = '\0';
return str;
}
void mem_rcopy(u8_t *dst, u8_t const *src, u16_t len)
{
src += len;
while (len--) {
*dst++ = *--src;
}
}
unsigned int _copy(uint8_t *to, unsigned int to_len,
const uint8_t *from, unsigned int from_len)
{
if (from_len <= to_len) {
(void)memcpy(to, from, from_len);
return from_len;
} else {
return TC_CRYPTO_FAIL;
}
}
void _set(void *to, uint8_t val, unsigned int len)
{
(void)memset(to, val, len);
}
/*
* Doubles the value of a byte for values up to 127.
*/
uint8_t _double_byte(uint8_t a)
{
return ((a << 1) ^ ((a >> 7) * MASK_TWENTY_SEVEN));
}
int _compare(const uint8_t *a, const uint8_t *b, size_t size)
{
const uint8_t *tempa = a;
const uint8_t *tempb = b;
uint8_t result = 0;
for (unsigned int i = 0; i < size; i++) {
result |= tempa[i] ^ tempb[i];
}
return result;
}
#endif /* #if CONFIG_BT_MESH */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,391 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _NET_H_
#define _NET_H_
#include "mesh_util.h"
#include "mesh_kernel.h"
#include "mesh_access.h"
#define BT_MESH_NET_FLAG_KR BIT(0)
#define BT_MESH_NET_FLAG_IVU BIT(1)
#define BT_MESH_KR_NORMAL 0x00
#define BT_MESH_KR_PHASE_1 0x01
#define BT_MESH_KR_PHASE_2 0x02
#define BT_MESH_KR_PHASE_3 0x03
#define BT_MESH_IV_UPDATE(flags) ((flags >> 1) & 0x01)
#define BT_MESH_KEY_REFRESH(flags) (flags & 0x01)
/* Special time-stamp to indicate that we don't know when the last IV
* Update happened.
*/
#define BT_MESH_NET_IVU_UNKNOWN -1
#if defined(CONFIG_BT_MESH_IV_UPDATE_TEST)
/* Small test timeout for IV Update Procedure testing */
#define BT_MESH_NET_IVU_TIMEOUT K_SECONDS(120)
#else
/* Maximum time to stay in IV Update mode (96 < time < 144) */
#define BT_MESH_NET_IVU_TIMEOUT K_HOURS(120)
#endif /* CONFIG_BT_MESH_IV_UPDATE_TEST */
struct bt_mesh_app_key {
u16_t net_idx;
u16_t app_idx;
bool updated;
struct bt_mesh_app_keys {
u8_t id;
u8_t val[16];
} keys[2];
};
struct bt_mesh_subnet {
u32_t beacon_sent; /* Timestamp of last sent beacon */
u8_t beacons_last; /* Number of beacons during last
* observation window
*/
u8_t beacons_cur; /* Number of beaconds observed during
* currently ongoing window.
*/
u8_t beacon_cache[21]; /* Cached last authenticated beacon */
u16_t net_idx; /* NetKeyIndex */
bool kr_flag; /* Key Refresh Flag */
u8_t kr_phase; /* Key Refresh Phase */
u8_t node_id; /* Node Identity State */
u32_t node_id_start; /* Node Identity started timestamp */
u8_t auth[8]; /* Beacon Authentication Value */
struct bt_mesh_subnet_keys {
u8_t net[16]; /* NetKey */
u8_t nid; /* NID */
u8_t enc[16]; /* EncKey */
u8_t net_id[8]; /* Network ID */
#if defined(CONFIG_BT_MESH_GATT_PROXY)
u8_t identity[16]; /* IdentityKey */
#endif
u8_t privacy[16]; /* PrivacyKey */
u8_t beacon[16]; /* BeaconKey */
} keys[2];
};
struct bt_mesh_rpl {
u16_t src;
bool old_iv;
#if defined(CONFIG_BT_MESH_SETTINGS)
bool store;
#endif
u32_t seq;
};
#if defined(CONFIG_BT_MESH_FRIEND)
#define FRIEND_SEG_RX CONFIG_BT_MESH_FRIEND_SEG_RX
#define FRIEND_SUB_LIST_SIZE CONFIG_BT_MESH_FRIEND_SUB_LIST_SIZE
#else
#define FRIEND_SEG_RX 0
#define FRIEND_SUB_LIST_SIZE 0
#endif
struct bt_mesh_friend {
u16_t lpn;
u8_t recv_delay;
u8_t fsn: 1,
send_last: 1,
pending_req: 1,
sec_update: 1,
pending_buf: 1,
valid: 1,
established: 1;
s32_t poll_to;
u8_t num_elem;
u16_t lpn_counter;
u16_t counter;
u16_t net_idx;
u16_t sub_list[FRIEND_SUB_LIST_SIZE];
struct k_delayed_work timer;
struct bt_mesh_friend_seg {
sys_slist_t queue;
} seg[FRIEND_SEG_RX];
struct net_buf *last;
sys_slist_t queue;
u32_t queue_size;
/* Friend Clear Procedure */
struct {
u32_t start; /* Clear Procedure start */
u16_t frnd; /* Previous Friend's address */
u16_t repeat_sec; /* Repeat timeout in seconds */
struct k_delayed_work timer; /* Repeat timer */
} clear;
};
#if defined(CONFIG_BT_MESH_LOW_POWER)
#define LPN_GROUPS CONFIG_BT_MESH_LOW_POWER
#else
#define LPN_GROUPS 0
#endif
/* Low Power Node state */
struct bt_mesh_lpn {
enum __packed {
BT_MESH_LPN_DISABLED, /* LPN feature is disabled */
BT_MESH_LPN_CLEAR, /* Clear in progress */
BT_MESH_LPN_TIMER, /* Waiting for auto timer expiry */
BT_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */
BT_MESH_LPN_REQ_WAIT, /* Wait before scanning for offers */
BT_MESH_LPN_WAIT_OFFER, /* Friend Req sent */
BT_MESH_LPN_ESTABLISHED, /* Friendship established */
BT_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */
BT_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */
BT_MESH_LPN_OFFER_RECV, /* Friend offer received */
} state;
/* Transaction Number (used for subscription list) */
u8_t xact_next;
u8_t xact_pending;
u8_t sent_req;
/* Address of our Friend when we're a LPN. Unassigned if we don't
* have a friend yet.
*/
u16_t frnd;
/* Value from the friend offer */
u8_t recv_win;
u8_t req_attempts; /* Number of Request attempts */
s32_t poll_timeout;
u8_t groups_changed: 1, /* Friend Subscription List needs updating */
pending_poll: 1, /* Poll to be sent after subscription */
disable: 1, /* Disable LPN after clearing */
fsn: 1, /* Friend Sequence Number */
established: 1, /* Friendship established */
clear_success: 1; /* Friend Clear Confirm received */
/* Friend Queue Size */
u8_t queue_size;
/* LPNCounter */
u16_t counter;
/* Previous Friend of this LPN */
u16_t old_friend;
/* Duration reported for last advertising packet */
u16_t adv_duration;
/* Next LPN related action timer */
struct k_delayed_work timer;
/* Subscribed groups */
u16_t groups[LPN_GROUPS];
/* Bit fields for tracking which groups the Friend knows about */
ATOMIC_DEFINE(added, LPN_GROUPS);
ATOMIC_DEFINE(pending, LPN_GROUPS);
ATOMIC_DEFINE(to_remove, LPN_GROUPS);
};
/* bt_mesh_net.flags, mainly used for pending storage actions */
enum {
BT_MESH_RPL_PENDING,
BT_MESH_KEYS_PENDING,
BT_MESH_NET_PENDING,
BT_MESH_IV_PENDING,
BT_MESH_SEQ_PENDING,
BT_MESH_HB_PUB_PENDING,
BT_MESH_CFG_PENDING,
BT_MESH_MOD_PENDING,
/* Don't touch - intentionally last */
BT_MESH_FLAG_COUNT,
};
struct bt_mesh_net {
u32_t iv_index; /* Current IV Index */
u32_t seq: 24, /* Next outgoing sequence number */
iv_update: 1, /* 1 if IV Update in Progress */
ivu_initiator: 1, /* IV Update initiated by us */
ivu_test: 1, /* IV Update test mode */
pending_update: 1, /* Update blocked by SDU in progress */
valid: 1; /* 0 if unused */
s64_t last_update; /* Time since last IV Update change */
ATOMIC_DEFINE(flags, BT_MESH_FLAG_COUNT);
/* Local network interface */
struct k_work local_work;
sys_slist_t local_queue;
#if defined(CONFIG_BT_MESH_FRIEND)
/* Friend state, unique for each LPN that we're Friends for */
struct bt_mesh_friend frnd[CONFIG_BT_MESH_FRIEND_LPN_COUNT];
#endif
#if defined(CONFIG_BT_MESH_LOW_POWER)
struct bt_mesh_lpn lpn; /* Low Power Node state */
#endif
/* Timer to transition IV Update in Progress state */
struct k_delayed_work ivu_complete;
u8_t dev_key[16];
struct bt_mesh_app_key app_keys[CONFIG_BT_MESH_APP_KEY_COUNT];
struct bt_mesh_subnet sub[CONFIG_BT_MESH_SUBNET_COUNT];
struct bt_mesh_rpl rpl[CONFIG_BT_MESH_CRPL];
#if CONFIG_BT_MESH_PROVISIONER
/* Provisioner and node share arguments from 'iv_index' to 'local_queue' + 'ivu_complete' */
/* Application keys stored by provisioner */
struct bt_mesh_app_key *p_app_keys[CONFIG_BT_MESH_PROVISIONER_APP_KEY_COUNT];
/* Next app_idx can be assigned */
u16_t p_app_idx_next;
/* Network keys stored by provisioner */
struct bt_mesh_subnet *p_sub[CONFIG_BT_MESH_PROVISIONER_SUBNET_COUNT];
/* Next net_idx can be assigned */
u16_t p_net_idx_next;
#endif
};
/* Network interface */
enum bt_mesh_net_if {
BT_MESH_NET_IF_ADV,
BT_MESH_NET_IF_LOCAL,
BT_MESH_NET_IF_PROXY,
BT_MESH_NET_IF_PROXY_CFG,
};
/* Decoding context for Network/Transport data */
struct bt_mesh_net_rx {
struct bt_mesh_subnet *sub;
struct bt_mesh_msg_ctx ctx;
u32_t seq; /* Sequence Number */
u16_t dst; /* Destination address */
u8_t old_iv: 1, /* iv_index - 1 was used */
new_key: 1, /* Data was encrypted with updated key */
friend_cred: 1, /* Data was encrypted with friend cred */
ctl: 1, /* Network Control */
net_if: 2, /* Network interface */
local_match: 1, /* Matched a local element */
friend_match: 1; /* Matched an LPN we're friends for */
s8_t rssi;
};
/* Encoding context for Network/Transport data */
struct bt_mesh_net_tx {
struct bt_mesh_subnet *sub;
struct bt_mesh_msg_ctx *ctx;
u16_t src;
u8_t xmit;
u8_t friend_cred: 1,
aszmic: 1,
aid: 6;
};
extern struct bt_mesh_net bt_mesh;
#define BT_MESH_NET_IVI_TX (bt_mesh.iv_index - bt_mesh.iv_update)
#define BT_MESH_NET_IVI_RX(rx) (bt_mesh.iv_index - (rx)->old_iv)
#define BT_MESH_NET_HDR_LEN 9
int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys,
const u8_t key[16]);
int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16],
u32_t iv_index);
u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub);
bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key);
void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub);
int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub);
void bt_mesh_rpl_reset(void);
bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update);
void bt_mesh_net_sec_update(struct bt_mesh_subnet *sub);
struct bt_mesh_subnet *bt_mesh_subnet_get(u16_t net_idx);
struct bt_mesh_subnet *bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags,
u32_t iv_index, const u8_t auth[8],
bool *new_key);
int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf,
bool proxy);
int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
const struct bt_mesh_send_cb *cb, void *cb_data);
int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
bool new_key, const struct bt_mesh_send_cb *cb,
void *cb_data);
int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
struct bt_mesh_net_rx *rx, struct net_buf_simple *buf);
void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi,
enum bt_mesh_net_if net_if);
u32_t bt_mesh_next_seq(void);
void bt_mesh_net_init(void);
void bt_mesh_net_start(void);
/* Friendship Credential Management */
struct friend_cred {
u16_t net_idx;
u16_t addr;
u16_t lpn_counter;
u16_t frnd_counter;
struct {
u8_t nid; /* NID */
u8_t enc[16]; /* EncKey */
u8_t privacy[16]; /* PrivacyKey */
} cred[2];
};
int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid,
const u8_t **enc, const u8_t **priv);
int friend_cred_set(struct friend_cred *cred, u8_t idx, const u8_t net_key[16]);
void friend_cred_refresh(u16_t net_idx);
int friend_cred_update(struct bt_mesh_subnet *sub);
struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr,
u16_t lpn_counter, u16_t frnd_counter);
void friend_cred_clear(struct friend_cred *cred);
int friend_cred_del(u16_t net_idx, u16_t addr);
#endif /* #ifndef _NET_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _PROV_H_
#define _PROV_H_
#include "mesh_main.h"
#include "mesh_buf.h"
#include "mesh_bearer_adapt.h"
void bt_mesh_pb_adv_recv(struct net_buf_simple *buf);
bool bt_prov_active(void);
int bt_mesh_pb_gatt_open(struct bt_conn *conn);
int bt_mesh_pb_gatt_close(struct bt_conn *conn);
int bt_mesh_pb_gatt_recv(struct bt_conn *conn, struct net_buf_simple *buf);
int bt_mesh_set_oob_pub_key(const u8_t pub_key_x[32], const u8_t pub_key_y[32],
const u8_t pri_key[32]);
const u8_t *bt_mesh_prov_get_uuid(void);
int bt_mesh_prov_init(const struct bt_mesh_prov *prov);
void bt_mesh_prov_complete(u16_t net_idx, u16_t addr, u8_t flags, u32_t iv_index);
void bt_mesh_prov_reset(void);
#endif /* #ifndef _PROV_H_ */

View File

@@ -0,0 +1,77 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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 <errno.h>
#include <string.h>
#include "mesh_util.h"
#include "mesh_buf.h"
#include "sdkconfig.h"
#include "mesh_main.h"
#if CONFIG_BT_MESH
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_BEACON)
#include "mesh_trace.h"
#include "adv.h"
#include "mesh.h"
#include "net.h"
#include "prov.h"
#include "crypto.h"
#include "beacon.h"
#include "foundation.h"
#include "provisioner_prov.h"
#define BEACON_TYPE_UNPROVISIONED 0x00
#define BEACON_TYPE_SECURE 0x01
#if CONFIG_BT_MESH_PROVISIONER
static void provisioner_secure_beacon_recv(struct net_buf_simple *buf)
{
// TODO: Provisioner receive and handle Secure Beacon
}
void provisioner_beacon_recv(struct net_buf_simple *buf)
{
u8_t type;
BT_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len));
if (buf->len < 1) {
BT_ERR("Too short beacon");
return;
}
type = net_buf_simple_pull_u8(buf);
switch (type) {
case BEACON_TYPE_UNPROVISIONED:
BT_DBG("Unprovisioned device beacon received");
provisioner_unprov_beacon_recv(buf);
break;
case BEACON_TYPE_SECURE:
provisioner_secure_beacon_recv(buf);
break;
default:
BT_WARN("%s, Unknown beacon type 0x%02x", __func__, type);
break;
}
}
#endif /* CONFIG_BT_MESH_PROVISIONER */
#endif /* #if CONFIG_BT_MESH */

View File

@@ -0,0 +1,22 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// 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.
#ifndef _PROVISIONER_BEACON_H_
#define _PROVISIONER_BEACON_H_
void provisioner_beacon_recv(struct net_buf_simple *buf);
void bt_mesh_beacon_init(void);
#endif /* _PROVISIONER_BEACON_H_ */

Some files were not shown because too many files have changed in this diff Show More