local.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /* Bluetooth Mesh */
  2. /*
  3. * SPDX-FileCopyrightText: 2017 Intel Corporation
  4. * SPDX-FileContributor: 2020-2021 Espressif Systems (Shanghai) CO LTD
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. */
  8. #include <string.h>
  9. #include <errno.h>
  10. #include "mesh.h"
  11. #include "lpn.h"
  12. #include "crypto.h"
  13. #include "access.h"
  14. #include "foundation.h"
  15. #include "transport.h"
  16. #include "mesh/main.h"
  17. #include "settings.h"
  18. static struct bt_mesh_model *find_model(uint16_t elem_addr, uint16_t cid, uint16_t mod_id)
  19. {
  20. struct bt_mesh_elem *elem = NULL;
  21. if (!BLE_MESH_ADDR_IS_UNICAST(elem_addr)) {
  22. BT_ERR("Invalid unicast address 0x%04x", elem_addr);
  23. return NULL;
  24. }
  25. elem = bt_mesh_elem_find(elem_addr);
  26. if (elem == NULL) {
  27. BT_ERR("No element found, addr 0x%04x", elem_addr);
  28. return NULL;
  29. }
  30. if (cid == BLE_MESH_CID_NVAL) {
  31. return bt_mesh_model_find(elem, mod_id);
  32. }
  33. return bt_mesh_model_find_vnd(elem, cid, mod_id);
  34. }
  35. int bt_mesh_model_subscribe_group_addr(uint16_t elem_addr, uint16_t cid,
  36. uint16_t mod_id, uint16_t group_addr)
  37. {
  38. struct bt_mesh_model *model = NULL;
  39. int i;
  40. model = find_model(elem_addr, cid, mod_id);
  41. if (model == NULL) {
  42. BT_ERR("Subscribe, model not found, cid 0x%04x, mod_id 0x%04x", cid, mod_id);
  43. return -ENODEV;
  44. }
  45. if (!BLE_MESH_ADDR_IS_GROUP(group_addr)) {
  46. BT_ERR("Subscribe, not a group address 0x%04x", group_addr);
  47. return -EINVAL;
  48. }
  49. if (bt_mesh_model_find_group(model, group_addr)) {
  50. BT_INFO("Group address 0x%04x already exists", group_addr);
  51. return 0;
  52. }
  53. for (i = 0; i < ARRAY_SIZE(model->groups); i++) {
  54. if (model->groups[i] == BLE_MESH_ADDR_UNASSIGNED) {
  55. model->groups[i] = group_addr;
  56. if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
  57. bt_mesh_store_mod_sub(model);
  58. }
  59. if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
  60. bt_mesh_lpn_group_add(group_addr);
  61. }
  62. BT_INFO("Subscribe group address 0x%04x", group_addr);
  63. return 0;
  64. }
  65. }
  66. BT_ERR("Subscribe, model sub is full!");
  67. return -ENOMEM;
  68. }
  69. int bt_mesh_model_unsubscribe_group_addr(uint16_t elem_addr, uint16_t cid,
  70. uint16_t mod_id, uint16_t group_addr)
  71. {
  72. struct bt_mesh_model *model = NULL;
  73. uint16_t *match = NULL;
  74. model = find_model(elem_addr, cid, mod_id);
  75. if (model == NULL) {
  76. BT_ERR("Unsubscribe, model not found, cid 0x%04x, mod_id 0x%04x", cid, mod_id);
  77. return -ENODEV;
  78. }
  79. if (!BLE_MESH_ADDR_IS_GROUP(group_addr)) {
  80. BT_ERR("Unsubscribe, not a group address 0x%04x", group_addr);
  81. return -EINVAL;
  82. }
  83. match = bt_mesh_model_find_group(model, group_addr);
  84. if (match == NULL) {
  85. BT_WARN("Group address 0x%04x not exists", group_addr);
  86. return -EEXIST;
  87. }
  88. *match = BLE_MESH_ADDR_UNASSIGNED;
  89. if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
  90. bt_mesh_store_mod_sub(model);
  91. }
  92. if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
  93. bt_mesh_lpn_group_del(&group_addr, 1);
  94. }
  95. BT_INFO("Unsubscribe group address 0x%04x", group_addr);
  96. return 0;
  97. }
  98. #if CONFIG_BLE_MESH_DF_SRV
  99. int bt_mesh_enable_directed_forwarding(uint16_t net_idx, bool directed_forwarding,
  100. bool directed_forwarding_relay)
  101. {
  102. struct bt_mesh_subnet *sub = NULL;
  103. if (net_idx > 0xFFF) {
  104. BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
  105. return -EINVAL;
  106. }
  107. sub = bt_mesh_subnet_get(net_idx);
  108. if (!sub) {
  109. BT_ERR("NetKey 0x%04x not exists", net_idx);
  110. return -EINVAL;
  111. }
  112. if (directed_forwarding == BLE_MESH_DIRECTED_FORWARDING_DISABLED &&
  113. directed_forwarding_relay == BLE_MESH_DIRECTED_RELAY_ENABLED) {
  114. BT_ERR("Invalid Config directed forwarding: %d, directed forwarding relay: %d", directed_forwarding, directed_forwarding_relay);
  115. return -EINVAL;
  116. }
  117. sub->directed_forwarding = directed_forwarding;
  118. sub->directed_relay = directed_forwarding_relay;
  119. return 0;
  120. }
  121. #endif /* CONFIG_BLE_MESH_DF_SRV */
  122. #if CONFIG_BLE_MESH_NODE
  123. const uint8_t *bt_mesh_node_get_local_net_key(uint16_t net_idx)
  124. {
  125. struct bt_mesh_subnet *sub = NULL;
  126. if (net_idx > 0xFFF) {
  127. BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
  128. return NULL;
  129. }
  130. sub = bt_mesh_subnet_get(net_idx);
  131. if (!sub) {
  132. BT_ERR("NetKey 0x%04x not exists", net_idx);
  133. return NULL;
  134. }
  135. return sub->kr_flag ? sub->keys[1].net : sub->keys[0].net;
  136. }
  137. const uint8_t *bt_mesh_node_get_local_app_key(uint16_t app_idx)
  138. {
  139. struct bt_mesh_app_key *key = NULL;
  140. if (app_idx > 0xFFF) {
  141. BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx);
  142. return NULL;
  143. }
  144. key = bt_mesh_app_key_get(app_idx);
  145. if (!key) {
  146. BT_ERR("AppKey 0x%04x not exists", app_idx);
  147. return NULL;
  148. }
  149. return key->updated ? key->keys[1].val : key->keys[0].val;
  150. }
  151. int bt_mesh_node_local_net_key_add(uint16_t net_idx, const uint8_t net_key[16])
  152. {
  153. struct bt_mesh_subnet *sub = NULL;
  154. int err = 0;
  155. int i;
  156. if (net_idx > 0xFFF || net_key == NULL) {
  157. BT_ERR("%s, Invalid parameter", __func__);
  158. return -EINVAL;
  159. }
  160. if (!bt_mesh_is_provisioned()) {
  161. BT_ERR("Not provisioned, failed to add NetKey");
  162. return -EIO;
  163. }
  164. sub = bt_mesh_subnet_get(net_idx);
  165. if (sub) {
  166. BT_WARN("NetKey 0x%04x already exists", net_idx);
  167. return -EEXIST;
  168. }
  169. for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
  170. if (bt_mesh.sub[i].net_idx != BLE_MESH_KEY_UNUSED) {
  171. if ((bt_mesh.sub[i].kr_flag == false &&
  172. memcmp(bt_mesh.sub[i].keys[0].net, net_key, 16) == 0) ||
  173. (bt_mesh.sub[i].kr_flag == true &&
  174. memcmp(bt_mesh.sub[i].keys[1].net, net_key, 16) == 0)) {
  175. BT_WARN("Key value %s already exists", bt_hex(net_key, 16));
  176. return -EEXIST;
  177. }
  178. }
  179. }
  180. for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
  181. if (bt_mesh.sub[i].net_idx == BLE_MESH_KEY_UNUSED) {
  182. sub = &bt_mesh.sub[i];
  183. break;
  184. }
  185. }
  186. if (sub == NULL) {
  187. BT_ERR("NetKey is full!");
  188. return -ENOMEM;
  189. }
  190. err = bt_mesh_net_keys_create(&sub->keys[0], net_key);
  191. if (err) {
  192. BT_ERR("Failed to create keys for NetKey 0x%04x", net_idx);
  193. return -EIO;
  194. }
  195. sub->net_idx = net_idx;
  196. sub->kr_flag = false;
  197. sub->kr_phase = BLE_MESH_KR_NORMAL;
  198. if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
  199. sub->node_id = BLE_MESH_NODE_IDENTITY_STOPPED;
  200. } else {
  201. sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED;
  202. }
  203. if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
  204. BT_DBG("Storing NetKey persistently");
  205. bt_mesh_store_subnet(sub);
  206. }
  207. /* Make sure we have valid beacon data to be sent */
  208. bt_mesh_net_secure_beacon_update(sub);
  209. return 0;
  210. }
  211. int bt_mesh_node_local_app_key_add(uint16_t net_idx, uint16_t app_idx,
  212. const uint8_t app_key[16])
  213. {
  214. struct bt_mesh_app_key *key = NULL;
  215. if (net_idx > 0xFFF || app_idx > 0xFFF || app_key == NULL) {
  216. BT_ERR("%s, Invalid parameter", __func__);
  217. return -EINVAL;
  218. }
  219. if (!bt_mesh_is_provisioned()) {
  220. BT_ERR("Not provisioned, failed to add AppKey");
  221. return -EIO;
  222. }
  223. if (bt_mesh_subnet_get(net_idx) == NULL) {
  224. BT_ERR("Subnet 0x%04x not exists", net_idx);
  225. return -EIO;
  226. }
  227. key = bt_mesh_app_key_get(app_idx);
  228. if (key) {
  229. BT_WARN("AppKey 0x%04x already exists", app_idx);
  230. return -EEXIST;
  231. }
  232. for (int i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
  233. if (bt_mesh.app_keys[i].net_idx != BLE_MESH_KEY_UNUSED) {
  234. if ((bt_mesh.app_keys[i].updated == false &&
  235. memcmp(bt_mesh.app_keys[i].keys[0].val, app_key, 16) == 0) ||
  236. (bt_mesh.app_keys[i].updated == true &&
  237. memcmp(bt_mesh.app_keys[i].keys[1].val, app_key, 16) == 0)) {
  238. BT_WARN("Key value %s already exists", bt_hex(app_key, 16));
  239. return -EEXIST;
  240. }
  241. }
  242. }
  243. key = bt_mesh_app_key_alloc(app_idx);
  244. if (key) {
  245. struct bt_mesh_app_keys *keys = &key->keys[0];
  246. if (bt_mesh_app_id(app_key, &keys->id)) {
  247. BT_ERR("Failed to generate AID");
  248. return -EIO;
  249. }
  250. key->net_idx = net_idx;
  251. key->app_idx = app_idx;
  252. key->updated = false;
  253. memcpy(keys->val, app_key, 16);
  254. if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
  255. BT_DBG("Storing AppKey persistently");
  256. bt_mesh_store_app_key(key);
  257. }
  258. BT_INFO("Add AppKey 0x%04x, NetKeyIndex 0x%04x", app_idx, net_idx);
  259. return 0;
  260. }
  261. BT_ERR("AppKey is full!");
  262. return -ENOMEM;
  263. }
  264. int bt_mesh_node_bind_app_key_to_model(uint16_t elem_addr, uint16_t mod_id,
  265. uint16_t cid, uint16_t app_idx)
  266. {
  267. struct bt_mesh_model *model = NULL;
  268. int i;
  269. if (!bt_mesh_is_provisioned()) {
  270. BT_ERR("Not provisioned, failed to bind AppKey");
  271. return -EIO;
  272. }
  273. model = find_model(elem_addr, cid, mod_id);
  274. if (model == NULL) {
  275. BT_ERR("Bind, model(id 0x%04x, cid 0x%04x) not found", mod_id, cid);
  276. return -ENODEV;
  277. }
  278. if (bt_mesh_app_key_get(app_idx) == NULL) {
  279. BT_ERR("Bind, AppKey 0x%03x not exists", app_idx);
  280. return -ENODEV;
  281. }
  282. for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
  283. if (model->keys[i] == app_idx) {
  284. BT_WARN("Already bound to AppKey 0x%04x", app_idx);
  285. return -EALREADY;
  286. }
  287. }
  288. for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
  289. if (model->keys[i] == BLE_MESH_KEY_UNUSED) {
  290. model->keys[i] = app_idx;
  291. if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
  292. bt_mesh_store_mod_bind(model);
  293. }
  294. BT_INFO("Model(id 0x%04x, cid 0x%04x) bound to AppKey 0x%04x", mod_id, cid, app_idx);
  295. return 0;
  296. }
  297. }
  298. BT_ERR("Model bound is full!");
  299. return -ENOMEM;
  300. }
  301. #endif /* CONFIG_BLE_MESH_NODE */