xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/mesh/src/net.h (revision 042d53a763ad75cb1465103098bb88c245d95138)
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