gatt_write_common.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (c) 2022 Nordic Semiconductor ASA
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "base/types.h"
  7. #include <bluetooth/bluetooth.h>
  8. #include <bluetooth/conn.h>
  9. #include <bluetooth/gatt.h>
  10. #include <logging/bt_log_impl.h>
  11. static struct bt_gatt_exchange_params mtu_exchange_params;
  12. // static uint32_t write_count;
  13. // static uint32_t write_len;
  14. // static uint32_t write_rate;
  15. struct bt_conn *conn_connected;
  16. uint32_t last_write_rate;
  17. void (*start_scan_func)(void);
  18. static void write_cmd_cb(struct bt_conn *conn, void *user_data)
  19. {
  20. // static uint32_t cycle_stamp;
  21. // uint64_t delta;
  22. uint16_t len;
  23. /* Extract the 16-bit data length stored in user_data */
  24. len = (uint32_t)user_data & 0xFFFF;
  25. printk("len= %u.\n", len);
  26. }
  27. static void mtu_exchange_cb(struct bt_conn *conn, uint8_t err,
  28. struct bt_gatt_exchange_params *params)
  29. {
  30. printk("%s: MTU exchange %s (%u)\n", __func__, err == 0U ? "successful" : "failed",
  31. bt_gatt_get_mtu(conn));
  32. }
  33. static int mtu_exchange(struct bt_conn *conn)
  34. {
  35. int err;
  36. printk("%s: Current MTU = %u\n", __func__, bt_gatt_get_mtu(conn));
  37. mtu_exchange_params.func = mtu_exchange_cb;
  38. printk("%s: Exchange MTU...\n", __func__);
  39. err = bt_gatt_exchange_mtu(conn, &mtu_exchange_params);
  40. if (err)
  41. {
  42. printk("%s: MTU exchange failed (err %d)", __func__, err);
  43. }
  44. return err;
  45. }
  46. static void connected(struct bt_conn *conn, uint8_t conn_err)
  47. {
  48. struct bt_conn_info conn_info;
  49. char addr[BT_ADDR_LE_STR_LEN];
  50. int err;
  51. bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
  52. if (conn_err)
  53. {
  54. printk("%s: Failed to connect to %s (%u)\n", __func__, addr, conn_err);
  55. return;
  56. }
  57. err = bt_conn_get_info(conn, &conn_info);
  58. if (err)
  59. {
  60. printk("Failed to get connection info (%d).\n", err);
  61. return;
  62. }
  63. printk("%s: %s role %u\n", __func__, addr, conn_info.role);
  64. // conn_connected = bt_conn_ref(conn);
  65. conn_connected = conn;
  66. (void)mtu_exchange(conn);
  67. #if defined(CONFIG_BT_SMP)
  68. if (conn_info.role == BT_CONN_ROLE_CENTRAL)
  69. {
  70. err = bt_conn_set_security(conn, BT_SECURITY_L2);
  71. if (err)
  72. {
  73. printk("Failed to set security (%d).\n", err);
  74. }
  75. }
  76. #endif
  77. }
  78. static void disconnected(struct bt_conn *conn, uint8_t reason)
  79. {
  80. struct bt_conn_info conn_info;
  81. char addr[BT_ADDR_LE_STR_LEN];
  82. int err;
  83. bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
  84. err = bt_conn_get_info(conn, &conn_info);
  85. if (err)
  86. {
  87. printk("Failed to get connection info (%d).\n", err);
  88. return;
  89. }
  90. printk("%s: %s role %u (reason %u)\n", __func__, addr, conn_info.role, reason);
  91. conn_connected = NULL;
  92. // bt_conn_unref(conn);
  93. if (conn_info.role == BT_CONN_ROLE_CENTRAL)
  94. {
  95. start_scan_func();
  96. }
  97. }
  98. static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param)
  99. {
  100. printk("%s: int (0x%04x, 0x%04x) lat %u to %u\n", __func__, param->interval_min,
  101. param->interval_max, param->latency, param->timeout);
  102. return true;
  103. }
  104. static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency,
  105. uint16_t timeout)
  106. {
  107. printk("%s: int 0x%04x lat %u to %u\n", __func__, interval, latency, timeout);
  108. }
  109. #if defined(CONFIG_BT_SMP)
  110. static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err)
  111. {
  112. printk("%s: to level %u (err %u)\n", __func__, level, err);
  113. }
  114. #endif
  115. struct bt_conn_cb conn_callbacks = {
  116. .connected = connected,
  117. .disconnected = disconnected,
  118. .le_param_req = le_param_req,
  119. .le_param_updated = le_param_updated,
  120. #if defined(CONFIG_BT_SMP)
  121. .security_changed = security_changed,
  122. #endif
  123. };
  124. int write_cmd(struct bt_conn *conn)
  125. {
  126. static uint8_t data[BT_ATT_MAX_ATTRIBUTE_LEN] = {
  127. 0,
  128. };
  129. static uint16_t data_len;
  130. uint16_t data_len_max;
  131. int err;
  132. data_len_max = bt_gatt_get_mtu(conn) - 3;
  133. if (data_len_max > BT_ATT_MAX_ATTRIBUTE_LEN)
  134. {
  135. data_len_max = BT_ATT_MAX_ATTRIBUTE_LEN;
  136. }
  137. #if TEST_FRAGMENTATION_WITH_VARIABLE_LENGTH_DATA
  138. /* Use incremental length data for every write command */
  139. /* TODO: Include test case in BabbleSim tests */
  140. static bool decrement;
  141. if (decrement)
  142. {
  143. data_len--;
  144. if (data_len <= 1)
  145. {
  146. data_len = 1;
  147. decrement = false;
  148. }
  149. }
  150. else
  151. {
  152. data_len++;
  153. if (data_len >= data_len_max)
  154. {
  155. data_len = data_len_max;
  156. decrement = true;
  157. }
  158. }
  159. #else
  160. /* Use fixed length data for every write command */
  161. data_len = data_len_max;
  162. #endif
  163. /* Pass the 16-bit data length value (instead of reference) in
  164. * user_data so that unique value is pass for each write callback.
  165. * Using handle 0x0001, we do not care if it is writable, we just want
  166. * to transmit the data across.
  167. */
  168. err = bt_gatt_write_without_response_cb(conn, 0x0001, data, data_len, false, write_cmd_cb,
  169. (void *)((uint32_t)data_len));
  170. if (err)
  171. {
  172. printk("%s: Write cmd failed (%d).\n", __func__, err);
  173. }
  174. return err;
  175. }