Merge branch 'feature/ble_mesh_feature' into 'master'

component/ble_mesh: Add BLE Mesh Stack onto ESP-IDF

See merge request idf/esp-idf!4079
This commit is contained in:
Jiang Jiang Jian 2019-06-24 14:31:23 +08:00
commit f4eb3ddfee
260 changed files with 71487 additions and 1 deletions

View File

@ -287,6 +287,75 @@ if(CONFIG_BT_ENABLED)
endif()
endif()
if (CONFIG_BLE_MESH)
list(APPEND COMPONENT_ADD_INCLUDEDIRS
"bluedroid/osi/include"
"ble_mesh/mesh_core"
"ble_mesh/mesh_core/include"
"ble_mesh/mesh_core/settings"
"ble_mesh/btc/include"
"ble_mesh/mesh_models/include"
"ble_mesh/api/core/include"
"ble_mesh/api/models/include"
"ble_mesh/api")
list(APPEND COMPONENT_SRCS
"ble_mesh/api/core/esp_ble_mesh_common_api.c"
"ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c"
"ble_mesh/api/core/esp_ble_mesh_low_power_api.c"
"ble_mesh/api/core/esp_ble_mesh_networking_api.c"
"ble_mesh/api/core/esp_ble_mesh_provisioning_api.c"
"ble_mesh/api/core/esp_ble_mesh_proxy_api.c"
"ble_mesh/api/models/esp_ble_mesh_config_model_api.c"
"ble_mesh/api/models/esp_ble_mesh_generic_model_api.c"
"ble_mesh/api/models/esp_ble_mesh_health_model_api.c"
"ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c"
"ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c"
"ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c"
"ble_mesh/btc/btc_ble_mesh_config_model.c"
"ble_mesh/btc/btc_ble_mesh_generic_model.c"
"ble_mesh/btc/btc_ble_mesh_health_model.c"
"ble_mesh/btc/btc_ble_mesh_lighting_model.c"
"ble_mesh/btc/btc_ble_mesh_prov.c"
"ble_mesh/btc/btc_ble_mesh_sensor_model.c"
"ble_mesh/btc/btc_ble_mesh_time_scene_model.c"
"ble_mesh/mesh_core/settings/settings_nvs.c"
"ble_mesh/mesh_core/access.c"
"ble_mesh/mesh_core/adv.c"
"ble_mesh/mesh_core/beacon.c"
"ble_mesh/mesh_core/cfg_cli.c"
"ble_mesh/mesh_core/cfg_srv.c"
"ble_mesh/mesh_core/crypto.c"
"ble_mesh/mesh_core/friend.c"
"ble_mesh/mesh_core/health_cli.c"
"ble_mesh/mesh_core/health_srv.c"
"ble_mesh/mesh_core/lpn.c"
"ble_mesh/mesh_core/mesh_aes_encrypt.c"
"ble_mesh/mesh_core/mesh_atomic.c"
"ble_mesh/mesh_core/mesh_bearer_adapt.c"
"ble_mesh/mesh_core/mesh_buf.c"
"ble_mesh/mesh_core/mesh_hci.c"
"ble_mesh/mesh_core/mesh_kernel.c"
"ble_mesh/mesh_core/mesh_main.c"
"ble_mesh/mesh_core/mesh_util.c"
"ble_mesh/mesh_core/net.c"
"ble_mesh/mesh_core/prov.c"
"ble_mesh/mesh_core/provisioner_beacon.c"
"ble_mesh/mesh_core/provisioner_main.c"
"ble_mesh/mesh_core/provisioner_prov.c"
"ble_mesh/mesh_core/provisioner_proxy.c"
"ble_mesh/mesh_core/proxy.c"
"ble_mesh/mesh_core/settings.c"
"ble_mesh/mesh_core/test.c"
"ble_mesh/mesh_core/transport.c"
"ble_mesh/mesh_models/generic_client.c"
"ble_mesh/mesh_models/lighting_client.c"
"ble_mesh/mesh_models/mesh_common.c"
"ble_mesh/mesh_models/model_common.c"
"ble_mesh/mesh_models/sensor_client.c"
"ble_mesh/mesh_models/time_scene_client.c")
endif()
# requirements can't depend on config
set(COMPONENT_PRIV_REQUIRES nvs_flash soc)

View File

@ -1352,3 +1352,814 @@ menu Bluetooth
default 0
endmenu
menuconfig BLE_MESH
bool "BLE Mesh Support"
help
This option enables BLE Mesh support. The specific features that are
available may depend on other features that have been enabled in the
stack, such as Bluetooth Support, Bluedroid Support & GATT support.
if BLE_MESH
config BLE_MESH_HCI_5_0
bool "Support sending 20ms non-connectable adv packets"
default y
help
It is a temporary solution and needs further modifications.
config BLE_MESH_USE_DUPLICATE_SCAN
bool "Support Duplicate Scan in BLE Mesh"
select BLE_SCAN_DUPLICATE
select BLE_MESH_SCAN_DUPLICATE_EN
default y
help
Enable this option to allow using specific duplicate scan filter
in BLE Mesh, and Scan Duplicate Type must be set to 0x02.
config BLE_MESH_FAST_PROV
bool "Enable BLE Mesh Fast Provisioning"
select BLE_MESH_NODE
select BLE_MESH_PROVISIONER
select BLE_MESH_PB_ADV
default n
help
Enable this option to allow BLE Mesh fast provisioning solution to be used.
config BLE_MESH_NODE
bool "Support for BLE Mesh Node"
help
Enable the device to be provisioned into a node.
config BLE_MESH_PROVISIONER
bool "Support for BLE Mesh Provisioner"
help
Enable the device to be a provisioner.
if BLE_MESH_PROVISIONER
config BLE_MESH_WAIT_FOR_PROV_MAX_DEV_NUM
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 BLE_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 BLE_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 BLE_MESH_PB_ADV
config BLE_MESH_PBA_SAME_TIME
int "Maximum number of PB-ADV running at the same time by provisioner"
default 2
range 1 10
help
This option specifies how many devices can be provisioned at the same
time using PB-ADV.
endif # BLE_MESH_PB_ADV
if BLE_MESH_PB_GATT
config BLE_MESH_PBG_SAME_TIME
int "Maximum number of PB-GATT running at the same time by provisioner"
default 1
range 1 5
help
This option specifies how many devices can be provisioned at the same
time using PB-GATT.
endif # BLE_MESH_PB_GATT
config BLE_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 BLE_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 # BLE_MESH_PROVISIONER
# Virtual option enabled whenever Generic Provisioning layer is needed
config BLE_MESH_PROV
bool "BLE Mesh Provisioning support"
default y
help
Enable this option to support BLE Mesh Provisioning functionality. For
BLE Mesh, this option should be always enabled.
config BLE_MESH_PB_ADV
bool "Provisioning support using the advertising bearer (PB-ADV)"
select BLE_MESH_PROV
default y
help
Enable this option to allow the device to be provisioned over the
advertising bearer.
config BLE_MESH_PB_GATT
bool "Provisioning support using GATT (PB-GATT)"
select BLE_MESH_PROXY
select BLE_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 BLE_MESH_PROXY
bool "BLE Mesh Proxy protocol support"
default y
help
Enable this option to support BLE Mesh Proxy protocol used by PB-GATT
and other proxy pdu transmission.
config BLE_MESH_GATT_PROXY
bool "BLE Mesh GATT Proxy Service"
select BLE_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 BLE_MESH_NODE_ID_TIMEOUT
int "Node Identity advertising timeout"
depends on BLE_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 BLE_MESH_PROXY
config BLE_MESH_PROXY_FILTER_SIZE
int "Maximum number of filter entries per Proxy Client"
default 1
default 3 if BLE_MESH_GATT_PROXY
range 1 32767
help
This option specifies how many Proxy Filter entries the local node supports.
endif # BLE_MESH_PROXY
config BLE_MESH_NET_BUF_POOL_USAGE
bool "BLE Mesh net buffer pool usage tracking"
default y
help
Enable BLE Mesh net buffer pool tracking.
config BLE_MESH_SETTINGS
bool "Store BLE Mesh Node configuration persistently"
default n
help
When selected, the BLE Mesh stack will take care of storing/restoring the
BLE Mesh configuration persistently in flash. Currently this only supports
storing BLE Mesh node configuration.
if BLE_MESH_SETTINGS
config BLE_MESH_STORE_TIMEOUT
int "Delay (in seconds) before storing anything persistently"
range 0 1000000
default 0
help
This value defines in seconds how soon any pending changes are actually
written into persistent storage (flash) after a change occurs.
config BLE_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 BLE_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(Replay Protection List)
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.
endif # if BLE_MESH_SETTINGS
config BLE_MESH_SUBNET_COUNT
int "Maximum number of mesh subnets per network"
default 3
range 1 4096
help
This option specifies how many subnets a Mesh network can have at the same time.
config BLE_MESH_APP_KEY_COUNT
int "Maximum number of application keys per network"
default 3
range 1 4096
help
This option specifies how many application keys the device can store per network.
config BLE_MESH_MODEL_KEY_COUNT
int "Maximum number of application keys per model"
default 3
range 1 4096
help
This option specifies the maximum number of application keys to which each model
can be bound.
config BLE_MESH_MODEL_GROUP_COUNT
int "Maximum number of group address subscriptions per model"
default 3
range 1 4096
help
This option specifies the maximum number of addresses to which each model can
be subscribed.
config BLE_MESH_LABEL_COUNT
int "Maximum number of Label UUIDs used for Virtual Addresses"
default 3
range 0 4096
help
This option specifies how many Label UUIDs can be stored.
config BLE_MESH_CRPL
int "Maximum capacity of the replay protection list"
default 10
range 2 65535
help
This option specifies the maximum capacity of the replay protection list.
It is similar to Network message cache size, but has a different purpose.
config BLE_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 BLE_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 BLE_MESH_IVU_DIVIDER
int "Divider for IV Update state refresh timer"
default 4
range 2 96
help
When the IV Update state enters Normal operation or IV Update
in Progress, we need to keep track of how many hours has passed
in the state, since the specification requires us to remain in
the state at least for 96 hours (Update in Progress has an
additional upper limit of 144 hours).
In order to fulfill the above requirement, even if the node might
be powered off once in a while, we need to store persistently
how many hours the node has been in the state. This doesn't
necessarily need to happen every hour (thanks to the flexible
duration range). The exact cadence will depend a lot on the
ways that the node will be used and what kind of power source it
has.
Since there is no single optimal answer, this configuration
option allows specifying a divider, i.e. how many intervals
the 96 hour minimum gets split into. After each interval the
duration that the node has been in the current state gets
stored to flash. E.g. the default value of 4 means that the
state is saved every 24 hours (96 / 4).
config BLE_MESH_TX_SEG_MSG_COUNT
int "Maximum number of simultaneous outgoing segmented messages"
default 1
range 1 BLE_MESH_ADV_BUF_COUNT
help
Maximum number of simultaneous outgoing multi-segment and/or reliable messages.
config BLE_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 BLE_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 BLE_MESH_TX_SEG_MAX
int "Maximum number of segments in outgoing messages"
default 20
range 2 32
help
Maximum number of segments supported for outgoing messages.
This value should typically be fine-tuned based on what
models the local node supports, i.e. what's the largest
message payload that the node needs to be able to send.
This value affects memory and call stack consumption, which
is why the default is lower than the maximum that the
specification would allow (32 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.
Be sure to specify a sufficient number of advertising buffers
when setting this option to a higher value. There must be at
least three more advertising buffers (BLE_MESH_ADV_BUF_COUNT)
as there are outgoing segments.
config BLE_MESH_RELAY
bool "Relay support"
help
Support for acting as a Mesh Relay Node.
config BLE_MESH_LOW_POWER
bool "Support for Low Power features"
help
Enable this option to operate as a Low Power Node.
if BLE_MESH_LOW_POWER
config BLE_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 BLE_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 BLE_MESH_LPN_AUTO_TIMEOUT
int "Time from last received message before going to LPN mode"
default 15
range 0 3600
depends on BLE_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 BLE_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 BLE_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 BLE_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 BLE_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 BLE_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 BLE_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
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 BLE_MESH_LPN_INIT_POLL_TIMEOUT
int "The starting value of the PollTimeout timer"
range 10 BLE_MESH_LPN_POLL_TIMEOUT
default BLE_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 BLE_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 BLE_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 # BLE_MESH_LOW_POWER
config BLE_MESH_FRIEND
bool "Support for acting as a Friend Node"
help
Enable this option to be able to act as a Friend Node.
if BLE_MESH_FRIEND
config BLE_MESH_FRIEND_RECV_WIN
int "Friend Receive Window"
range 1 255
default 255
help
Receive Window in milliseconds supported by the Friend node.
config BLE_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 BLE_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 BLE_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 BLE_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 # BLE_MESH_FRIEND
config BLE_MESH_NO_LOG
bool "Disable BLE Mesh debug logs (minimize bin size)"
depends on BLE_MESH
default n
help
Select this to save the BLE Mesh related rodata code size.
menu "BLE Mesh STACK DEBUG LOG LEVEL"
depends on BLE_MESH && !BLE_MESH_NO_LOG
choice BLE_MESH_STACK_TRACE_LEVEL
prompt "BLE_MESH_STACK"
default BLE_MESH_TRACE_LEVEL_WARNING
depends on BLE_MESH && !BLE_MESH_NO_LOG
help
Define BLE Mesh trace level for BLE Mesh stack.
config BLE_MESH_TRACE_LEVEL_NONE
bool "NONE"
config BLE_MESH_TRACE_LEVEL_ERROR
bool "ERROR"
config BLE_MESH_TRACE_LEVEL_WARNING
bool "WARNING"
config BLE_MESH_TRACE_LEVEL_INFO
bool "INFO"
config BLE_MESH_TRACE_LEVEL_DEBUG
bool "DEBUG"
config BLE_MESH_TRACE_LEVEL_VERBOSE
bool "VERBOSE"
endchoice
config BLE_MESH_STACK_TRACE_LEVEL
int
depends on BLE_MESH
default 0 if BLE_MESH_TRACE_LEVEL_NONE
default 1 if BLE_MESH_TRACE_LEVEL_ERROR
default 2 if BLE_MESH_TRACE_LEVEL_WARNING
default 3 if BLE_MESH_TRACE_LEVEL_INFO
default 4 if BLE_MESH_TRACE_LEVEL_DEBUG
default 5 if BLE_MESH_TRACE_LEVEL_VERBOSE
default 2
endmenu #BLE Mesh DEBUG LOG LEVEL
menu "BLE Mesh NET BUF DEBUG LOG LEVEL"
depends on BLE_MESH && !BLE_MESH_NO_LOG
choice BLE_MESH_NET_BUF_TRACE_LEVEL
prompt "BLE_MESH_NET_BUF"
default BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING
depends on BLE_MESH && !BLE_MESH_NO_LOG
help
Define BLE Mesh trace level for BLE Mesh net buffer.
config BLE_MESH_NET_BUF_TRACE_LEVEL_NONE
bool "NONE"
config BLE_MESH_NET_BUF_TRACE_LEVEL_ERROR
bool "ERROR"
config BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING
bool "WARNING"
config BLE_MESH_NET_BUF_TRACE_LEVEL_INFO
bool "INFO"
config BLE_MESH_NET_BUF_TRACE_LEVEL_DEBUG
bool "DEBUG"
config BLE_MESH_NET_BUF_TRACE_LEVEL_VERBOSE
bool "VERBOSE"
endchoice
config BLE_MESH_NET_BUF_TRACE_LEVEL
int
depends on BLE_MESH
default 0 if BLE_MESH_NET_BUF_TRACE_LEVEL_NONE
default 1 if BLE_MESH_NET_BUF_TRACE_LEVEL_ERROR
default 2 if BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING
default 3 if BLE_MESH_NET_BUF_TRACE_LEVEL_INFO
default 4 if BLE_MESH_NET_BUF_TRACE_LEVEL_DEBUG
default 5 if BLE_MESH_NET_BUF_TRACE_LEVEL_VERBOSE
default 2
endmenu #BLE Mesh NET BUF DEBUG LOG LEVEL
config BLE_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 BLE_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 of the acknowledged
message which is sent by the client model.
menu "Support for BLE Mesh Client Models"
config BLE_MESH_CFG_CLI
bool "Configuration Client Model"
help
Enable support for Configuration client model.
config BLE_MESH_HEALTH_CLI
bool "Health Client Model"
help
Enable support for Health client model.
config BLE_MESH_GENERIC_ONOFF_CLI
bool "Generic OnOff Client Model"
help
Enable support for Generic OnOff client model.
config BLE_MESH_GENERIC_LEVEL_CLI
bool "Generic Level Client Model"
help
Enable support for Generic Level client model.
config BLE_MESH_GENERIC_DEF_TRANS_TIME_CLI
bool "Generic Default Transition Time Client Model"
help
Enable support for Generic Default Transition Time client model.
config BLE_MESH_GENERIC_POWER_ONOFF_CLI
bool "Generic Power Onoff Client Model"
help
Enable support for Generic Power Onoff client model.
config BLE_MESH_GENERIC_POWER_LEVEL_CLI
bool "Generic Power Level Client Model"
help
Enable support for Generic Power Level client model.
config BLE_MESH_GENERIC_BATTERY_CLI
bool "Generic Battery Client Model"
help
Enable support for Generic Battery client model.
config BLE_MESH_GENERIC_LOCATION_CLI
bool "Generic Location Client Model"
help
Enable support for Generic Location client model.
config BLE_MESH_GENERIC_PROPERTY_CLI
bool "Generic Property Client Model"
help
Enable support for Generic Property client model.
config BLE_MESH_SENSOR_CLI
bool "Sensor Client Model"
help
Enable support for Sensor client model.
config BLE_MESH_TIME_CLI
bool "Time Client Model"
help
Enable support for Time client model.
config BLE_MESH_SCENE_CLI
bool "Scene Client Model"
help
Enable support for Scene client model.
config BLE_MESH_SCHEDULER_CLI
bool "Scheduler Client Model"
help
Enable support for Scheduler client model.
config BLE_MESH_LIGHT_LIGHTNESS_CLI
bool "Light Lightness Client Model"
help
Enable support for Light Lightness client model.
config BLE_MESH_LIGHT_CTL_CLI
bool "Light CTL Client Model"
help
Enable support for Light CTL client model.
config BLE_MESH_LIGHT_HSL_CLI
bool "Light HSL Client Model"
help
Enable support for Light HSL client model.
config BLE_MESH_LIGHT_XYL_CLI
bool "Light XYL Client Model"
help
Enable support for Light XYL client model.
config BLE_MESH_LIGHT_LC_CLI
bool "Light LC Client Model"
help
Enable support for Light LC client model.
endmenu
config BLE_MESH_IV_UPDATE_TEST
bool "Test the IV Update Procedure"
default n
help
This option removes the 96 hour limit of the IV Update Procedure and
lets the state to be changed at any time.
menu "BLE Mesh specific test option"
config BLE_MESH_SELF_TEST
bool "Perform BLE Mesh self-tests"
default n
help
This option adds extra self-tests which are run every time BLE Mesh
networking is initialized.
config BLE_MESH_SHELL
bool "Enable BLE Mesh shell"
default n
help
Activate shell module that provides BLE Mesh commands to the console.
config BLE_MESH_DEBUG
bool "Enable BLE Mesh debug logs"
default n
help
Enable debug logs for the BLE Mesh functionality.
if BLE_MESH_DEBUG
config BLE_MESH_DEBUG_NET
bool "Network layer debug"
help
Enable Network layer debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_TRANS
bool "Transport layer debug"
help
Enable Transport layer debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_BEACON
bool "Beacon debug"
help
Enable Beacon-related debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_CRYPTO
bool "Crypto debug"
help
Enable cryptographic debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_PROV
bool "Provisioning debug"
help
Enable Provisioning debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_ACCESS
bool "Access layer debug"
help
Enable Access layer debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_MODEL
bool "Foundation model debug"
help
Enable Foundation Models debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_ADV
bool "Advertising debug"
help
Enable advertising debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_LOW_POWER
bool "Low Power debug"
help
Enable Low Power debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_FRIEND
bool "Friend debug"
help
Enable Friend debug logs for the BLE Mesh functionality.
config BLE_MESH_DEBUG_PROXY
bool "Proxy debug"
depends on BLE_MESH_PROXY
help
Enable Proxy protocol debug logs for the BLE Mesh functionality.
endif # BLE_MESH_DEBUG
endmenu
endif # BLE_MESH

View File

@ -0,0 +1,70 @@
// 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 <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_prov.h"
#include "esp_ble_mesh_defs.h"
esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp)
{
btc_ble_mesh_prov_args_t arg = {0};
SemaphoreHandle_t semaphore = NULL;
btc_msg_t msg = {0};
if (prov == NULL || comp == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
// Create a semaphore
if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) {
LOG_ERROR("%s, Failed to allocate memory for the semaphore", __func__);
return ESP_ERR_NO_MEM;
}
arg.mesh_init.prov = prov;
arg.mesh_init.comp = comp;
/* Transport semaphore pointer to BTC layer, and will give the semaphore in the BTC task */
arg.mesh_init.semaphore = semaphore;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_PROV;
msg.act = BTC_BLE_MESH_ACT_MESH_INIT;
if (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL) != BT_STATUS_SUCCESS) {
vSemaphoreDelete(semaphore);
LOG_ERROR("%s, BLE Mesh initialise failed", __func__);
return ESP_FAIL;
}
/* Take the Semaphore, wait BLE Mesh initialization to finish. */
xSemaphoreTake(semaphore, portMAX_DELAY);
/* Don't forget to delete the semaphore at the end. */
vSemaphoreDelete(semaphore);
return ESP_OK;
}

View File

@ -0,0 +1,80 @@
// 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 <stdint.h>
#include <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_prov.h"
#include "esp_ble_mesh_defs.h"
int32_t esp_ble_mesh_get_model_publish_period(esp_ble_mesh_model_t *model)
{
if (model == NULL) {
return 0;
}
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(const 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(const 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();
}

View File

@ -0,0 +1,26 @@
// 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 <stdint.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_prov.h"
#include "esp_ble_mesh_defs.h"

View File

@ -0,0 +1,338 @@
// 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 <stdint.h>
#include <errno.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_prov.h"
#include "esp_ble_mesh_networking_api.h"
#define ESP_BLE_MESH_TX_SDU_MAX ((CONFIG_BLE_MESH_ADV_BUF_COUNT - 3) * 12)
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_ble_mesh_model_args_t arg = {0};
uint8_t op_len = 0, mic_len = 0;
uint8_t *msg_data = NULL;
btc_msg_t msg = {0};
esp_err_t status;
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 publication 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, ESP_BLE_MESH_TX_SDU_MAX)) {
LOG_ERROR("%s, 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;
}
esp_err_t esp_ble_mesh_client_model_init(esp_ble_mesh_model_t *model)
{
if (model == NULL) {
return ESP_ERR_INVALID_ARG;
}
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 = {0};
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_BLE_MESH_PROVISIONER)
esp_err_t esp_ble_mesh_provisioner_set_node_name(int index, const char *name)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (!name || (strlen(name) > ESP_BLE_MESH_NODE_NAME_MAX_LEN)) {
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_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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (!ESP_BLE_MESH_ADDR_IS_UNICAST(element_addr)) {
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_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)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (net_idx == ESP_BLE_MESH_KEY_PRIMARY) {
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_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_BLE_MESH_PROVISIONER */
#if (CONFIG_BLE_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_BLE_MESH_FAST_PROV */

View File

@ -0,0 +1,423 @@
// 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 <stdint.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_prov.h"
#include "esp_ble_mesh_provisioning_api.h"
#define MAX_PROV_LINK_IDX (CONFIG_BLE_MESH_PBA_SAME_TIME + CONFIG_BLE_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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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.node_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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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.node_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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_number.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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_string.string, 0, sizeof(arg.input_string.string));
strncpy(arg.input_string.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)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
if (!name || strlen(name) > ESP_BLE_MESH_DEVICE_NAME_MAX_LEN) {
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_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_BLE_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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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)
{
uint8_t val = DEL_DEV_ADDR_FLAG | DEL_DEV_UUID_FLAG;
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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)
{
uint8_t val = PROV_DATA_NET_IDX_FLAG | PROV_DATA_FLAGS_FLAG | PROV_DATA_IV_INDEX_FLAG;
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_BLE_MESH_PROVISIONER */
/* The following APIs are for fast provisioning */
#if (CONFIG_BLE_MESH_FAST_PROV)
esp_err_t esp_ble_mesh_set_fast_prov_info(esp_ble_mesh_fast_prov_info_t *fast_prov_info)
{
btc_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_ble_mesh_prov_args_t arg = {0};
btc_msg_t msg = {0};
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_BLE_MESH_FAST_PROV */

View File

@ -0,0 +1,65 @@
// 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 <stdint.h>
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "esp_bt_defs.h"
#include "esp_bt_main.h"
#include "btc_ble_mesh_prov.h"
#include "esp_ble_mesh_defs.h"
esp_err_t esp_ble_mesh_proxy_identity_enable(void)
{
btc_msg_t msg = {0};
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 = {0};
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 = {0};
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);
}

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.
#ifndef _ESP_BLE_MESH_COMMON_API_H_
#define _ESP_BLE_MESH_COMMON_API_H_
#include "esp_ble_mesh_defs.h"
/**
* @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. This pointer must
* remain valid during the lifetime of the BLE Mesh device.
* @param[in] comp: Pointer to the device composition data information. This pointer
* must remain valid during the lifetime of the BLE Mesh device.
*
* @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 /* _ESP_BLE_MESH_COMMON_API_H_ */

View File

@ -0,0 +1,113 @@
// 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"
/**
* @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(const 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(const 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 /* _ESP_BLE_MESH_LOCAL_DATA_OPERATION_API_H_ */

View File

@ -0,0 +1,20 @@
// 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"
#endif /* _ESP_BLE_MESH_LOW_POWER_API_H_ */

View File

@ -0,0 +1,267 @@
// 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"
/** @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);
/**
* @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);
/**
* @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 /* _ESP_BLE_MESH_NETWORKING_API_H_ */

View File

@ -0,0 +1,316 @@
// 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"
/** @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);
/**
* @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);
/**
* @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 /* _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 <stdint.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_model.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)
{
btc_ble_mesh_cfg_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_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)
{
btc_ble_mesh_cfg_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_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 <stdint.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_model.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)
{
btc_ble_mesh_generic_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_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)
{
btc_ble_mesh_generic_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_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 <stdint.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_model.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)
{
btc_ble_mesh_health_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_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)
{
btc_ble_mesh_health_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_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 = {0};
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 <stdint.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_lighting_model.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)
{
btc_ble_mesh_light_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_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)
{
btc_ble_mesh_light_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_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 <stdint.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_model.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)
{
btc_ble_mesh_sensor_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_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)
{
btc_ble_mesh_sensor_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_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 <stdint.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_model.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)
{
btc_ble_mesh_time_scene_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !get_state) {
return ESP_ERR_INVALID_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)
{
btc_ble_mesh_time_scene_client_args_t arg = {0};
btc_msg_t msg = {0};
if (!params || !params->model || !params->ctx.addr || !set_state) {
return ESP_ERR_INVALID_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 "lighting_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,725 @@
// 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 "mesh_common.h"
#include "btc_ble_mesh_config_model.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, Invalid parameter", __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, Failed to allocate memory, act %d", __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, Failed to allocate memory, act %d", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s, Unknown deep copy act %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, Invalid parameter", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __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, Invalid parameter", __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, Invalid parameter", __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 client event type %d", __func__, evt_type);
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, Invalid parameter", __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, Invalid parameter", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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, Invalid parameter", __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, Invalid parameter", __func__);
return -EINVAL;
}
ctx.net_idx = params->ctx.net_idx;
ctx.app_idx = BLE_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, Invalid parameter", __func__);
return -EINVAL;
}
ctx.net_idx = params->ctx.net_idx;
ctx.app_idx = BLE_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 server event type %d", __func__, evt_type);
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, Invalid parameter", __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,540 @@
// 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_model.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, Invalid parameter", __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, Failed to allocate memory, act %d", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s, Unknown deep copy act %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, Invalid parameter", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __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, Invalid parameter", __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, Invalid parameter", __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 client event type %d", __func__, evt_type);
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, Invalid parameter", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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, Invalid parameter", __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,592 @@
// 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 "mesh_common.h"
#include "btc_ble_mesh_health_model.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, Invalid parameter", __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, Failed to allocate memory, act %d", __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, Failed to allocate memory, act %d", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s, Unknown deep copy act %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, Invalid parameter", __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, Invalid parameter", __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, Invalid parameter", __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, Invalid parameter", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __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, Invalid parameter", __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, Invalid parameter", __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, Invalid parameter", __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, Invalid parameter", __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, Invalid parameter", __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 client event type %d", __func__, evt_type);
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, Invalid parameter", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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, Invalid parameter", __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, Invalid parameter", __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, Invalid parameter", __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,381 @@
// 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 "lighting_client.h"
#include "btc_ble_mesh_lighting_model.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, Invalid parameter", __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, Failed to allocate memory, act %d", __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, Failed to allocate memory, act %d", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s, Unknown deep copy act %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, Invalid parameter", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __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, Invalid parameter", __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, Invalid parameter", __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 lighting client 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, Invalid parameter", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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, Invalid parameter", __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,632 @@
// 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_model.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, Invalid parameter", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s, Unknown deep copy act %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, Invalid parameter", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __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, Invalid parameter", __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, Invalid parameter", __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 client event type %d", __func__, evt_type);
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, Invalid parameter", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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, Invalid parameter", __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,383 @@
// 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_model.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, Invalid parameter", __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, Failed to allocate memory, act %d", __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, Failed to allocate memory, act %d", __func__, msg->act);
}
break;
}
default:
LOG_DEBUG("%s, Unknown deep copy act %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, Invalid parameter", __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, Failed to allocate memory, act %d", __func__, msg->act);
return;
}
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, Failed to allocate memory, act %d", __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, Invalid parameter", __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, Invalid parameter", __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 client event type %d", __func__, evt_type);
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, Invalid parameter", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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_set_model_role(&role_param)) {
LOG_ERROR("%s, Failed to set model role", __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, Invalid parameter", __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_MODEL_H_
#define _BTC_BLE_MESH_CONFIG_MODEL_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_MODEL_H_ */

View File

@ -0,0 +1,52 @@
// 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_MODEL_H_
#define _BTC_BLE_MESH_GENERIC_MODEL_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_MODEL_H_ */

View File

@ -0,0 +1,78 @@
// 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_MODEL_H_
#define _BTC_BLE_MESH_HEALTH_MODEL_H_
#include <stdint.h>
#include "btc/btc_task.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_MODEL_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_LIGHTING_MODEL_H_
#define _BTC_BLE_MESH_LIGHTING_MODEL_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_LIGHTING_MODEL_H_ */

View File

@ -0,0 +1,210 @@
// 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 "provisioner_prov.h"
#include "esp_ble_mesh_defs.h"
typedef enum {
BTC_BLE_MESH_ACT_MESH_INIT = 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,
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,
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_init_args {
esp_ble_mesh_prov_t *prov;
esp_ble_mesh_comp_t *comp;
SemaphoreHandle_t semaphore;
} mesh_init;
struct ble_mesh_node_prov_enable_args {
esp_ble_mesh_prov_bearer_t bearers;
} node_prov_enable;
struct ble_mesh_node_prov_disable_args {
esp_ble_mesh_prov_bearer_t bearers;
} node_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_node_input_num_args {
uint32_t number;
} input_number;
struct ble_mesh_node_input_str_args {
char string[8];
} input_string;
struct ble_mesh_set_device_name_args {
char name[ESP_BLE_MESH_DEVICE_NAME_MAX_LEN];
} set_device_name;
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;
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;
} 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(const esp_ble_mesh_elem_t *elem,
uint16_t company, uint16_t id);
esp_ble_mesh_model_t *btc_ble_mesh_model_find(const esp_ble_mesh_elem_t *elem,
uint16_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_ */

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_MODEL_H_
#define _BTC_BLE_MESH_SENSOR_MODEL_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_MODEL_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_MODEL_H_
#define _BTC_BLE_MESH_TIME_SCENE_MODEL_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_MODEL_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
/* 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"
/* bt_mesh_model.flags */
enum {
BLE_MESH_MOD_BIND_PENDING = BIT(0),
BLE_MESH_MOD_SUB_PENDING = BIT(1),
BLE_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);
const struct bt_mesh_comp *bt_mesh_comp_get(void);
struct bt_mesh_model *bt_mesh_model_get(bool vnd, u8_t elem_idx, u8_t mod_idx);
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 /* _ACCESS_H_ */

View File

@ -0,0 +1,411 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "osi/thread.h"
#include "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_ADV)
#include "mesh_util.h"
#include "mesh_buf.h"
#include "mesh_bearer_adapt.h"
#include "mesh_trace.h"
#include "mesh_hci.h"
#include "mesh.h"
#include "adv.h"
#include "net.h"
#include "foundation.h"
#include "beacon.h"
#include "prov.h"
#include "proxy.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "provisioner_beacon.h"
/* Convert from ms to 0.625ms units */
#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
/* Window and Interval are equal for continuous scanning */
#define MESH_SCAN_INTERVAL 0x20
#define MESH_SCAN_WINDOW 0x20
/* Pre-5.0 controllers enforce a minimum interval of 100ms
* whereas 5.0+ controllers can go down to 20ms.
*/
#define ADV_INT_DEFAULT_MS 100
#define ADV_INT_FAST_MS 20
#if defined(CONFIG_BT_HOST_CRYPTO)
#define ADV_STACK_SIZE 1024
#else
#define ADV_STACK_SIZE 768
#endif
static xQueueHandle xBleMeshQueue;
static const bt_mesh_addr_t *dev_addr;
static const u8_t adv_type[] = {
[BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV,
[BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
[BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON,
[BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI,
};
NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT + 3 * CONFIG_BLE_MESH_PBA_SAME_TIME,
BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT + 3 * CONFIG_BLE_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_mesh_dev.hci_version >= BLE_MESH_HCI_VERSION_5_0) ?
ADV_INT_FAST_MS : ADV_INT_DEFAULT_MS);
const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
struct bt_mesh_adv_param param = {0};
u16_t duration, adv_int;
struct bt_mesh_adv_data ad = {0};
int err;
adv_int = MAX(adv_int_min,
BLE_MESH_TRANSMIT_INT(BLE_MESH_ADV(buf)->xmit));
duration = (BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1) *
(adv_int + 10);
BT_DBG("type %u len %u: %s", BLE_MESH_ADV(buf)->type,
buf->len, bt_hex(buf->data, buf->len));
BT_DBG("count %u interval %ums duration %ums",
BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1, adv_int,
duration);
ad.type = adv_type[BLE_MESH_ADV(buf)->type];
ad.data_len = buf->len;
ad.data = buf->data;
param.options = 0U;
param.interval_min = ADV_SCAN_UNIT(adv_int);
param.interval_max = param.interval_min;
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("%s, Advertising failed: err %d", __func__, err);
return err;
}
BT_DBG("Advertising started. Sleeping %u ms", duration);
k_sleep(K_MSEC(duration));
err = bt_le_adv_stop();
adv_send_end(err, cb, cb_data);
if (err) {
BT_ERR("%s, Stop advertising failed: err %d", __func__, err);
return 0;
}
BT_DBG("Advertising stopped");
return 0;
}
static void adv_thread(void *p)
{
struct net_buf **buf = NULL;
bt_mesh_msg_t msg = {0};
int status;
BT_DBG("started");
buf = (struct net_buf **)(&msg.arg);
while (1) {
*buf = NULL;
#if CONFIG_BLE_MESH_NODE
if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) {
xQueueReceive(xBleMeshQueue, &msg, K_NO_WAIT);
while (!(*buf)) {
s32_t timeout;
BT_DBG("Proxy advertising start");
timeout = bt_mesh_proxy_adv_start();
BT_DBG("Proxy Advertising up to %d ms", timeout);
xQueueReceive(xBleMeshQueue, &msg, timeout);
BT_DBG("Proxy advertising stop");
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 (BLE_MESH_ADV(*buf)->busy) {
BLE_MESH_ADV(*buf)->busy = 0U;
status = adv_send(*buf);
if (status) {
if (xQueueSendToFront(xBleMeshQueue, &msg, K_NO_WAIT) != pdTRUE) {
BT_ERR("%s, xQueueSendToFront failed", __func__);
}
}
}
/* Give other threads a chance to run */
taskYIELD();
}
}
void bt_mesh_adv_update(void)
{
BT_DBG("%s", __func__);
bt_mesh_msg_t msg = {0};
bt_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, s32_t timeout)
{
struct bt_mesh_adv *adv;
struct net_buf *buf;
if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
BT_WARN("Refusing to allocate buffer while suspended");
return NULL;
}
buf = net_buf_alloc(pool, timeout);
if (!buf) {
return NULL;
}
BT_DBG("%s, pool = %p, buf_count = %d, uinit_count = %d", __func__,
buf->pool, pool->buf_count, pool->uninit_count);
adv = get_id(net_buf_id(buf));
BLE_MESH_ADV(buf) = adv;
(void)memset(adv, 0, sizeof(*adv));
adv->type = type;
adv->xmit = xmit;
return buf;
}
struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit,
s32_t timeout)
{
return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_alloc, type,
xmit, timeout);
}
void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
{
BT_DBG("%s", __func__);
if (xQueueSend(xBleMeshQueue, msg, timeout) != pdTRUE) {
BT_ERR("%s, Failed to post msg to queue", __func__);
}
}
void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
void *cb_data)
{
BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
bt_hex(buf->data, buf->len));
BLE_MESH_ADV(buf)->cb = cb;
BLE_MESH_ADV(buf)->cb_data = cb_data;
BLE_MESH_ADV(buf)->busy = 1U;
bt_mesh_msg_t msg = {0};
msg.arg = (void *)net_buf_ref(buf);
bt_mesh_task_post(&msg, portMAX_DELAY);
}
const bt_mesh_addr_t *bt_mesh_pba_get_addr(void)
{
return dev_addr;
}
static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
u8_t adv_type, struct net_buf_simple *buf)
{
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
u16_t uuid = 0;
#endif
if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_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 == 0U) {
return;
}
if (len > buf->len) {
BT_WARN("AD malformed");
return;
}
net_buf_simple_save(buf, &state);
type = net_buf_simple_pull_u8(buf);
buf->len = len - 1;
#if 0
/* TODO: Check with BLE Mesh BQB test cases */
if ((type == BLE_MESH_DATA_MESH_PROV || type == BLE_MESH_DATA_MESH_MESSAGE ||
type == BLE_MESH_DATA_MESH_BEACON) && (adv_type != BLE_MESH_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 BLE_MESH_DATA_MESH_MESSAGE:
bt_mesh_net_recv(buf, rssi, BLE_MESH_NET_IF_ADV);
break;
#if CONFIG_BLE_MESH_PB_ADV
case BLE_MESH_DATA_MESH_PROV:
#if CONFIG_BLE_MESH_NODE
if (!bt_mesh_is_provisioner_en()) {
bt_mesh_pb_adv_recv(buf);
}
#endif
#if CONFIG_BLE_MESH_PROVISIONER
if (bt_mesh_is_provisioner_en()) {
provisioner_pb_adv_recv(buf);
}
#endif
break;
#endif /* CONFIG_BLE_MESH_PB_ADV */
case BLE_MESH_DATA_MESH_BEACON:
#if CONFIG_BLE_MESH_NODE
if (!bt_mesh_is_provisioner_en()) {
bt_mesh_beacon_recv(buf);
}
#endif
#if CONFIG_BLE_MESH_PROVISIONER
if (bt_mesh_is_provisioner_en()) {
provisioner_beacon_recv(buf);
}
#endif
break;
#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
case BLE_MESH_DATA_FLAGS:
if (bt_mesh_is_provisioner_en()) {
if (!provisioner_flags_match(buf)) {
BT_DBG("Flags mismatch, ignore this adv pkt");
return;
}
}
break;
case BLE_MESH_DATA_UUID16_ALL:
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 BLE_MESH_DATA_SVC_DATA16:
if (bt_mesh_is_provisioner_en()) {
provisioner_srv_data_recv(buf, addr, uuid);
}
break;
#endif /* CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT */
default:
break;
}
net_buf_simple_restore(buf, &state);
net_buf_simple_pull(buf, len);
}
return;
}
void bt_mesh_adv_init(void)
{
xBleMeshQueue = xQueueCreate(150, sizeof(bt_mesh_msg_t));
xTaskCreatePinnedToCore(adv_thread, "BLE_Mesh_ADV_Task", 3072, NULL,
configMAX_PRIORITIES - 7, NULL, TASK_PINNED_TO_CORE);
}
int bt_mesh_scan_enable(void)
{
struct bt_mesh_scan_param scan_param = {
.type = BLE_MESH_SCAN_PASSIVE,
#if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN)
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_ENABLE,
#else
.filter_dup = BLE_MESH_SCAN_FILTER_DUP_DISABLE,
#endif
.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();
}

View File

@ -0,0 +1,86 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ADV_H_
#define _ADV_H_
#include "mesh_bearer_adapt.h"
/* Maximum advertising data payload for a single data type */
#define BLE_MESH_ADV_DATA_SIZE 29
/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */
#define BLE_MESH_ADV_USER_DATA_SIZE 4
#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
typedef struct bt_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
} bt_mesh_msg_t;
enum bt_mesh_adv_type {
BLE_MESH_ADV_PROV,
BLE_MESH_ADV_DATA,
BLE_MESH_ADV_BEACON,
BLE_MESH_ADV_URI,
};
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 xmit;
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,
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, s32_t timeout);
void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
void *cb_data);
const bt_mesh_addr_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 bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout);
#endif /* _ADV_H_ */

View File

@ -0,0 +1,422 @@
/* 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 "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_BEACON)
#include "mesh_util.h"
#include "mesh_buf.h"
#include "mesh_main.h"
#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"
#if CONFIG_BLE_MESH_NODE
#if defined(CONFIG_BLE_MESH_FAST_PROV)
#define UNPROVISIONED_INTERVAL K_SECONDS(3)
#else
#define UNPROVISIONED_INTERVAL K_SECONDS(5)
#endif /* CONFIG_BLE_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 BLE_MESH_TRANSMIT(2, 20)
/* 1 transmission, 20ms interval */
#define PROV_XMIT BLE_MESH_TRANSMIT(0, 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 == BLE_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 == BLE_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(BLE_MESH_ADV_BEACON, PROV_XMIT,
K_NO_WAIT);
if (!buf) {
BT_ERR("%s, Unable to allocate beacon buffer", __func__);
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_BLE_MESH_PB_ADV)
const struct bt_mesh_prov *prov;
u8_t uri_hash[16] = { 0 };
struct net_buf *buf;
u16_t oob_info;
BT_DBG("%s", __func__);
buf = bt_mesh_adv_create(BLE_MESH_ADV_BEACON, UNPROV_XMIT, K_NO_WAIT);
if (!buf) {
BT_ERR("%s, Unable to allocate beacon buffer", __func__);
return -ENOBUFS;
}
prov = bt_mesh_prov_get();
net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED);
net_buf_add_mem(buf, prov->uuid, 16);
if (prov->uri && bt_mesh_s1(prov->uri, uri_hash) == 0) {
oob_info = prov->oob_info | BLE_MESH_PROV_OOB_URI;
} else {
oob_info = prov->oob_info;
}
net_buf_add_be16(buf, oob_info);
net_buf_add_mem(buf, uri_hash, 4);
bt_mesh_adv_send(buf, NULL, NULL);
net_buf_unref(buf);
if (prov->uri) {
size_t len;
buf = bt_mesh_adv_create(BLE_MESH_ADV_URI, UNPROV_XMIT,
K_NO_WAIT);
if (!buf) {
BT_ERR("Unable to allocate URI buffer");
return -ENOBUFS;
}
len = strlen(prov->uri);
if (net_buf_tailroom(buf) < len) {
BT_WARN("Too long URI to fit advertising data");
} else {
net_buf_add_mem(buf, prov->uri, len);
bt_mesh_adv_send(buf, NULL, NULL);
}
net_buf_unref(buf);
}
#endif /* CONFIG_BLE_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 == BLE_MESH_KEY_UNUSED) {
continue;
}
sub->beacons_last = sub->beacons_cur;
sub->beacons_cur = 0U;
}
}
static void beacon_send(struct k_work *work)
{
/* Don't send anything if we have an active provisioning link */
if (IS_ENABLED(CONFIG_BLE_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() == BLE_MESH_BEACON_ENABLED ||
bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_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("%s, Too short secure beacon (len %u)", __func__, 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 = net_buf_simple_pull_mem(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 == BLE_MESH_KR_PHASE_2 && !new_key) {
BT_WARN("Ignoring Phase 2 KR Update secured using old key");
return;
}
cache_add(data, sub);
/* If we have NetKey0 accept initiation only from it */
if (bt_mesh_subnet_get(BLE_MESH_KEY_PRIMARY) &&
sub->net_idx != BLE_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_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR) &&
(bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS) ==
BLE_MESH_IV_UPDATE(flags))) {
bt_mesh_beacon_ivu_initiator(false);
}
iv_change = bt_mesh_net_iv_update(iv_index, BLE_MESH_IV_UPDATE(flags));
kr_change = bt_mesh_kr_update(sub, BLE_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() == BLE_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("%s, Too short beacon", __func__);
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_DBG("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_atomic_set_bit_to(bt_mesh.flags, BLE_MESH_IVU_INITIATOR, enable);
if (enable) {
k_work_submit(&beacon_timer.work);
} else if (bt_mesh_beacon_get() == BLE_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 == BLE_MESH_KEY_UNUSED) {
continue;
}
sub->beacons_last = 0U;
sub->beacons_cur = 0U;
bt_mesh_net_beacon_update(sub);
}
k_work_submit(&beacon_timer.work);
}
void bt_mesh_beacon_disable(void)
{
if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR)) {
k_delayed_work_cancel(&beacon_timer);
}
}
#endif /* CONFIG_BLE_MESH_NODE */

View File

@ -0,0 +1,24 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BEACON_H_
#define _BEACON_H_
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);
#endif /* _BEACON_H_ */

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,878 @@
/* 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 "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_CRYPTO)
#include "mesh_types.h"
#include "mesh_util.h"
#include "mesh_buf.h"
#include "mesh_trace.h"
#include "mesh_bearer_adapt.h"
#include "mesh_aes_encrypt.h"
#include "mesh.h"
#include "crypto.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_mesh_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_mesh_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_mesh_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_mesh_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 = 16U;
}
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_mesh_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_mesh_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_mesh_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_mesh_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_mesh_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_mesh_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_mesh_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_mesh_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 = 16U;
}
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_mesh_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_mesh_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_mesh_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_mesh_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_BLE_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] = 0U;
nonce[8] = 0U;
/* 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] = 0U;
nonce[8] = 0U;
/* 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_mesh_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_BLE_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_BLE_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_BLE_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;
}

View File

@ -0,0 +1,166 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _CRYPTO_H_
#define _CRYPTO_H_
#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]);
int bt_mesh_prov_encrypt(const u8_t key[16], u8_t nonce[13],
const u8_t data[25], u8_t out[33]);
#endif /* _CRYPTO_H_ */

View File

@ -0,0 +1,166 @@
/* 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 BLE_MESH_MODEL_OP_1(0x00)
#define OP_APP_KEY_UPDATE BLE_MESH_MODEL_OP_1(0x01)
#define OP_DEV_COMP_DATA_STATUS BLE_MESH_MODEL_OP_1(0x02)
#define OP_MOD_PUB_SET BLE_MESH_MODEL_OP_1(0x03)
#define OP_HEALTH_CURRENT_STATUS BLE_MESH_MODEL_OP_1(0x04)
#define OP_HEALTH_FAULT_STATUS BLE_MESH_MODEL_OP_1(0x05)
#define OP_HEARTBEAT_PUB_STATUS BLE_MESH_MODEL_OP_1(0x06)
#define OP_APP_KEY_DEL BLE_MESH_MODEL_OP_2(0x80, 0x00)
#define OP_APP_KEY_GET BLE_MESH_MODEL_OP_2(0x80, 0x01)
#define OP_APP_KEY_LIST BLE_MESH_MODEL_OP_2(0x80, 0x02)
#define OP_APP_KEY_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x03)
#define OP_ATTENTION_GET BLE_MESH_MODEL_OP_2(0x80, 0x04)
#define OP_ATTENTION_SET BLE_MESH_MODEL_OP_2(0x80, 0x05)
#define OP_ATTENTION_SET_UNREL BLE_MESH_MODEL_OP_2(0x80, 0x06)
#define OP_ATTENTION_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x07)
#define OP_DEV_COMP_DATA_GET BLE_MESH_MODEL_OP_2(0x80, 0x08)
#define OP_BEACON_GET BLE_MESH_MODEL_OP_2(0x80, 0x09)
#define OP_BEACON_SET BLE_MESH_MODEL_OP_2(0x80, 0x0a)
#define OP_BEACON_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x0b)
#define OP_DEFAULT_TTL_GET BLE_MESH_MODEL_OP_2(0x80, 0x0c)
#define OP_DEFAULT_TTL_SET BLE_MESH_MODEL_OP_2(0x80, 0x0d)
#define OP_DEFAULT_TTL_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x0e)
#define OP_FRIEND_GET BLE_MESH_MODEL_OP_2(0x80, 0x0f)
#define OP_FRIEND_SET BLE_MESH_MODEL_OP_2(0x80, 0x10)
#define OP_FRIEND_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x11)
#define OP_GATT_PROXY_GET BLE_MESH_MODEL_OP_2(0x80, 0x12)
#define OP_GATT_PROXY_SET BLE_MESH_MODEL_OP_2(0x80, 0x13)
#define OP_GATT_PROXY_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x14)
#define OP_KRP_GET BLE_MESH_MODEL_OP_2(0x80, 0x15)
#define OP_KRP_SET BLE_MESH_MODEL_OP_2(0x80, 0x16)
#define OP_KRP_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x17)
#define OP_MOD_PUB_GET BLE_MESH_MODEL_OP_2(0x80, 0x18)
#define OP_MOD_PUB_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x19)
#define OP_MOD_PUB_VA_SET BLE_MESH_MODEL_OP_2(0x80, 0x1a)
#define OP_MOD_SUB_ADD BLE_MESH_MODEL_OP_2(0x80, 0x1b)
#define OP_MOD_SUB_DEL BLE_MESH_MODEL_OP_2(0x80, 0x1c)
#define OP_MOD_SUB_DEL_ALL BLE_MESH_MODEL_OP_2(0x80, 0x1d)
#define OP_MOD_SUB_OVERWRITE BLE_MESH_MODEL_OP_2(0x80, 0x1e)
#define OP_MOD_SUB_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x1f)
#define OP_MOD_SUB_VA_ADD BLE_MESH_MODEL_OP_2(0x80, 0x20)
#define OP_MOD_SUB_VA_DEL BLE_MESH_MODEL_OP_2(0x80, 0x21)
#define OP_MOD_SUB_VA_OVERWRITE BLE_MESH_MODEL_OP_2(0x80, 0x22)
#define OP_NET_TRANSMIT_GET BLE_MESH_MODEL_OP_2(0x80, 0x23)
#define OP_NET_TRANSMIT_SET BLE_MESH_MODEL_OP_2(0x80, 0x24)
#define OP_NET_TRANSMIT_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x25)
#define OP_RELAY_GET BLE_MESH_MODEL_OP_2(0x80, 0x26)
#define OP_RELAY_SET BLE_MESH_MODEL_OP_2(0x80, 0x27)
#define OP_RELAY_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x28)
#define OP_MOD_SUB_GET BLE_MESH_MODEL_OP_2(0x80, 0x29)
#define OP_MOD_SUB_LIST BLE_MESH_MODEL_OP_2(0x80, 0x2a)
#define OP_MOD_SUB_GET_VND BLE_MESH_MODEL_OP_2(0x80, 0x2b)
#define OP_MOD_SUB_LIST_VND BLE_MESH_MODEL_OP_2(0x80, 0x2c)
#define OP_LPN_TIMEOUT_GET BLE_MESH_MODEL_OP_2(0x80, 0x2d)
#define OP_LPN_TIMEOUT_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x2e)
#define OP_HEALTH_FAULT_CLEAR BLE_MESH_MODEL_OP_2(0x80, 0x2f)
#define OP_HEALTH_FAULT_CLEAR_UNREL BLE_MESH_MODEL_OP_2(0x80, 0x30)
#define OP_HEALTH_FAULT_GET BLE_MESH_MODEL_OP_2(0x80, 0x31)
#define OP_HEALTH_FAULT_TEST BLE_MESH_MODEL_OP_2(0x80, 0x32)
#define OP_HEALTH_FAULT_TEST_UNREL BLE_MESH_MODEL_OP_2(0x80, 0x33)
#define OP_HEALTH_PERIOD_GET BLE_MESH_MODEL_OP_2(0x80, 0x34)
#define OP_HEALTH_PERIOD_SET BLE_MESH_MODEL_OP_2(0x80, 0x35)
#define OP_HEALTH_PERIOD_SET_UNREL BLE_MESH_MODEL_OP_2(0x80, 0x36)
#define OP_HEALTH_PERIOD_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x37)
#define OP_HEARTBEAT_PUB_GET BLE_MESH_MODEL_OP_2(0x80, 0x38)
#define OP_HEARTBEAT_PUB_SET BLE_MESH_MODEL_OP_2(0x80, 0x39)
#define OP_HEARTBEAT_SUB_GET BLE_MESH_MODEL_OP_2(0x80, 0x3a)
#define OP_HEARTBEAT_SUB_SET BLE_MESH_MODEL_OP_2(0x80, 0x3b)
#define OP_HEARTBEAT_SUB_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x3c)
#define OP_MOD_APP_BIND BLE_MESH_MODEL_OP_2(0x80, 0x3d)
#define OP_MOD_APP_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x3e)
#define OP_MOD_APP_UNBIND BLE_MESH_MODEL_OP_2(0x80, 0x3f)
#define OP_NET_KEY_ADD BLE_MESH_MODEL_OP_2(0x80, 0x40)
#define OP_NET_KEY_DEL BLE_MESH_MODEL_OP_2(0x80, 0x41)
#define OP_NET_KEY_GET BLE_MESH_MODEL_OP_2(0x80, 0x42)
#define OP_NET_KEY_LIST BLE_MESH_MODEL_OP_2(0x80, 0x43)
#define OP_NET_KEY_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x44)
#define OP_NET_KEY_UPDATE BLE_MESH_MODEL_OP_2(0x80, 0x45)
#define OP_NODE_IDENTITY_GET BLE_MESH_MODEL_OP_2(0x80, 0x46)
#define OP_NODE_IDENTITY_SET BLE_MESH_MODEL_OP_2(0x80, 0x47)
#define OP_NODE_IDENTITY_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x48)
#define OP_NODE_RESET BLE_MESH_MODEL_OP_2(0x80, 0x49)
#define OP_NODE_RESET_STATUS BLE_MESH_MODEL_OP_2(0x80, 0x4a)
#define OP_SIG_MOD_APP_GET BLE_MESH_MODEL_OP_2(0x80, 0x4b)
#define OP_SIG_MOD_APP_LIST BLE_MESH_MODEL_OP_2(0x80, 0x4c)
#define OP_VND_MOD_APP_GET BLE_MESH_MODEL_OP_2(0x80, 0x4d)
#define OP_VND_MOD_APP_LIST BLE_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);
void bt_mesh_hb_pub_disable(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, bool store);
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, bool store);
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 /* _FOUNDATION_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _FRIEND_H_
#define _FRIEND_H_
enum bt_mesh_friend_pdu_type {
BLE_MESH_FRIEND_PDU_SINGLE,
BLE_MESH_FRIEND_PDU_PARTIAL,
BLE_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);
#endif /* _FRIEND_H_ */

View File

@ -0,0 +1,462 @@
/* 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 "osi/allocator.h"
#include "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_MODEL)
#include "mesh_types.h"
#include "mesh_util.h"
#include "mesh_trace.h"
#include "health_cli.h"
#include "foundation.h"
#include "mesh_common.h"
#include "btc_ble_mesh_health_model.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)
{
health_internal_data_t *internal = NULL;
bt_mesh_health_client_t *client = 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, Invalid parameter", __func__);
return;
}
client = (bt_mesh_health_client_t *)node->ctx.model->user_data;
if (!client) {
BT_ERR("%s, Health Client user_data is NULL", __func__);
return;
}
internal = (health_internal_data_t *)client->internal_data;
if (!internal) {
BT_ERR("%s, Health Client 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, Failed to allocate memory", __func__);
return;
}
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 },
BLE_MESH_MODEL_OP_END,
};
int bt_mesh_health_attention_get(struct bt_mesh_msg_ctx *ctx)
{
NET_BUF_SIMPLE_DEFINE(msg, 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)
{
NET_BUF_SIMPLE_DEFINE(msg, 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)
{
NET_BUF_SIMPLE_DEFINE(msg, 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)
{
NET_BUF_SIMPLE_DEFINE(msg, 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)
{
NET_BUF_SIMPLE_DEFINE(msg, 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)
{
NET_BUF_SIMPLE_DEFINE(msg, 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)
{
NET_BUF_SIMPLE_DEFINE(msg, 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("%s, No Health Client context for given model", __func__);
return -EINVAL;
}
health_cli = model->user_data;
return 0;
}
int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary)
{
health_internal_data_t *internal = NULL;
bt_mesh_health_client_t *client = NULL;
BT_DBG("primary %u", primary);
if (!model) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
client = (bt_mesh_health_client_t *)model->user_data;
if (!client) {
BT_ERR("%s, No Health Client context provided", __func__);
return -EINVAL;
}
/* TODO: call osi_free() when deinit function is invoked*/
internal = osi_calloc(sizeof(health_internal_data_t));
if (!internal) {
BT_ERR("%s, Failed to allocate memory", __func__);
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;
}

View File

@ -0,0 +1,529 @@
/* 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 "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_MODEL)
#include "mesh_types.h"
#include "mesh_util.h"
#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 "mesh_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("%s, Failed to get faults (err %d)", __func__, 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("%s, Failed to get faults (err %d)", __func__, err);
sys_put_le16(comp->cid, company_ptr);
*test_id = HEALTH_TEST_STANDARD;
fault_count = 0U;
} 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 = 0U;
}
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(BLE_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("%s, Unable to send Health Current Status", __func__);
}
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(BLE_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("%s, Unable to send Health Current Status", __func__);
}
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(BLE_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("%s, Unable to send Health Current Status", __func__);
}
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 */
NET_BUF_SIMPLE_DEFINE(msg, 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 == 1U) ? "" : "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("%s, Unable to send Health Attention Status", __func__);
}
}
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 == 1U) ? "" : "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 */
NET_BUF_SIMPLE_DEFINE(msg, 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("%s, Unable to send Health Period Status", __func__);
}
}
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("%s, Prohibited period value %u", __func__, 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 },
BLE_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->fast_period = 1U;
} else {
pub->fast_period = 0U;
}
return 0;
}
int bt_mesh_fault_update(struct bt_mesh_elem *elem)
{
struct bt_mesh_model *mod;
mod = bt_mesh_model_find(elem, BLE_MESH_MODEL_ID_HEALTH_SRV);
if (!mod) {
BT_ERR("%s, Health Server does not exist", __func__);
return -EINVAL;
}
if (!mod->pub) {
BT_ERR("%s, Health Server has no publication support", __func__);
return -EIO;
}
/* Let periodic publishing, if enabled, take care of sending the
* Health Current Status.
*/
if (bt_mesh_model_pub_period_get(mod)) {
return 0;
}
health_pub_update(mod);
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 * 1000U);
} else {
k_delayed_work_cancel(&srv->attn_timer);
if (srv->cb && srv->cb->attn_off) {
srv->cb->attn_off(model);
}
}
}

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 _BLE_MESH_CFG_CLI_H_
#define _BLE_MESH_CFG_CLI_H_
#include "mesh_access.h"
#include "mesh_kernel.h"
#include "model_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 BLE_MESH_MODEL_CFG_CLI(cli_data) \
BLE_MESH_MODEL(BLE_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 /* __BLE_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 _BLE_MESH_CFG_SRV_H_
#define _BLE_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 BLE_MESH_MODEL_CFG_SRV(srv_data) \
BLE_MESH_MODEL(BLE_MESH_MODEL_ID_CFG_SRV, \
bt_mesh_cfg_srv_op, NULL, srv_data)
/**
* @}
*/
#endif /* __BLE_MESH_CFG_SRV_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 _BLE_MESH_HEALTH_CLI_H_
#define _BLE_MESH_HEALTH_CLI_H_
#include "mesh_access.h"
#include "mesh_kernel.h"
#include "model_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 BLE_MESH_MODEL_HEALTH_CLI(cli_data) \
BLE_MESH_MODEL(BLE_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 /* __BLE_MESH_HEALTH_CLI_H */

View File

@ -0,0 +1,93 @@
/** @file
* @brief Bluetooth Mesh Health Server Model APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BLE_MESH_HEALTH_SRV_H_
#define _BLE_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 BLE_MESH_HEALTH_PUB_DEFINE
*
* A helper to define a health publication context
*
* @param _name Name given to the publication context variable.
* @param _max_faults Maximum number of faults the element can have.
*/
#define BLE_MESH_HEALTH_PUB_DEFINE(_name, _max_faults) \
BLE_MESH_MODEL_PUB_DEFINE(_name, NULL, (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;
};
extern const struct bt_mesh_model_op bt_mesh_health_srv_op[];
/** @def BLE_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 BLE_MESH_MODEL_HEALTH_SRV(srv, pub) \
BLE_MESH_MODEL(BLE_MESH_MODEL_ID_HEALTH_SRV, \
bt_mesh_health_srv_op, pub, srv)
int bt_mesh_fault_update(struct bt_mesh_elem *elem);
/**
* @}
*/
#endif /* __BLE_MESH_HEALTH_SRV_H */

View File

@ -0,0 +1,444 @@
/** @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
*/
#ifndef _BLE_MESH_ACCESS_H_
#define _BLE_MESH_ACCESS_H_
#include <stddef.h>
#include "mesh_types.h"
#include "mesh_util.h"
#include "mesh_buf.h"
#include "sdkconfig.h"
/**
* @brief Bluetooth Mesh Access Layer
* @defgroup bt_mesh_access Bluetooth Mesh Access Layer
* @ingroup bt_mesh
* @{
*/
#define BLE_MESH_ADDR_UNASSIGNED 0x0000
#define BLE_MESH_ADDR_ALL_NODES 0xffff
#define BLE_MESH_ADDR_PROXIES 0xfffc
#define BLE_MESH_ADDR_FRIENDS 0xfffd
#define BLE_MESH_ADDR_RELAYS 0xfffe
#define BLE_MESH_KEY_UNUSED 0xffff
#define BLE_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 BLE_MESH_MODEL_NONE can be given instead.
*
* @param _loc Location Descriptor.
* @param _mods Array of models.
* @param _vnd_mods Array of vendor models.
*/
#define BLE_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 BLE_MESH_MODEL_ID_CFG_SRV 0x0000
#define BLE_MESH_MODEL_ID_CFG_CLI 0x0001
#define BLE_MESH_MODEL_ID_HEALTH_SRV 0x0002
#define BLE_MESH_MODEL_ID_HEALTH_CLI 0x0003
/* Models from the Mesh Model Specification */
#define BLE_MESH_MODEL_ID_GEN_ONOFF_SRV 0x1000
#define BLE_MESH_MODEL_ID_GEN_ONOFF_CLI 0x1001
#define BLE_MESH_MODEL_ID_GEN_LEVEL_SRV 0x1002
#define BLE_MESH_MODEL_ID_GEN_LEVEL_CLI 0x1003
#define BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV 0x1004
#define BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI 0x1005
#define BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV 0x1006
#define BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV 0x1007
#define BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI 0x1008
#define BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV 0x1009
#define BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV 0x100a
#define BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI 0x100b
#define BLE_MESH_MODEL_ID_GEN_BATTERY_SRV 0x100c
#define BLE_MESH_MODEL_ID_GEN_BATTERY_CLI 0x100d
#define BLE_MESH_MODEL_ID_GEN_LOCATION_SRV 0x100e
#define BLE_MESH_MODEL_ID_GEN_LOCATION_SETUPSRV 0x100f
#define BLE_MESH_MODEL_ID_GEN_LOCATION_CLI 0x1010
#define BLE_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV 0x1011
#define BLE_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV 0x1012
#define BLE_MESH_MODEL_ID_GEN_USER_PROP_SRV 0x1013
#define BLE_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV 0x1014
#define BLE_MESH_MODEL_ID_GEN_PROP_CLI 0x1015
#define BLE_MESH_MODEL_ID_SENSOR_SRV 0x1100
#define BLE_MESH_MODEL_ID_SENSOR_SETUP_SRV 0x1101
#define BLE_MESH_MODEL_ID_SENSOR_CLI 0x1102
#define BLE_MESH_MODEL_ID_TIME_SRV 0x1200
#define BLE_MESH_MODEL_ID_TIME_SETUP_SRV 0x1201
#define BLE_MESH_MODEL_ID_TIME_CLI 0x1202
#define BLE_MESH_MODEL_ID_SCENE_SRV 0x1203
#define BLE_MESH_MODEL_ID_SCENE_SETUP_SRV 0x1204
#define BLE_MESH_MODEL_ID_SCENE_CLI 0x1205
#define BLE_MESH_MODEL_ID_SCHEDULER_SRV 0x1206
#define BLE_MESH_MODEL_ID_SCHEDULER_SETUP_SRV 0x1207
#define BLE_MESH_MODEL_ID_SCHEDULER_CLI 0x1208
#define BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV 0x1300
#define BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV 0x1301
#define BLE_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI 0x1302
#define BLE_MESH_MODEL_ID_LIGHT_CTL_SRV 0x1303
#define BLE_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV 0x1304
#define BLE_MESH_MODEL_ID_LIGHT_CTL_CLI 0x1305
#define BLE_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV 0x1306
#define BLE_MESH_MODEL_ID_LIGHT_HSL_SRV 0x1307
#define BLE_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV 0x1308
#define BLE_MESH_MODEL_ID_LIGHT_HSL_CLI 0x1309
#define BLE_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV 0x130a
#define BLE_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV 0x130b
#define BLE_MESH_MODEL_ID_LIGHT_XYL_SRV 0x130c
#define BLE_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV 0x130d
#define BLE_MESH_MODEL_ID_LIGHT_XYL_CLI 0x130e
#define BLE_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f
#define BLE_MESH_MODEL_ID_LIGHT_LC_SETUPSRV 0x1310
#define BLE_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;
/** Destination address of a received message. Not used for sending. */
u16_t recv_dst;
/** 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 BLE_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, 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 BLE_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 BLE_MESH_MODEL_OP_1(b0) (b0)
#define BLE_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1))
#define BLE_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid))
#define BLE_MESH_MODEL_OP_END { 0, 0, NULL }
#define BLE_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \
{ BLE_MESH_MODEL_OP_END })
/** Helper to define an empty model array */
#define BLE_MESH_MODEL_NONE ((struct bt_mesh_model []){})
#define BLE_MESH_MODEL(_id, _op, _pub, _user_data) \
{ \
.id = (_id), \
.op = _op, \
.keys = { [0 ... (CONFIG_BLE_MESH_MODEL_KEY_COUNT - 1)] = \
BLE_MESH_KEY_UNUSED }, \
.pub = _pub, \
.groups = { [0 ... (CONFIG_BLE_MESH_MODEL_GROUP_COUNT - 1)] = \
BLE_MESH_ADDR_UNASSIGNED }, \
.user_data = _user_data, \
}
#define BLE_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \
{ \
.vnd.company = (_company), \
.vnd.id = (_id), \
.op = _op, \
.pub = _pub, \
.keys = { [0 ... (CONFIG_BLE_MESH_MODEL_KEY_COUNT - 1)] = \
BLE_MESH_KEY_UNUSED }, \
.groups = { [0 ... (CONFIG_BLE_MESH_MODEL_GROUP_COUNT - 1)] = \
BLE_MESH_ADDR_UNASSIGNED }, \
.user_data = _user_data, \
}
/** @def BLE_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 BLE_MESH_TRANSMIT(count, int_ms) ((count) | (((int_ms / 10) - 1) << 3))
/** @def BLE_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 BLE_MESH_TRANSMIT_COUNT(transmit) (((transmit) & (u8_t)BIT_MASK(3)))
/** @def BLE_MESH_TRANSMIT_INT
*
* @brief Decode transmit interval from a transmit value.
*
* @param transmit Encoded transmit count & interval value.
*
* @return Transmission interval in milliseconds.
*/
#define BLE_MESH_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 10)
/** @def BLE_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 BLE_MESH_PUB_TRANSMIT(count, int_ms) BLE_MESH_TRANSMIT(count, (int_ms) / 5)
/** @def BLE_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 BLE_MESH_PUB_TRANSMIT_COUNT(transmit) BLE_MESH_TRANSMIT_COUNT(transmit)
/** @def BLE_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 BLE_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. */
u16_t period_div: 4, /**< Divisor for the Period. */
cred: 1, /**< Friendship Credentials Flag. */
fast_period: 1, /**< Use FastPeriodDivisor */
count: 3; /**< Retransmissions left. */
u32_t period_start; /**< Start of the current period. */
/** @brief Publication buffer, containing the publication message.
*
* This will get correctly created when the publication context
* has been defined using the BLE_MESH_MODEL_PUB_DEFINE macro.
*
* BLE_MESH_MODEL_PUB_DEFINE(name, update, 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 BLE_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 BLE_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;
};
/* Internal information, mainly for persistent storage */
u8_t elem_idx; /* Belongs to Nth element */
u8_t model_idx; /* Is the Nth model in the element */
u16_t flags; /* Information about what has changed */
/* 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_BLE_MESH_MODEL_KEY_COUNT];
/* Subscription List (group or virtual addresses) */
u16_t groups[CONFIG_BLE_MESH_MODEL_GROUP_COUNT];
const struct bt_mesh_model_op *const op;
/* Model-specific user data */
void *user_data;
};
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 BLE_MESH_TTL_DEFAULT 0xff
/** Maximum allowed TTL value */
#define BLE_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);
/**
* @brief Get the element that a model belongs to.
*
* @param mod Mesh model.
*
* @return Pointer to the element that the given model belongs to.
*/
struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod);
/** 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 /* __BLE_MESH_ACCESS_H */

View File

@ -0,0 +1,171 @@
/* 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 _BLE_MESH_AES_ENCRYPT_H_
#define _BLE_MESH_AES_ENCRYPT_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 /* _BLE_MESH_AES_ENCRYPT_H_ */

View File

@ -0,0 +1,305 @@
/* atomic operations */
/*
* Copyright (c) 1997-2015, Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BLE_MESH_ATOMIC_H_
#define _BLE_MESH_ATOMIC_H_
#include "mesh_types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef bt_mesh_atomic_t bt_mesh_atomic_val_t;
/**
* @defgroup atomic_apis Atomic Services APIs
* @ingroup kernel_apis
* @{
*/
/**
*
* @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 bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
{
return bt_mesh_atomic_add(target, 1);
}
#else
extern bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_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 bt_mesh_atomic_val_t bt_mesh_atomic_dec(bt_mesh_atomic_t *target)
{
return bt_mesh_atomic_sub(target, 1);
}
#else
extern bt_mesh_atomic_val_t bt_mesh_atomic_dec(bt_mesh_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 bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_atomic_t *target)
{
return __atomic_load_n(target, __ATOMIC_SEQ_CST);
}
#else
extern bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_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 bt_mesh_atomic_val_t bt_mesh_atomic_set(bt_mesh_atomic_t *target, bt_mesh_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 bt_mesh_atomic_val_t bt_mesh_atomic_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value);
#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 bt_mesh_atomic_val_t bt_mesh_atomic_or(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
{
return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST);
}
#else
extern bt_mesh_atomic_val_t bt_mesh_atomic_or(bt_mesh_atomic_t *target, bt_mesh_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 bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
{
return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST);
}
#else
extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value);
#endif
/**
* @cond INTERNAL_HIDDEN
*/
#define BLE_MESH_ATOMIC_BITS (sizeof(bt_mesh_atomic_val_t) * 8)
#define BLE_MESH_ATOMIC_MASK(bit) (1 << ((bit) & (BLE_MESH_ATOMIC_BITS - 1)))
#define BLE_MESH_ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / BLE_MESH_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 BLE_MESH_ATOMIC_DEFINE(name, num_bits) \
bt_mesh_atomic_t name[1 + ((num_bits) - 1) / BLE_MESH_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 bt_mesh_atomic_test_bit(const bt_mesh_atomic_t *target, int bit)
{
bt_mesh_atomic_val_t val = bt_mesh_atomic_get(BLE_MESH_ATOMIC_ELEM(target, bit));
return (1 & (val >> (bit & (BLE_MESH_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 bt_mesh_atomic_test_and_clear_bit(bt_mesh_atomic_t *target, int bit)
{
bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
bt_mesh_atomic_val_t old;
old = bt_mesh_atomic_and(BLE_MESH_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 bt_mesh_atomic_test_and_set_bit(bt_mesh_atomic_t *target, int bit)
{
bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
bt_mesh_atomic_val_t old;
old = bt_mesh_atomic_or(BLE_MESH_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 bt_mesh_atomic_clear_bit(bt_mesh_atomic_t *target, int bit)
{
bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
(void)bt_mesh_atomic_and(BLE_MESH_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 bt_mesh_atomic_set_bit(bt_mesh_atomic_t *target, int bit)
{
bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
(void)bt_mesh_atomic_or(BLE_MESH_ATOMIC_ELEM(target, bit), mask);
}
/**
* @brief Atomically set a bit to a given value.
*
* Atomically set bit number @a bit of @a target to value @a val.
* 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).
* @param val true for 1, false for 0.
*
* @return N/A
*/
static inline void bt_mesh_atomic_set_bit_to(bt_mesh_atomic_t *target, int bit, bool val)
{
bt_mesh_atomic_val_t mask = BLE_MESH_ATOMIC_MASK(bit);
if (val) {
(void)bt_mesh_atomic_or(BLE_MESH_ATOMIC_ELEM(target, bit), mask);
} else {
(void)bt_mesh_atomic_and(BLE_MESH_ATOMIC_ELEM(target, bit), ~mask);
}
}
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* _BLE_MESH_ATOMIC_H_ */

View File

@ -0,0 +1,733 @@
/*
* 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 _BLE_MESH_BEARER_ADRPT_H_
#define _BLE_MESH_BEARER_ADRPT_H_
#include <string.h>
#include "mesh_types.h"
#include "mesh_util.h"
#include "mesh_buf.h"
#include "mesh_uuid.h"
/* BLE Mesh Max Connection Count */
#define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS
/* BD ADDR types */
#define BLE_MESH_ADDR_PUBLIC 0x00
#define BLE_MESH_ADDR_RANDOM 0x01
#define BLE_MESH_ADDR_PUBLIC_ID 0x02
#define BLE_MESH_ADDR_RANDOM_ID 0x03
/* BD ADDR length */
#define BLE_MESH_ADDR_LEN 0x06
/* Advertising types */
#define BLE_MESH_ADV_IND 0x00
#define BLE_MESH_ADV_DIRECT_IND 0x01
#define BLE_MESH_ADV_SCAN_IND 0x02
#define BLE_MESH_ADV_NONCONN_IND 0x03
#define BLE_MESH_ADV_DIRECT_IND_LOW_DUTY 0x04
/* advertising channel map */
#define BLE_MESH_ADV_CHNL_37 BIT(0)
#define BLE_MESH_ADV_CHNL_38 BIT(1)
#define BLE_MESH_ADV_CHNL_39 BIT(2)
/* Advertising filter policy */
#define BLE_MESH_AP_SCAN_CONN_ALL 0x00
#define BLE_MESH_AP_SCAN_WL_CONN_ALL 0x01
#define BLE_MESH_AP_SCAN_ALL_CONN_WL 0x02
#define BLE_MESH_AP_SCAN_CONN_WL 0x03
/* Scan types */
#define BLE_MESH_SCAN_PASSIVE 0x00
#define BLE_MESH_SCAN_ACTIVE 0x01
/* Scan operation */
#define BLE_MESH_SCAN_DISABLE 0x00
#define BLE_MESH_SCAN_ENABLE 0x01
/* Scan duplicate operation */
#define BLE_MESH_SCAN_FILTER_DUP_DISABLE 0x00
#define BLE_MESH_SCAN_FILTER_DUP_ENABLE 0x01
/* Scan filter policy */
#define BLE_MESH_SP_ADV_ALL 0x00
#define BLE_MESH_SP_ADV_WL 0x01
#define BLE_MESH_SP_ADV_ALL_RPA_DIR_ADV 0x02
#define BLE_MESH_SP_ADV_WL_RPA_DIR_ADV 0x03
/* Error codes for Error response PDU */
#define BLE_MESH_ATT_ERR_INVALID_HANDLE 0x01
#define BLE_MESH_ATT_ERR_READ_NOT_PERMITTED 0x02
#define BLE_MESH_ATT_ERR_WRITE_NOT_PERMITTED 0x03
#define BLE_MESH_ATT_ERR_INVALID_PDU 0x04
#define BLE_MESH_ATT_ERR_AUTHENTICATION 0x05
#define BLE_MESH_ATT_ERR_NOT_SUPPORTED 0x06
#define BLE_MESH_ATT_ERR_INVALID_OFFSET 0x07
#define BLE_MESH_ATT_ERR_AUTHORIZATION 0x08
#define BLE_MESH_ATT_ERR_PREPARE_QUEUE_FULL 0x09
#define BLE_MESH_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0a
#define BLE_MESH_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0b
#define BLE_MESH_ATT_ERR_ENCRYPTION_KEY_SIZE 0x0c
#define BLE_MESH_ATT_ERR_INVALID_ATTRIBUTE_LEN 0x0d
#define BLE_MESH_ATT_ERR_UNLIKELY 0x0e
#define BLE_MESH_ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f
#define BLE_MESH_ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10
#define BLE_MESH_ATT_ERR_INSUFFICIENT_RESOURCES 0x11
/* Common Profile Error Codes (from CSS) */
#define BLE_MESH_ATT_ERR_WRITE_REQ_REJECTED 0xfc
#define BLE_MESH_ATT_ERR_CCC_IMPROPER_CONF 0xfd
#define BLE_MESH_ATT_ERR_PROCEDURE_IN_PROGRESS 0xfe
#define BLE_MESH_ATT_ERR_OUT_OF_RANGE 0xff
/* EIR/AD data type definitions */
#define BLE_MESH_DATA_FLAGS 0x01 /* AD flags */
#define BLE_MESH_DATA_UUID16_SOME 0x02 /* 16-bit UUID, more available */
#define BLE_MESH_DATA_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
#define BLE_MESH_DATA_UUID32_SOME 0x04 /* 32-bit UUID, more available */
#define BLE_MESH_DATA_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
#define BLE_MESH_DATA_UUID128_SOME 0x06 /* 128-bit UUID, more available */
#define BLE_MESH_DATA_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
#define BLE_MESH_DATA_NAME_SHORTENED 0x08 /* Shortened name */
#define BLE_MESH_DATA_NAME_COMPLETE 0x09 /* Complete name */
#define BLE_MESH_DATA_TX_POWER 0x0a /* Tx Power */
#define BLE_MESH_DATA_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */
#define BLE_MESH_DATA_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */
#define BLE_MESH_DATA_SVC_DATA16 0x16 /* Service data, 16-bit UUID */
#define BLE_MESH_DATA_GAP_APPEARANCE 0x19 /* GAP appearance */
#define BLE_MESH_DATA_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */
#define BLE_MESH_DATA_SVC_DATA32 0x20 /* Service data, 32-bit UUID */
#define BLE_MESH_DATA_SVC_DATA128 0x21 /* Service data, 128-bit UUID */
#define BLE_MESH_DATA_URI 0x24 /* URI */
#define BLE_MESH_DATA_MESH_PROV 0x29 /* Mesh Provisioning PDU */
#define BLE_MESH_DATA_MESH_MESSAGE 0x2a /* Mesh Networking PDU */
#define BLE_MESH_DATA_MESH_BEACON 0x2b /* Mesh Beacon */
#define BLE_MESH_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */
#define BLE_MESH_AD_LIMITED 0x01 /* Limited Discoverable */
#define BLE_MESH_AD_GENERAL 0x02 /* General Discoverable */
#define BLE_MESH_AD_NO_BREDR 0x04 /* BR/EDR not supported */
/* Client Characteristic Configuration Values */
/** @def BLE_MESH_GATT_CCC_NOTIFY
* @brief Client Characteristic Configuration Notification.
*
* If set, changes to Characteristic Value shall be notified.
*/
#define BLE_MESH_GATT_CCC_NOTIFY 0x0001
/** @def BLE_MESH_GATT_CCC_INDICATE
* @brief Client Characteristic Configuration Indication.
*
* If set, changes to Characteristic Value shall be indicated.
*/
#define BLE_MESH_GATT_CCC_INDICATE 0x0002
/** @def BLE_MESH_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 BLE_MESH_GATT_ERR(_att_err) (-(_att_err))
enum {
BLE_MESH_GATT_ITER_STOP = 0,
BLE_MESH_GATT_ITER_CONTINUE,
};
/* GATT attribute permission bit field values */
enum {
/** No operations supported, e.g. for notify-only */
BLE_MESH_GATT_PERM_NONE = 0,
/** Attribute read permission. */
BLE_MESH_GATT_PERM_READ = BIT(0),
/** Attribute write permission. */
BLE_MESH_GATT_PERM_WRITE = BIT(1),
/** Attribute read permission with encryption.
*
* If set, requires encryption for read access.
*/
BLE_MESH_GATT_PERM_READ_ENCRYPT = BIT(2),
/** Attribute write permission with encryption.
*
* If set, requires encryption for write access.
*/
BLE_MESH_GATT_PERM_WRITE_ENCRYPT = BIT(3),
/** Attribute read permission with authentication.
*
* If set, requires encryption using authenticated link-key for read
* access.
*/
BLE_MESH_GATT_PERM_READ_AUTHEN = BIT(4),
/** Attribute write permission with authentication.
*
* If set, requires encryption using authenticated link-key for write
* access.
*/
BLE_MESH_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.
*/
BLE_MESH_GATT_PERM_PREPARE_WRITE = BIT(6),
};
/** Advertising options */
enum {
/** Convenience value when no options are specified. */
BLE_MESH_ADV_OPT_NONE = 0,
/** Advertise as connectable. Type of advertising is determined by
* providing SCAN_RSP data and/or enabling local privacy support.
*/
BLE_MESH_ADV_OPT_CONNECTABLE = BIT(0),
/** Don't try to resume connectable advertising after a connection.
* This option is only meaningful when used together with
* BLE_MESH_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.
*/
BLE_MESH_ADV_OPT_ONE_TIME = BIT(1),
};
/* Defined GAP timers */
#define BLE_MESH_GAP_SCAN_FAST_INTERVAL 0x0060 /* 60 ms */
#define BLE_MESH_GAP_SCAN_FAST_WINDOW 0x0030 /* 30 ms */
#define BLE_MESH_GAP_SCAN_SLOW_INTERVAL_1 0x0800 /* 1.28 s */
#define BLE_MESH_GAP_SCAN_SLOW_WINDOW_1 0x0012 /* 11.25 ms */
#define BLE_MESH_GAP_SCAN_SLOW_INTERVAL_2 0x1000 /* 2.56 s */
#define BLE_MESH_GAP_SCAN_SLOW_WINDOW_2 0x0012 /* 11.25 ms */
#define BLE_MESH_GAP_ADV_FAST_INT_MIN_0 0x0020 /* 20 ms */
#define BLE_MESH_GAP_ADV_FAST_INT_MAX_0 0x0020 /* 20 ms */
#define BLE_MESH_GAP_ADV_FAST_INT_MIN_1 0x0030 /* 30 ms */
#define BLE_MESH_GAP_ADV_FAST_INT_MAX_1 0x0060 /* 60 ms */
#define BLE_MESH_GAP_ADV_FAST_INT_MIN_2 0x00a0 /* 100 ms */
#define BLE_MESH_GAP_ADV_FAST_INT_MAX_2 0x00f0 /* 150 ms */
#define BLE_MESH_GAP_ADV_SLOW_INT_MIN 0x0320 /* 500 ms */
#define BLE_MESH_GAP_ADV_SLOW_INT_MAX 0x0320 /* 500 ms */
#define BLE_MESH_GAP_INIT_CONN_INT_MIN 0x0018 /* 30 ms */
#define BLE_MESH_GAP_INIT_CONN_INT_MAX 0x0028 /* 50 ms */
/* Characteristic Properties Bit field values */
/** @def BLE_MESH_GATT_CHRC_BROADCAST
* @brief Characteristic broadcast property.
*
* If set, permits broadcasts of the Characteristic Value using Server
* Characteristic Configuration Descriptor.
*/
#define BLE_MESH_GATT_CHRC_BROADCAST 0x01
/** @def BLE_MESH_GATT_CHRC_READ
* @brief Characteristic read property.
*
* If set, permits reads of the Characteristic Value.
*/
#define BLE_MESH_GATT_CHRC_READ 0x02
/** @def BLE_MESH_GATT_CHRC_WRITE_WITHOUT_RESP
* @brief Characteristic write without response property.
*
* If set, permits write of the Characteristic Value without response.
*/
#define BLE_MESH_GATT_CHRC_WRITE_WITHOUT_RESP 0x04
/** @def BLE_MESH_GATT_CHRC_WRITE
* @brief Characteristic write with response property.
*
* If set, permits write of the Characteristic Value with response.
*/
#define BLE_MESH_GATT_CHRC_WRITE 0x08
/** @def BLE_MESH_GATT_CHRC_NOTIFY
* @brief Characteristic notify property.
*
* If set, permits notifications of a Characteristic Value without
* acknowledgment.
*/
#define BLE_MESH_GATT_CHRC_NOTIFY 0x10
/** @def BLE_MESH_GATT_CHRC_INDICATE
* @brief Characteristic indicate property.
*
* If set, permits indications of a Characteristic Value with acknowledgment.
*/
#define BLE_MESH_GATT_CHRC_INDICATE 0x20
/** @def BLE_MESH_GATT_CHRC_AUTH
* @brief Characteristic Authenticated Signed Writes property.
*
* If set, permits signed writes to the Characteristic Value.
*/
#define BLE_MESH_GATT_CHRC_AUTH 0x40
/** @def BLE_MESH_GATT_CHRC_EXT_PROP
* @brief Characteristic Extended Properties property.
*
* If set, additional characteristic properties are defined in the
* Characteristic Extended Properties Descriptor.
*/
#define BLE_MESH_GATT_CHRC_EXT_PROP 0x80
/** @brief Characteristic Attribute Value. */
struct bt_mesh_gatt_char {
/** Characteristic UUID. */
const struct bt_mesh_uuid *uuid;
/** Characteristic properties. */
u8_t properties;
};
/** @brief GATT Service structure */
struct bt_mesh_gatt_service {
/** Service Attributes */
struct bt_mesh_gatt_attr *attrs;
/** Service Attribute count */
u16_t attr_count;
sys_snode_t node;
};
struct bt_mesh_ecb_param {
u8_t key[16];
u8_t clear_text[16];
u8_t cipher_text[16];
} __packed;
typedef struct {
u8_t type;
u8_t val[6];
} bt_mesh_addr_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_mesh_adv_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_mesh_adv_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 BLE_MESH_ADV_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_mesh_adv_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 BLE_MESH_ADV_DATA_BYTES(_type, _bytes...) \
BLE_MESH_ADV_DATA(_type, ((u8_t []) { _bytes }), \
sizeof((u8_t []) { _bytes }))
/* BLE Mesh Advertising Parameters */
struct bt_mesh_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;
};
/* BLE Mesh scan parameters */
struct bt_mesh_scan_param {
/** Scan type (BLE_MESH_SCAN_ACTIVE or BLE_MESH_SCAN_PASSIVE) */
u8_t type;
/** Duplicate filtering (BLE_MESH_SCAN_FILTER_DUP_ENABLE or
* BLE_MESH_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;
};
struct bt_mesh_conn {
u16_t handle;
bt_mesh_atomic_t ref;
};
/** @typedef bt_mesh_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_mesh_scan_cb_t(const bt_mesh_addr_t *addr, s8_t rssi,
u8_t adv_type, struct net_buf_simple *buf);
/* @typedef bt_mesh_dh_key_cb_t
* @brief Callback type for DH Key calculation.
*
* Used to notify of the calculated DH Key.
*
* @param key Public key.
* @param idx Provisioning link index, only used by Provisioner.
*
* @return The DH Key, or NULL in case of failure.
*/
typedef void (*bt_mesh_dh_key_cb_t)(const u8_t key[32], const u8_t idx);
/** @typedef bt_mesh_gatt_attr_func_t
* @brief Attribute iterator callback.
*
* @param attr Attribute found.
* @param user_data Data given.
*
* @return BLE_MESH_GATT_ITER_CONTINUE if should continue to the next attribute
* or BLE_MESH_GATT_ITER_STOP to stop.
*/
typedef u8_t (*bt_mesh_gatt_attr_func_t)(const struct bt_mesh_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_mesh_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_mesh_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_mesh_conn *conn, u8_t reason);
};
struct bt_mesh_prov_conn_cb {
void (*connected)(const u8_t addr[6], struct bt_mesh_conn *conn, int id);
void (*disconnected)(struct bt_mesh_conn *conn, u8_t reason);
ssize_t (*prov_write_descr)(struct bt_mesh_conn *conn, u8_t *addr);
ssize_t (*prov_notify)(struct bt_mesh_conn *conn, u8_t *data, u16_t len);
ssize_t (*proxy_write_descr)(struct bt_mesh_conn *conn);
ssize_t (*proxy_notify)(struct bt_mesh_conn *conn, u8_t *data, u16_t len);
};
/** @brief GATT Attribute structure. */
struct bt_mesh_gatt_attr {
/** Attribute UUID */
const struct bt_mesh_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
* BLE_MESH_GATT_ERR() with a specific ATT error code.
*/
ssize_t (*read)(struct bt_mesh_conn *conn,
const struct bt_mesh_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
* BLE_MESH_GATT_ERR() with a specific ATT error code.
*/
ssize_t (*write)(struct bt_mesh_conn *conn,
const struct bt_mesh_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 BLE_MESH_GATT_PRIMARY_SERVICE
* @brief Primary Service Declaration Macro.
*
* Helper macro to declare a primary service attribute.
*
* @param _service Service attribute value.
*/
#define BLE_MESH_GATT_PRIMARY_SERVICE(_service) \
{ \
.uuid = BLE_MESH_UUID_GATT_PRIMARY, \
.perm = BLE_MESH_GATT_PERM_READ, \
.read = bt_mesh_gatts_attr_read_service, \
.user_data = _service, \
}
/** @def BLE_MESH_GATT_SECONDARY_SERVICE
* @brief Secondary Service Declaration Macro.
*
* Helper macro to declare a secondary service attribute.
*
* @param _service Service attribute value.
*/
#define BLE_MESH_GATT_SECONDARY_SERVICE(_service) \
{ \
.uuid = BLE_MESH_UUID_GATT_SECONDARY, \
.perm = BLE_MESH_GATT_PERM_READ, \
.read = bt_mesh_gatts_attr_read_service, \
.user_data = _service, \
}
/** @def BLE_MESH_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 BLE_MESH_GATT_INCLUDE_SERVICE(_service_incl) \
{ \
.uuid = BLE_MESH_UUID_GATT_INCLUDE, \
.perm = BLE_MESH_GATT_PERM_READ, \
.read = bt_mesh_gatts_attr_read_included, \
.user_data = _service_incl, \
}
/** @def BLE_MESH_GATT_CHARACTERISTIC
* @brief Characteristic Declaration Macro.
*
* Helper macro to declare a characteristic attribute.
*
* @param _uuid Characteristic attribute uuid.
* @param _props Characteristic attribute properties.
*/
#define BLE_MESH_GATT_CHARACTERISTIC(_uuid, _props) \
{ \
.uuid = BLE_MESH_UUID_GATT_CHRC, \
.perm = BLE_MESH_GATT_PERM_READ, \
.read = bt_mesh_gatts_attr_read_chrc, \
.user_data = (&(struct bt_mesh_gatt_char) { .uuid = _uuid, \
.properties = _props, }), \
}
/** @def BLE_MESH_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 BLE_MESH_GATT_DESCRIPTOR(_uuid, _perm, _read, _write, _value) \
{ \
.uuid = _uuid, \
.perm = _perm, \
.read = _read, \
.write = _write, \
.user_data = _value, \
}
/** @def BLE_MESH_GATT_SERVICE
* @brief Service Structure Declaration Macro.
*
* Helper macro to declare a service structure.
*
* @param _attrs Service attributes.
*/
#define BLE_MESH_GATT_SERVICE(_attrs) \
{ \
.attrs = _attrs, \
.attr_count = ARRAY_SIZE(_attrs), \
}
int bt_le_adv_start(const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
const struct bt_mesh_adv_data *sd, size_t sd_len);
int bt_le_adv_stop(void);
int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb);
int bt_le_scan_stop(void);
void bt_mesh_gatts_conn_cb_register(struct bt_mesh_conn_cb *cb);
int bt_mesh_gatts_disconnect(struct bt_mesh_conn *conn, u8_t reason);
int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc);
int bt_mesh_gatts_service_unregister(struct bt_mesh_gatt_service *svc);
ssize_t bt_mesh_gatts_attr_read_included(struct bt_mesh_conn *conn,
const struct bt_mesh_gatt_attr *attr,
void *buf, u16_t len, u16_t offset);
ssize_t bt_mesh_gatts_attr_read(struct bt_mesh_conn *conn, const struct bt_mesh_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_mesh_conn *conn,
const struct bt_mesh_gatt_attr *attr,
void *buf, u16_t len, u16_t offset);
ssize_t bt_mesh_gatts_attr_read_chrc(struct bt_mesh_conn *conn,
const struct bt_mesh_gatt_attr *attr, void *buf,
u16_t len, u16_t offset);
int bt_mesh_gatts_notify(struct bt_mesh_conn *conn, const struct bt_mesh_gatt_attr *attr,
const void *data, u16_t len);
u16_t bt_mesh_gatt_get_mtu(struct bt_mesh_conn *conn);
/** APIs added by Espressif */
int bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service *svc);
int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc);
void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb);
u16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn);
int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, u16_t service_uuid);
void bt_gattc_conn_close(struct bt_mesh_conn *conn);
void bt_mesh_gattc_exchange_mtu(u8_t index);
u16_t bt_mesh_gattc_get_mtu_info(struct bt_mesh_conn *conn);
int bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn *conn, const struct bt_mesh_gatt_attr *attr,
const void *data, u16_t len);
void bt_mesh_gattc_disconnect(struct bt_mesh_conn *conn);
struct bt_mesh_conn *bt_mesh_conn_ref(struct bt_mesh_conn *conn);
void bt_mesh_conn_unref(struct bt_mesh_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_mesh_dh_key_cb_t cb, const u8_t idx);
int bt_mesh_encrypt_le(const u8_t key[16], const u8_t plaintext[16],
u8_t enc_data[16]);
int bt_mesh_encrypt_be(const u8_t key[16], const u8_t plaintext[16],
u8_t enc_data[16]);
enum {
BLE_MESH_EXCEP_LIST_ADD = 0,
BLE_MESH_EXCEP_LIST_REMOVE,
BLE_MESH_EXCEP_LIST_CLEAN,
};
enum {
BLE_MESH_EXCEP_INFO_ADV_ADDR = 0,
BLE_MESH_EXCEP_INFO_MESH_LINK_ID,
BLE_MESH_EXCEP_INFO_MESH_BEACON,
BLE_MESH_EXCEP_INFO_MESH_PROV_ADV,
BLE_MESH_EXCEP_INFO_MESH_PROXY_ADV,
};
enum {
BLE_MESH_EXCEP_CLEAN_ADDR_LIST = BIT(0),
BLE_MESH_EXCEP_CLEAN_MESH_LINK_ID_LIST = BIT(1),
BLE_MESH_EXCEP_CLEAN_MESH_BEACON_LIST = BIT(2),
BLE_MESH_EXCEP_CLEAN_MESH_PROV_ADV_LIST = BIT(3),
BLE_MESH_EXCEP_CLEAN_MESH_PROXY_ADV_LIST = BIT(4),
BLE_MESH_EXCEP_CLEAN_ALL_LIST = 0xFFFF,
};
int bt_mesh_update_exceptional_list(u8_t sub_code, u8_t type, void *info);
#endif /* _BLE_MESH_BEARER_ADRPT_H_ */

File diff suppressed because it is too large Load Diff

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 _BLE_MESH_DLIST_H_
#define _BLE_MESH_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 /* _BLE_MESH_DLIST_H_ */

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2015-2016 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BLE_MESH_HCI_H_
#define _BLE_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 */
#define BLE_MESH_LMP_FEAT_PAGES_COUNT 1
/* bt_mesh_dev flags: the flags defined here represent BT controller state */
enum {
BLE_MESH_DEV_ENABLE,
BLE_MESH_DEV_READY,
BLE_MESH_DEV_ID_STATIC_RANDOM,
BLE_MESH_DEV_HAS_PUB_KEY,
BLE_MESH_DEV_PUB_KEY_BUSY,
BLE_MESH_DEV_ADVERTISING,
BLE_MESH_DEV_KEEP_ADVERTISING,
BLE_MESH_DEV_SCANNING,
BLE_MESH_DEV_EXPLICIT_SCAN,
BLE_MESH_DEV_ACTIVE_SCAN,
BLE_MESH_DEV_SCAN_FILTER_DUP,
BLE_MESH_DEV_RPA_VALID,
BLE_MESH_DEV_ID_PENDING,
/* Total number of flags - must be at the end of the enum */
BLE_MESH_DEV_NUM_FLAGS,
};
struct bt_mesh_dev_le {
/* LE features */
u8_t features[8];
/* LE states */
u64_t states;
};
/* State tracking for the local Bluetooth controller */
struct bt_mesh_dev {
/* Flags indicate which functionality is enabled */
BLE_MESH_ATOMIC_DEFINE(flags, BLE_MESH_DEV_NUM_FLAGS);
/* 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[BLE_MESH_LMP_FEAT_PAGES_COUNT][8];
/* LE controller specific features */
struct bt_mesh_dev_le le;
};
/*Porting from zephyr/subsys/bluetooth/host/hci_core.h */
/* HCI version from Assigned Numbers */
#define BLE_MESH_HCI_VERSION_1_0B 0
#define BLE_MESH_HCI_VERSION_1_1 1
#define BLE_MESH_HCI_VERSION_1_2 2
#define BLE_MESH_HCI_VERSION_2_0 3
#define BLE_MESH_HCI_VERSION_2_1 4
#define BLE_MESH_HCI_VERSION_3_0 5
#define BLE_MESH_HCI_VERSION_4_0 6
#define BLE_MESH_HCI_VERSION_4_1 7
#define BLE_MESH_HCI_VERSION_4_2 8
#define BLE_MESH_HCI_VERSION_5_0 9
/* OpCode Group Fields */
#define BLE_MESH_OGF_LINK_CTRL 0x01
#define BLE_MESH_OGF_BASEBAND 0x03
#define BLE_MESH_OGF_INFO 0x04
#define BLE_MESH_OGF_STATUS 0x05
#define BLE_MESH_OGF_LE 0x08
#define BLE_MESH_OGF_VS 0x3f
/* Construct OpCode from OGF and OCF */
#define BLE_MESH_OP(ogf, ocf) ((ocf) | ((ogf) << 10))
/* Obtain OGF from OpCode */
#define BLE_MESH_OGF(opcode) (((opcode) >> 10) & BIT_MASK(6))
/* Obtain OCF from OpCode */
#define BLE_MESH_OCF(opcode) ((opcode) & BIT_MASK(10))
#define BLE_MESH_HCI_OP_SET_ADV_PARAM BLE_MESH_OP(BLE_MESH_OGF_LE, 0x0006)
struct bt_mesh_hci_cp_set_adv_param {
u16_t min_interval;
u16_t max_interval;
u8_t type;
u8_t own_addr_type;
bt_mesh_addr_t direct_addr;
u8_t channel_map;
u8_t filter_policy;
} __packed;
#define BLE_MESH_HCI_OP_SET_ADV_DATA BLE_MESH_OP(BLE_MESH_OGF_LE, 0x0008)
struct bt_mesh_hci_cp_set_adv_data {
u8_t len;
u8_t data[31];
} __packed;
#define BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA BLE_MESH_OP(BLE_MESH_OGF_LE, 0x0009)
struct bt_mesh_hci_cp_set_scan_rsp_data {
u8_t len;
u8_t data[31];
} __packed;
/* Added by Espressif */
extern struct bt_mesh_dev bt_mesh_dev;
void bt_mesh_hci_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _BLE_MESH_HCI_H_ */

View File

@ -0,0 +1,275 @@
/*
* Copyright (c) 2016, Wind River Systems, Inc.
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BLE_MESH_KERNEL_H_
#define _BLE_MESH_KERNEL_H_
#include "osi/mutex.h"
#include "mesh_types.h"
#include "mesh_slist.h"
#include "mesh_atomic.h"
#include "mesh_dlist.h"
/* 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))
/* timeout is not in use */
#define _INACTIVE (-1)
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;
k_work_handler_t handler;
int index;
};
#define _K_WORK_INITIALIZER(work_handler) \
{ \
._reserved = NULL, \
.handler = work_handler, \
}
/**
* @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_delayed_work {
struct k_work work;
};
/**
* @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)
{
if (work && work->handler) {
work->handler(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);
unsigned int bt_mesh_irq_lock(void);
void bt_mesh_irq_unlock(unsigned int key);
void bt_mesh_k_init(void);
#endif /* _BLE_MESH_KERNEL_H_ */

View File

@ -0,0 +1,584 @@
/** @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 _BLE_MESH_MAIN_H_
#define _BLE_MESH_MAIN_H_
#include "mesh_util.h"
#include "mesh_access.h"
/**
* @brief Bluetooth Mesh Provisioning
* @defgroup bt_mesh_prov Bluetooth Mesh Provisioning
* @ingroup bt_mesh
* @{
*/
typedef enum {
BLE_MESH_NO_OUTPUT = 0,
BLE_MESH_BLINK = BIT(0),
BLE_MESH_BEEP = BIT(1),
BLE_MESH_VIBRATE = BIT(2),
BLE_MESH_DISPLAY_NUMBER = BIT(3),
BLE_MESH_DISPLAY_STRING = BIT(4),
} bt_mesh_output_action_t;
typedef enum {
BLE_MESH_NO_INPUT = 0,
BLE_MESH_PUSH = BIT(0),
BLE_MESH_TWIST = BIT(1),
BLE_MESH_ENTER_NUMBER = BIT(2),
BLE_MESH_ENTER_STRING = BIT(3),
} bt_mesh_input_action_t;
typedef enum {
BLE_MESH_PROV_ADV = BIT(0),
BLE_MESH_PROV_GATT = BIT(1),
} bt_mesh_prov_bearer_t;
typedef enum {
BLE_MESH_PROV_OOB_OTHER = BIT(0),
BLE_MESH_PROV_OOB_URI = BIT(1),
BLE_MESH_PROV_OOB_2D_CODE = BIT(2),
BLE_MESH_PROV_OOB_BAR_CODE = BIT(3),
BLE_MESH_PROV_OOB_NFC = BIT(4),
BLE_MESH_PROV_OOB_NUMBER = BIT(5),
BLE_MESH_PROV_OOB_STRING = BIT(6),
/* 7 - 10 are reserved */
BLE_MESH_PROV_OOB_ON_BOX = BIT(11),
BLE_MESH_PROV_OOB_IN_BOX = BIT(12),
BLE_MESH_PROV_OOB_ON_PAPER = BIT(13),
BLE_MESH_PROV_OOB_IN_MANUAL = BIT(14),
BLE_MESH_PROV_OOB_ON_DEV = BIT(15),
} bt_mesh_prov_oob_info_t;
/** Provisioning properties & capabilities. */
struct bt_mesh_prov {
#if CONFIG_BLE_MESH_NODE
/** The UUID that's used when advertising as unprovisioned */
const u8_t *uuid;
/** Optional URI. This will be advertised separately from the
* unprovisioned beacon, however the unprovisioned beacon will
* contain a hash of it so the two can be associated by the
* provisioner.
*/
const char *uri;
/** Out of Band information field. */
bt_mesh_prov_oob_info_t oob_info;
/** 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_BLE_MESH_NODE */
#if CONFIG_BLE_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_BLE_MESH_PROVISIONER */
};
/* The following APIs are for BLE Mesh Node */
/** @brief Provide provisioning input OOB string.
*
* This is intended to be called after the bt_mesh_prov input callback
* has been called with BLE_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 BLE_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 BLE Mesh Fast Provisioning */
/** @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);
/* The following APIs are for BLE 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 BLE_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 BLE_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);
/**
* @}
*/
/**
* @brief Bluetooth Mesh
* @defgroup bt_mesh Bluetooth Mesh
* @ingroup bluetooth
* @{
*/
/* Primary Network Key index */
#define BLE_MESH_NET_PRIMARY 0x000
#define BLE_MESH_RELAY_DISABLED 0x00
#define BLE_MESH_RELAY_ENABLED 0x01
#define BLE_MESH_RELAY_NOT_SUPPORTED 0x02
#define BLE_MESH_BEACON_DISABLED 0x00
#define BLE_MESH_BEACON_ENABLED 0x01
#define BLE_MESH_GATT_PROXY_DISABLED 0x00
#define BLE_MESH_GATT_PROXY_ENABLED 0x01
#define BLE_MESH_GATT_PROXY_NOT_SUPPORTED 0x02
#define BLE_MESH_FRIEND_DISABLED 0x00
#define BLE_MESH_FRIEND_ENABLED 0x01
#define BLE_MESH_FRIEND_NOT_SUPPORTED 0x02
#define BLE_MESH_NODE_IDENTITY_STOPPED 0x00
#define BLE_MESH_NODE_IDENTITY_RUNNING 0x01
#define BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED 0x02
/* Features */
#define BLE_MESH_FEAT_RELAY BIT(0)
#define BLE_MESH_FEAT_PROXY BIT(1)
#define BLE_MESH_FEAT_FRIEND BIT(2)
#define BLE_MESH_FEAT_LOW_POWER BIT(3)
#define BLE_MESH_FEAT_SUPPORTED (BLE_MESH_FEAT_RELAY | \
BLE_MESH_FEAT_PROXY | \
BLE_MESH_FEAT_FRIEND | \
BLE_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 Suspend the Mesh network temporarily.
*
* This API can be used for power saving purposes, but the user should be
* aware that leaving the local node suspended for a long period of time
* may cause it to become permanently disconnected from the Mesh network.
* If at all possible, the Friendship feature should be used instead, to
* make the node into a Low Power Node.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_suspend(void);
/** @brief Resume a suspended Mesh network.
*
* This API resumes the local node, after it has been suspended using the
* bt_mesh_suspend() API.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_resume(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 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, u16_t addr,
const u8_t dev_key[16]);
/** @brief Check if the local node has been provisioned.
*
* This API can be used to check if the local node has been provisioned
* or not. It can e.g. be helpful to determine if there was a stored
* network in flash, i.e. if the network was restored after calling
* settings_load().
*
* @return True if the node is provisioned. False otherwise.
*/
bool bt_mesh_is_provisioned(void);
/** @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 /* _BLE_MESH_MAIN_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 _BLE_MESH_PROXY_H_
#define _BLE_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 /* _BLE_MESH_PROXY_H_ */

View File

@ -0,0 +1,468 @@
/*
* 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 _BLE_MESH_SLIST_H_
#define _BLE_MESH_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 /* _BLE_MESH_SLIST_H_ */

View File

@ -0,0 +1,131 @@
/*
* 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
*/
#ifndef _BLE_MESH_TRACE_H_
#define _BLE_MESH_TRACE_H_
#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_BLE_MESH_STACK_TRACE_LEVEL
#define MESH_LOG_LEVEL CONFIG_BLE_MESH_STACK_TRACE_LEVEL
#else
#define MESH_LOG_LEVEL LOG_LEVEL_WARN
#endif
#ifdef CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL
#define NET_BUF_LOG_LEVEL CONFIG_BLE_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 BLE_MESH_LOG_LOCAL_LEVEL_MAPPING (LOG_LOCAL_LEVEL + 1)
#else
#define BLE_MESH_LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif /* MAX(a, b) */
#define BLE_MESH_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_LOG_LEVEL, BLE_MESH_LOG_LOCAL_LEVEL_MAPPING) >= LOG_LEVEL_##LEVEL)
#define BLE_MESH_PRINT_E(tag, format, ...) {esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define BLE_MESH_PRINT_W(tag, format, ...) {esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define BLE_MESH_PRINT_I(tag, format, ...) {esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define BLE_MESH_PRINT_D(tag, format, ...) {esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define BLE_MESH_PRINT_V(tag, format, ...) {esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); }
#define printk ets_printf
#define _STRINGIFY(x) #x
#define STRINGIFY(s) _STRINGIFY(s)
#ifndef __ASSERT
#define __ASSERT(test, fmt, ...) \
do { \
if (!(test)) { \
printk("ASSERTION FAIL [%s] @ %s:%d:\n\t", \
_STRINGIFY(test), \
__FILE__, \
__LINE__); \
printk(fmt, ##__VA_ARGS__); \
for (;;); \
} \
} while ((0))
#endif
#ifndef __ASSERT_NO_MSG
#define __ASSERT_NO_MSG(x) do { if (!(x)) BLE_MESH_PRINT_E(MESH_TRACE_TAG, "error %s %u", __FILE__, __LINE__); } while (0)
#endif
#if !CONFIG_BLE_MESH_NO_LOG
#define BT_ERR(fmt, args...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_ERROR) && BLE_MESH_LOG_LEVEL_CHECK(MESH, ERROR)) BLE_MESH_PRINT_E(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define BT_WARN(fmt, args...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_WARN) && BLE_MESH_LOG_LEVEL_CHECK(MESH, WARN)) BLE_MESH_PRINT_W(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define BT_INFO(fmt, args...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_INFO) && BLE_MESH_LOG_LEVEL_CHECK(MESH, INFO)) BLE_MESH_PRINT_I(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define BT_DBG(fmt, args...) do {if ((MESH_LOG_LEVEL >= LOG_LEVEL_DEBUG) && BLE_MESH_LOG_LEVEL_CHECK(MESH, DEBUG)) BLE_MESH_PRINT_D(MESH_TRACE_TAG, fmt, ## args);} while(0)
#else
#define BT_ERR(fmt, args...)
#define BT_WARN(fmt, args...)
#define BT_INFO(fmt, args...)
#define BT_DBG(fmt, args...)
#endif
#if defined(CONFIG_BLE_MESH_NET_BUF_LOG) && (!CONFIG_BLE_MESH_NO_LOG)
#define NET_BUF_ERR(fmt, args...) do {if ((NET_BUF_LOG_LEVEL >= LOG_LEVEL_ERROR) && BLE_MESH_LOG_LEVEL_CHECK(NET_BUF, ERROR)) BLE_MESH_PRINT_E(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_WARN(fmt, args...) do {if ((NET_BUF_LOG_LEVEL >= LOG_LEVEL_WARN) && BLE_MESH_LOG_LEVEL_CHECK(NET_BUF, WARN)) BLE_MESH_PRINT_W(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_INFO(fmt, args...) do {if ((NET_BUF_LOG_LEVEL >= LOG_LEVEL_INFO) && BLE_MESH_LOG_LEVEL_CHECK(NET_BUF, INFO)) BLE_MESH_PRINT_I(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_DBG(fmt, args...) do {if ((NET_BUF_LOG_LEVEL >= LOG_LEVEL_DEBUG) && BLE_MESH_LOG_LEVEL_CHECK(NET_BUF, DEBUG)) BLE_MESH_PRINT_D(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_ASSERT(cond) __ASSERT_NO_MSG(cond)
#else
#define NET_BUF_ERR(fmt, args...)
#define NET_BUF_WARN(fmt, args...)
#define NET_BUF_INFO(fmt, args...)
#define NET_BUF_DBG(fmt, args...)
#define NET_BUF_ASSERT(cond)
#endif
#if defined(CONFIG_BLE_MESH_NET_BUF_SIMPLE_LOG) && (!CONFIG_BLE_MESH_NO_LOG)
#define NET_BUF_SIMPLE_ERR(fmt, args...) do {if ((NET_BUF_LOG_LEVEL >= LOG_LEVEL_ERROR) && BLE_MESH_LOG_LEVEL_CHECK(NET_BUF, ERROR)) BLE_MESH_PRINT_E(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_SIMPLE_WARN(fmt, args...) do {if ((NET_BUF_LOG_LEVEL >= LOG_LEVEL_WARN) && BLE_MESH_LOG_LEVEL_CHECK(NET_BUF, WARN)) BLE_MESH_PRINT_W(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_SIMPLE_INFO(fmt, args...) do {if ((NET_BUF_LOG_LEVEL >= LOG_LEVEL_INFO) && BLE_MESH_LOG_LEVEL_CHECK(NET_BUF, INFO)) BLE_MESH_PRINT_I(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_SIMPLE_DBG(fmt, args...) do {if ((NET_BUF_LOG_LEVEL >= LOG_LEVEL_DEBUG) && BLE_MESH_LOG_LEVEL_CHECK(NET_BUF, DEBUG)) BLE_MESH_PRINT_D(MESH_TRACE_TAG, fmt, ## args);} while(0)
#define NET_BUF_SIMPLE_ASSERT(cond) __ASSERT_NO_MSG(cond)
#else
#define NET_BUF_SIMPLE_ERR(fmt, args...)
#define NET_BUF_SIMPLE_WARN(fmt, args...)
#define NET_BUF_SIMPLE_INFO(fmt, args...)
#define NET_BUF_SIMPLE_DBG(fmt, args...)
#define NET_BUF_SIMPLE_ASSERT(cond)
#endif
#endif /* _BLE_MESH_TRACE_H_ */

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2017 Linaro Limited
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BLE_MESH_TYPES_H_
#define _BLE_MESH_TYPES_H_
#include <stdint.h>
#include <stdbool.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 bt_mesh_atomic_t;
#ifndef bool
#define bool int8_t
#endif
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
#ifdef __cplusplus
}
#endif
#endif /* _BLE_MESH_TYPES_H_ */

View File

@ -0,0 +1,440 @@
/*
* 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 _BLE_MESH_UTIL_H_
#define _BLE_MESH_UTIL_H_
#include <stddef.h>
#include "mesh_types.h"
#include "mesh_trace.h"
#include "soc/soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/* 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 */
#ifndef __bswap_16
#define __bswap_16(x) ((u16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
#endif
#ifndef __bswap_32
#define __bswap_32(x) ((u32_t) ((((x) >> 24) & 0xff) | \
(((x) >> 8) & 0xff00) | \
(((x) & 0xff00) << 8) | \
(((x) & 0xff) << 24)))
#endif
#ifndef __bswap_64
#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)))
#endif
#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)
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef BIT
#define BIT(n) (1UL << (n))
#endif
#ifndef BIT_MASK
#define BIT_MASK(n) (BIT(n) - 1)
#endif
/**
* @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
/* 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__)
#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
/**
* @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 /* _BLE_MESH_UTIL_H_ */

View File

@ -0,0 +1,530 @@
/** @file
* @brief Bluetooth UUID handling
*/
/*
* Copyright (c) 2015-2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _BLE_MESH_UUID_H_
#define _BLE_MESH_UUID_H_
/**
* @brief UUIDs
* @defgroup bt_uuid UUIDs
* @ingroup bluetooth
* @{
*/
#include "mesh_util.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Bluetooth UUID types */
enum {
BLE_MESH_UUID_TYPE_16,
BLE_MESH_UUID_TYPE_32,
BLE_MESH_UUID_TYPE_128,
};
/** @brief This is a 'tentative' type and should be used as a pointer only */
struct bt_mesh_uuid {
u8_t type;
};
struct bt_mesh_uuid_16 {
struct bt_mesh_uuid uuid;
u16_t val;
};
struct bt_mesh_uuid_32 {
struct bt_mesh_uuid uuid;
u32_t val;
};
struct bt_mesh_uuid_128 {
struct bt_mesh_uuid uuid;
u8_t val[16];
};
#define BLE_MESH_UUID_INIT_16(value) \
{ \
.uuid.type = BLE_MESH_UUID_TYPE_16, \
.val = (value), \
}
#define BLE_MESH_UUID_INIT_32(value) \
{ \
.uuid.type = BLE_MESH_UUID_TYPE_32, \
.val = (value), \
}
#define BLE_MESH_UUID_INIT_128(value...) \
{ \
.uuid.type = BLE_MESH_UUID_TYPE_128, \
.val = { value }, \
}
#define BLE_MESH_UUID_DECLARE_16(value) \
((struct bt_mesh_uuid *) (&(struct bt_mesh_uuid_16) BLE_MESH_UUID_INIT_16(value)))
#define BLE_MESH_UUID_DECLARE_32(value) \
((struct bt_mesh_uuid *) (&(struct bt_mesh_uuid_32) BLE_MESH_UUID_INIT_32(value)))
#define BLE_MESH_UUID_DECLARE_128(value...) \
((struct bt_mesh_uuid *) (&(struct bt_mesh_uuid_128) BLE_MESH_UUID_INIT_128(value)))
#define BLE_MESH_UUID_16(__u) CONTAINER_OF(__u, struct bt_mesh_uuid_16, uuid)
#define BLE_MESH_UUID_32(__u) CONTAINER_OF(__u, struct bt_mesh_uuid_32, uuid)
#define BLE_MESH_UUID_128(__u) CONTAINER_OF(__u, struct bt_mesh_uuid_128, uuid)
/** @def BLE_MESH_UUID_GAP
* @brief Generic Access
*/
#define BLE_MESH_UUID_GAP BLE_MESH_UUID_DECLARE_16(0x1800)
#define BLE_MESH_UUID_GAP_VAL 0x1800
/** @def BLE_MESH_UUID_GATT
* @brief Generic Attribute
*/
#define BLE_MESH_UUID_GATT BLE_MESH_UUID_DECLARE_16(0x1801)
#define BLE_MESH_UUID_GATT_VAL 0x1801
/** @def BLE_MESH_UUID_CTS
* @brief Current Time Service
*/
#define BLE_MESH_UUID_CTS BLE_MESH_UUID_DECLARE_16(0x1805)
#define BLE_MESH_UUID_CTS_VAL 0x1805
/** @def BLE_MESH_UUID_DIS
* @brief Device Information Service
*/
#define BLE_MESH_UUID_DIS BLE_MESH_UUID_DECLARE_16(0x180a)
#define BLE_MESH_UUID_DIS_VAL 0x180a
/** @def BLE_MESH_UUID_HRS
* @brief Heart Rate Service
*/
#define BLE_MESH_UUID_HRS BLE_MESH_UUID_DECLARE_16(0x180d)
#define BLE_MESH_UUID_HRS_VAL 0x180d
/** @def BLE_MESH_UUID_BAS
* @brief Battery Service
*/
#define BLE_MESH_UUID_BAS BLE_MESH_UUID_DECLARE_16(0x180f)
#define BLE_MESH_UUID_BAS_VAL 0x180f
/** @def BLE_MESH_UUID_HIDS
* @brief HID Service
*/
#define BLE_MESH_UUID_HIDS BLE_MESH_UUID_DECLARE_16(0x1812)
#define BLE_MESH_UUID_HIDS_VAL 0x1812
/** @def BLE_MESH_UUID_CSC
* @brief Cycling Speed and Cadence Service
*/
#define BLE_MESH_UUID_CSC BLE_MESH_UUID_DECLARE_16(0x1816)
#define BLE_MESH_UUID_CSC_VAL 0x1816
/** @def BLE_MESH_UUID_ESS
* @brief Environmental Sensing Service
*/
#define BLE_MESH_UUID_ESS BLE_MESH_UUID_DECLARE_16(0x181a)
#define BLE_MESH_UUID_ESS_VAL 0x181a
/** @def BLE_MESH_UUID_IPSS
* @brief IP Support Service
*/
#define BLE_MESH_UUID_IPSS BLE_MESH_UUID_DECLARE_16(0x1820)
#define BLE_MESH_UUID_IPSS_VAL 0x1820
/** @def BLE_MESH_UUID_MESH_PROV
* @brief Mesh Provisioning Service
*/
#define BLE_MESH_UUID_MESH_PROV BLE_MESH_UUID_DECLARE_16(0x1827)
#define BLE_MESH_UUID_MESH_PROV_VAL 0x1827
/** @def BLE_MESH_UUID_MESH_PROXY
* @brief Mesh Proxy Service
*/
#define BLE_MESH_UUID_MESH_PROXY BLE_MESH_UUID_DECLARE_16(0x1828)
#define BLE_MESH_UUID_MESH_PROXY_VAL 0x1828
/** @def BLE_MESH_UUID_GATT_PRIMARY
* @brief GATT Primary Service
*/
#define BLE_MESH_UUID_GATT_PRIMARY BLE_MESH_UUID_DECLARE_16(0x2800)
#define BLE_MESH_UUID_GATT_PRIMARY_VAL 0x2800
/** @def BLE_MESH_UUID_GATT_SECONDARY
* @brief GATT Secondary Service
*/
#define BLE_MESH_UUID_GATT_SECONDARY BLE_MESH_UUID_DECLARE_16(0x2801)
#define BLE_MESH_UUID_GATT_SECONDARY_VAL 0x2801
/** @def BLE_MESH_UUID_GATT_INCLUDE
* @brief GATT Include Service
*/
#define BLE_MESH_UUID_GATT_INCLUDE BLE_MESH_UUID_DECLARE_16(0x2802)
#define BLE_MESH_UUID_GATT_INCLUDE_VAL 0x2802
/** @def BLE_MESH_UUID_GATT_CHRC
* @brief GATT Characteristic
*/
#define BLE_MESH_UUID_GATT_CHRC BLE_MESH_UUID_DECLARE_16(0x2803)
#define BLE_MESH_UUID_GATT_CHRC_VAL 0x2803
/** @def BLE_MESH_UUID_GATT_CEP
* @brief GATT Characteristic Extended Properties
*/
#define BLE_MESH_UUID_GATT_CEP BLE_MESH_UUID_DECLARE_16(0x2900)
#define BLE_MESH_UUID_GATT_CEP_VAL 0x2900
/** @def BLE_MESH_UUID_GATT_CUD
* @brief GATT Characteristic User Description
*/
#define BLE_MESH_UUID_GATT_CUD BLE_MESH_UUID_DECLARE_16(0x2901)
#define BLE_MESH_UUID_GATT_CUD_VAL 0x2901
/** @def BLE_MESH_UUID_GATT_CCC
* @brief GATT Client Characteristic Configuration
*/
#define BLE_MESH_UUID_GATT_CCC BLE_MESH_UUID_DECLARE_16(0x2902)
#define BLE_MESH_UUID_GATT_CCC_VAL 0x2902
/** @def BLE_MESH_UUID_GATT_SCC
* @brief GATT Server Characteristic Configuration
*/
#define BLE_MESH_UUID_GATT_SCC BLE_MESH_UUID_DECLARE_16(0x2903)
#define BLE_MESH_UUID_GATT_SCC_VAL 0x2903
/** @def BLE_MESH_UUID_GATT_CPF
* @brief GATT Characteristic Presentation Format
*/
#define BLE_MESH_UUID_GATT_CPF BLE_MESH_UUID_DECLARE_16(0x2904)
#define BLE_MESH_UUID_GATT_CPF_VAL 0x2904
/** @def BLE_MESH_UUID_VALID_RANGE
* @brief Valid Range Descriptor
*/
#define BLE_MESH_UUID_VALID_RANGE BLE_MESH_UUID_DECLARE_16(0x2906)
#define BLE_MESH_UUID_VALID_RANGE_VAL 0x2906
/** @def BLE_MESH_UUID_HIDS_EXT_REPORT
* @brief HID External Report Descriptor
*/
#define BLE_MESH_UUID_HIDS_EXT_REPORT BLE_MESH_UUID_DECLARE_16(0x2907)
#define BLE_MESH_UUID_HIDS_EXT_REPORT_VAL 0x2907
/** @def BLE_MESH_UUID_HIDS_REPORT_REF
* @brief HID Report Reference Descriptor
*/
#define BLE_MESH_UUID_HIDS_REPORT_REF BLE_MESH_UUID_DECLARE_16(0x2908)
#define BLE_MESH_UUID_HIDS_REPORT_REF_VAL 0x2908
/** @def BLE_MESH_UUID_ES_CONFIGURATION
* @brief Environmental Sensing Configuration Descriptor
*/
#define BLE_MESH_UUID_ES_CONFIGURATION BLE_MESH_UUID_DECLARE_16(0x290b)
#define BLE_MESH_UUID_ES_CONFIGURATION_VAL 0x290b
/** @def BLE_MESH_UUID_ES_MEASUREMENT
* @brief Environmental Sensing Measurement Descriptor
*/
#define BLE_MESH_UUID_ES_MEASUREMENT BLE_MESH_UUID_DECLARE_16(0x290c)
#define BLE_MESH_UUID_ES_MEASUREMENT_VAL 0x290c
/** @def BLE_MESH_UUID_ES_TRIGGER_SETTING
* @brief Environmental Sensing Trigger Setting Descriptor
*/
#define BLE_MESH_UUID_ES_TRIGGER_SETTING BLE_MESH_UUID_DECLARE_16(0x290d)
#define BLE_MESH_UUID_ES_TRIGGER_SETTING_VAL 0x290d
/** @def BLE_MESH_UUID_GAP_DEVICE_NAME
* @brief GAP Characteristic Device Name
*/
#define BLE_MESH_UUID_GAP_DEVICE_NAME BLE_MESH_UUID_DECLARE_16(0x2a00)
#define BLE_MESH_UUID_GAP_DEVICE_NAME_VAL 0x2a00
/** @def BLE_MESH_UUID_GAP_APPEARANCE
* @brief GAP Characteristic Appearance
*/
#define BLE_MESH_UUID_GAP_APPEARANCE BLE_MESH_UUID_DECLARE_16(0x2a01)
#define BLE_MESH_UUID_GAP_APPEARANCE_VAL 0x2a01
/** @def BLE_MESH_UUID_GAP_PPCP
* @brief GAP Characteristic Peripheral Preferred Connection Parameters
*/
#define BLE_MESH_UUID_GAP_PPCP BLE_MESH_UUID_DECLARE_16(0x2a04)
#define BLE_MESH_UUID_GAP_PPCP_VAL 0x2a04
/** @def BLE_MESH_UUID_GATT_SC
* @brief GATT Characteristic Service Changed
*/
#define BLE_MESH_UUID_GATT_SC BLE_MESH_UUID_DECLARE_16(0x2a05)
#define BLE_MESH_UUID_GATT_SC_VAL 0x2a05
/** @def BLE_MESH_UUID_BAS_BATTERY_LEVEL
* @brief BAS Characteristic Battery Level
*/
#define BLE_MESH_UUID_BAS_BATTERY_LEVEL BLE_MESH_UUID_DECLARE_16(0x2a19)
#define BLE_MESH_UUID_BAS_BATTERY_LEVEL_VAL 0x2a19
/** @def BLE_MESH_UUID_DIS_SYSTEM_ID
* @brief DIS Characteristic System ID
*/
#define BLE_MESH_UUID_DIS_SYSTEM_ID BLE_MESH_UUID_DECLARE_16(0x2a23)
#define BLE_MESH_UUID_DIS_SYSTEM_ID_VAL 0x2a23
/** @def BLE_MESH_UUID_DIS_MODEL_NUMBER
* @brief DIS Characteristic Model Number String
*/
#define BLE_MESH_UUID_DIS_MODEL_NUMBER BLE_MESH_UUID_DECLARE_16(0x2a24)
#define BLE_MESH_UUID_DIS_MODEL_NUMBER_VAL 0x2a24
/** @def BLE_MESH_UUID_DIS_SERIAL_NUMBER
* @brief DIS Characteristic Serial Number String
*/
#define BLE_MESH_UUID_DIS_SERIAL_NUMBER BLE_MESH_UUID_DECLARE_16(0x2a25)
#define BLE_MESH_UUID_DIS_SERIAL_NUMBER_VAL 0x2a25
/** @def BLE_MESH_UUID_DIS_FIRMWARE_REVISION
* @brief DIS Characteristic Firmware Revision String
*/
#define BLE_MESH_UUID_DIS_FIRMWARE_REVISION BLE_MESH_UUID_DECLARE_16(0x2a26)
#define BLE_MESH_UUID_DIS_FIRMWARE_REVISION_VAL 0x2a26
/** @def BLE_MESH_UUID_DIS_HARDWARE_REVISION
* @brief DIS Characteristic Hardware Revision String
*/
#define BLE_MESH_UUID_DIS_HARDWARE_REVISION BLE_MESH_UUID_DECLARE_16(0x2a27)
#define BLE_MESH_UUID_DIS_HARDWARE_REVISION_VAL 0x2a27
/** @def BLE_MESH_UUID_DIS_SOFTWARE_REVISION
* @brief DIS Characteristic Software Revision String
*/
#define BLE_MESH_UUID_DIS_SOFTWARE_REVISION BLE_MESH_UUID_DECLARE_16(0x2a28)
#define BLE_MESH_UUID_DIS_SOFTWARE_REVISION_VAL 0x2a28
/** @def BLE_MESH_UUID_DIS_MANUFACTURER_NAME
* @brief DIS Characteristic Manufacturer Name String
*/
#define BLE_MESH_UUID_DIS_MANUFACTURER_NAME BLE_MESH_UUID_DECLARE_16(0x2a29)
#define BLE_MESH_UUID_DIS_MANUFACTURER_NAME_VAL 0x2a29
/** @def BLE_MESH_UUID_DIS_PNP_ID
* @brief DIS Characteristic PnP ID
*/
#define BLE_MESH_UUID_DIS_PNP_ID BLE_MESH_UUID_DECLARE_16(0x2a50)
#define BLE_MESH_UUID_DIS_PNP_ID_VAL 0x2a50
/** @def BLE_MESH_UUID_CTS_CURRENT_TIME
* @brief CTS Characteristic Current Time
*/
#define BLE_MESH_UUID_CTS_CURRENT_TIME BLE_MESH_UUID_DECLARE_16(0x2a2b)
#define BLE_MESH_UUID_CTS_CURRENT_TIME_VAL 0x2a2b
/** @def BLE_MESH_UUID_MAGN_DECLINATION
* @brief Magnetic Declination Characteristic
*/
#define BLE_MESH_UUID_MAGN_DECLINATION BLE_MESH_UUID_DECLARE_16(0x2a2c)
#define BLE_MESH_UUID_MAGN_DECLINATION_VAL 0x2a2c
/** @def BLE_MESH_UUID_HRS_MEASUREMENT
* @brief HRS Characteristic Measurement Interval
*/
#define BLE_MESH_UUID_HRS_MEASUREMENT BLE_MESH_UUID_DECLARE_16(0x2a37)
#define BLE_MESH_UUID_HRS_MEASUREMENT_VAL 0x2a37
/** @def BLE_MESH_UUID_HRS_BODY_SENSOR
* @brief HRS Characteristic Body Sensor Location
*/
#define BLE_MESH_UUID_HRS_BODY_SENSOR BLE_MESH_UUID_DECLARE_16(0x2a38)
#define BLE_MESH_UUID_HRS_BODY_SENSOR_VAL 0x2a38
/** @def BLE_MESH_UUID_HRS_CONTROL_POINT
* @brief HRS Characteristic Control Point
*/
#define BLE_MESH_UUID_HRS_CONTROL_POINT BLE_MESH_UUID_DECLARE_16(0x2a39)
#define BLE_MESH_UUID_HRS_CONTROL_POINT_VAL 0x2a39
/** @def BLE_MESH_UUID_HIDS_INFO
* @brief HID Information Characteristic
*/
#define BLE_MESH_UUID_HIDS_INFO BLE_MESH_UUID_DECLARE_16(0x2a4a)
#define BLE_MESH_UUID_HIDS_INFO_VAL 0x2a4a
/** @def BLE_MESH_UUID_HIDS_REPORT_MAP
* @brief HID Report Map Characteristic
*/
#define BLE_MESH_UUID_HIDS_REPORT_MAP BLE_MESH_UUID_DECLARE_16(0x2a4b)
#define BLE_MESH_UUID_HIDS_REPORT_MAP_VAL 0x2a4b
/** @def BLE_MESH_UUID_HIDS_CTRL_POINT
* @brief HID Control Point Characteristic
*/
#define BLE_MESH_UUID_HIDS_CTRL_POINT BLE_MESH_UUID_DECLARE_16(0x2a4c)
#define BLE_MESH_UUID_HIDS_CTRL_POINT_VAL 0x2a4c
/** @def BLE_MESH_UUID_HIDS_REPORT
* @brief HID Report Characteristic
*/
#define BLE_MESH_UUID_HIDS_REPORT BLE_MESH_UUID_DECLARE_16(0x2a4d)
#define BLE_MESH_UUID_HIDS_REPORT_VAL 0x2a4d
/** @def BLE_MESH_UUID_CSC_MEASUREMENT
* @brief CSC Measurement Characteristic
*/
#define BLE_MESH_UUID_CSC_MEASUREMENT BLE_MESH_UUID_DECLARE_16(0x2a5b)
#define BLE_MESH_UUID_CSC_MEASUREMENT_VAL 0x2a5b
/** @def BLE_MESH_UUID_CSC_FEATURE
* @brief CSC Feature Characteristic
*/
#define BLE_MESH_UUID_CSC_FEATURE BLE_MESH_UUID_DECLARE_16(0x2a5c)
#define BLE_MESH_UUID_CSC_FEATURE_VAL 0x2a5c
/** @def BLE_MESH_UUID_SENSOR_LOCATION
* @brief Sensor Location Characteristic
*/
#define BLE_MESH_UUID_SENSOR_LOCATION BLE_MESH_UUID_DECLARE_16(0x2a5d)
#define BLE_MESH_UUID_SENSOR_LOCATION_VAL 0x2a5d
/** @def BLE_MESH_UUID_SC_CONTROL_POINT
* @brief SC Control Point Characteristic
*/
#define BLE_MESH_UUID_SC_CONTROL_POINT BLE_MESH_UUID_DECLARE_16(0x2a55)
#define BLE_MESH_UUID_SC_CONTROL_POINT_VAl 0x2a55
/** @def BLE_MESH_UUID_ELEVATION
* @brief Elevation Characteristic
*/
#define BLE_MESH_UUID_ELEVATION BLE_MESH_UUID_DECLARE_16(0x2a6c)
#define BLE_MESH_UUID_ELEVATION_VAL 0x2a6c
/** @def BLE_MESH_UUID_PRESSURE
* @brief Pressure Characteristic
*/
#define BLE_MESH_UUID_PRESSURE BLE_MESH_UUID_DECLARE_16(0x2a6d)
#define BLE_MESH_UUID_PRESSURE_VAL 0x2a6d
/** @def BLE_MESH_UUID_TEMPERATURE
* @brief Temperature Characteristic
*/
#define BLE_MESH_UUID_TEMPERATURE BLE_MESH_UUID_DECLARE_16(0x2a6e)
#define BLE_MESH_UUID_TEMPERATURE_VAL 0x2a6e
/** @def BLE_MESH_UUID_HUMIDITY
* @brief Humidity Characteristic
*/
#define BLE_MESH_UUID_HUMIDITY BLE_MESH_UUID_DECLARE_16(0x2a6f)
#define BLE_MESH_UUID_HUMIDITY_VAL 0x2a6f
/** @def BLE_MESH_UUID_TRUE_WIND_SPEED
* @brief True Wind Speed Characteristic
*/
#define BLE_MESH_UUID_TRUE_WIND_SPEED BLE_MESH_UUID_DECLARE_16(0x2a70)
#define BLE_MESH_UUID_TRUE_WIND_SPEED_VAL 0x2a70
/** @def BLE_MESH_UUID_TRUE_WIND_DIR
* @brief True Wind Direction Characteristic
*/
#define BLE_MESH_UUID_TRUE_WIND_DIR BLE_MESH_UUID_DECLARE_16(0x2a71)
#define BLE_MESH_UUID_TRUE_WIND_DIR_VAL 0x2a71
/** @def BLE_MESH_UUID_APPARENT_WIND_SPEED
* @brief Apparent Wind Speed Characteristic
*/
#define BLE_MESH_UUID_APPARENT_WIND_SPEED BLE_MESH_UUID_DECLARE_16(0x2a72)
#define BLE_MESH_UUID_APPARENT_WIND_SPEED_VAL 0x2a72
/** @def BLE_MESH_UUID_APPARENT_WIND_DIR
* @brief Apparent Wind Direction Characteristic
*/
#define BLE_MESH_UUID_APPARENT_WIND_DIR BLE_MESH_UUID_DECLARE_16(0x2a73)
#define BLE_MESH_UUID_APPARENT_WIND_DIR_VAL 0x2a73
/** @def BLE_MESH_UUID_GUST_FACTOR
* @brief Gust Factor Characteristic
*/
#define BLE_MESH_UUID_GUST_FACTOR BLE_MESH_UUID_DECLARE_16(0x2a74)
#define BLE_MESH_UUID_GUST_FACTOR_VAL 0x2a74
/** @def BLE_MESH_UUID_POLLEN_CONCENTRATION
* @brief Pollen Concentration Characteristic
*/
#define BLE_MESH_UUID_POLLEN_CONCENTRATION BLE_MESH_UUID_DECLARE_16(0x2a75)
#define BLE_MESH_UUID_POLLEN_CONCENTRATION_VAL 0x2a75
/** @def BLE_MESH_UUID_UV_INDEX
* @brief UV Index Characteristic
*/
#define BLE_MESH_UUID_UV_INDEX BLE_MESH_UUID_DECLARE_16(0x2a76)
#define BLE_MESH_UUID_UV_INDEX_VAL 0x2a76
/** @def BLE_MESH_UUID_IRRADIANCE
* @brief Irradiance Characteristic
*/
#define BLE_MESH_UUID_IRRADIANCE BLE_MESH_UUID_DECLARE_16(0x2a77)
#define BLE_MESH_UUID_IRRADIANCE_VAL 0x2a77
/** @def BLE_MESH_UUID_RAINFALL
* @brief Rainfall Characteristic
*/
#define BLE_MESH_UUID_RAINFALL BLE_MESH_UUID_DECLARE_16(0x2a78)
#define BLE_MESH_UUID_RAINFALL_VAL 0x2a78
/** @def BLE_MESH_UUID_WIND_CHILL
* @brief Wind Chill Characteristic
*/
#define BLE_MESH_UUID_WIND_CHILL BLE_MESH_UUID_DECLARE_16(0x2a79)
#define BLE_MESH_UUID_WIND_CHILL_VAL 0x2a79
/** @def BLE_MESH_UUID_HEAT_INDEX
* @brief Heat Index Characteristic
*/
#define BLE_MESH_UUID_HEAT_INDEX BLE_MESH_UUID_DECLARE_16(0x2a7a)
#define BLE_MESH_UUID_HEAT_INDEX_VAL 0x2a7a
/** @def BLE_MESH_UUID_DEW_POINT
* @brief Dew Point Characteristic
*/
#define BLE_MESH_UUID_DEW_POINT BLE_MESH_UUID_DECLARE_16(0x2a7b)
#define BLE_MESH_UUID_DEW_POINT_VAL 0x2a7b
/** @def BLE_MESH_UUID_DESC_VALUE_CHANGED
* @brief Descriptor Value Changed Characteristic
*/
#define BLE_MESH_UUID_DESC_VALUE_CHANGED BLE_MESH_UUID_DECLARE_16(0x2a7d)
#define BLE_MESH_UUID_DESC_VALUE_CHANGED_VAL 0x2a7d
/** @def BLE_MESH_UUID_MAGN_FLUX_DENSITY_2D
* @brief Magnetic Flux Density - 2D Characteristic
*/
#define BLE_MESH_UUID_MAGN_FLUX_DENSITY_2D BLE_MESH_UUID_DECLARE_16(0x2aa0)
#define BLE_MESH_UUID_MAGN_FLUX_DENSITY_2D_VAL 0x2aa0
/** @def BLE_MESH_UUID_MAGN_FLUX_DENSITY_3D
* @brief Magnetic Flux Density - 3D Characteristic
*/
#define BLE_MESH_UUID_MAGN_FLUX_DENSITY_3D BLE_MESH_UUID_DECLARE_16(0x2aa1)
#define BLE_MESH_UUID_MAGN_FLUX_DENSITY_3D_VAL 0x2aa1
/** @def BLE_MESH_UUID_BAR_PRESSURE_TREND
* @brief Barometric Pressure Trend Characteristic
*/
#define BLE_MESH_UUID_BAR_PRESSURE_TREND BLE_MESH_UUID_DECLARE_16(0x2aa3)
#define BLE_MESH_UUID_BAR_PRESSURE_TREND_VAL 0x2aa3
/** @def BLE_MESH_UUID_MESH_PROV_DATA_IN
* @brief Mesh Provisioning Data In
*/
#define BLE_MESH_UUID_MESH_PROV_DATA_IN BLE_MESH_UUID_DECLARE_16(0x2adb)
#define BLE_MESH_UUID_MESH_PROV_DATA_IN_VAL 0x2adb
/** @def BLE_MESH_UUID_MESH_PROV_DATA_OUT
* @brief Mesh Provisioning Data Out
*/
#define BLE_MESH_UUID_MESH_PROV_DATA_OUT BLE_MESH_UUID_DECLARE_16(0x2adc)
#define BLE_MESH_UUID_MESH_PROV_DATA_OUT_VAL 0x2adc
/** @def BLE_MESH_UUID_MESH_PROXY_DATA_IN
* @brief Mesh Proxy Data In
*/
#define BLE_MESH_UUID_MESH_PROXY_DATA_IN BLE_MESH_UUID_DECLARE_16(0x2add)
#define BLE_MESH_UUID_MESH_PROXY_DATA_IN_VAL 0x2add
/** @def BLE_MESH_UUID_MESH_PROXY_DATA_OUT
* @brief Mesh Proxy Data Out
*/
#define BLE_MESH_UUID_MESH_PROXY_DATA_OUT BLE_MESH_UUID_DECLARE_16(0x2ade)
#define BLE_MESH_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade
/*
* Protocol UUIDs
*/
#define BLE_MESH_UUID_SDP BLE_MESH_UUID_DECLARE_16(0x0001)
#define BLE_MESH_UUID_SDP_VAL 0x0001
#define BLE_MESH_UUID_UDP BLE_MESH_UUID_DECLARE_16(0x0002)
#define BLE_MESH_UUID_UDP_VAL 0x0002
#define BLE_MESH_UUID_RFCOMM BLE_MESH_UUID_DECLARE_16(0x0003)
#define BLE_MESH_UUID_RFCOMM_VAL 0x0003
#define BLE_MESH_UUID_TCP BLE_MESH_UUID_DECLARE_16(0x0004)
#define BLE_MESH_UUID_TCP_VAL 0x0004
#define BLE_MESH_UUID_TCS_BIN BLE_MESH_UUID_DECLARE_16(0x0005)
#define BLE_MESH_UUID_TCS_BIN_VAL 0x0005
#define BLE_MESH_UUID_TCS_AT BLE_MESH_UUID_DECLARE_16(0x0006)
#define BLE_MESH_UUID_TCS_AT_VAL 0x0006
#define BLE_MESH_UUID_ATT BLE_MESH_UUID_DECLARE_16(0x0007)
#define BLE_MESH_UUID_ATT_VAL 0x0007
#define BLE_MESH_UUID_OBEX BLE_MESH_UUID_DECLARE_16(0x0008)
#define BLE_MESH_UUID_OBEX_VAL 0x0008
#define BLE_MESH_UUID_IP BLE_MESH_UUID_DECLARE_16(0x0009)
#define BLE_MESH_UUID_IP_VAL 0x0009
#define BLE_MESH_UUID_FTP BLE_MESH_UUID_DECLARE_16(0x000a)
#define BLE_MESH_UUID_FTP_VAL 0x000a
#define BLE_MESH_UUID_HTTP BLE_MESH_UUID_DECLARE_16(0x000c)
#define BLE_MESH_UUID_HTTP_VAL 0x000c
#define BLE_MESH_UUID_BNEP BLE_MESH_UUID_DECLARE_16(0x000f)
#define BLE_MESH_UUID_BNEP_VAL 0x000f
#define BLE_MESH_UUID_UPNP BLE_MESH_UUID_DECLARE_16(0x0010)
#define BLE_MESH_UUID_UPNP_VAL 0x0010
#define BLE_MESH_UUID_HIDP BLE_MESH_UUID_DECLARE_16(0x0011)
#define BLE_MESH_UUID_HIDP_VAL 0x0011
#define BLE_MESH_UUID_HCRP_CTRL BLE_MESH_UUID_DECLARE_16(0x0012)
#define BLE_MESH_UUID_HCRP_CTRL_VAL 0x0012
#define BLE_MESH_UUID_HCRP_DATA BLE_MESH_UUID_DECLARE_16(0x0014)
#define BLE_MESH_UUID_HCRP_DATA_VAL 0x0014
#define BLE_MESH_UUID_HCRP_NOTE BLE_MESH_UUID_DECLARE_16(0x0016)
#define BLE_MESH_UUID_HCRP_NOTE_VAL 0x0016
#define BLE_MESH_UUID_AVCTP BLE_MESH_UUID_DECLARE_16(0x0017)
#define BLE_MESH_UUID_AVCTP_VAL 0x0017
#define BLE_MESH_UUID_AVDTP BLE_MESH_UUID_DECLARE_16(0x0019)
#define BLE_MESH_UUID_AVDTP_VAL 0x0019
#define BLE_MESH_UUID_CMTP BLE_MESH_UUID_DECLARE_16(0x001b)
#define BLE_MESH_UUID_CMTP_VAL 0x001b
#define BLE_MESH_UUID_UDI BLE_MESH_UUID_DECLARE_16(0x001d)
#define BLE_MESH_UUID_UDI_VAL 0x001d
#define BLE_MESH_UUID_MCAP_CTRL BLE_MESH_UUID_DECLARE_16(0x001e)
#define BLE_MESH_UUID_MCAP_CTRL_VAL 0x001e
#define BLE_MESH_UUID_MCAP_DATA BLE_MESH_UUID_DECLARE_16(0x001f)
#define BLE_MESH_UUID_MCAP_DATA_VAL 0x001f
#define BLE_MESH_UUID_L2CAP BLE_MESH_UUID_DECLARE_16(0x0100)
#define BLE_MESH_UUID_L2CAP_VAL 0x0100
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* _BLE_MESH_UUID_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _LPN_H_
#define _LPN_H_
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_BLE_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_BLE_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_BLE_MESH_LOW_POWER)
return (bt_mesh.lpn.state == BLE_MESH_LPN_WAIT_UPDATE);
#else
return false;
#endif
}
static inline bool bt_mesh_lpn_timer(void)
{
#if defined(CONFIG_BLE_MESH_LPN_AUTO)
return (bt_mesh.lpn.state == BLE_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);
#endif /* _LPN_H_ */

View File

@ -0,0 +1,22 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _MESH_H_
#define _MESH_H_
#define BLE_MESH_KEY_PRIMARY 0x0000
#define BLE_MESH_KEY_ANY 0xffff
#define BLE_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000)
#define BLE_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00)
#define BLE_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000)
#define BLE_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb)
struct bt_mesh_net;
#endif /* _MESH_H_ */

View File

@ -0,0 +1,409 @@
/* 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"
/* 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;
}

View File

@ -0,0 +1,179 @@
/**
* @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"
#ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN
/**
*
* @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>
*/
bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_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>
*/
bt_mesh_atomic_val_t bt_mesh_atomic_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
{
unsigned int key;
bt_mesh_atomic_val_t ret;
key = bt_mesh_irq_lock();
ret = *target;
*target = value;
bt_mesh_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>
*/
bt_mesh_atomic_val_t bt_mesh_atomic_or(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
{
unsigned int key;
bt_mesh_atomic_val_t ret;
key = bt_mesh_irq_lock();
ret = *target;
*target |= value;
bt_mesh_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>
*/
bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
{
unsigned int key;
bt_mesh_atomic_val_t ret;
key = bt_mesh_irq_lock();
ret = *target;
*target &= value;
bt_mesh_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
*/
bt_mesh_atomic_val_t bt_mesh_atomic_dec(bt_mesh_atomic_t *target)
{
unsigned int key;
bt_mesh_atomic_val_t ret;
key = bt_mesh_irq_lock();
ret = *target;
(*target)--;
bt_mesh_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
*/
bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
{
unsigned int key;
bt_mesh_atomic_val_t ret;
key = bt_mesh_irq_lock();
ret = *target;
(*target)++;
bt_mesh_irq_unlock(key);
return ret;
}
#endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,453 @@
/*
* Copyright (c) 2015 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "sdkconfig.h"
#include "mesh_buf.h"
#include "mesh_trace.h"
int net_buf_id(struct net_buf *buf)
{
struct net_buf_pool *pool = buf->pool;
return buf - pool->__bufs;
}
static inline struct net_buf *pool_get_uninit(struct net_buf_pool *pool,
u16_t uninit_count)
{
struct net_buf *buf;
buf = &pool->__bufs[pool->buf_count - uninit_count];
buf->pool = 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;
}
void *net_buf_simple_pull_mem(struct net_buf_simple *buf, size_t len)
{
void *data = buf->data;
NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len);
NET_BUF_SIMPLE_ASSERT(buf->len >= len);
buf->len -= len;
buf->data += len;
return data;
}
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);
net_buf_simple_reset(&buf->b);
}
void net_buf_simple_reserve(struct net_buf_simple *buf, size_t reserve)
{
NET_BUF_ASSERT(buf);
NET_BUF_ASSERT(buf->len == 0U);
NET_BUF_DBG("buf %p reserve %zu", 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 = bt_mesh_irq_lock();
sys_slist_append_list(list, &buf->node, &tail->node);
bt_mesh_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 = bt_mesh_irq_lock();
buf = (void *)sys_slist_get(list);
bt_mesh_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 = bt_mesh_irq_lock();
frag->frags = (void *)sys_slist_get(list);
bt_mesh_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;
}
struct net_buf *net_buf_ref(struct net_buf *buf)
{
NET_BUF_ASSERT(buf);
NET_BUF_DBG("buf %p (old) ref %u pool %p", buf, buf->ref, buf->pool);
buf->ref++;
return buf;
}
#if defined(CONFIG_BLE_MESH_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_BLE_MESH_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 %p frags %p", buf, buf->ref,
buf->pool, buf->frags);
/* Changed by Espressif. Add !buf->ref to avoid minus 0 */
if (!buf->ref || --buf->ref > 0) {
return;
}
buf->frags = NULL;
pool = buf->pool;
pool->uninit_count++;
#if defined(CONFIG_BLE_MESH_NET_BUF_POOL_USAGE)
pool->avail_count++;
NET_BUF_DBG("%s, pool %p, avail_count %d, uninit_count %d", __func__,
pool, pool->avail_count, pool->uninit_count);
NET_BUF_ASSERT(pool->avail_count <= pool->buf_count);
#endif
if (pool->destroy) {
pool->destroy(buf);
}
buf = frags;
}
}
static u8_t *fixed_data_alloc(struct net_buf *buf, size_t *size, s32_t timeout)
{
struct net_buf_pool *pool = buf->pool;
const struct net_buf_pool_fixed *fixed = pool->alloc->alloc_data;
*size = MIN(fixed->data_size, *size);
return fixed->data_pool + fixed->data_size * net_buf_id(buf);
}
static void fixed_data_unref(struct net_buf *buf, u8_t *data)
{
/* Nothing needed for fixed-size data pools */
}
const struct net_buf_data_cb net_buf_fixed_cb = {
.alloc = fixed_data_alloc,
.unref = fixed_data_unref,
};
static u8_t *data_alloc(struct net_buf *buf, size_t *size, s32_t timeout)
{
struct net_buf_pool *pool = buf->pool;
return pool->alloc->cb->alloc(buf, size, timeout);
}
#if defined(CONFIG_BLE_MESH_NET_BUF_LOG)
struct net_buf *net_buf_alloc_len_debug(struct net_buf_pool *pool, size_t size,
s32_t timeout, const char *func, int line)
#else
struct net_buf *net_buf_alloc_len(struct net_buf_pool *pool, size_t size,
s32_t timeout)
#endif
{
struct net_buf *buf = NULL;
unsigned int key;
int i;
NET_BUF_ASSERT(pool);
NET_BUF_DBG("%s, pool %p, 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 = bt_mesh_irq_lock();
/* If there are uninitialized buffers we're guaranteed to succeed
* with the allocation one way or another.
*/
if (pool->uninit_count) {
/* Changed 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) {
bt_mesh_irq_unlock(key);
goto success;
}
}
}
bt_mesh_irq_unlock(key);
NET_BUF_ERR("%s, Failed to get free buffer", __func__);
return NULL;
success:
NET_BUF_DBG("allocated buf %p", buf);
if (size) {
buf->__buf = data_alloc(buf, &size, timeout);
if (!buf->__buf) {
NET_BUF_ERR("%s, Failed to allocate data", __func__);
return NULL;
}
} else {
NET_BUF_WARN("%s, Zero data size", __func__);
buf->__buf = NULL;
}
buf->ref = 1;
buf->flags = 0;
buf->frags = NULL;
buf->size = size;
net_buf_reset(buf);
pool->uninit_count--;
#if defined(CONFIG_BLE_MESH_NET_BUF_POOL_USAGE)
pool->avail_count--;
NET_BUF_ASSERT(pool->avail_count >= 0);
#endif
return buf;
}
#if defined(CONFIG_BLE_MESH_NET_BUF_LOG)
struct net_buf *net_buf_alloc_fixed_debug(struct net_buf_pool *pool,
s32_t timeout, const char *func,
int line)
{
const struct net_buf_pool_fixed *fixed = pool->alloc->alloc_data;
return net_buf_alloc_len_debug(pool, fixed->data_size, timeout, func, line);
}
#else
struct net_buf *net_buf_alloc_fixed(struct net_buf_pool *pool, s32_t timeout)
{
const struct net_buf_pool_fixed *fixed = pool->alloc->alloc_data;
return net_buf_alloc_len(pool, fixed->data_size, timeout);
}
#endif

View File

@ -0,0 +1,45 @@
/*
* 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 "sdkconfig.h"
#include "stack/bt_types.h"
#include "device/controller.h"
#include "mesh_hci.h"
struct bt_mesh_dev bt_mesh_dev;
void bt_mesh_hci_init(void)
{
const uint8_t *features = controller_get_interface()->get_features_ble()->as_array;
if (features != NULL) {
memcpy(bt_mesh_dev.features[0], features, 8);
memcpy(bt_mesh_dev.le.features, features, 8);
}
/**
* Currently 20ms non-connectable adv interval is supported, and we need to add
* a flag to indicate this support.
*/
#ifdef CONFIG_BLE_MESH_HCI_5_0
bt_mesh_dev.hci_version = BLE_MESH_HCI_VERSION_5_0;
#else
bt_mesh_dev.hci_version = controller_get_interface()->get_bt_version()->hci_version;
#endif
bt_mesh_dev.lmp_version = controller_get_interface()->get_bt_version()->lmp_version;
bt_mesh_dev.hci_revision = controller_get_interface()->get_bt_version()->hci_revision;
bt_mesh_dev.lmp_subversion = controller_get_interface()->get_bt_version()->lmp_subversion;
bt_mesh_dev.manufacturer = controller_get_interface()->get_bt_version()->manufacturer;
const uint8_t *p = controller_get_interface()->get_ble_supported_states();
uint64_t states_fh = 0, states_sh = 0;
STREAM_TO_UINT32(states_fh, p);
STREAM_TO_UINT32(states_sh, p);
bt_mesh_dev.le.states = (states_sh << 32) | states_fh;
}

View File

@ -0,0 +1,205 @@
/*
* 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 <errno.h>
#include "sdkconfig.h"
#include "osi/hash_map.h"
#include "osi/alarm.h"
#include "osi/hash_functions.h"
#include "common/bt_trace.h"
#include "common/bt_defs.h"
#include "esp_timer.h"
#include "mesh_kernel.h"
#include "mesh_trace.h"
#include "provisioner_prov.h"
static osi_mutex_t bm_alarm_lock;
static osi_mutex_t bm_irq_lock;
static hash_map_t *bm_alarm_hash_map;
static const size_t BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BLE_MESH_PBA_SAME_TIME + \
CONFIG_BLE_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 bt_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 bt_mesh_irq_lock(void)
{
#if defined(CONFIG_BLE_MESH_IRQ_LOCK) && CONFIG_BLE_MESH_IRQ_LOCK
unsigned int key = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
return key;
#else
/* 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(&bm_irq_lock, OSI_MUTEX_MAX_TIMEOUT);
return 0;
#endif
}
void bt_mesh_irq_unlock(unsigned int key)
{
#if defined(CONFIG_BLE_MESH_IRQ_LOCK) && CONFIG_BLE_MESH_IRQ_LOCK
XTOS_RESTORE_INTLEVEL(key);
#else
osi_mutex_unlock(&bm_irq_lock);
#endif
}
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 bt_mesh_k_init(void)
{
osi_mutex_new(&bm_alarm_lock);
osi_mutex_new(&bm_irq_lock);
bm_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(bm_alarm_hash_map != NULL);
}
void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler)
{
osi_alarm_t *alarm = NULL;
assert(work != NULL && bm_alarm_hash_map != NULL);
k_work_init(&work->work, handler);
osi_mutex_lock(&bm_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) {
alarm = osi_alarm_new("bt_mesh", bt_mesh_alarm_cb, (void *)work, 0);
if (alarm == NULL) {
BT_ERR("%s, Unable to create alarm", __func__);
return;
}
if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) {
BT_ERR("%s Unable to add the timer to hash map.", __func__);
}
}
osi_mutex_unlock(&bm_alarm_lock);
alarm = hash_map_get(bm_alarm_hash_map, work);
if (alarm == NULL) {
BT_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 && bm_alarm_hash_map != NULL);
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
if (alarm == NULL) {
BT_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 && bm_alarm_hash_map != NULL);
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
if (alarm == NULL) {
BT_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 && bm_alarm_hash_map != NULL);
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, work);
if (alarm == NULL) {
BT_WARN("%s Unable to find expected alarm in hash map", __func__);
return -EINVAL;
}
hash_map_erase(bm_alarm_hash_map, work);
return 0;
}
s32_t k_delayed_work_remaining_get(struct k_delayed_work *work)
{
assert(work != NULL && bm_alarm_hash_map != NULL);
osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work);
if (alarm == NULL) {
BT_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;
}

View File

@ -0,0 +1,509 @@
/* 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 "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG)
#include "mesh_buf.h"
#include "mesh_trace.h"
#include "mesh_main.h"
#include "mesh_hci.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 "settings.h"
#include "mesh.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "provisioner_main.h"
static volatile bool provisioner_en = false;
#define ACTION_ENTER 0x01
#define ACTION_SUSPEND 0x02
#define ACTION_EXIT 0x03
#if CONFIG_BLE_MESH_NODE
int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
u8_t flags, u32_t iv_index, u16_t addr,
const u8_t dev_key[16])
{
bool pb_gatt_enabled;
int err;
BT_INFO("Primary Element: 0x%04x", addr);
BT_DBG("net_idx 0x%04x flags 0x%02x iv_index 0x%04x",
net_idx, flags, iv_index);
if (bt_mesh_atomic_test_and_set_bit(bt_mesh.flags, BLE_MESH_VALID)) {
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) {
if (bt_mesh_proxy_prov_disable(false) == 0) {
pb_gatt_enabled = true;
} else {
pb_gatt_enabled = false;
}
} else {
pb_gatt_enabled = false;
}
err = bt_mesh_net_create(net_idx, flags, net_key, iv_index);
if (err) {
bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID);
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && pb_gatt_enabled) {
bt_mesh_proxy_prov_enable();
}
return err;
}
bt_mesh.seq = 0U;
bt_mesh_comp_provision(addr);
memcpy(bt_mesh.dev_key, dev_key, 16);
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
BT_DBG("Storing network information persistently");
bt_mesh_store_net();
bt_mesh_store_subnet(&bt_mesh.sub[0]);
bt_mesh_store_iv(false);
}
/* Add this to avoid "already active status" for bt_mesh_scan_enable() */
bt_mesh_scan_disable();
bt_mesh_net_start();
return 0;
}
void bt_mesh_reset(void)
{
if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) {
BT_WARN("%s, Not provisioned", __func__);
return;
}
bt_mesh.iv_index = 0U;
bt_mesh.seq = 0U;
memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
k_delayed_work_cancel(&bt_mesh.ivu_timer);
bt_mesh_cfg_reset();
bt_mesh_rx_reset();
bt_mesh_tx_reset();
if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
bt_mesh_lpn_disable(true);
}
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY);
}
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
bt_mesh_proxy_gatt_disable();
}
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
bt_mesh_clear_net();
}
(void)memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
bt_mesh_scan_disable();
bt_mesh_beacon_disable();
bt_mesh_comp_unprovision();
if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) {
bt_mesh_prov_reset();
}
}
bool bt_mesh_is_provisioned(void)
{
return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID);
}
int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
{
if (bt_mesh_is_provisioned()) {
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
(bearers & BLE_MESH_PROV_ADV)) {
/* Make sure we're scanning for provisioning inviations */
bt_mesh_scan_enable();
/* Enable unprovisioned beacon sending */
bt_mesh_beacon_enable();
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
(bearers & BLE_MESH_PROV_GATT)) {
bt_mesh_proxy_prov_enable();
bt_mesh_adv_update();
}
return 0;
}
int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)
{
if (bt_mesh_is_provisioned()) {
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
(bearers & BLE_MESH_PROV_ADV)) {
bt_mesh_beacon_disable();
bt_mesh_scan_disable();
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
(bearers & BLE_MESH_PROV_GATT)) {
bt_mesh_proxy_prov_disable(true);
}
return 0;
}
#endif /* CONFIG_BLE_MESH_NODE */
static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
bool vnd, bool primary, void *user_data)
{
if (mod->pub && mod->pub->update) {
mod->pub->count = 0U;
k_delayed_work_cancel(&mod->pub->timer);
}
}
int bt_mesh_suspend(void)
{
int err;
if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) {
return -EINVAL;
}
if (bt_mesh_atomic_test_and_set_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
return -EALREADY;
}
err = bt_mesh_scan_disable();
if (err) {
bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_SUSPENDED);
BT_WARN("%s, Disabling scanning failed (err %d)", __func__, err);
return err;
}
bt_mesh_hb_pub_disable();
if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED) {
bt_mesh_beacon_disable();
}
bt_mesh_model_foreach(model_suspend, NULL);
return 0;
}
static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
bool vnd, bool primary, void *user_data)
{
if (mod->pub && mod->pub->update) {
s32_t period_ms = bt_mesh_model_pub_period_get(mod);
if (period_ms) {
k_delayed_work_submit(&mod->pub->timer, period_ms);
}
}
}
int bt_mesh_resume(void)
{
int err;
if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) {
return -EINVAL;
}
if (!bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
return -EALREADY;
}
err = bt_mesh_scan_enable();
if (err) {
BT_WARN("%s, Re-enabling scanning failed (err %d)", __func__, err);
bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_SUSPENDED);
return err;
}
if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED) {
bt_mesh_beacon_enable();
}
bt_mesh_model_foreach(model_resume, NULL);
return err;
}
int bt_mesh_init(const struct bt_mesh_prov *prov,
const struct bt_mesh_comp *comp)
{
int err;
bt_mesh_k_init();
bt_mesh_hci_init();
bt_mesh_adapt_init();
err = bt_mesh_comp_register(comp);
if (err) {
return err;
}
bt_mesh_gatt_init();
#if CONFIG_BLE_MESH_NODE
extern struct bt_mesh_gatt_service proxy_svc;
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY)) {
bt_mesh_gatts_service_register(&proxy_svc);
}
extern struct bt_mesh_gatt_service prov_svc;
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) {
bt_mesh_gatts_service_register(&prov_svc);
}
#endif
if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) {
#if CONFIG_BLE_MESH_NODE
err = bt_mesh_prov_init(prov);
if (err) {
return err;
}
#endif
#if CONFIG_BLE_MESH_PROVISIONER
err = provisioner_prov_init(prov);
if (err) {
return err;
}
#endif
}
bt_mesh_net_init();
bt_mesh_trans_init();
#if CONFIG_BLE_MESH_NODE
/* Changed by Espressif, add random delay (0 ~ 3s) */
#if defined(CONFIG_BLE_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_BLE_MESH_PROXY)) {
#if CONFIG_BLE_MESH_NODE
bt_mesh_proxy_init();
#endif
#if CONFIG_BLE_MESH_PROVISIONER
provisioner_proxy_init();
#endif
}
#if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_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_BLE_MESH_SETTINGS)
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
bt_mesh_settings_init();
}
#endif
return 0;
}
bool bt_mesh_is_provisioner_en(void)
{
return provisioner_en;
}
/* The following APIs are for fast provisioning */
#if CONFIG_BLE_MESH_PROVISIONER
int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)
{
int err;
if (bt_mesh_is_provisioner_en()) {
BT_WARN("%s, Provisioner is already enabled", __func__);
return -EALREADY;
}
err = provisioner_upper_init();
if (err) {
BT_ERR("%s, provisioner_upper_init fail", __func__);
return err;
}
#if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN)
if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
(bearers & BLE_MESH_PROV_ADV)) {
bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_ADD,
BLE_MESH_EXCEP_INFO_MESH_BEACON, NULL);
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
(bearers & BLE_MESH_PROV_GATT)) {
bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_ADD,
BLE_MESH_EXCEP_INFO_MESH_PROV_ADV, NULL);
}
if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) {
bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_ADD,
BLE_MESH_EXCEP_INFO_MESH_PROXY_ADV, NULL);
}
#endif
if ((IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
(bearers & BLE_MESH_PROV_ADV)) ||
(IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
(bearers & BLE_MESH_PROV_GATT))) {
bt_mesh_scan_enable();
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
(bearers & BLE_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_WARN("%s, Provisioner is already disabled", __func__);
return -EALREADY;
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
(bearers & BLE_MESH_PROV_GATT)) {
provisioner_pb_gatt_disable();
}
if ((IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
(bearers & BLE_MESH_PROV_ADV)) &&
(IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
(bearers & BLE_MESH_PROV_GATT))) {
bt_mesh_scan_disable();
}
provisioner_en = false;
return 0;
}
#endif /* CONFIG_BLE_MESH_PROVISIONER */
/* The following API is for fast provisioning */
#if CONFIG_BLE_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_BLE_MESH_GATT_PROXY)) {
bt_mesh_proxy_gatt_disable();
}
#endif
if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED) {
bt_mesh_beacon_disable();
}
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) {
provisioner_pb_gatt_enable();
}
provisioner_set_fast_prov_flag(true);
provisioner_en = true;
} else {
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) {
provisioner_pb_gatt_disable();
}
if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED) {
bt_mesh_beacon_enable();
}
#if 0
/* Mesh Proxy GATT will be re-enabled on application layer */
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY) &&
bt_mesh_gatt_proxy_get() != BLE_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_BLE_MESH_FAST_PROV */

View File

@ -0,0 +1,86 @@
/*
* 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"
#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 = bt_mesh_irq_lock();
str = hexbufs[curbuf++];
curbuf %= ARRAY_SIZE(hexbufs);
bt_mesh_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;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,388 @@
/* 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 BLE_MESH_NET_FLAG_KR BIT(0)
#define BLE_MESH_NET_FLAG_IVU BIT(1)
#define BLE_MESH_KR_NORMAL 0x00
#define BLE_MESH_KR_PHASE_1 0x01
#define BLE_MESH_KR_PHASE_2 0x02
#define BLE_MESH_KR_PHASE_3 0x03
#define BLE_MESH_IV_UPDATE(flags) ((flags >> 1) & 0x01)
#define BLE_MESH_KEY_REFRESH(flags) (flags & 0x01)
/* How many hours in between updating IVU duration */
#define BLE_MESH_IVU_MIN_HOURS 96
#define BLE_MESH_IVU_HOURS (BLE_MESH_IVU_MIN_HOURS / \
CONFIG_BLE_MESH_IVU_DIVIDER)
#define BLE_MESH_IVU_TIMEOUT K_HOURS(BLE_MESH_IVU_HOURS)
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_BLE_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_BLE_MESH_SETTINGS)
bool store;
#endif
u32_t seq;
};
#if defined(CONFIG_BLE_MESH_FRIEND)
#define FRIEND_SEG_RX CONFIG_BLE_MESH_FRIEND_SEG_RX
#define FRIEND_SUB_LIST_SIZE CONFIG_BLE_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_BLE_MESH_LOW_POWER)
#define LPN_GROUPS CONFIG_BLE_MESH_LPN_GROUPS
#else
#define LPN_GROUPS 0
#endif
/* Low Power Node state */
struct bt_mesh_lpn {
enum __packed {
BLE_MESH_LPN_DISABLED, /* LPN feature is disabled */
BLE_MESH_LPN_CLEAR, /* Clear in progress */
BLE_MESH_LPN_TIMER, /* Waiting for auto timer expiry */
BLE_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */
BLE_MESH_LPN_REQ_WAIT, /* Wait before scanning for offers */
BLE_MESH_LPN_WAIT_OFFER, /* Friend Req sent */
BLE_MESH_LPN_ESTABLISHED, /* Friendship established */
BLE_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */
BLE_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */
BLE_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 */
BLE_MESH_ATOMIC_DEFINE(added, LPN_GROUPS);
BLE_MESH_ATOMIC_DEFINE(pending, LPN_GROUPS);
BLE_MESH_ATOMIC_DEFINE(to_remove, LPN_GROUPS);
};
/* bt_mesh_net.flags */
enum {
BLE_MESH_VALID, /* We have been provisioned */
BLE_MESH_SUSPENDED, /* Network is temporarily suspended */
BLE_MESH_IVU_IN_PROGRESS, /* IV Update in Progress */
BLE_MESH_IVU_INITIATOR, /* IV Update initiated by us */
BLE_MESH_IVU_TEST, /* IV Update test mode */
BLE_MESH_IVU_PENDING, /* Update blocked by SDU in progress */
/* pending storage actions */
BLE_MESH_RPL_PENDING,
BLE_MESH_KEYS_PENDING,
BLE_MESH_NET_PENDING,
BLE_MESH_IV_PENDING,
BLE_MESH_SEQ_PENDING,
BLE_MESH_HB_PUB_PENDING,
BLE_MESH_CFG_PENDING,
BLE_MESH_MOD_PENDING,
/* Don't touch - intentionally last */
BLE_MESH_FLAG_COUNT,
};
struct bt_mesh_net {
u32_t iv_index; /* Current IV Index */
u32_t seq; /* Next outgoing sequence number (24 bits) */
BLE_MESH_ATOMIC_DEFINE(flags, BLE_MESH_FLAG_COUNT);
/* Local network interface */
struct k_work local_work;
sys_slist_t local_queue;
#if defined(CONFIG_BLE_MESH_FRIEND)
/* Friend state, unique for each LPN that we're Friends for */
struct bt_mesh_friend frnd[CONFIG_BLE_MESH_FRIEND_LPN_COUNT];
#endif
#if defined(CONFIG_BLE_MESH_LOW_POWER)
struct bt_mesh_lpn lpn; /* Low Power Node state */
#endif
/* Number of hours in current IV Update state */
u8_t ivu_duration;
/* Timer to track duration in current IV Update state */
struct k_delayed_work ivu_timer;
u8_t dev_key[16];
struct bt_mesh_app_key app_keys[CONFIG_BLE_MESH_APP_KEY_COUNT];
struct bt_mesh_subnet sub[CONFIG_BLE_MESH_SUBNET_COUNT];
struct bt_mesh_rpl rpl[CONFIG_BLE_MESH_CRPL];
#if defined(CONFIG_BLE_MESH_PROVISIONER)
/* Application keys stored by provisioner */
struct bt_mesh_app_key *p_app_keys[CONFIG_BLE_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_BLE_MESH_PROVISIONER_SUBNET_COUNT];
/* Next net_idx can be assigned */
u16_t p_net_idx_next;
#endif
};
/* Network interface */
enum bt_mesh_net_if {
BLE_MESH_NET_IF_ADV,
BLE_MESH_NET_IF_LOCAL,
BLE_MESH_NET_IF_PROXY,
BLE_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 */
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 BLE_MESH_NET_IVI_TX (bt_mesh.iv_index - \
bt_mesh_atomic_test_bit(bt_mesh.flags, \
BLE_MESH_IVU_IN_PROGRESS))
#define BLE_MESH_NET_IVI_RX(rx) (bt_mesh.iv_index - (rx)->old_iv)
#define BLE_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_start(void);
void bt_mesh_net_init(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 /* _NET_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
/* 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_mesh_conn *conn);
int bt_mesh_pb_gatt_close(struct bt_mesh_conn *conn);
int bt_mesh_pb_gatt_recv(struct bt_mesh_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 struct bt_mesh_prov *bt_mesh_prov_get(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 /* _PROV_H_ */

View File

@ -0,0 +1,71 @@
// 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 "sdkconfig.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_BEACON)
#include "mesh_util.h"
#include "mesh_buf.h"
#include "mesh_main.h"
#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_BLE_MESH_PROVISIONER
static void provisioner_secure_beacon_recv(struct net_buf_simple *buf)
{
// TODO: Provisioner receive and handle Secure Network 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("%s, Too short beacon", __func__);
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_DBG("%s, Unknown beacon type 0x%02x", __func__, type);
break;
}
}
#endif /* CONFIG_BLE_MESH_PROVISIONER */

View File

@ -0,0 +1,20 @@
// 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);
#endif /* _PROVISIONER_BEACON_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
// 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_MAIN_H_
#define _PROVISIONER_MAIN_H_
#include "mesh_util.h"
#include "mesh_kernel.h"
#include "mesh_access.h"
#include "net.h"
#define MESH_NAME_SIZE 31
/* Each node information stored by provisioner */
struct bt_mesh_node_t {
char node_name[MESH_NAME_SIZE]; /* Node name */
u8_t dev_uuid[16]; /* Device UUID pointer, stored in provisioner_prov.c */
u16_t oob_info; /* Node OOB information */
u16_t unicast_addr; /* Node unicast address */
u8_t element_num; /* Node element number */
u16_t net_idx; /* Node provision net_idx */
u8_t flags; /* Node key refresh flag and iv update flag */
u32_t iv_index; /* Node IV Index */
u8_t dev_key[16]; /* Node device key */
} __packed;
/* The following APIs are for key init, node provision & node reset. */
int provisioner_node_provision(int node_index, const u8_t uuid[16], u16_t oob_info,
u16_t unicast_addr, u8_t element_num, u16_t net_idx,
u8_t flags, u32_t iv_index, const u8_t dev_key[16]);
int provisioner_node_reset(int node_index);
int provisioner_upper_reset_all_nodes(void);
int provisioner_upper_init(void);
/* The following APIs are for provisioner upper layers internal usage. */
const u8_t *provisioner_net_key_get(u16_t net_idx);
struct bt_mesh_subnet *provisioner_subnet_get(u16_t net_idx);
bool provisioner_check_msg_dst_addr(u16_t dst_addr);
const u8_t *provisioner_get_device_key(u16_t dst_addr);
struct bt_mesh_app_key *provisioner_app_key_find(u16_t app_idx);
u32_t provisioner_get_prov_node_count(void);
/* The following APIs are for provisioner application use. */
int bt_mesh_provisioner_store_node_info(struct bt_mesh_node_t *node_info);
int bt_mesh_provisioner_get_all_node_unicast_addr(struct net_buf_simple *buf);
int bt_mesh_provisioner_set_node_name(int node_index, const char *name);
const char *bt_mesh_provisioner_get_node_name(int node_index);
int bt_mesh_provisioner_get_node_index(const char *name);
struct bt_mesh_node_t *bt_mesh_provisioner_get_node_info(u16_t unicast_addr);
u32_t bt_mesh_provisioner_get_net_key_count(void);
u32_t bt_mesh_provisioner_get_app_key_count(void);
int bt_mesh_provisioner_local_app_key_add(const u8_t app_key[16], u16_t net_idx, u16_t *app_idx);
const u8_t *bt_mesh_provisioner_local_app_key_get(u16_t net_idx, u16_t app_idx);
int bt_mesh_provisioner_local_app_key_delete(u16_t net_idx, u16_t app_idx);
int bt_mesh_provisioner_local_net_key_add(const u8_t net_key[16], u16_t *net_idx);
const u8_t *bt_mesh_provisioner_local_net_key_get(u16_t net_idx);
int bt_mesh_provisioner_local_net_key_delete(u16_t net_idx);
int bt_mesh_provisioner_get_own_unicast_addr(u16_t *addr, u8_t *elem_num);
/* Provisioner bind local client model with proper appkey index */
int bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr, u16_t mod_id,
u16_t cid, u16_t app_idx);
/* This API can be used to change the net_idx binded with the app_idx. */
int bt_mesh_provisioner_bind_local_app_net_idx(u16_t net_idx, u16_t app_idx);
/* Provisioner print own element information */
int bt_mesh_provisioner_print_local_element_info(void);
/* The following APIs are for fast provisioning */
const u8_t *get_fast_prov_device_key(u16_t dst_addr);
struct bt_mesh_subnet *get_fast_prov_subnet(u16_t net_idx);
struct bt_mesh_app_key *get_fast_prov_app_key(u16_t net_idx, u16_t app_idx);
u8_t bt_mesh_set_fast_prov_net_idx(u16_t net_idx);
u8_t bt_mesh_add_fast_prov_net_key(const u8_t net_key[16]);
const u8_t *bt_mesh_get_fast_prov_net_key(u16_t net_idx);
const u8_t *bt_mesh_get_fast_prov_app_key(u16_t net_idx, u16_t app_idx);
#endif /* _PROVISIONER_MAIN_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,379 @@
// 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_PROV_H_
#define _PROVISIONER_PROV_H_
#include "mesh_bearer_adapt.h"
#include "mesh_main.h"
#if !CONFIG_BLE_MESH_PROVISIONER
#define CONFIG_BLE_MESH_PBA_SAME_TIME 0
#define CONFIG_BLE_MESH_PBG_SAME_TIME 0
#else
#if !defined(CONFIG_BLE_MESH_PB_ADV)
#define CONFIG_BLE_MESH_PBA_SAME_TIME 0
#endif /* !CONFIG_BLE_MESH_PB_ADV */
#if !defined(CONFIG_BLE_MESH_PB_GATT)
#define CONFIG_BLE_MESH_PBG_SAME_TIME 0
#endif /* !CONFIG_BLE_MESH_PB_GATT */
#endif /* !CONFIG_BLE_MESH_PROVISIONER */
#define RM_AFTER_PROV BIT(0)
#define START_PROV_NOW BIT(1)
#define FLUSHABLE_DEV BIT(2)
struct bt_mesh_unprov_dev_add {
u8_t addr[6];
u8_t addr_type;
u8_t uuid[16];
u16_t oob_info;
u8_t bearer;
};
struct bt_mesh_device_delete {
u8_t addr[6];
u8_t addr_type;
u8_t uuid[16];
};
#define NET_IDX_FLAG BIT(0)
#define FLAGS_FLAG BIT(1)
#define IV_INDEX_FLAG BIT(2)
struct bt_mesh_prov_data_info {
union {
u16_t net_idx;
u8_t flags;
u32_t iv_index;
};
u8_t flag;
};
/* The following APIs are for primary provisioner internal use */
/**
* @brief This function decrements the current PB-GATT count.
*
* @return None
*/
void provisioner_pbg_count_dec(void);
/**
* @brief This function increments the current PB-GATT count.
*
* @return None
*/
void provisioner_pbg_count_inc(void);
/**
* @brief This function clears the part of the link info of the proper device.
*
* @param[in] addr: Remote device address
*
* @return None
*/
void provisioner_clear_link_conn_info(const u8_t addr[6]);
/**
* @brief This function handles the received PB-ADV PDUs.
*
* @param[in] buf: Pointer to the buffer containing generic provisioning PDUs
*
* @return Zero - success, otherwise - fail
*/
void provisioner_pb_adv_recv(struct net_buf_simple *buf);
/**
* @brief This function sends provisioning invite to start
* provisioning this unprovisioned device.
*
* @param[in] addr: Remote device address
* @param[in] conn: Pointer to the bt_conn structure
*
* @return Zero - success, otherwise - fail
*/
int provisioner_set_prov_conn(const u8_t addr[6], struct bt_mesh_conn *conn);
/**
* @brief This function sends provisioning invite to start
* provisioning this unprovisioned device.
*
* @param[in] conn: Pointer to the bt_conn structure
* @param[in] addr: Address of the connected device
*
* @return Zero - success, otherwise - fail
*/
int provisioner_pb_gatt_open(struct bt_mesh_conn *conn, u8_t *addr);
/**
* @brief This function resets the used information when
* related connection is terminated.
*
* @param[in] conn: Pointer to the bt_conn structure
* @param[in] reason: Connection terminated reason
*
* @return Zero - success, otherwise - fail
*/
int provisioner_pb_gatt_close(struct bt_mesh_conn *conn, u8_t reason);
/**
* @brief This function handles the received PB-GATT provision
* PDUs.
*
* @param[in] conn: Pointer to the bt_conn structure
* @param[in] buf: Pointer to the buffer containing provision PDUs
*
* @return Zero - success, otherwise - fail
*/
int provisioner_pb_gatt_recv(struct bt_mesh_conn *conn, struct net_buf_simple *buf);
/**
* @brief This function initializes provisioner's PB-GATT and PB-ADV
* related information.
*
* @param[in] prov_info: Pointer to the application-initialized provisioner info.
*
* @return Zero - success, otherwise - fail
*/
int provisioner_prov_init(const struct bt_mesh_prov *prov_info);
/**
* @brief This function parses the received unprovisioned device
* beacon advertising packets, and if checked, starts to provision this device
* using PB-ADV bearer.
*
* @param[in] buf: Pointer to the buffer containing unprovisioned device beacon
*
* @return None
*/
void provisioner_unprov_beacon_recv(struct net_buf_simple *buf);
/**
* @brief This function parses the flags part of the
* received connectable mesh provisioning advertising packets.
*
* @param[in] buf: Pointer to the buffer containing advertising flags part
*
* @return True - success, False - fail
*/
bool provisioner_flags_match(struct net_buf_simple *buf);
/**
* @brief This function parses the service UUID part of the
* received connectable mesh provisioning advertising packets.
*
* @param[in] buf: Pointer to the buffer containing service UUID part
*
* @return Zero - fail, otherwise - Service UUID(0x1827 or 0x1828)
*/
u16_t provisioner_srv_uuid_recv(struct net_buf_simple *buf);
/**
* @brief This function parses the service data part of the
* received connectable mesh provisioning advertising packets.
*
* @param[in] buf: Pointer to the buffer containing the remianing service data part
* @param[in] addr: Pointer to the received device address
* @param[in] uuid: Service UUID contained in the service UUID part
*
* @return None
*/
void provisioner_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr, u16_t uuid);
/**
* @brief This function gets the bt_mesh_prov pointer.
*
* @return bt_mesh_prov pointer(prov)
*/
const struct bt_mesh_prov *provisioner_get_prov_info(void);
/**
* @brief This function resets all nodes information in provisioner_prov.c.
*
* @return Zero
*/
int provisioner_prov_reset_all_nodes(void);
/* The following APIs are for primary provisioner application use */
/** @brief Add unprovisioned device info to unprov_dev queue
*
* @param[in] add_dev: Pointer to the structure containing the device information
* @param[in] flags: Flags indicate several operations of the device information
* - Remove device information from queue after it is provisioned (BIT0)
* - Start provisioning as soon as device is added to queue (BIT1)
* - Device can be flushed when device queue is full (BIT2)
*
* @return Zero on success or (negative) error code otherwise.
*
* @Note: 1. Currently address type only supports public address and static random address.
* 2. If device UUID and/or device address and address type already exist in the
* device queue, but the bearer differs from the existing one, add operation
* will also be successful and it will update the provision bearer supported by
* the device.
*/
int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u8_t flags);
/** @brief Delete device from queue, reset current provisioning link and reset the node
*
* @param[in] del_dev: Pointer to the structure containing the device information
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev);
/**
* @brief This function sets a part of the device UUID for comparison before
* starting to provision the device.
*
* @param[in] offset: offset of the device UUID to be compared
* @param[in] length: length of the device UUID to be compared
* @param[in] match: value to be compared
* @param[in] prov_flag: flags indicate if uuid_match advertising packets are received, after that
* the device will be provisioned at once or reported to the application layer
*
* @return Zero - success, otherwise - fail
*/
int bt_mesh_provisioner_set_dev_uuid_match(u8_t offset, u8_t length,
const u8_t *match, bool prov_flag);
/** @brief Callback for provisioner receiving advertising packet from unprovisioned devices which are
* not in the unprovisioned device queue.
*
* Report on the unprovisioned device beacon and mesh provisioning service advertising data to application layer
*
* @param addr Unprovisioned device address pointer
* @param addr_type Unprovisioned device address type
* @param dev_uuid Unprovisioned device device UUID pointer
* @param bearer Advertising packet received from PB-GATT or PB-ADV bearer
* @param adv_type Adv packet type, currently this is not used and we can use bearer to device
* the adv_type(ADV_IND or ADV_NONCONN_IND). This parameter will be used, when
* scan response data will be supported.
*
*/
typedef void (*unprov_adv_pkt_cb_t)(const u8_t addr[6], const u8_t addr_type,
const u8_t adv_type, const u8_t dev_uuid[16],
u16_t oob_info, bt_mesh_prov_bearer_t bearer);
/**
* @brief This function registers the callback which notifies the application
* layer of the received mesh provisioning or unprovisioned device
* beacon advertizing packets (from devices not in the unprov device queue).
*
* @param[in] cb: Callback of the notifying adv pkts function
*
* @return Zero - success, otherwise - fail
*/
int bt_mesh_prov_adv_pkt_cb_register(unprov_adv_pkt_cb_t cb);
/**
* @brief This function changes net_idx or flags or iv_index used in provisioning data.
*
* @param[in] info: Pointer of structure containing net_idx or flags or iv_index
*
* @return Zero - success, otherwise - fail
*/
int bt_mesh_provisioner_set_prov_data_info(struct bt_mesh_prov_data_info *info);
/**
* @brief This function is called to input number/string out-put by unprovisioned device.
*
* @param[in] idx The provisioning link index
* @param[in] val Pointer of the input number/string
* @param[in] num_flag Flag indicates if it is a number or string
*
* @return Zero - success, otherwise - fail
*/
int bt_mesh_prov_set_oob_input_data(const u8_t idx, const u8_t *val, bool num_flag);
/**
* @brief This function is called to output number/string which will be input by unprovisioned device.
*
* @param[in] idx The provisioning link index
* @param[in] num Pointer of the output number/string
* @param[in] size Size of the output number/string
* @param[in] num_flag Flag indicates if it is a number or string
*
* @return Zero - success, otherwise - fail
*/
#if 0
int bt_mesh_prov_set_oob_output_data(const u8_t idx, u8_t *num, u8_t size, bool num_flag);
#endif
/**
* @brief This function is called to read unprovisioned device's oob public key.
*
* @param[in] 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 Zero - success, otherwise - fail
*/
int bt_mesh_prov_read_oob_pub_key(const u8_t idx, const u8_t pub_key_x[32], const u8_t pub_key_y[32]);
/* The following APIs are for fast provisioning */
/**
* @brief This function is called to set fast_prov_flag.
*
* @param[in] flag: Flag set to fast_prov_flag
*
* @return None
*/
void provisioner_set_fast_prov_flag(bool flag);
/**
* @brief This function is called to set netkey index used for fast provisioning.
*
* @param[in] net_key: Netkey value
* @param[in] net_idx: Netkey index
*
* @return status for set netkey index msg
*/
u8_t provisioner_set_fast_prov_net_idx(const u8_t *net_key, u16_t net_idx);
/**
* @brief This function is called to get netkey index used for fast provisioning.
*
* @return net_idx of fast provisioning
*/
u16_t provisioner_get_fast_prov_net_idx(void);
/**
* @brief This function is called to set unicast address range used for fast provisioning.
*
* @param[in] min: Minimum unicast address
* @param[in] max: Maximum unicast address
*
* @return status for set unicast address range message
*/
u8_t bt_mesh_set_fast_prov_unicast_addr_range(u16_t min, u16_t max);
/**
* @brief This function is called to set flags & iv_index used for fast provisioning.
*
* @param[in] flags: Key refresh flag and iv update flag
* @param[in] iv_index: IV index
*
* @return None
*/
void bt_mesh_set_fast_prov_flags_iv_index(u8_t flags, u32_t iv_index);
#endif /* _PROVISIONER_PROV_H_ */

View File

@ -0,0 +1,608 @@
// 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 "sdkconfig.h"
#include "mesh_bearer_adapt.h"
#include "mesh_trace.h"
#include "net.h"
#include "beacon.h"
#include "foundation.h"
#include "provisioner_prov.h"
#include "provisioner_proxy.h"
#include "provisioner_beacon.h"
#if CONFIG_BLE_MESH_PROVISIONER
#define PDU_TYPE(data) (data[0] & BIT_MASK(6))
#define PDU_SAR(data) (data[0] >> 6)
#define SAR_COMPLETE 0x00
#define SAR_FIRST 0x01
#define SAR_CONT 0x02
#define SAR_LAST 0x03
#define CFG_FILTER_SET 0x00
#define CFG_FILTER_ADD 0x01
#define CFG_FILTER_REMOVE 0x02
#define CFG_FILTER_STATUS 0x03
#define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6)))
#define SERVER_BUF_SIZE 68
#define ID_TYPE_NET 0x00
#define ID_TYPE_NODE 0x01
#define NODE_ID_LEN 19
#define NET_ID_LEN 11
#define CLOSE_REASON_PROXY 0xFF
static int conn_count;
static struct bt_mesh_proxy_server {
struct bt_mesh_conn *conn;
/* Provisioner can use filter to double check the dst within mesh messages */
u16_t filter[CONFIG_BLE_MESH_PROXY_FILTER_SIZE];
enum __packed {
NONE,
WHITELIST,
BLACKLIST,
PROV,
} filter_type;
u8_t msg_type;
struct net_buf_simple buf;
} servers[BLE_MESH_MAX_CONN];
static u8_t server_buf_data[SERVER_BUF_SIZE * BLE_MESH_MAX_CONN];
static struct bt_mesh_proxy_server *find_server(struct bt_mesh_conn *conn)
{
int i;
for (i = 0; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn == conn) {
return &servers[i];
}
}
return NULL;
}
static int filter_status(struct bt_mesh_proxy_server *server,
struct net_buf_simple *buf)
{
/* TODO: Deal with received proxy configuration status messages */
return 0;
}
#if 0
static void send_filter_set(struct bt_mesh_proxy_server *server,
struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf)
{
/* TODO: Act as proxy client, send proxy configuration set messages */
}
static void send_filter_add(struct bt_mesh_proxy_server *server,
struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf)
{
/* TODO: Act as proxy client, send proxy configuration add messages */
}
static void send_filter_remove(struct bt_mesh_proxy_server *server,
struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf)
{
/* TODO: Act as proxy client, send proxy configuration remove messages */
}
#endif
static void proxy_cfg(struct bt_mesh_proxy_server *server)
{
NET_BUF_SIMPLE_DEFINE(buf, 29);
struct bt_mesh_net_rx rx;
u8_t opcode;
int err;
/** In order to deal with proxy configuration messages, provisioner should
* do sth. like create mesh network after each device is provisioned.
*/
err = bt_mesh_net_decode(&server->buf, BLE_MESH_NET_IF_PROXY_CFG,
&rx, &buf);
if (err) {
BT_ERR("%s, Failed to decode Proxy Configuration (err %d)", __func__, err);
return;
}
/* Remove network headers */
net_buf_simple_pull(&buf, BLE_MESH_NET_HDR_LEN);
BT_DBG("%u bytes: %s", buf.len, bt_hex(buf.data, buf.len));
if (buf.len < 1) {
BT_WARN("Too short proxy configuration PDU");
return;
}
opcode = net_buf_simple_pull_u8(&buf);
switch (opcode) {
case CFG_FILTER_STATUS:
filter_status(server, &buf);
break;
default:
BT_WARN("Unhandled configuration OpCode 0x%02x", opcode);
break;
}
}
static void proxy_complete_pdu(struct bt_mesh_proxy_server *server)
{
switch (server->msg_type) {
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
case BLE_MESH_PROXY_NET_PDU:
BT_DBG("Mesh Network PDU");
bt_mesh_net_recv(&server->buf, 0, BLE_MESH_NET_IF_PROXY);
break;
case BLE_MESH_PROXY_BEACON:
BT_DBG("Mesh Beacon PDU");
provisioner_beacon_recv(&server->buf);
break;
case BLE_MESH_PROXY_CONFIG:
BT_DBG("Mesh Configuration PDU");
proxy_cfg(server);
break;
#endif
#if defined(CONFIG_BLE_MESH_PB_GATT)
case BLE_MESH_PROXY_PROV:
BT_DBG("Mesh Provisioning PDU");
provisioner_pb_gatt_recv(server->conn, &server->buf);
break;
#endif
default:
BT_WARN("Unhandled Message Type 0x%02x", server->msg_type);
break;
}
net_buf_simple_reset(&server->buf);
}
#define ATTR_IS_PROV(uuid) (uuid == BLE_MESH_UUID_MESH_PROV_VAL)
static ssize_t proxy_recv(struct bt_mesh_conn *conn,
const struct bt_mesh_gatt_attr *attr, const void *buf,
u16_t len, u16_t offset, u8_t flags)
{
struct bt_mesh_proxy_server *server = find_server(conn);
const u8_t *data = buf;
u16_t srvc_uuid = 0;
if (!server) {
return -ENOTCONN;
}
if (len < 1) {
BT_WARN("Too small Proxy PDU");
return -EINVAL;
}
srvc_uuid = bt_mesh_gattc_get_service_uuid(conn);
if (!srvc_uuid) {
BT_ERR("%s, No service uuid found", __func__);
return -ENOTCONN;
}
if (ATTR_IS_PROV(srvc_uuid) != (PDU_TYPE(data) == BLE_MESH_PROXY_PROV)) {
BT_WARN("Proxy PDU type doesn't match GATT service uuid");
return -EINVAL;
}
if (len - 1 > net_buf_simple_tailroom(&server->buf)) {
BT_WARN("Too big proxy PDU");
return -EINVAL;
}
switch (PDU_SAR(data)) {
case SAR_COMPLETE:
if (server->buf.len) {
BT_WARN("Complete PDU while a pending incomplete one");
return -EINVAL;
}
server->msg_type = PDU_TYPE(data);
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
proxy_complete_pdu(server);
break;
case SAR_FIRST:
if (server->buf.len) {
BT_WARN("First PDU while a pending incomplete one");
return -EINVAL;
}
server->msg_type = PDU_TYPE(data);
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
break;
case SAR_CONT:
if (!server->buf.len) {
BT_WARN("Continuation with no prior data");
return -EINVAL;
}
if (server->msg_type != PDU_TYPE(data)) {
BT_WARN("Unexpected message type in continuation");
return -EINVAL;
}
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
break;
case SAR_LAST:
if (!server->buf.len) {
BT_WARN("Last SAR PDU with no prior data");
return -EINVAL;
}
if (server->msg_type != PDU_TYPE(data)) {
BT_WARN("Unexpected message type in last SAR PDU");
return -EINVAL;
}
net_buf_simple_add_mem(&server->buf, data + 1, len - 1);
proxy_complete_pdu(server);
break;
}
return len;
}
static void proxy_prov_connected(const u8_t addr[6], struct bt_mesh_conn *conn, int id)
{
struct bt_mesh_proxy_server *server = NULL;
conn_count++;
if (!servers[id].conn) {
server = &servers[id];
}
if (!server) {
BT_ERR("%s, No matching Proxy Client objects", __func__);
/** Disconnect current connection, clear part of prov_link
* information, like uuid, dev_addr, linking flag, etc.
*/
return;
}
server->conn = bt_mesh_conn_ref(conn);
server->filter_type = NONE;
memset(server->filter, 0, sizeof(server->filter));
net_buf_simple_reset(&server->buf);
#if defined(CONFIG_BLE_MESH_PB_GATT)
if (provisioner_set_prov_conn(addr, server->conn)) {
BT_ERR("%s, provisioner_set_prov_conn failed", __func__);
bt_mesh_gattc_disconnect(server->conn);
return;
}
#endif
bt_mesh_gattc_exchange_mtu(id);
}
static void proxy_prov_disconnected(struct bt_mesh_conn *conn, u8_t reason)
{
struct bt_mesh_proxy_server *server = NULL;
int i;
BT_DBG("conn %p, handle is %d, reason 0x%02x", conn, conn->handle, reason);
if (conn_count) {
conn_count--;
}
for (i = 0; i < ARRAY_SIZE(servers); i++) {
server = &servers[i];
if (server->conn == conn) {
if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
server->filter_type == PROV) {
provisioner_pb_gatt_close(conn, reason);
}
server->conn = NULL;
break;
}
}
}
#if defined(CONFIG_BLE_MESH_PB_GATT)
static ssize_t prov_write_ccc_descr(struct bt_mesh_conn *conn, u8_t *addr)
{
struct bt_mesh_proxy_server *server;
server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server found", __func__);
return -ENOTCONN;
}
if (server->filter_type == NONE) {
server->filter_type = PROV;
return provisioner_pb_gatt_open(conn, addr);
}
return -EINVAL;
}
static ssize_t prov_notification(struct bt_mesh_conn *conn, u8_t *data, u16_t len)
{
struct bt_mesh_proxy_server *server;
server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server found", __func__);
return -ENOTCONN;
}
if (server->filter_type == PROV) {
return proxy_recv(conn, NULL, data, len, 0, 0);
}
return -EINVAL;
}
int provisioner_pb_gatt_enable(void)
{
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn) {
servers[i].filter_type = PROV;
}
}
return 0;
}
int provisioner_pb_gatt_disable(void)
{
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
if (server->conn && server->filter_type == PROV) {
bt_mesh_gattc_disconnect(server->conn);
server->filter_type = NONE;
}
}
return 0;
}
#endif /* CONFIG_BLE_MESH_PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
static ssize_t proxy_write_ccc_descr(struct bt_mesh_conn *conn)
{
struct bt_mesh_proxy_server *server;
server = find_server(conn);
if (!server) {
BT_ERR("%s, No Proxy Server found", __func__);
return -ENOTCONN;
}
if (server->filter_type == NONE) {
server->filter_type = WHITELIST;
return 0;
}
return -EINVAL;
}
static ssize_t proxy_notification(struct bt_mesh_conn *conn, u8_t *data, u16_t len)
{
return proxy_recv(conn, NULL, data, len, 0, 0);
}
/** Currently provisioner does't need bt_mesh_provisioner_proxy_enable()
* and bt_mesh_provisioner_proxy_disable() functions, and once they are
* used, provisioner can be enabled to parse node_id_adv and net_id_adv
* in order to support proxy client role.
* And if gatt_proxy is disabled, provisioner can stop dealing with
* these two kinds of connectable advertising packets.
*/
int bt_mesh_provisioner_proxy_enable(void)
{
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(servers); i++) {
if (servers[i].conn) {
servers[i].filter_type = WHITELIST;
}
}
/** TODO: Once at leat one device has been provisioned, provisioner
* can be set to allow receiving and parsing node_id & net_id adv
* packets, and we may use a global flag to indicate this.
*/
return 0;
}
static void bt_mesh_proxy_gatt_proxy_disconnect(void)
{
int i;
BT_DBG("%s", __func__);
for (i = 0; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
if (server->conn && (server->filter_type == WHITELIST ||
server->filter_type == BLACKLIST)) {
server->filter_type = NONE;
bt_mesh_gattc_disconnect(server->conn);
}
}
}
int bt_mesh_provisioner_proxy_disable(void)
{
BT_DBG("%s", __func__);
/** TODO: Once this function is invoked, provisioner shall stop
* receiving and parsing node_id & net_id adv packets, and if
* proxy connection exists, we should disconnect it.
*/
bt_mesh_proxy_gatt_proxy_disconnect();
return 0;
}
#endif /* CONFIG_BLE_MESH_GATT_PROXY */
static int proxy_send(struct bt_mesh_conn *conn, const void *data, u16_t len)
{
BT_DBG("%u bytes: %s", len, bt_hex(data, len));
#if defined(CONFIG_BLE_MESH_GATT_PROXY) || defined(CONFIG_BLE_MESH_PB_GATT)
return bt_mesh_gattc_write_no_rsp(conn, NULL, data, len);
#endif
return 0;
}
static int proxy_prov_segment_and_send(struct bt_mesh_conn *conn, u8_t type,
struct net_buf_simple *msg)
{
u16_t mtu;
if (conn == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
}
BT_DBG("conn %p type 0x%02x len %u: %s", conn, type, msg->len,
bt_hex(msg->data, msg->len));
mtu = bt_mesh_gattc_get_mtu_info(conn);
if (!mtu) {
BT_ERR("%s, Conn used to get mtu does not exist", __func__);
return -ENOTCONN;
}
/* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */
mtu -= 3;
if (mtu > msg->len) {
net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type));
return proxy_send(conn, msg->data, msg->len);
}
net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type));
proxy_send(conn, msg->data, mtu);
net_buf_simple_pull(msg, mtu);
while (msg->len) {
if (msg->len + 1 < mtu) {
net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type));
proxy_send(conn, msg->data, msg->len);
break;
}
net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type));
proxy_send(conn, msg->data, mtu);
net_buf_simple_pull(msg, mtu);
}
return 0;
}
int provisioner_proxy_send(struct bt_mesh_conn *conn, u8_t type,
struct net_buf_simple *msg)
{
struct bt_mesh_proxy_server *server = find_server(conn);
if (!server) {
BT_ERR("$%s, No Proxy Server found", __func__);
return -ENOTCONN;
}
if ((server->filter_type == PROV) != (type == BLE_MESH_PROXY_PROV)) {
BT_ERR("%s, Invalid PDU type for Proxy Client", __func__);
return -EINVAL;
}
return proxy_prov_segment_and_send(conn, type, msg);
}
static struct bt_mesh_prov_conn_cb conn_callbacks = {
.connected = proxy_prov_connected,
.disconnected = proxy_prov_disconnected,
#if defined(CONFIG_BLE_MESH_PB_GATT)
.prov_write_descr = prov_write_ccc_descr,
.prov_notify = prov_notification,
#endif /* CONFIG_BLE_MESH_PB_GATT */
#if defined(CONFIG_BLE_MESH_GATT_PROXY)
.proxy_write_descr = proxy_write_ccc_descr,
.proxy_notify = proxy_notification,
#endif /* CONFIG_BLE_MESH_GATT_PROXY */
};
void provisioner_proxy_srv_data_recv(struct net_buf_simple *buf)
{
/** TODO: Parse node_id_adv or net_id_adv pkts. Currently we
* don't support this function, and if realized later, proxy
* client need to check if there is server structure left
* before create connection with a server.
* check conn_count & CONFIG_BLE_MESH_PBG_SAME_TIME
*/
}
int provisioner_proxy_init(void)
{
int i;
/* Initialize the server receive buffers */
for (i = 0; i < ARRAY_SIZE(servers); i++) {
struct bt_mesh_proxy_server *server = &servers[i];
server->buf.size = SERVER_BUF_SIZE;
server->buf.__buf = server_buf_data + (i * SERVER_BUF_SIZE);
}
bt_mesh_gattc_conn_cb_register(&conn_callbacks);
return 0;
}
#endif /* CONFIG_BLE_MESH_PROVISIONER */

View File

@ -0,0 +1,89 @@
// 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_PROXY_H_
#define _PROVISIONER_PROXY_H_
#include "mesh_buf.h"
#define BLE_MESH_PROXY_NET_PDU 0x00
#define BLE_MESH_PROXY_BEACON 0x01
#define BLE_MESH_PROXY_CONFIG 0x02
#define BLE_MESH_PROXY_PROV 0x03
/**
* @brief This function is called to send proxy protocol messages.
*
* @param[in] conn: Pointer to bt_conn structure
* @param[in] type: Proxy protocol message type
* @param[in] msg: Pointer to the buffer contains sending message.
*
* @return Zero-success, other-fail
*/
int provisioner_proxy_send(struct bt_mesh_conn *conn, u8_t type, struct net_buf_simple *msg);
/**
* @brief This function is called to parse received node identity and net
* id adv pkts and create connection if deceided to.
*
* @param[in] buf: Pointer to the buffer contains received message.
*
* @return None
*/
void provisioner_proxy_srv_data_recv(struct net_buf_simple *buf);
/**
* @brief This function is called to initialize proxy provisioner structure
* and register proxy connection related callbacks.
*
* @return Zero-success, other-fail
*/
int provisioner_proxy_init(void);
/**
* @brief This function is called to enable dealing with proxy provisioning
* messages.
*
* @return Zero-success, other-fail
*/
int provisioner_pb_gatt_enable(void);
/**
* @brief This function is called to disable dealing with proxy provisioning
* messages and if proxy provisioning connections exist, the connections
* will be disconnected.
*
* @return Zero-success, other-fail
*/
int provisioner_pb_gatt_disable(void);
/* The following APIs are for application use */
/**
* @brief This function is called to enable receiving node identity and net
* id adv pkts.
*
* @return Zero-success, other-fail
*/
int bt_mesh_provisioner_proxy_enable(void);
/**
* @brief This function is called to disable receiving node identity and net
* id adv pkts, and if proxy connections exist, these connections will
* be disconnected.
*
* @return Zero-success, other-fail
*/
int bt_mesh_provisioner_proxy_disable(void);
#endif /* _PROVISIONER_PROXY_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _PROXY_H_
#define _PROXY_H_
#include "net.h"
#include "mesh_buf.h"
#include "mesh_bearer_adapt.h"
#define BLE_MESH_PROXY_NET_PDU 0x00
#define BLE_MESH_PROXY_BEACON 0x01
#define BLE_MESH_PROXY_CONFIG 0x02
#define BLE_MESH_PROXY_PROV 0x03
#define DEVICE_NAME_SIZE 29
int bt_mesh_set_device_name(const char *name);
int bt_mesh_proxy_send(struct bt_mesh_conn *conn, u8_t type,
struct net_buf_simple *msg);
int bt_mesh_proxy_prov_enable(void);
int bt_mesh_proxy_prov_disable(bool disconnect);
int bt_mesh_proxy_gatt_enable(void);
int bt_mesh_proxy_gatt_disable(void);
void bt_mesh_proxy_gatt_disconnect(void);
void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub);
struct net_buf_simple *bt_mesh_proxy_get_buf(void);
s32_t bt_mesh_proxy_adv_start(void);
void bt_mesh_proxy_adv_stop(void);
void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub);
void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub);
bool bt_mesh_proxy_relay(struct net_buf_simple *buf, u16_t dst);
void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, u16_t addr);
int bt_mesh_proxy_init(void);
#endif /* _PROXY_H_ */

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