util.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2017 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <stdio.h>
  14. #include <stdbool.h>
  15. #include <inttypes.h>
  16. #include <glib.h>
  17. #include "src/shared/shell.h"
  18. #include "src/shared/util.h"
  19. #include "tools/mesh-gatt/mesh-net.h"
  20. #include "tools/mesh-gatt/node.h"
  21. #include "tools/mesh-gatt/util.h"
  22. void set_menu_prompt(const char *name, const char *id)
  23. {
  24. char *prompt;
  25. prompt = g_strdup_printf(COLOR_BLUE "[%s%s%s]" COLOR_OFF "# ", name,
  26. id ? ": Target = " : "", id ? id : "");
  27. bt_shell_set_prompt(prompt);
  28. g_free(prompt);
  29. }
  30. void print_byte_array(const char *prefix, const void *ptr, int len)
  31. {
  32. const uint8_t *data = ptr;
  33. char *line, *bytes;
  34. int i;
  35. line = g_malloc(strlen(prefix) + (16 * 3) + 2);
  36. sprintf(line, "%s ", prefix);
  37. bytes = line + strlen(prefix) + 1;
  38. for (i = 0; i < len; ++i) {
  39. sprintf(bytes, "%2.2x ", data[i]);
  40. if ((i + 1) % 16) {
  41. bytes += 3;
  42. } else {
  43. bt_shell_printf("\r%s\n", line);
  44. bytes = line + strlen(prefix) + 1;
  45. }
  46. }
  47. if (i % 16)
  48. bt_shell_printf("\r%s\n", line);
  49. g_free(line);
  50. }
  51. bool str2hex(const char *str, uint16_t in_len, uint8_t *out,
  52. uint16_t out_len)
  53. {
  54. uint16_t i;
  55. if (in_len < out_len * 2)
  56. return false;
  57. for (i = 0; i < out_len; i++) {
  58. if (sscanf(&str[i * 2], "%02hhx", &out[i]) != 1)
  59. return false;
  60. }
  61. return true;
  62. }
  63. size_t hex2str(uint8_t *in, size_t in_len, char *out,
  64. size_t out_len)
  65. {
  66. static const char hexdigits[] = "0123456789abcdef";
  67. size_t i;
  68. if(in_len * 2 > out_len - 1)
  69. return 0;
  70. for (i = 0; i < in_len; i++) {
  71. out[i * 2] = hexdigits[in[i] >> 4];
  72. out[i * 2 + 1] = hexdigits[in[i] & 0xf];
  73. }
  74. out[in_len * 2] = '\0';
  75. return i;
  76. }
  77. uint16_t mesh_opcode_set(uint32_t opcode, uint8_t *buf)
  78. {
  79. if (opcode <= 0x7e) {
  80. buf[0] = opcode;
  81. return 1;
  82. } else if (opcode >= 0x8000 && opcode <= 0xbfff) {
  83. put_be16(opcode, buf);
  84. return 2;
  85. } else if (opcode >= 0xc00000 && opcode <= 0xffffff) {
  86. buf[0] = (opcode >> 16) & 0xff;
  87. put_be16(opcode, buf + 1);
  88. return 3;
  89. } else {
  90. bt_shell_printf("Illegal Opcode %x", opcode);
  91. return 0;
  92. }
  93. }
  94. bool mesh_opcode_get(const uint8_t *buf, uint16_t sz, uint32_t *opcode, int *n)
  95. {
  96. if (!n || !opcode || sz < 1) return false;
  97. switch (buf[0] & 0xc0) {
  98. case 0x00:
  99. case 0x40:
  100. /* RFU */
  101. if (buf[0] == 0x7f)
  102. return false;
  103. *n = 1;
  104. *opcode = buf[0];
  105. break;
  106. case 0x80:
  107. if (sz < 2)
  108. return false;
  109. *n = 2;
  110. *opcode = get_be16(buf);
  111. break;
  112. case 0xc0:
  113. if (sz < 3)
  114. return false;
  115. *n = 3;
  116. *opcode = get_be16(buf + 1);
  117. *opcode |= buf[0] << 16;
  118. break;
  119. default:
  120. bt_shell_printf("Bad Packet:\n");
  121. print_byte_array("\t", (void *) buf, sz);
  122. return false;
  123. }
  124. return true;
  125. }
  126. const char *mesh_status_str(uint8_t status)
  127. {
  128. switch (status) {
  129. case MESH_STATUS_SUCCESS: return "Success";
  130. case MESH_STATUS_INVALID_ADDRESS: return "Invalid Address";
  131. case MESH_STATUS_INVALID_MODEL: return "Invalid Model";
  132. case MESH_STATUS_INVALID_APPKEY: return "Invalid AppKey";
  133. case MESH_STATUS_INVALID_NETKEY: return "Invalid NetKey";
  134. case MESH_STATUS_INSUFF_RESOURCES: return "Insufficient Resources";
  135. case MESH_STATUS_IDX_ALREADY_STORED: return "Key Idx Already Stored";
  136. case MESH_STATUS_INVALID_PUB_PARAM: return "Invalid Publish Parameters";
  137. case MESH_STATUS_NOT_SUB_MOD: return "Not a Subscribe Model";
  138. case MESH_STATUS_STORAGE_FAIL: return "Storage Failure";
  139. case MESH_STATUS_FEAT_NOT_SUP: return "Feature Not Supported";
  140. case MESH_STATUS_CANNOT_UPDATE: return "Cannot Update";
  141. case MESH_STATUS_CANNOT_REMOVE: return "Cannot Remove";
  142. case MESH_STATUS_CANNOT_BIND: return "Cannot bind";
  143. case MESH_STATUS_UNABLE_CHANGE_STATE: return "Unable to change state";
  144. case MESH_STATUS_CANNOT_SET: return "Cannot set";
  145. case MESH_STATUS_UNSPECIFIED_ERROR: return "Unspecified error";
  146. case MESH_STATUS_INVALID_BINDING: return "Invalid Binding";
  147. default: return "Unknown";
  148. }
  149. }
  150. void print_model_pub(uint16_t ele_addr, uint32_t mod_id,
  151. struct mesh_publication *pub)
  152. {
  153. bt_shell_printf("\tElement: %4.4x\n", ele_addr);
  154. bt_shell_printf("\tPub Addr: %4.4x", pub->u.addr16);
  155. if (mod_id > 0xffff0000)
  156. bt_shell_printf("\tModel: %8.8x \n", mod_id);
  157. else
  158. bt_shell_printf("\tModel: %4.4x \n",
  159. (uint16_t) (mod_id & 0xffff));
  160. bt_shell_printf("\tApp Key Idx: %4.4x", pub->app_idx);
  161. bt_shell_printf("\tTTL: %2.2x", pub->ttl);
  162. }
  163. void swap_u256_bytes(uint8_t *u256)
  164. {
  165. int i;
  166. /* End-to-End byte reflection of 32 octet buffer */
  167. for (i = 0; i < 16; i++) {
  168. u256[i] ^= u256[31 - i];
  169. u256[31 - i] ^= u256[i];
  170. u256[i] ^= u256[31 - i];
  171. }
  172. }