lpn.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138
  1. /* Bluetooth Mesh */
  2. /*
  3. * SPDX-FileCopyrightText: 2017 Intel Corporation
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. */
  7. #include <stdint.h>
  8. #include <errno.h>
  9. #include "crypto.h"
  10. #include "adv.h"
  11. #include "scan.h"
  12. #include "mesh.h"
  13. #include "transport.h"
  14. #include "access.h"
  15. #include "beacon.h"
  16. #include "lpn.h"
  17. #include "rpl.h"
  18. #include "foundation.h"
  19. #include "mesh/main.h"
  20. #include "mesh/cfg_srv.h"
  21. #include "heartbeat.h"
  22. #include "mesh_v1.1/utils.h"
  23. #ifdef CONFIG_BLE_MESH_LOW_POWER
  24. #if CONFIG_BLE_MESH_LPN_AUTO
  25. #define LPN_AUTO_TIMEOUT K_SECONDS(CONFIG_BLE_MESH_LPN_AUTO_TIMEOUT)
  26. #else
  27. #define LPN_AUTO_TIMEOUT 0
  28. #endif
  29. #define LPN_RECV_DELAY CONFIG_BLE_MESH_LPN_RECV_DELAY
  30. #define SCAN_LATENCY MIN(CONFIG_BLE_MESH_LPN_SCAN_LATENCY, LPN_RECV_DELAY)
  31. #define FRIEND_REQ_RETRY_TIMEOUT K_SECONDS(CONFIG_BLE_MESH_LPN_RETRY_TIMEOUT)
  32. #define FRIEND_REQ_WAIT K_MSEC(100)
  33. #define FRIEND_REQ_SCAN K_SECONDS(1)
  34. #define FRIEND_REQ_TIMEOUT (FRIEND_REQ_WAIT + FRIEND_REQ_SCAN)
  35. #define POLL_RETRY_TIMEOUT K_MSEC(100)
  36. #define REQ_RETRY_DURATION(lpn) (4 * (LPN_RECV_DELAY + (lpn)->adv_duration + \
  37. (lpn)->recv_win + POLL_RETRY_TIMEOUT))
  38. #define POLL_TIMEOUT_INIT (CONFIG_BLE_MESH_LPN_INIT_POLL_TIMEOUT * 100)
  39. #define POLL_TIMEOUT_MAX(lpn) ((CONFIG_BLE_MESH_LPN_POLL_TIMEOUT * 100) - \
  40. REQ_RETRY_DURATION(lpn))
  41. /**
  42. * 1. Should use 20 attempts for BQB test case MESH/NODE/FRND/LPM/BI-02-C.
  43. * 2. We should use more specific value for each PollTimeout range.
  44. */
  45. #define REQ_ATTEMPTS(lpn) (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 6)
  46. #define CLEAR_ATTEMPTS 2
  47. #define LPN_CRITERIA ((CONFIG_BLE_MESH_LPN_MIN_QUEUE_SIZE) | \
  48. (CONFIG_BLE_MESH_LPN_RSSI_FACTOR << 3) | \
  49. (CONFIG_BLE_MESH_LPN_RECV_WIN_FACTOR << 5))
  50. #define POLL_TO(to) { (uint8_t)((to) >> 16), (uint8_t)((to) >> 8), (uint8_t)(to) }
  51. #define LPN_POLL_TO POLL_TO(CONFIG_BLE_MESH_LPN_POLL_TIMEOUT)
  52. /* 2 transmissions, 20ms interval */
  53. #define POLL_XMIT BLE_MESH_TRANSMIT(1, 20)
  54. #define FIRST_POLL_ATTEMPTS 6
  55. static void (*lpn_cb)(uint16_t friend_addr, bool established);
  56. #if !CONFIG_BLE_MESH_NO_LOG
  57. static const char *state2str(int state)
  58. {
  59. switch (state) {
  60. case BLE_MESH_LPN_DISABLED:
  61. return "disabled";
  62. case BLE_MESH_LPN_CLEAR:
  63. return "clear";
  64. case BLE_MESH_LPN_TIMER:
  65. return "timer";
  66. case BLE_MESH_LPN_ENABLED:
  67. return "enabled";
  68. case BLE_MESH_LPN_REQ_WAIT:
  69. return "req wait";
  70. case BLE_MESH_LPN_WAIT_OFFER:
  71. return "wait offer";
  72. case BLE_MESH_LPN_ESTABLISHED:
  73. return "established";
  74. case BLE_MESH_LPN_RECV_DELAY:
  75. return "recv delay";
  76. case BLE_MESH_LPN_WAIT_UPDATE:
  77. return "wait update";
  78. case BLE_MESH_LPN_OFFER_RECV:
  79. return "offer recv";
  80. default:
  81. return "(unknown)";
  82. }
  83. }
  84. #endif
  85. static inline void lpn_set_state(int state)
  86. {
  87. BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state));
  88. bt_mesh.lpn.state = state;
  89. }
  90. static inline void group_zero(bt_mesh_atomic_t *target)
  91. {
  92. #if CONFIG_BLE_MESH_LPN_GROUPS > 32
  93. int i;
  94. for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
  95. bt_mesh_atomic_set(&target[i], 0);
  96. }
  97. #else
  98. bt_mesh_atomic_set(target, 0);
  99. #endif
  100. }
  101. static inline void group_set(bt_mesh_atomic_t *target, bt_mesh_atomic_t *source)
  102. {
  103. #if CONFIG_BLE_MESH_LPN_GROUPS > 32
  104. int i;
  105. for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
  106. (void)bt_mesh_atomic_or(&target[i], bt_mesh_atomic_get(&source[i]));
  107. }
  108. #else
  109. (void)bt_mesh_atomic_or(target, bt_mesh_atomic_get(source));
  110. #endif
  111. }
  112. static inline void group_clear(bt_mesh_atomic_t *target, bt_mesh_atomic_t *source)
  113. {
  114. #if CONFIG_BLE_MESH_LPN_GROUPS > 32
  115. int i;
  116. for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
  117. (void)bt_mesh_atomic_and(&target[i], ~bt_mesh_atomic_get(&source[i]));
  118. }
  119. #else
  120. (void)bt_mesh_atomic_and(target, ~bt_mesh_atomic_get(source));
  121. #endif
  122. }
  123. static void clear_friendship(bool force, bool disable);
  124. static bool scan_after_clear;
  125. static void friend_clear_sent(int err, void *user_data)
  126. {
  127. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  128. /* We're switching away from Low Power behavior, so permanently
  129. * enable scanning.
  130. */
  131. if (scan_after_clear == false) {
  132. bt_mesh_scan_enable();
  133. scan_after_clear = true;
  134. }
  135. lpn->req_attempts++;
  136. if (err) {
  137. BT_ERR("Sending Friend Clear failed (err %d)", err);
  138. lpn_set_state(BLE_MESH_LPN_ENABLED);
  139. clear_friendship(false, lpn->disable);
  140. return;
  141. }
  142. lpn_set_state(BLE_MESH_LPN_CLEAR);
  143. k_delayed_work_submit(&lpn->timer, FRIEND_REQ_TIMEOUT);
  144. }
  145. static const struct bt_mesh_send_cb clear_sent_cb = {
  146. .end = friend_clear_sent,
  147. };
  148. static int send_friend_clear(void)
  149. {
  150. struct bt_mesh_msg_ctx ctx = {
  151. .net_idx = bt_mesh.sub[0].net_idx,
  152. .app_idx = BLE_MESH_KEY_UNUSED,
  153. .addr = bt_mesh.lpn.frnd,
  154. .send_ttl = 0,
  155. .send_cred = BLE_MESH_FLOODING_CRED,
  156. /* Tag with immutable-credentials */
  157. .send_tag = BLE_MESH_TAG_IMMUTABLE_CRED,
  158. };
  159. struct bt_mesh_net_tx tx = {
  160. .sub = &bt_mesh.sub[0],
  161. .ctx = &ctx,
  162. .src = bt_mesh_primary_addr(),
  163. .xmit = bt_mesh_net_transmit_get(),
  164. };
  165. struct bt_mesh_ctl_friend_clear req = {
  166. .lpn_addr = sys_cpu_to_be16(tx.src),
  167. .lpn_counter = sys_cpu_to_be16(bt_mesh.lpn.counter),
  168. };
  169. return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req,
  170. sizeof(req), &clear_sent_cb, NULL);
  171. }
  172. static void clear_friendship(bool force, bool disable)
  173. {
  174. struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get();
  175. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  176. BT_DBG("force %u disable %u", force, disable);
  177. if (!force && lpn->established && !lpn->clear_success &&
  178. lpn->req_attempts < CLEAR_ATTEMPTS) {
  179. send_friend_clear();
  180. lpn->disable = disable;
  181. return;
  182. }
  183. bt_mesh_rx_reset();
  184. bt_mesh_rpl_reset(true);
  185. k_delayed_work_cancel(&lpn->timer);
  186. friend_cred_del(bt_mesh.sub[0].net_idx, lpn->frnd);
  187. if (lpn->clear_success) {
  188. lpn->old_friend = BLE_MESH_ADDR_UNASSIGNED;
  189. } else {
  190. lpn->old_friend = lpn->frnd;
  191. }
  192. if (lpn_cb && lpn->frnd != BLE_MESH_ADDR_UNASSIGNED) {
  193. lpn_cb(lpn->frnd, false);
  194. }
  195. /* If the Low Power node supports directed forwarding functionality when
  196. * the friendship is established in a subnet, the Low Power node shall
  197. * store the current value of the Directed Forwarding state and shall set
  198. * the state to 0x00 for that subnet. When that friendship is terminated,
  199. * the Low Power node shall set the Directed Forwarding state to the stored
  200. * value.
  201. */
  202. #if CONFIG_BLE_MESH_DF_SRV
  203. if (lpn->established) {
  204. bt_mesh_restore_directed_forwarding_state(bt_mesh.sub[0].net_idx,
  205. lpn->old_directed_forwarding);
  206. }
  207. #endif
  208. lpn->frnd = BLE_MESH_ADDR_UNASSIGNED;
  209. lpn->fsn = 0U;
  210. lpn->req_attempts = 0U;
  211. lpn->recv_win = 0U;
  212. lpn->queue_size = 0U;
  213. lpn->disable = 0U;
  214. lpn->sent_req = 0U;
  215. lpn->established = 0U;
  216. lpn->clear_success = 0U;
  217. group_zero(lpn->added);
  218. group_zero(lpn->pending);
  219. group_zero(lpn->to_remove);
  220. /* Set this to 1 to force group subscription when the next
  221. * Friendship is created, in case lpn->groups doesn't get
  222. * modified meanwhile.
  223. */
  224. lpn->groups_changed = 1U;
  225. if (cfg->hb_pub.feat & BLE_MESH_FEAT_LOW_POWER) {
  226. bt_mesh_heartbeat_send();
  227. }
  228. if (disable) {
  229. lpn_set_state(BLE_MESH_LPN_DISABLED);
  230. return;
  231. }
  232. lpn_set_state(BLE_MESH_LPN_ENABLED);
  233. k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
  234. scan_after_clear = false;
  235. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  236. bt_mesh_scan_disable();
  237. }
  238. }
  239. static void friend_req_sent(uint16_t duration, int err, void *user_data)
  240. {
  241. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  242. if (err) {
  243. BT_ERR("Sending Friend Request failed (err %d)", err);
  244. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  245. bt_mesh_scan_enable();
  246. }
  247. return;
  248. }
  249. lpn->adv_duration = duration;
  250. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  251. k_delayed_work_submit(&lpn->timer, FRIEND_REQ_WAIT);
  252. lpn_set_state(BLE_MESH_LPN_REQ_WAIT);
  253. } else {
  254. k_delayed_work_submit(&lpn->timer,
  255. duration + FRIEND_REQ_TIMEOUT);
  256. lpn_set_state(BLE_MESH_LPN_WAIT_OFFER);
  257. }
  258. }
  259. static const struct bt_mesh_send_cb friend_req_sent_cb = {
  260. .start = friend_req_sent,
  261. };
  262. static int send_friend_req(struct bt_mesh_lpn *lpn)
  263. {
  264. const struct bt_mesh_comp *comp = bt_mesh_comp_get();
  265. struct bt_mesh_msg_ctx ctx = {
  266. .net_idx = bt_mesh.sub[0].net_idx,
  267. .app_idx = BLE_MESH_KEY_UNUSED,
  268. .addr = BLE_MESH_ADDR_FRIENDS,
  269. .send_ttl = 0,
  270. .send_cred = BLE_MESH_FLOODING_CRED,
  271. /* Tag with immutable-credentials and as a friendship PDU */
  272. .send_tag = BLE_MESH_TAG_IMMUTABLE_CRED | BLE_MESH_TAG_FRIENDSHIP,
  273. };
  274. struct bt_mesh_net_tx tx = {
  275. .sub = &bt_mesh.sub[0],
  276. .ctx = &ctx,
  277. .src = bt_mesh_primary_addr(),
  278. .xmit = POLL_XMIT,
  279. };
  280. struct bt_mesh_ctl_friend_req req = {
  281. .criteria = LPN_CRITERIA,
  282. .recv_delay = LPN_RECV_DELAY,
  283. .poll_to = LPN_POLL_TO,
  284. .prev_addr = sys_cpu_to_be16(lpn->old_friend),
  285. .num_elem = comp->elem_count,
  286. .lpn_counter = sys_cpu_to_be16(lpn->counter),
  287. };
  288. return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_REQ, &req,
  289. sizeof(req), &friend_req_sent_cb, NULL);
  290. }
  291. static void req_sent(uint16_t duration, int err, void *user_data)
  292. {
  293. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  294. BT_DBG("req 0x%02x duration %u err %d state %s",
  295. lpn->sent_req, duration, err, state2str(lpn->state));
  296. if (err) {
  297. BT_ERR("Sending request failed (err %d)", err);
  298. lpn->sent_req = 0U;
  299. group_zero(lpn->pending);
  300. return;
  301. }
  302. lpn->req_attempts++;
  303. lpn->adv_duration = duration;
  304. if (lpn->established || IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  305. lpn_set_state(BLE_MESH_LPN_RECV_DELAY);
  306. /* We start scanning a bit early to eliminate risk of missing
  307. * response data due to HCI and other latencies.
  308. */
  309. k_delayed_work_submit(&lpn->timer,
  310. LPN_RECV_DELAY - SCAN_LATENCY);
  311. } else {
  312. lpn_set_state(BLE_MESH_LPN_OFFER_RECV);
  313. /**
  314. * Friend Update is replied by Friend Node with TTL set to 0 and Network
  315. * Transmit set to 30ms which will cause the packet easy to be missed.
  316. * Regarding this situation, here we can reduce the duration of receiving
  317. * the first Friend Update.
  318. */
  319. k_delayed_work_submit(&lpn->timer,
  320. LPN_RECV_DELAY + duration +
  321. lpn->recv_win);
  322. }
  323. }
  324. static const struct bt_mesh_send_cb req_sent_cb = {
  325. .start = req_sent,
  326. };
  327. static int send_friend_poll(void)
  328. {
  329. struct bt_mesh_msg_ctx ctx = {
  330. .net_idx = bt_mesh.sub[0].net_idx,
  331. .app_idx = BLE_MESH_KEY_UNUSED,
  332. .addr = bt_mesh.lpn.frnd,
  333. .send_ttl = 0,
  334. .send_cred = BLE_MESH_FRIENDSHIP_CRED,
  335. /* Tag with immutable-credentials and as a friendship PDU */
  336. .send_tag = BLE_MESH_TAG_IMMUTABLE_CRED | BLE_MESH_TAG_FRIENDSHIP,
  337. };
  338. struct bt_mesh_net_tx tx = {
  339. .sub = &bt_mesh.sub[0],
  340. .ctx = &ctx,
  341. .src = bt_mesh_primary_addr(),
  342. .xmit = POLL_XMIT,
  343. };
  344. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  345. uint8_t fsn = lpn->fsn;
  346. int err = 0;
  347. BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req);
  348. if (lpn->sent_req) {
  349. if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
  350. lpn->pending_poll = 1U;
  351. }
  352. return 0;
  353. }
  354. err = bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_POLL, &fsn, 1,
  355. &req_sent_cb, NULL);
  356. if (err == 0) {
  357. lpn->pending_poll = 0U;
  358. lpn->sent_req = TRANS_CTL_OP_FRIEND_POLL;
  359. }
  360. return err;
  361. }
  362. void bt_mesh_lpn_disable(bool force)
  363. {
  364. if (bt_mesh.lpn.state == BLE_MESH_LPN_DISABLED) {
  365. return;
  366. }
  367. clear_friendship(force, true);
  368. }
  369. int bt_mesh_lpn_set(bool enable, bool force)
  370. {
  371. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  372. if (enable) {
  373. if (lpn->state != BLE_MESH_LPN_DISABLED) {
  374. return 0;
  375. }
  376. } else {
  377. if (lpn->state == BLE_MESH_LPN_DISABLED) {
  378. return 0;
  379. }
  380. }
  381. if (!bt_mesh_is_provisioned()) {
  382. if (enable) {
  383. lpn_set_state(BLE_MESH_LPN_ENABLED);
  384. } else {
  385. lpn_set_state(BLE_MESH_LPN_DISABLED);
  386. }
  387. return 0;
  388. }
  389. if (enable) {
  390. lpn_set_state(BLE_MESH_LPN_ENABLED);
  391. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  392. bt_mesh_scan_disable();
  393. }
  394. send_friend_req(lpn);
  395. } else {
  396. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_AUTO) &&
  397. lpn->state == BLE_MESH_LPN_TIMER) {
  398. k_delayed_work_cancel(&lpn->timer);
  399. lpn_set_state(BLE_MESH_LPN_DISABLED);
  400. } else {
  401. bt_mesh_lpn_disable(force);
  402. }
  403. }
  404. return 0;
  405. }
  406. static void friend_response_received(struct bt_mesh_lpn *lpn)
  407. {
  408. BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req);
  409. if (lpn->sent_req == TRANS_CTL_OP_FRIEND_POLL) {
  410. lpn->fsn++;
  411. }
  412. k_delayed_work_cancel(&lpn->timer);
  413. bt_mesh_scan_disable();
  414. lpn_set_state(BLE_MESH_LPN_ESTABLISHED);
  415. lpn->req_attempts = 0U;
  416. lpn->sent_req = 0U;
  417. }
  418. void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx)
  419. {
  420. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  421. if (lpn->state == BLE_MESH_LPN_TIMER) {
  422. BT_DBG("Restarting establishment timer");
  423. k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT);
  424. return;
  425. }
  426. if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
  427. BT_WARN("Unexpected message without a preceding Poll");
  428. return;
  429. }
  430. friend_response_received(lpn);
  431. BT_DBG("Requesting more messages from Friend");
  432. send_friend_poll();
  433. }
  434. int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx,
  435. struct net_buf_simple *buf)
  436. {
  437. struct bt_mesh_ctl_friend_offer *msg = (void *)buf->data;
  438. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  439. struct bt_mesh_subnet *sub = rx->sub;
  440. struct friend_cred *cred = NULL;
  441. uint16_t frnd_counter = 0U;
  442. int err = 0;
  443. if (buf->len < sizeof(*msg)) {
  444. BT_WARN("Too short Friend Offer");
  445. return -EINVAL;
  446. }
  447. if (lpn->state != BLE_MESH_LPN_WAIT_OFFER) {
  448. BT_WARN("Ignoring unexpected Friend Offer");
  449. return 0;
  450. }
  451. if (!msg->recv_win) {
  452. BT_WARN("Prohibited ReceiveWindow value");
  453. return -EINVAL;
  454. }
  455. frnd_counter = sys_be16_to_cpu(msg->frnd_counter);
  456. BT_INFO("recv_win %u queue_size %u sub_list_size %u rssi %d counter %u",
  457. msg->recv_win, msg->queue_size, msg->sub_list_size, msg->rssi,
  458. frnd_counter);
  459. lpn->frnd = rx->ctx.addr;
  460. cred = friend_cred_create(sub, lpn->frnd, lpn->counter, frnd_counter);
  461. if (!cred) {
  462. lpn->frnd = BLE_MESH_ADDR_UNASSIGNED;
  463. return -ENOMEM;
  464. }
  465. /* TODO: Add offer acceptance criteria check */
  466. k_delayed_work_cancel(&lpn->timer);
  467. lpn->recv_win = msg->recv_win;
  468. lpn->queue_size = msg->queue_size;
  469. err = send_friend_poll();
  470. if (err) {
  471. friend_cred_clear(cred);
  472. lpn->frnd = BLE_MESH_ADDR_UNASSIGNED;
  473. lpn->recv_win = 0U;
  474. lpn->queue_size = 0U;
  475. return err;
  476. }
  477. lpn->counter++;
  478. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  479. bt_mesh_scan_disable();
  480. }
  481. return 0;
  482. }
  483. int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx,
  484. struct net_buf_simple *buf)
  485. {
  486. struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->data;
  487. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  488. uint16_t addr = 0U, counter = 0U;
  489. if (buf->len < sizeof(*msg)) {
  490. BT_WARN("Too short Friend Clear Confirm");
  491. return -EINVAL;
  492. }
  493. if (lpn->state != BLE_MESH_LPN_CLEAR) {
  494. BT_WARN("Ignoring unexpected Friend Clear Confirm");
  495. return 0;
  496. }
  497. addr = sys_be16_to_cpu(msg->lpn_addr);
  498. counter = sys_be16_to_cpu(msg->lpn_counter);
  499. BT_DBG("LPNAddress 0x%04x LPNCounter 0x%04x", addr, counter);
  500. if (addr != bt_mesh_primary_addr() || counter != lpn->counter) {
  501. BT_WARN("Invalid parameters in Friend Clear Confirm");
  502. return 0;
  503. }
  504. lpn->clear_success = 1U;
  505. clear_friendship(false, lpn->disable);
  506. return 0;
  507. }
  508. static void lpn_group_add(uint16_t group)
  509. {
  510. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  511. uint16_t *free_slot = NULL;
  512. int i;
  513. for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
  514. if (lpn->groups[i] == group) {
  515. bt_mesh_atomic_clear_bit(lpn->to_remove, i);
  516. return;
  517. }
  518. if (!free_slot && lpn->groups[i] == BLE_MESH_ADDR_UNASSIGNED) {
  519. free_slot = &lpn->groups[i];
  520. }
  521. }
  522. if (!free_slot) {
  523. BT_WARN("Friend Subscription List exceeded!");
  524. return;
  525. }
  526. *free_slot = group;
  527. lpn->groups_changed = 1U;
  528. }
  529. static void lpn_group_del(uint16_t group)
  530. {
  531. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  532. int i;
  533. for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
  534. if (lpn->groups[i] == group) {
  535. if (bt_mesh_atomic_test_bit(lpn->added, i) ||
  536. bt_mesh_atomic_test_bit(lpn->pending, i)) {
  537. bt_mesh_atomic_set_bit(lpn->to_remove, i);
  538. lpn->groups_changed = 1U;
  539. } else {
  540. lpn->groups[i] = BLE_MESH_ADDR_UNASSIGNED;
  541. }
  542. }
  543. }
  544. }
  545. static inline int group_popcount(bt_mesh_atomic_t *target)
  546. {
  547. #if CONFIG_BLE_MESH_LPN_GROUPS > 32
  548. int i, count = 0;
  549. for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) {
  550. count += popcount(bt_mesh_atomic_get(&target[i]));
  551. }
  552. #else
  553. return popcount(bt_mesh_atomic_get(target));
  554. #endif
  555. }
  556. static bool sub_update(uint8_t op)
  557. {
  558. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  559. int added_count = group_popcount(lpn->added);
  560. struct bt_mesh_msg_ctx ctx = {
  561. .net_idx = bt_mesh.sub[0].net_idx,
  562. .app_idx = BLE_MESH_KEY_UNUSED,
  563. .addr = lpn->frnd,
  564. .send_ttl = 0,
  565. .send_cred = BLE_MESH_FRIENDSHIP_CRED,
  566. /* Tag with immutable-credentials and as a friendship PDU */
  567. .send_tag = BLE_MESH_TAG_IMMUTABLE_CRED | BLE_MESH_TAG_FRIENDSHIP,
  568. };
  569. struct bt_mesh_net_tx tx = {
  570. .sub = &bt_mesh.sub[0],
  571. .ctx = &ctx,
  572. .src = bt_mesh_primary_addr(),
  573. .xmit = POLL_XMIT,
  574. };
  575. struct bt_mesh_ctl_friend_sub req = {0};
  576. size_t i = 0U, g = 0U;
  577. BT_DBG("op 0x%02x sent_req 0x%02x", op, lpn->sent_req);
  578. if (lpn->sent_req) {
  579. return false;
  580. }
  581. for (i = 0U, g = 0U; i < ARRAY_SIZE(lpn->groups); i++) {
  582. if (lpn->groups[i] == BLE_MESH_ADDR_UNASSIGNED) {
  583. continue;
  584. }
  585. if (op == TRANS_CTL_OP_FRIEND_SUB_ADD) {
  586. if (bt_mesh_atomic_test_bit(lpn->added, i)) {
  587. continue;
  588. }
  589. } else {
  590. if (!bt_mesh_atomic_test_bit(lpn->to_remove, i)) {
  591. continue;
  592. }
  593. }
  594. if (added_count + g >= lpn->queue_size) {
  595. BT_WARN("Friend Queue Size exceeded");
  596. break;
  597. }
  598. req.addr_list[g++] = sys_cpu_to_be16(lpn->groups[i]);
  599. bt_mesh_atomic_set_bit(lpn->pending, i);
  600. if (g == ARRAY_SIZE(req.addr_list)) {
  601. break;
  602. }
  603. }
  604. if (g == 0U) {
  605. group_zero(lpn->pending);
  606. return false;
  607. }
  608. req.xact = lpn->xact_next++;
  609. if (bt_mesh_ctl_send(&tx, op, &req, 1 + g * 2,
  610. &req_sent_cb, NULL) < 0) {
  611. group_zero(lpn->pending);
  612. return false;
  613. }
  614. lpn->xact_pending = req.xact;
  615. lpn->sent_req = op;
  616. return true;
  617. }
  618. static void update_timeout(struct bt_mesh_lpn *lpn)
  619. {
  620. if (lpn->established) {
  621. BT_WARN("No response from Friend during ReceiveWindow");
  622. bt_mesh_scan_disable();
  623. lpn_set_state(BLE_MESH_LPN_ESTABLISHED);
  624. k_delayed_work_submit(&lpn->timer, POLL_RETRY_TIMEOUT);
  625. } else {
  626. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  627. bt_mesh_scan_disable();
  628. }
  629. if (lpn->req_attempts < FIRST_POLL_ATTEMPTS) {
  630. BT_WARN("Retrying first Friend Poll");
  631. lpn->sent_req = 0U;
  632. if (send_friend_poll() == 0) {
  633. return;
  634. }
  635. }
  636. BT_ERR("Timed out waiting for first Friend Update");
  637. clear_friendship(false, false);
  638. }
  639. }
  640. static void lpn_timeout(struct k_work *work)
  641. {
  642. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  643. BT_DBG("state: %s", state2str(lpn->state));
  644. switch (lpn->state) {
  645. case BLE_MESH_LPN_DISABLED:
  646. break;
  647. case BLE_MESH_LPN_CLEAR:
  648. clear_friendship(false, bt_mesh.lpn.disable);
  649. break;
  650. case BLE_MESH_LPN_TIMER:
  651. BT_DBG("Starting to look for Friend nodes");
  652. lpn_set_state(BLE_MESH_LPN_ENABLED);
  653. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  654. bt_mesh_scan_disable();
  655. }
  656. /* fall through */
  657. case BLE_MESH_LPN_ENABLED:
  658. send_friend_req(lpn);
  659. break;
  660. case BLE_MESH_LPN_REQ_WAIT:
  661. bt_mesh_scan_enable();
  662. k_delayed_work_submit(&lpn->timer,
  663. lpn->adv_duration + FRIEND_REQ_SCAN);
  664. lpn_set_state(BLE_MESH_LPN_WAIT_OFFER);
  665. break;
  666. case BLE_MESH_LPN_WAIT_OFFER:
  667. BT_WARN("No acceptable Friend Offers received");
  668. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  669. bt_mesh_scan_disable();
  670. }
  671. lpn->counter++;
  672. lpn_set_state(BLE_MESH_LPN_ENABLED);
  673. lpn->sent_req = 0U;
  674. k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT);
  675. break;
  676. case BLE_MESH_LPN_OFFER_RECV:
  677. if (lpn->req_attempts < FIRST_POLL_ATTEMPTS) {
  678. BT_WARN("Retrying the first Friend Poll, %d attempts", lpn->req_attempts);
  679. lpn->sent_req = 0U;
  680. send_friend_poll();
  681. break;
  682. }
  683. BT_ERR("Timeout waiting for the first Friend Update");
  684. clear_friendship(true, false);
  685. break;
  686. case BLE_MESH_LPN_ESTABLISHED:
  687. if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) {
  688. uint8_t req = lpn->sent_req;
  689. lpn->sent_req = 0U;
  690. if (!req || req == TRANS_CTL_OP_FRIEND_POLL) {
  691. send_friend_poll();
  692. } else {
  693. sub_update(req);
  694. }
  695. break;
  696. }
  697. BT_ERR("No response from Friend after %u retries",
  698. lpn->req_attempts);
  699. lpn->req_attempts = 0U;
  700. clear_friendship(false, false);
  701. break;
  702. case BLE_MESH_LPN_RECV_DELAY:
  703. k_delayed_work_submit(&lpn->timer,
  704. lpn->adv_duration + SCAN_LATENCY +
  705. lpn->recv_win);
  706. bt_mesh_scan_enable();
  707. lpn_set_state(BLE_MESH_LPN_WAIT_UPDATE);
  708. break;
  709. case BLE_MESH_LPN_WAIT_UPDATE:
  710. update_timeout(lpn);
  711. break;
  712. default:
  713. BT_ERR("Unhandled LPN state");
  714. break;
  715. }
  716. }
  717. void bt_mesh_lpn_group_add(uint16_t group)
  718. {
  719. BT_DBG("group 0x%04x", group);
  720. lpn_group_add(group);
  721. if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) {
  722. return;
  723. }
  724. sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
  725. }
  726. void bt_mesh_lpn_group_del(uint16_t *groups, size_t group_count)
  727. {
  728. int i;
  729. for (i = 0; i < group_count; i++) {
  730. if (groups[i] != BLE_MESH_ADDR_UNASSIGNED) {
  731. BT_DBG("group 0x%04x", groups[i]);
  732. lpn_group_del(groups[i]);
  733. }
  734. }
  735. if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) {
  736. return;
  737. }
  738. sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
  739. }
  740. static int32_t poll_timeout(struct bt_mesh_lpn *lpn)
  741. {
  742. /* If we're waiting for segment acks keep polling at high freq */
  743. if (bt_mesh_tx_in_progress()) {
  744. return MIN(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1));
  745. }
  746. if (lpn->poll_timeout < POLL_TIMEOUT_MAX(lpn)) {
  747. lpn->poll_timeout *= 2;
  748. lpn->poll_timeout = MIN(lpn->poll_timeout,
  749. POLL_TIMEOUT_MAX(lpn));
  750. }
  751. BT_DBG("Poll Timeout is %ums", lpn->poll_timeout);
  752. return lpn->poll_timeout;
  753. }
  754. int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx,
  755. struct net_buf_simple *buf)
  756. {
  757. struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->data;
  758. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  759. if (buf->len < sizeof(*msg)) {
  760. BT_WARN("Too short Friend Subscription Confirm");
  761. return -EINVAL;
  762. }
  763. BT_DBG("xact 0x%02x", msg->xact);
  764. if (!lpn->sent_req) {
  765. BT_WARN("No pending subscription list message");
  766. return 0;
  767. }
  768. if (msg->xact != lpn->xact_pending) {
  769. BT_WARN("Transaction mismatch (0x%02x != 0x%02x)",
  770. msg->xact, lpn->xact_pending);
  771. return 0;
  772. }
  773. if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_ADD) {
  774. group_set(lpn->added, lpn->pending);
  775. group_zero(lpn->pending);
  776. } else if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_REM) {
  777. int i;
  778. group_clear(lpn->added, lpn->pending);
  779. for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) {
  780. if (bt_mesh_atomic_test_and_clear_bit(lpn->pending, i) &&
  781. bt_mesh_atomic_test_and_clear_bit(lpn->to_remove, i)) {
  782. lpn->groups[i] = BLE_MESH_ADDR_UNASSIGNED;
  783. }
  784. }
  785. } else {
  786. BT_WARN("Unexpected Friend Subscription Confirm");
  787. return 0;
  788. }
  789. friend_response_received(lpn);
  790. if (lpn->groups_changed) {
  791. sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
  792. sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
  793. if (!lpn->sent_req) {
  794. lpn->groups_changed = 0U;
  795. }
  796. }
  797. if (lpn->pending_poll) {
  798. send_friend_poll();
  799. }
  800. if (!lpn->sent_req) {
  801. k_delayed_work_submit(&lpn->timer, poll_timeout(lpn));
  802. }
  803. return 0;
  804. }
  805. int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx,
  806. struct net_buf_simple *buf)
  807. {
  808. struct bt_mesh_ctl_friend_update *msg = (void *)buf->data;
  809. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  810. struct bt_mesh_subnet *sub = rx->sub;
  811. uint32_t iv_index = 0U;
  812. if (buf->len < sizeof(*msg)) {
  813. BT_WARN("Too short Friend Update");
  814. return -EINVAL;
  815. }
  816. if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) {
  817. BT_WARN("Unexpected friend update");
  818. return 0;
  819. }
  820. if (sub->kr_phase == BLE_MESH_KR_PHASE_2 && !rx->new_key) {
  821. BT_WARN("Ignoring Phase 2 KR Update secured using old key");
  822. return 0;
  823. }
  824. if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR) &&
  825. (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS) ==
  826. BLE_MESH_IV_UPDATE(msg->flags))) {
  827. bt_mesh_beacon_ivu_initiator(false);
  828. }
  829. if (!lpn->established) {
  830. struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get();
  831. /* This is normally checked on the transport layer, however
  832. * in this state we're also still accepting master
  833. * credentials so we need to ensure the right ones (Friend
  834. * Credentials) were used for this message.
  835. */
  836. if (rx->ctx.recv_cred != BLE_MESH_FRIENDSHIP_CRED) {
  837. BT_WARN("Friend Update with wrong credentials");
  838. return -EINVAL;
  839. }
  840. lpn->established = 1U;
  841. BT_INFO("Friendship established with 0x%04x", lpn->frnd);
  842. if (cfg->hb_pub.feat & BLE_MESH_FEAT_LOW_POWER) {
  843. bt_mesh_heartbeat_send();
  844. }
  845. if (lpn_cb) {
  846. lpn_cb(lpn->frnd, true);
  847. }
  848. /* Set initial poll timeout */
  849. lpn->poll_timeout = MIN(POLL_TIMEOUT_MAX(lpn),
  850. POLL_TIMEOUT_INIT);
  851. /* If the Low Power node supports directed forwarding functionality when
  852. * the friendship is established in a subnet, the Low Power node shall
  853. * store the current value of the Directed Forwarding state and shall set
  854. * the state to 0x00 for that subnet. When that friendship is terminated,
  855. * the Low Power node shall set the Directed Forwarding state to the stored
  856. * value.
  857. */
  858. #if CONFIG_BLE_MESH_DF_SRV
  859. lpn->old_directed_forwarding = bt_mesh_get_and_disable_directed_forwarding_state(sub);
  860. #endif
  861. }
  862. friend_response_received(lpn);
  863. iv_index = sys_be32_to_cpu(msg->iv_index);
  864. BT_INFO("flags 0x%02x iv_index 0x%08x md %u", msg->flags, iv_index,
  865. msg->md);
  866. if (bt_mesh_kr_update(sub, BLE_MESH_KEY_REFRESH(msg->flags),
  867. rx->new_key)) {
  868. bt_mesh_net_secure_beacon_update(sub);
  869. }
  870. bt_mesh_net_iv_update(iv_index, BLE_MESH_IV_UPDATE(msg->flags));
  871. if (lpn->groups_changed) {
  872. sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD);
  873. sub_update(TRANS_CTL_OP_FRIEND_SUB_REM);
  874. if (!lpn->sent_req) {
  875. lpn->groups_changed = 0U;
  876. }
  877. }
  878. if (msg->md) {
  879. BT_DBG("Requesting for more messages");
  880. send_friend_poll();
  881. }
  882. if (!lpn->sent_req) {
  883. k_delayed_work_submit(&lpn->timer, poll_timeout(lpn));
  884. }
  885. return 0;
  886. }
  887. int bt_mesh_lpn_poll(void)
  888. {
  889. if (!bt_mesh.lpn.established) {
  890. return -EAGAIN;
  891. }
  892. BT_DBG("Requesting more messages");
  893. return send_friend_poll();
  894. }
  895. void bt_mesh_lpn_set_cb(void (*cb)(uint16_t friend_addr, bool established))
  896. {
  897. lpn_cb = cb;
  898. }
  899. int bt_mesh_lpn_init(void)
  900. {
  901. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  902. k_delayed_work_init(&lpn->timer, lpn_timeout);
  903. if (lpn->state == BLE_MESH_LPN_ENABLED) {
  904. if (!IS_ENABLED(CONFIG_BLE_MESH_LPN_ESTABLISHMENT)) {
  905. bt_mesh_scan_enable();
  906. }
  907. send_friend_req(lpn);
  908. } else {
  909. bt_mesh_scan_enable();
  910. if (IS_ENABLED(CONFIG_BLE_MESH_LPN_AUTO)) {
  911. BT_DBG("Waiting %u ms for messages", LPN_AUTO_TIMEOUT);
  912. lpn_set_state(BLE_MESH_LPN_TIMER);
  913. k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT);
  914. }
  915. }
  916. return 0;
  917. }
  918. #if CONFIG_BLE_MESH_DEINIT
  919. int bt_mesh_lpn_deinit(void)
  920. {
  921. struct bt_mesh_lpn *lpn = &bt_mesh.lpn;
  922. bt_mesh_lpn_disable(true);
  923. k_delayed_work_free(&lpn->timer);
  924. return 0;
  925. }
  926. #endif /* CONFIG_BLE_MESH_DEINIT */
  927. #endif /* CONFIG_BLE_MESH_LOW_POWER */