1*042d53a7SEvalZero /* Bluetooth Mesh */ 2*042d53a7SEvalZero 3*042d53a7SEvalZero /* 4*042d53a7SEvalZero * Copyright (c) 2017 Intel Corporation 5*042d53a7SEvalZero * 6*042d53a7SEvalZero * SPDX-License-Identifier: Apache-2.0 7*042d53a7SEvalZero */ 8*042d53a7SEvalZero 9*042d53a7SEvalZero #ifndef __NET_H__ 10*042d53a7SEvalZero #define __NET_H__ 11*042d53a7SEvalZero 12*042d53a7SEvalZero #define BT_MESH_NET_FLAG_KR BIT(0) 13*042d53a7SEvalZero #define BT_MESH_NET_FLAG_IVU BIT(1) 14*042d53a7SEvalZero 15*042d53a7SEvalZero #define BT_MESH_KR_NORMAL 0x00 16*042d53a7SEvalZero #define BT_MESH_KR_PHASE_1 0x01 17*042d53a7SEvalZero #define BT_MESH_KR_PHASE_2 0x02 18*042d53a7SEvalZero #define BT_MESH_KR_PHASE_3 0x03 19*042d53a7SEvalZero 20*042d53a7SEvalZero #define BT_MESH_IV_UPDATE(flags) ((flags >> 1) & 0x01) 21*042d53a7SEvalZero #define BT_MESH_KEY_REFRESH(flags) (flags & 0x01) 22*042d53a7SEvalZero 23*042d53a7SEvalZero #include <stdbool.h> 24*042d53a7SEvalZero #include "atomic.h" 25*042d53a7SEvalZero #include "mesh/mesh.h" 26*042d53a7SEvalZero #include "mesh/glue.h" 27*042d53a7SEvalZero 28*042d53a7SEvalZero /* How many hours in between updating IVU duration */ 29*042d53a7SEvalZero #define BT_MESH_IVU_MIN_HOURS 96 30*042d53a7SEvalZero #define BT_MESH_IVU_HOURS (BT_MESH_IVU_MIN_HOURS / \ 31*042d53a7SEvalZero CONFIG_BT_MESH_IVU_DIVIDER) 32*042d53a7SEvalZero #define BT_MESH_IVU_TIMEOUT K_HOURS(BT_MESH_IVU_HOURS) 33*042d53a7SEvalZero 34*042d53a7SEvalZero struct bt_mesh_app_key { 35*042d53a7SEvalZero u16_t net_idx; 36*042d53a7SEvalZero u16_t app_idx; 37*042d53a7SEvalZero bool updated; 38*042d53a7SEvalZero struct bt_mesh_app_keys { 39*042d53a7SEvalZero u8_t id; 40*042d53a7SEvalZero u8_t val[16]; 41*042d53a7SEvalZero } keys[2]; 42*042d53a7SEvalZero }; 43*042d53a7SEvalZero 44*042d53a7SEvalZero struct bt_mesh_subnet { 45*042d53a7SEvalZero u32_t beacon_sent; /* Timestamp of last sent beacon */ 46*042d53a7SEvalZero u8_t beacons_last; /* Number of beacons during last 47*042d53a7SEvalZero * observation window 48*042d53a7SEvalZero */ 49*042d53a7SEvalZero u8_t beacons_cur; /* Number of beaconds observed during 50*042d53a7SEvalZero * currently ongoing window. 51*042d53a7SEvalZero */ 52*042d53a7SEvalZero 53*042d53a7SEvalZero u8_t beacon_cache[21]; /* Cached last authenticated beacon */ 54*042d53a7SEvalZero 55*042d53a7SEvalZero u16_t net_idx; /* NetKeyIndex */ 56*042d53a7SEvalZero 57*042d53a7SEvalZero bool kr_flag; /* Key Refresh Flag */ 58*042d53a7SEvalZero u8_t kr_phase; /* Key Refresh Phase */ 59*042d53a7SEvalZero 60*042d53a7SEvalZero u8_t node_id; /* Node Identity State */ 61*042d53a7SEvalZero u32_t node_id_start; /* Node Identity started timestamp */ 62*042d53a7SEvalZero 63*042d53a7SEvalZero u8_t auth[8]; /* Beacon Authentication Value */ 64*042d53a7SEvalZero 65*042d53a7SEvalZero struct bt_mesh_subnet_keys { 66*042d53a7SEvalZero u8_t net[16]; /* NetKey */ 67*042d53a7SEvalZero u8_t nid; /* NID */ 68*042d53a7SEvalZero u8_t enc[16]; /* EncKey */ 69*042d53a7SEvalZero u8_t net_id[8]; /* Network ID */ 70*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) 71*042d53a7SEvalZero u8_t identity[16]; /* IdentityKey */ 72*042d53a7SEvalZero #endif 73*042d53a7SEvalZero u8_t privacy[16]; /* PrivacyKey */ 74*042d53a7SEvalZero u8_t beacon[16]; /* BeaconKey */ 75*042d53a7SEvalZero } keys[2]; 76*042d53a7SEvalZero }; 77*042d53a7SEvalZero 78*042d53a7SEvalZero struct bt_mesh_rpl { 79*042d53a7SEvalZero u16_t src; 80*042d53a7SEvalZero bool old_iv; 81*042d53a7SEvalZero #if defined(CONFIG_BT_SETTINGS) 82*042d53a7SEvalZero bool store; 83*042d53a7SEvalZero #endif 84*042d53a7SEvalZero u32_t seq; 85*042d53a7SEvalZero }; 86*042d53a7SEvalZero 87*042d53a7SEvalZero #if MYNEWT_VAL(BLE_MESH_FRIEND) 88*042d53a7SEvalZero #define FRIEND_SEG_RX MYNEWT_VAL(BLE_MESH_FRIEND_SEG_RX) 89*042d53a7SEvalZero #define FRIEND_SUB_LIST_SIZE MYNEWT_VAL(BLE_MESH_FRIEND_SUB_LIST_SIZE) 90*042d53a7SEvalZero #else 91*042d53a7SEvalZero #define FRIEND_SEG_RX 0 92*042d53a7SEvalZero #define FRIEND_SUB_LIST_SIZE 0 93*042d53a7SEvalZero #endif 94*042d53a7SEvalZero 95*042d53a7SEvalZero struct bt_mesh_friend { 96*042d53a7SEvalZero u16_t lpn; 97*042d53a7SEvalZero u8_t recv_delay; 98*042d53a7SEvalZero u8_t fsn:1, 99*042d53a7SEvalZero send_last:1, 100*042d53a7SEvalZero pending_req:1, 101*042d53a7SEvalZero sec_update:1, 102*042d53a7SEvalZero pending_buf:1, 103*042d53a7SEvalZero valid:1, 104*042d53a7SEvalZero established:1; 105*042d53a7SEvalZero s32_t poll_to; 106*042d53a7SEvalZero u16_t lpn_counter; 107*042d53a7SEvalZero u16_t counter; 108*042d53a7SEvalZero 109*042d53a7SEvalZero u16_t net_idx; 110*042d53a7SEvalZero 111*042d53a7SEvalZero u16_t sub_list[FRIEND_SUB_LIST_SIZE]; 112*042d53a7SEvalZero 113*042d53a7SEvalZero struct k_delayed_work timer; 114*042d53a7SEvalZero 115*042d53a7SEvalZero struct bt_mesh_friend_seg { 116*042d53a7SEvalZero struct net_buf_slist_t queue; 117*042d53a7SEvalZero } seg[FRIEND_SEG_RX]; 118*042d53a7SEvalZero 119*042d53a7SEvalZero struct os_mbuf *last; 120*042d53a7SEvalZero 121*042d53a7SEvalZero struct net_buf_slist_t queue; 122*042d53a7SEvalZero u32_t queue_size; 123*042d53a7SEvalZero 124*042d53a7SEvalZero /* Friend Clear Procedure */ 125*042d53a7SEvalZero struct { 126*042d53a7SEvalZero u32_t start; /* Clear Procedure start */ 127*042d53a7SEvalZero u16_t frnd; /* Previous Friend's address */ 128*042d53a7SEvalZero u16_t repeat_sec; /* Repeat timeout in seconds */ 129*042d53a7SEvalZero struct k_delayed_work timer; /* Repeat timer */ 130*042d53a7SEvalZero } clear; 131*042d53a7SEvalZero }; 132*042d53a7SEvalZero 133*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) 134*042d53a7SEvalZero #define LPN_GROUPS CONFIG_BT_MESH_LPN_GROUPS 135*042d53a7SEvalZero #else 136*042d53a7SEvalZero #define LPN_GROUPS 0 137*042d53a7SEvalZero #endif 138*042d53a7SEvalZero 139*042d53a7SEvalZero /* Low Power Node state */ 140*042d53a7SEvalZero struct bt_mesh_lpn { 141*042d53a7SEvalZero enum __packed { 142*042d53a7SEvalZero BT_MESH_LPN_DISABLED, /* LPN feature is disabled */ 143*042d53a7SEvalZero BT_MESH_LPN_CLEAR, /* Clear in progress */ 144*042d53a7SEvalZero BT_MESH_LPN_TIMER, /* Waiting for auto timer expiry */ 145*042d53a7SEvalZero BT_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */ 146*042d53a7SEvalZero BT_MESH_LPN_REQ_WAIT, /* Wait before scanning for offers */ 147*042d53a7SEvalZero BT_MESH_LPN_WAIT_OFFER, /* Friend Req sent */ 148*042d53a7SEvalZero BT_MESH_LPN_ESTABLISHED, /* Friendship established */ 149*042d53a7SEvalZero BT_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */ 150*042d53a7SEvalZero BT_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */ 151*042d53a7SEvalZero } state; 152*042d53a7SEvalZero 153*042d53a7SEvalZero /* Transaction Number (used for subscription list) */ 154*042d53a7SEvalZero u8_t xact_next; 155*042d53a7SEvalZero u8_t xact_pending; 156*042d53a7SEvalZero u8_t sent_req; 157*042d53a7SEvalZero 158*042d53a7SEvalZero /* Address of our Friend when we're a LPN. Unassigned if we don't 159*042d53a7SEvalZero * have a friend yet. 160*042d53a7SEvalZero */ 161*042d53a7SEvalZero u16_t frnd; 162*042d53a7SEvalZero 163*042d53a7SEvalZero /* Value from the friend offer */ 164*042d53a7SEvalZero u8_t recv_win; 165*042d53a7SEvalZero 166*042d53a7SEvalZero u8_t req_attempts; /* Number of Request attempts */ 167*042d53a7SEvalZero 168*042d53a7SEvalZero s32_t poll_timeout; 169*042d53a7SEvalZero 170*042d53a7SEvalZero u8_t groups_changed:1, /* Friend Subscription List needs updating */ 171*042d53a7SEvalZero pending_poll:1, /* Poll to be sent after subscription */ 172*042d53a7SEvalZero disable:1, /* Disable LPN after clearing */ 173*042d53a7SEvalZero fsn:1, /* Friend Sequence Number */ 174*042d53a7SEvalZero established:1, /* Friendship established */ 175*042d53a7SEvalZero clear_success:1; /* Friend Clear Confirm received */ 176*042d53a7SEvalZero 177*042d53a7SEvalZero /* Friend Queue Size */ 178*042d53a7SEvalZero u8_t queue_size; 179*042d53a7SEvalZero 180*042d53a7SEvalZero /* LPNCounter */ 181*042d53a7SEvalZero u16_t counter; 182*042d53a7SEvalZero 183*042d53a7SEvalZero /* Previous Friend of this LPN */ 184*042d53a7SEvalZero u16_t old_friend; 185*042d53a7SEvalZero 186*042d53a7SEvalZero /* Duration reported for last advertising packet */ 187*042d53a7SEvalZero u16_t adv_duration; 188*042d53a7SEvalZero 189*042d53a7SEvalZero /* Next LPN related action timer */ 190*042d53a7SEvalZero struct k_delayed_work timer; 191*042d53a7SEvalZero 192*042d53a7SEvalZero /* Subscribed groups */ 193*042d53a7SEvalZero u16_t groups[LPN_GROUPS]; 194*042d53a7SEvalZero 195*042d53a7SEvalZero /* Bit fields for tracking which groups the Friend knows about */ 196*042d53a7SEvalZero ATOMIC_DEFINE(added, LPN_GROUPS); 197*042d53a7SEvalZero ATOMIC_DEFINE(pending, LPN_GROUPS); 198*042d53a7SEvalZero ATOMIC_DEFINE(to_remove, LPN_GROUPS); 199*042d53a7SEvalZero }; 200*042d53a7SEvalZero 201*042d53a7SEvalZero /* bt_mesh_net.flags, mainly used for pending storage actions */ 202*042d53a7SEvalZero enum { 203*042d53a7SEvalZero BT_MESH_RPL_PENDING, 204*042d53a7SEvalZero BT_MESH_KEYS_PENDING, 205*042d53a7SEvalZero BT_MESH_NET_PENDING, 206*042d53a7SEvalZero BT_MESH_IV_PENDING, 207*042d53a7SEvalZero BT_MESH_SEQ_PENDING, 208*042d53a7SEvalZero BT_MESH_HB_PUB_PENDING, 209*042d53a7SEvalZero BT_MESH_CFG_PENDING, 210*042d53a7SEvalZero BT_MESH_MOD_PENDING, 211*042d53a7SEvalZero 212*042d53a7SEvalZero /* Don't touch - intentionally last */ 213*042d53a7SEvalZero BT_MESH_FLAG_COUNT, 214*042d53a7SEvalZero }; 215*042d53a7SEvalZero 216*042d53a7SEvalZero struct bt_mesh_net { 217*042d53a7SEvalZero u32_t iv_index; /* Current IV Index */ 218*042d53a7SEvalZero u32_t seq:24, /* Next outgoing sequence number */ 219*042d53a7SEvalZero iv_update:1, /* 1 if IV Update in Progress */ 220*042d53a7SEvalZero ivu_initiator:1, /* IV Update initiated by us */ 221*042d53a7SEvalZero ivu_test:1, /* IV Update test mode */ 222*042d53a7SEvalZero pending_update:1, /* Update blocked by SDU in progress */ 223*042d53a7SEvalZero valid:1; /* 0 if unused */ 224*042d53a7SEvalZero 225*042d53a7SEvalZero ATOMIC_DEFINE(flags, BT_MESH_FLAG_COUNT); 226*042d53a7SEvalZero 227*042d53a7SEvalZero /* Local network interface */ 228*042d53a7SEvalZero struct ble_npl_callout local_work; 229*042d53a7SEvalZero struct net_buf_slist_t local_queue; 230*042d53a7SEvalZero 231*042d53a7SEvalZero #if MYNEWT_VAL(BLE_MESH_FRIEND) 232*042d53a7SEvalZero /* Friend state, unique for each LPN that we're Friends for */ 233*042d53a7SEvalZero struct bt_mesh_friend frnd[MYNEWT_VAL(BLE_MESH_FRIEND_LPN_COUNT)]; 234*042d53a7SEvalZero #endif 235*042d53a7SEvalZero 236*042d53a7SEvalZero #if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) 237*042d53a7SEvalZero struct bt_mesh_lpn lpn; /* Low Power Node state */ 238*042d53a7SEvalZero #endif 239*042d53a7SEvalZero 240*042d53a7SEvalZero /* Number of hours in current IV Update state */ 241*042d53a7SEvalZero u8_t ivu_duration; 242*042d53a7SEvalZero 243*042d53a7SEvalZero /* Timer to track duration in current IV Update state */ 244*042d53a7SEvalZero struct k_delayed_work ivu_timer; 245*042d53a7SEvalZero 246*042d53a7SEvalZero u8_t dev_key[16]; 247*042d53a7SEvalZero 248*042d53a7SEvalZero struct bt_mesh_app_key app_keys[MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT)]; 249*042d53a7SEvalZero 250*042d53a7SEvalZero struct bt_mesh_subnet sub[MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)]; 251*042d53a7SEvalZero 252*042d53a7SEvalZero struct bt_mesh_rpl rpl[MYNEWT_VAL(BLE_MESH_CRPL)]; 253*042d53a7SEvalZero }; 254*042d53a7SEvalZero 255*042d53a7SEvalZero /* Network interface */ 256*042d53a7SEvalZero enum bt_mesh_net_if { 257*042d53a7SEvalZero BT_MESH_NET_IF_ADV, 258*042d53a7SEvalZero BT_MESH_NET_IF_LOCAL, 259*042d53a7SEvalZero BT_MESH_NET_IF_PROXY, 260*042d53a7SEvalZero BT_MESH_NET_IF_PROXY_CFG, 261*042d53a7SEvalZero }; 262*042d53a7SEvalZero 263*042d53a7SEvalZero /* Decoding context for Network/Transport data */ 264*042d53a7SEvalZero struct bt_mesh_net_rx { 265*042d53a7SEvalZero struct bt_mesh_subnet *sub; 266*042d53a7SEvalZero struct bt_mesh_msg_ctx ctx; 267*042d53a7SEvalZero u32_t seq; /* Sequence Number */ 268*042d53a7SEvalZero u8_t old_iv:1, /* iv_index - 1 was used */ 269*042d53a7SEvalZero new_key:1, /* Data was encrypted with updated key */ 270*042d53a7SEvalZero friend_cred:1, /* Data was encrypted with friend cred */ 271*042d53a7SEvalZero ctl:1, /* Network Control */ 272*042d53a7SEvalZero net_if:2, /* Network interface */ 273*042d53a7SEvalZero local_match:1, /* Matched a local element */ 274*042d53a7SEvalZero friend_match:1; /* Matched an LPN we're friends for */ 275*042d53a7SEvalZero s8_t rssi; 276*042d53a7SEvalZero }; 277*042d53a7SEvalZero 278*042d53a7SEvalZero /* Encoding context for Network/Transport data */ 279*042d53a7SEvalZero struct bt_mesh_net_tx { 280*042d53a7SEvalZero struct bt_mesh_subnet *sub; 281*042d53a7SEvalZero struct bt_mesh_msg_ctx *ctx; 282*042d53a7SEvalZero u16_t src; 283*042d53a7SEvalZero u8_t xmit; 284*042d53a7SEvalZero u8_t friend_cred:1, 285*042d53a7SEvalZero aszmic:1, 286*042d53a7SEvalZero aid:6; 287*042d53a7SEvalZero }; 288*042d53a7SEvalZero 289*042d53a7SEvalZero extern struct bt_mesh_net bt_mesh; 290*042d53a7SEvalZero 291*042d53a7SEvalZero #define BT_MESH_NET_IVI_TX (bt_mesh.iv_index - bt_mesh.iv_update) 292*042d53a7SEvalZero #define BT_MESH_NET_IVI_RX(rx) (bt_mesh.iv_index - (rx)->old_iv) 293*042d53a7SEvalZero 294*042d53a7SEvalZero #define BT_MESH_NET_HDR_LEN 9 295*042d53a7SEvalZero 296*042d53a7SEvalZero int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, 297*042d53a7SEvalZero const u8_t key[16]); 298*042d53a7SEvalZero 299*042d53a7SEvalZero int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16], 300*042d53a7SEvalZero u32_t iv_index); 301*042d53a7SEvalZero 302*042d53a7SEvalZero u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub); 303*042d53a7SEvalZero 304*042d53a7SEvalZero bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key); 305*042d53a7SEvalZero 306*042d53a7SEvalZero void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub); 307*042d53a7SEvalZero 308*042d53a7SEvalZero int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub); 309*042d53a7SEvalZero 310*042d53a7SEvalZero void bt_mesh_rpl_reset(void); 311*042d53a7SEvalZero 312*042d53a7SEvalZero bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update); 313*042d53a7SEvalZero 314*042d53a7SEvalZero void bt_mesh_net_sec_update(struct bt_mesh_subnet *sub); 315*042d53a7SEvalZero 316*042d53a7SEvalZero struct bt_mesh_subnet *bt_mesh_subnet_get(u16_t net_idx); 317*042d53a7SEvalZero 318*042d53a7SEvalZero struct bt_mesh_subnet *bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags, 319*042d53a7SEvalZero u32_t iv_index, const u8_t auth[8], 320*042d53a7SEvalZero bool *new_key); 321*042d53a7SEvalZero 322*042d53a7SEvalZero int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, 323*042d53a7SEvalZero bool proxy); 324*042d53a7SEvalZero 325*042d53a7SEvalZero int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, 326*042d53a7SEvalZero const struct bt_mesh_send_cb *cb, void *cb_data); 327*042d53a7SEvalZero 328*042d53a7SEvalZero int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf, 329*042d53a7SEvalZero bool new_key, const struct bt_mesh_send_cb *cb, 330*042d53a7SEvalZero void *cb_data); 331*042d53a7SEvalZero 332*042d53a7SEvalZero int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if, 333*042d53a7SEvalZero struct bt_mesh_net_rx *rx, struct os_mbuf *buf); 334*042d53a7SEvalZero 335*042d53a7SEvalZero void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi, 336*042d53a7SEvalZero enum bt_mesh_net_if net_if); 337*042d53a7SEvalZero 338*042d53a7SEvalZero u32_t bt_mesh_next_seq(void); 339*042d53a7SEvalZero 340*042d53a7SEvalZero void bt_mesh_net_start(void); 341*042d53a7SEvalZero 342*042d53a7SEvalZero void bt_mesh_net_init(void); 343*042d53a7SEvalZero 344*042d53a7SEvalZero /* Friendship Credential Management */ 345*042d53a7SEvalZero struct friend_cred { 346*042d53a7SEvalZero u16_t net_idx; 347*042d53a7SEvalZero u16_t addr; 348*042d53a7SEvalZero 349*042d53a7SEvalZero u16_t lpn_counter; 350*042d53a7SEvalZero u16_t frnd_counter; 351*042d53a7SEvalZero 352*042d53a7SEvalZero struct { 353*042d53a7SEvalZero u8_t nid; /* NID */ 354*042d53a7SEvalZero u8_t enc[16]; /* EncKey */ 355*042d53a7SEvalZero u8_t privacy[16]; /* PrivacyKey */ 356*042d53a7SEvalZero } cred[2]; 357*042d53a7SEvalZero }; 358*042d53a7SEvalZero 359*042d53a7SEvalZero int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid, 360*042d53a7SEvalZero const u8_t **enc, const u8_t **priv); 361*042d53a7SEvalZero int friend_cred_set(struct friend_cred *cred, u8_t idx, const u8_t net_key[16]); 362*042d53a7SEvalZero void friend_cred_refresh(u16_t net_idx); 363*042d53a7SEvalZero int friend_cred_update(struct bt_mesh_subnet *sub); 364*042d53a7SEvalZero struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr, 365*042d53a7SEvalZero u16_t lpn_counter, u16_t frnd_counter); 366*042d53a7SEvalZero void friend_cred_clear(struct friend_cred *cred); 367*042d53a7SEvalZero int friend_cred_del(u16_t net_idx, u16_t addr); 368*042d53a7SEvalZero 369*042d53a7SEvalZero #endif 370