1 2 // ***************************************************************************** 3 // 4 // test rfcomm query tests 5 // 6 // ***************************************************************************** 7 8 9 #include <stdint.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 14 #include "CppUTest/TestHarness.h" 15 #include "CppUTest/CommandLineTestRunner.h" 16 17 #include "hci.h" 18 #include "ble/att_db.h" 19 #include "ble/att_db_util.h" 20 #include "ble/att_server.h" 21 #include "btstack_util.h" 22 #include "bluetooth.h" 23 #include "btstack_tlv.h" 24 #include "mock_btstack_tlv.h" 25 26 #include "bluetooth_gatt.h" 27 28 static uint8_t battery_level = 100; 29 static const uint8_t uuid128_with_bluetooth_base[] = { 0x00, 0x00, 0xBB, 0xBB, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}; 30 static const uint8_t uuid128_no_bluetooth_base[] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00 }; 31 32 extern "C" void l2cap_can_send_fixed_channel_packet_now_set_status(uint8_t status); 33 extern "C" void mock_call_att_server_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 34 extern "C" void hci_setup_le_connection(uint16_t con_handle); 35 extern "C" void mock_call_att_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 36 extern "C" void mock_l2cap_set_max_mtu(uint16_t mtu); 37 38 static uint8_t att_request[255]; 39 static uint16_t att_write_request(uint16_t request_type, uint16_t attribute_handle, uint16_t value_length, const uint8_t * value){ 40 att_request[0] = request_type; 41 little_endian_store_16(att_request, 1, attribute_handle); 42 (void)memcpy(&att_request[3], value, value_length); 43 return 3 + value_length; 44 } 45 46 static uint16_t att_read_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){ 47 UNUSED(connection_handle); 48 UNUSED(att_handle); 49 UNUSED(offset); 50 UNUSED(buffer); 51 UNUSED(buffer_size); 52 53 return 0; 54 } 55 56 static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){ 57 UNUSED(connection_handle); 58 UNUSED(att_handle); 59 UNUSED(transaction_mode); 60 UNUSED(offset); 61 UNUSED(buffer); 62 UNUSED(buffer_size); 63 64 return 0; 65 } 66 67 static void att_client_indication_callback(void * context){ 68 } 69 static void att_client_notification_callback(void * context){ 70 } 71 static void att_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { 72 } 73 74 75 TEST_GROUP(ATT_SERVER){ 76 uint16_t att_con_handle; 77 mock_btstack_tlv_t tlv_context; 78 const btstack_tlv_t * tlv_impl; 79 btstack_context_callback_registration_t indication_callback; 80 btstack_context_callback_registration_t notification_callback; 81 82 void setup(void){ 83 att_con_handle = 0x01; 84 85 hci_setup_le_connection(att_con_handle); 86 87 tlv_impl = mock_btstack_tlv_init_instance(&tlv_context); 88 btstack_tlv_set_instance(tlv_impl, &tlv_context); 89 90 l2cap_can_send_fixed_channel_packet_now_set_status(1); 91 indication_callback.callback = &att_client_indication_callback; 92 notification_callback.callback = &att_client_notification_callback; 93 94 // init att db util and add a service and characteristic 95 att_db_util_init(); 96 // 0x180F 97 att_db_util_add_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE); 98 // 0x2A19 99 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, ATT_PROPERTY_WRITE | ATT_PROPERTY_READ | ATT_PROPERTY_INDICATE, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 100 // 0x2A1B 101 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL_STATE, ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 102 // 0x2A1A 103 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_POWER_STATE, ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1); 104 // 0x2A49 105 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_FEATURE, ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_READ | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 106 // 0x2A35 107 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BLOOD_PRESSURE_MEASUREMENT, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_AUTHENTICATED, ATT_SECURITY_AUTHENTICATED, &battery_level, 1); 108 109 110 att_db_util_add_characteristic_uuid128(uuid128_no_bluetooth_base, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 111 // 0x2A38btstack_tlv_set_instance 112 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 113 114 115 att_db_util_add_characteristic_uuid128(uuid128_with_bluetooth_base, ATT_PROPERTY_WRITE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 116 // 0x2AAB 117 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME, ATT_PROPERTY_WRITE_WITHOUT_RESPONSE | ATT_PROPERTY_DYNAMIC | ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 118 // 0x2A5C 119 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_CSC_FEATURE, ATT_PROPERTY_AUTHENTICATED_SIGNED_WRITE | ATT_PROPERTY_DYNAMIC, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 120 // setup ATT server 121 att_server_init(att_db_util_get_address(), att_read_callback, att_write_callback); 122 } 123 124 void teardown(void) { 125 mock_btstack_tlv_deinit(&tlv_context); 126 hci_deinit(); 127 } 128 }; 129 130 131 TEST(ATT_SERVER, gatt_server_get_value_handle_for_characteristic_with_uuid16){ 132 // att_dump_attributes(); 133 uint16_t value_handle; 134 135 // start handle > value handle 136 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0xf000, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 137 CHECK_EQUAL(0, value_handle); 138 139 // end handle < value handle 140 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0x02, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 141 CHECK_EQUAL(0, value_handle); 142 143 // search value handle for unknown UUID 144 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xffff); 145 CHECK_EQUAL(0, value_handle); 146 147 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0); 148 CHECK_EQUAL(0, value_handle); 149 150 // search value handle after one with uuid128_no_bluetooth_base 151 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION); 152 CHECK_EQUAL(0x0014, value_handle); 153 154 // search value handle after one with uuid128_with_bluetooth_base 155 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME); 156 CHECK_EQUAL(0x001a, value_handle); 157 158 // search value handle registered with bluetooth_base 159 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xbbbb); 160 CHECK_EQUAL(0x0017, value_handle); 161 162 // correct read 163 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 164 CHECK_EQUAL(0x03, value_handle); 165 } 166 167 168 TEST(ATT_SERVER, att_server_indicate){ 169 static uint8_t value[] = {0x55}; 170 uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 171 uint8_t status; 172 173 // invalid connection handle 174 status = att_server_indicate(0x50, value_handle, &value[0], 0); 175 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 176 177 // L2CAP cannot send 178 l2cap_can_send_fixed_channel_packet_now_set_status(0); 179 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 180 CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status); 181 l2cap_can_send_fixed_channel_packet_now_set_status(1); 182 183 // correct command 184 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 185 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 186 187 // already in progress 188 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 189 CHECK_EQUAL(ATT_HANDLE_VALUE_INDICATION_IN_PROGRESS, status); 190 } 191 192 TEST(ATT_SERVER, att_server_notify){ 193 static uint8_t value[] = {0x55}; 194 uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 195 uint8_t status; 196 197 // invalid connection handle 198 status = att_server_notify(0x50, value_handle, &value[0], 0); 199 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 200 201 // L2CAP cannot send 202 l2cap_can_send_fixed_channel_packet_now_set_status(0); 203 status = att_server_notify(att_con_handle, value_handle, &value[0], 0); 204 CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status); 205 l2cap_can_send_fixed_channel_packet_now_set_status(1); 206 207 // correct command 208 status = att_server_notify(att_con_handle, value_handle, &value[0], 0); 209 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 210 } 211 212 TEST(ATT_SERVER, att_server_get_mtu){ 213 // invalid connection handle 214 uint8_t mtu = att_server_get_mtu(0x50); 215 CHECK_EQUAL(0, mtu); 216 217 mtu = att_server_get_mtu(att_con_handle); 218 CHECK_EQUAL(23, mtu); 219 } 220 221 TEST(ATT_SERVER, att_server_request_can_send_now_event){ 222 att_server_request_can_send_now_event(att_con_handle); 223 } 224 225 TEST(ATT_SERVER, att_server_can_send_packet_now){ 226 int status = att_server_can_send_packet_now(att_con_handle); 227 CHECK_EQUAL(1, status); 228 229 status = att_server_can_send_packet_now(0x50); 230 CHECK_EQUAL(0, status); 231 } 232 233 TEST(ATT_SERVER, att_server_request_to_send_indication){ 234 int status = att_server_request_to_send_indication(&indication_callback, 0x55); 235 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 236 237 l2cap_can_send_fixed_channel_packet_now_set_status(0); 238 239 status = att_server_request_to_send_indication(&indication_callback, att_con_handle); 240 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 241 242 status = att_server_request_to_send_indication(&indication_callback, att_con_handle); 243 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 244 } 245 246 TEST(ATT_SERVER, att_server_request_to_send_notification){ 247 int status = att_server_request_to_send_notification(¬ification_callback, 0x55); 248 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 249 250 l2cap_can_send_fixed_channel_packet_now_set_status(0); 251 252 status = att_server_request_to_send_notification(¬ification_callback, att_con_handle); 253 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 254 255 status = att_server_request_to_send_notification(¬ification_callback, att_con_handle); 256 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 257 } 258 259 TEST(ATT_SERVER, att_server_register_can_send_now_callback){ 260 int status = att_server_register_can_send_now_callback(¬ification_callback, 0x55); 261 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 262 263 att_server_register_packet_handler(&att_event_packet_handler); 264 } 265 266 TEST(ATT_SERVER, opcode_ATT_WRITE_REQUEST){ 267 uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 268 uint8_t buffer[] = {1, 0}; 269 270 uint16_t att_request_len = att_write_request(ATT_WRITE_REQUEST, value_handle, sizeof(buffer), buffer); 271 mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len); 272 } 273 274 TEST(ATT_SERVER, connection_complete_event){ 275 uint8_t buffer[21]; 276 buffer[0] = HCI_EVENT_LE_META; 277 buffer[1] = 19; 278 buffer[2] = HCI_SUBEVENT_LE_CONNECTION_COMPLETE; 279 280 // call with wrong con_handle 281 little_endian_store_16(buffer,4,HCI_CON_HANDLE_INVALID); 282 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 283 284 // call with correct con_handle 285 little_endian_store_16(buffer,4,att_con_handle); 286 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 287 288 // use max MTU > ATT_REQUEST_BUFFER_SIZE 289 mock_l2cap_set_max_mtu(ATT_REQUEST_BUFFER_SIZE + 10); 290 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 291 292 // wrong subevent 293 buffer[2] = 0xFF; 294 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 295 } 296 297 TEST(ATT_SERVER, connection_disconnect_complete_event) { 298 uint8_t buffer[6]; 299 buffer[0] = HCI_EVENT_DISCONNECTION_COMPLETE; 300 buffer[1] = 19; 301 buffer[2] = 0; 302 303 // call with wrong con_handle 304 hci_setup_le_connection(att_con_handle); 305 little_endian_store_16(buffer, 3, HCI_CON_HANDLE_INVALID); 306 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 307 308 // call with correct con_handle 309 hci_setup_le_connection(att_con_handle); 310 little_endian_store_16(buffer, 3, att_con_handle); 311 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 312 313 hci_setup_le_connection(att_con_handle); 314 static uint8_t value[] = {0x55}; 315 uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 316 l2cap_can_send_fixed_channel_packet_now_set_status(1); 317 // correct command 318 uint8_t status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 319 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 320 321 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 322 } 323 324 325 326 int main (int argc, const char * argv[]){ 327 return CommandLineTestRunner::RunAllTests(argc, argv); 328 } 329