zephyr/include/bluetooth/mesh.h
Johan Hedberg 8d0ef1eb85 Bluetooth: Mesh: Fix setting health period divider
A previous patch which moved dispatching the health publish callback
to a later moment introduced a regression where the period divider
does not get updated when it should. In fact, having the divider as
part of the Health Server context is redundant, since the same
information is already stored generically in the model publication
context. Switching to using the model publication context makes things
simpler and ensures that the value is always up-to-date.

With this patch it is possible to pass MESH/SR/HM/CFS/BV-02-C.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2017-09-29 13:21:40 +03:00

574 lines
17 KiB
C

/** @file
* @brief Bluetooth Mesh Profile APIs.
*/
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_MESH_H
#define __BT_MESH_H
#include <zephyr/types.h>
#include <stddef.h>
#include <net/buf.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);
/**
* @}
*/
/**
* @brief Bluetooth Mesh Composition
* @defgroup bt_comp Bluetooth Mesh Composition
* @ingroup bt_mesh
* @{
*/
#define BT_MESH_ADDR_UNASSIGNED 0x0000
#define BT_MESH_ADDR_ALL_NODES 0xffff
#define BT_MESH_ADDR_PROXIES 0xfffc
#define BT_MESH_ADDR_FRIENDS 0xfffd
#define BT_MESH_ADDR_RELAYS 0xfffe
#define BT_MESH_KEY_UNUSED 0xffff
#define BT_MESH_KEY_DEV 0xfffe
/**
* @brief Bluetooth Mesh Element
* @defgroup bt_mesh_elem Bluetooth Mesh Element
* @ingroup bt_comp
* @{
*/
/** Helper to define a mesh element within an array.
*
* @param _loc Location Descriptor.
* @param _mods Array of models
* @param _vnd_mods Array of vendor models.
*/
#define BT_MESH_ELEM(_loc, _mods, _vnd_mods) \
{ \
.loc = (_loc), \
.model_count = ARRAY_SIZE(_mods), \
.models = (_mods), \
.vnd_model_count = ARRAY_SIZE(_vnd_mods), \
.vnd_models = (_vnd_mods), \
}
/** Abstraction that describes a Mesh Element */
struct bt_mesh_elem {
/* Unicast Address. Set at runtime during provisioning. */
u16_t addr;
/* Location Descriptor (GATT Bluetooth Namespace Descriptors) */
const u16_t loc;
const u8_t model_count;
const u8_t vnd_model_count;
struct bt_mesh_model * const models;
struct bt_mesh_model * const vnd_models;
};
/**
* @}
*/
/**
* @brief Bluetooth Mesh Model
* @defgroup bt_mesh_model Bluetooth Mesh Model
* @ingroup bt_comp
* @{
*/
/* Foundation Models */
#define BT_MESH_MODEL_ID_CFG_SRV 0x0000
#define BT_MESH_MODEL_ID_CFG_CLI 0x0001
#define BT_MESH_MODEL_ID_HEALTH_SRV 0x0002
#define BT_MESH_MODEL_ID_HEALTH_CLI 0x0003
/* Models from the Mesh Model Specification */
#define BT_MESH_MODEL_ID_GEN_ONOFF_SRV 0x1000
#define BT_MESH_MODEL_ID_GEN_ONOFF_CLI 0x1001
#define BT_MESH_MODEL_ID_GEN_LEVEL_SRV 0x1002
#define BT_MESH_MODEL_ID_GEN_LEVEL_CLI 0x1003
#define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV 0x1004
#define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI 0x1005
#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV 0x1006
#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV 0x1007
#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI 0x1008
#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV 0x1009
#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV 0x100a
#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI 0x100b
#define BT_MESH_MODEL_ID_GEN_BATTERY_SRV 0x100c
#define BT_MESH_MODEL_ID_GEN_BATTERY_CLI 0x100d
#define BT_MESH_MODEL_ID_GEN_LOCATION_SRV 0x100e
#define BT_MESH_MODEL_ID_GEN_LOCATION_SETUPSRV 0x100f
#define BT_MESH_MODEL_ID_GEN_LOCATION_CLI 0x1010
#define BT_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV 0x1011
#define BT_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV 0x1012
#define BT_MESH_MODEL_ID_GEN_USER_PROP_SRV 0x1013
#define BT_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV 0x1014
#define BT_MESH_MODEL_ID_GEN_PROP_CLI 0x1015
#define BT_MESH_MODEL_ID_SENSOR_SRV 0x1100
#define BT_MESH_MODEL_ID_SENSOR_SETUP_SRV 0x1101
#define BT_MESH_MODEL_ID_SENSOR_CLI 0x1102
#define BT_MESH_MODEL_ID_TIME_SRV 0x1200
#define BT_MESH_MODEL_ID_TIME_SETUP_SRV 0x1201
#define BT_MESH_MODEL_ID_TIME_CLI 0x1202
#define BT_MESH_MODEL_ID_SCENE_SRV 0x1203
#define BT_MESH_MODEL_ID_SCENE_SETUP_SRV 0x1204
#define BT_MESH_MODEL_ID_SCENE_CLI 0x1205
#define BT_MESH_MODEL_ID_SCHEDULER_SRV 0x1206
#define BT_MESH_MODEL_ID_SCHEDULER_SETUP_SRV 0x1207
#define BT_MESH_MODEL_ID_SCHEDULER_CLI 0x1208
#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV 0x1300
#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV 0x1301
#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI 0x1302
#define BT_MESH_MODEL_ID_LIGHT_CTL_SRV 0x1303
#define BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV 0x1304
#define BT_MESH_MODEL_ID_LIGHT_CTL_CLI 0x1305
#define BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV 0x1306
#define BT_MESH_MODEL_ID_LIGHT_HSL_SRV 0x1307
#define BT_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV 0x1308
#define BT_MESH_MODEL_ID_LIGHT_HSL_CLI 0x1309
#define BT_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV 0x130a
#define BT_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV 0x130b
#define BT_MESH_MODEL_ID_LIGHT_XYL_SRV 0x130c
#define BT_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV 0x130d
#define BT_MESH_MODEL_ID_LIGHT_XYL_CLI 0x130e
#define BT_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f
#define BT_MESH_MODEL_ID_LIGHT_LC_SETUPSRV 0x1310
#define BT_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311
/** Message sending context. */
struct bt_mesh_msg_ctx {
/** NetKey Index of the subnet to send the message on. */
u16_t net_idx;
/** AppKey Index to encrypt the message with. */
u16_t app_idx;
/** Remote address. */
u16_t addr;
/** Received TTL value. Not used for sending. */
u8_t recv_ttl:7;
/** Whether friend credentials are used. */
u8_t friend_cred:1;
/** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */
u8_t send_ttl;
};
struct bt_mesh_model_op {
/* OpCode encoded using the BT_MESH_MODEL_OP_* macros */
const u32_t opcode;
/* Minimum required message length */
const size_t min_len;
/* Message handler for the opcode */
void (*const func)(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf);
};
#define BT_MESH_MODEL_OP_1(b0) (b0)
#define BT_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1))
#define BT_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid))
#define BT_MESH_MODEL_OP_END { 0, 0, NULL }
#define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \
{ BT_MESH_MODEL_OP_END })
/** Helper to define an empty model array */
#define BT_MESH_MODEL_EMPTY ((struct bt_mesh_model []){})
#define BT_MESH_MODEL(_id, _op, _pub, _user_data) \
{ \
.id = (_id), \
.op = _op, \
.keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] = \
BT_MESH_KEY_UNUSED }, \
.pub = _pub, \
.groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] = \
BT_MESH_ADDR_UNASSIGNED }, \
.user_data = _user_data, \
}
#define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \
{ \
.vnd.company = (_company), \
.vnd.id = (_id), \
.op = _op, \
.pub = _pub, \
.keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] = \
BT_MESH_KEY_UNUSED }, \
.groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] = \
BT_MESH_ADDR_UNASSIGNED }, \
.user_data = _user_data, \
}
/** Mesh Configuration Server Model Context */
struct bt_mesh_cfg {
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 {
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 {
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_op[];
#define BT_MESH_MODEL_CFG_SRV(srv_data) \
BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_SRV, \
bt_mesh_cfg_op, NULL, srv_data)
/** @def BT_MESH_TRANSMIT
*
* @brief Encode transmission count & interval steps.
*
* @param count Number of retransmissions (first transmission is excluded).
* @param int_ms Interval steps in milliseconds. Must be greater than 0
* and a multiple of 10.
*
* @return Mesh transmit value that can be used e.g. for the default
* values of the configuration model data.
*/
#define BT_MESH_TRANSMIT(count, int_ms) ((count) | (((int_ms / 10) - 1) << 3))
/** Mesh Health Server Model Context */
struct bt_mesh_health {
struct bt_mesh_model *model;
/* 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 Timer state */
struct {
struct k_delayed_work timer;
void (*on)(struct bt_mesh_model *model);
void (*off)(struct bt_mesh_model *model);
} attention;
};
int bt_mesh_fault_update(struct bt_mesh_elem *elem);
extern const struct bt_mesh_model_op bt_mesh_health_op[];
extern struct bt_mesh_model_pub bt_mesh_health_pub;
#define BT_MESH_MODEL_HEALTH_SRV(srv_data) \
BT_MESH_MODEL(BT_MESH_MODEL_ID_HEALTH_SRV, \
bt_mesh_health_op, &bt_mesh_health_pub, \
srv_data)
struct bt_mesh_model_pub {
/* Self-reference for easy lookup */
struct bt_mesh_model *mod;
u16_t addr; /* Publish Address */
u16_t key; /* Publish AppKey Index */
u32_t ttl:8, /* Publish Time to Live */
retransmit:8, /* Retransmit Count & Interval Steps */
period:8, /* Publish Period */
period_div:4, /* Divisor for the Period */
cred:1; /* Friendship Credentials Flag */
/* Publish callback */
void (*func)(struct bt_mesh_model *mod);
/* Publish Period Timer */
struct k_delayed_work timer;
};
/** Abstraction that describes a Mesh Model instance */
struct bt_mesh_model {
union {
const u16_t id;
struct {
u16_t company;
u16_t id;
} vnd;
};
/* The Element this Model belongs to */
struct bt_mesh_elem *elem;
/* Model Publication */
struct bt_mesh_model_pub * const pub;
/* AppKey List */
u16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT];
/* Subscription List (group or virtual addresses) */
u16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
const struct bt_mesh_model_op * const op;
/* Model-specific user data */
void *user_data;
};
typedef void (*bt_mesh_cb_t)(int err, void *cb_data);
void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode);
/** Special TTL value to request using configured default TTL */
#define BT_MESH_TTL_DEFAULT 0xff
/** Maximum allowed TTL value */
#define BT_MESH_TTL_MAX 0x7f
/**
* @brief Send an Access Layer message.
*
* @param model Mesh (client) Model that the message belongs to.
* @param ctx Message context, includes keys, TTL, etc.
* @param msg Access Layer payload (the actual message to be sent).
* @param cb Optional "message sent" callback.
* @param cb_data User data to be passed to the callback.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_model_send(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *msg, bt_mesh_cb_t cb,
void *cb_data);
/**
* @brief Send a model publication message.
*
* @param model Mesh (client) Model that's publishing the message.
* @param msg Access Layer message to publish.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_model_publish(struct bt_mesh_model *model,
struct net_buf_simple *msg);
/**
* @}
*/
/** Node Composition */
struct bt_mesh_comp {
u16_t cid;
u16_t pid;
u16_t vid;
size_t elem_count;
struct bt_mesh_elem *elem;
};
/**
* @}
*/
/**
* @brief Bluetooth Mesh Provisioning
* @defgroup bt_mesh_prov Bluetooth Mesh Provisioning
* @ingroup bt_mesh
* @{
*/
typedef enum {
BT_MESH_NO_OUTPUT = 0,
BT_MESH_BLINK = BIT(0),
BT_MESH_BEEP = BIT(1),
BT_MESH_VIBRATE = BIT(2),
BT_MESH_DISPLAY_NUMBER = BIT(3),
BT_MESH_DISPLAY_STRING = BIT(4),
} bt_mesh_output_action;
typedef enum {
BT_MESH_NO_INPUT = 0,
BT_MESH_PUSH = BIT(0),
BT_MESH_TWIST = BIT(1),
BT_MESH_ENTER_NUMBER = BIT(2),
BT_MESH_ENTER_STRING = BIT(3),
} bt_mesh_input_action;
struct bt_mesh_prov {
const u8_t *uuid;
u8_t *static_val;
u8_t static_val_len;
u8_t output_size;
u16_t output_actions;
u8_t input_size;
u16_t input_actions;
int (*output_number)(bt_mesh_output_action act, u32_t num);
int (*output_string)(const char *str);
int (*input)(bt_mesh_input_action act, u8_t size);
void (*complete)(void);
};
int bt_mesh_input_string(const char *str);
int bt_mesh_input_number(u32_t num);
/**
* @}
*/
/**
* @brief Bluetooth Mesh
* @defgroup bt_mesh Bluetooth Mesh
* @ingroup bluetooth
* @{
*/
/* Primary Network Key index */
#define BT_MESH_NET_PRIMARY 0x000
#define BT_MESH_RELAY_DISABLED 0x00
#define BT_MESH_RELAY_ENABLED 0x01
#define BT_MESH_RELAY_NOT_SUPPORTED 0x02
#define BT_MESH_BEACON_DISABLED 0x00
#define BT_MESH_BEACON_ENABLED 0x01
#define BT_MESH_GATT_PROXY_DISABLED 0x00
#define BT_MESH_GATT_PROXY_ENABLED 0x01
#define BT_MESH_GATT_PROXY_NOT_SUPPORTED 0x02
#define BT_MESH_FRIEND_DISABLED 0x00
#define BT_MESH_FRIEND_ENABLED 0x01
#define BT_MESH_FRIEND_NOT_SUPPORTED 0x02
#define BT_MESH_NODE_IDENTITY_STOPPED 0x00
#define BT_MESH_NODE_IDENTITY_RUNNING 0x01
#define BT_MESH_NODE_IDENTITY_NOT_SUPPORTED 0x02
/* Features */
#define BT_MESH_FEAT_RELAY BIT(0)
#define BT_MESH_FEAT_PROXY BIT(1)
#define BT_MESH_FEAT_FRIEND BIT(2)
#define BT_MESH_FEAT_LOW_POWER BIT(3)
/** @brief Initialize Mesh support
*
* @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 in turn causes it to start sending
* out unprovisioned beacons.
*/
void bt_mesh_reset(void);
/** @brief Provision the local Mesh Node.
*
* This API should normally not be used directly by the application. The
* only exception is for testing purposes where manual provisioning is
* desired without an actual external provisioner.
*
* @param net_key Network Key
* @param net_idx Network Key Index
* @param flags Provisioning Flags
* @param iv_index IV Index
* @param seq Sequence Number (0 if newly provisioned).
* @param addr Primary element address
* @param dev_key Device Key
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
u8_t flags, u32_t iv_index, u32_t seq,
u16_t addr, const u8_t dev_key[16]);
/** @brief Toggle the 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);
/**
* @}
*/
#endif /* __BT_MESH_H */