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 TEST(ATT_SERVER, gatt_server_get_value_handle_for_characteristic_with_uuid16){ 131 // att_dump_attributes(); 132 uint16_t value_handle; 133 134 // start handle > value handle 135 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0xf000, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 136 CHECK_EQUAL(0, value_handle); 137 138 // end handle < value handle 139 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0x02, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 140 CHECK_EQUAL(0, value_handle); 141 142 // search value handle for unknown UUID 143 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xffff); 144 CHECK_EQUAL(0, value_handle); 145 146 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0); 147 CHECK_EQUAL(0, value_handle); 148 149 // search value handle after one with uuid128_no_bluetooth_base 150 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION); 151 CHECK_EQUAL(0x0014, value_handle); 152 153 // search value handle after one with uuid128_with_bluetooth_base 154 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME); 155 CHECK_EQUAL(0x001a, value_handle); 156 157 // search value handle registered with bluetooth_base 158 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xbbbb); 159 CHECK_EQUAL(0x0017, value_handle); 160 161 // correct read 162 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 163 CHECK_EQUAL(0x03, value_handle); 164 } 165 166 167 TEST(ATT_SERVER, att_server_indicate){ 168 static uint8_t value[] = {0x55}; 169 uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 170 uint8_t status; 171 172 // invalid connection handle 173 status = att_server_indicate(0x50, value_handle, &value[0], 0); 174 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 175 176 // L2CAP cannot send 177 l2cap_can_send_fixed_channel_packet_now_set_status(0); 178 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 179 CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status); 180 l2cap_can_send_fixed_channel_packet_now_set_status(1); 181 182 // correct command 183 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 184 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 185 186 // already in progress 187 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 188 CHECK_EQUAL(ATT_HANDLE_VALUE_INDICATION_IN_PROGRESS, status); 189 } 190 191 TEST(ATT_SERVER, att_server_notify){ 192 static uint8_t value[] = {0x55}; 193 uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 194 uint8_t status; 195 196 // invalid connection handle 197 status = att_server_notify(0x50, value_handle, &value[0], 0); 198 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 199 200 // L2CAP cannot send 201 l2cap_can_send_fixed_channel_packet_now_set_status(0); 202 status = att_server_notify(att_con_handle, value_handle, &value[0], 0); 203 CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status); 204 l2cap_can_send_fixed_channel_packet_now_set_status(1); 205 206 // correct command 207 status = att_server_notify(att_con_handle, value_handle, &value[0], 0); 208 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 209 } 210 211 TEST(ATT_SERVER, att_server_get_mtu){ 212 // invalid connection handle 213 uint8_t mtu = att_server_get_mtu(0x50); 214 CHECK_EQUAL(0, mtu); 215 216 mtu = att_server_get_mtu(att_con_handle); 217 CHECK_EQUAL(23, mtu); 218 } 219 220 TEST(ATT_SERVER, att_server_request_can_send_now_event){ 221 att_server_request_can_send_now_event(att_con_handle); 222 } 223 224 TEST(ATT_SERVER, att_server_can_send_packet_now){ 225 int status = att_server_can_send_packet_now(att_con_handle); 226 CHECK_EQUAL(1, status); 227 228 status = att_server_can_send_packet_now(0x50); 229 CHECK_EQUAL(0, status); 230 } 231 232 TEST(ATT_SERVER, att_server_request_to_send_indication){ 233 int status = att_server_request_to_send_indication(&indication_callback, 0x55); 234 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 235 236 l2cap_can_send_fixed_channel_packet_now_set_status(0); 237 238 status = att_server_request_to_send_indication(&indication_callback, att_con_handle); 239 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 240 241 status = att_server_request_to_send_indication(&indication_callback, att_con_handle); 242 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 243 } 244 245 TEST(ATT_SERVER, att_server_request_to_send_notification){ 246 int status = att_server_request_to_send_notification(¬ification_callback, 0x55); 247 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 248 249 l2cap_can_send_fixed_channel_packet_now_set_status(0); 250 251 status = att_server_request_to_send_notification(¬ification_callback, att_con_handle); 252 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 253 254 status = att_server_request_to_send_notification(¬ification_callback, att_con_handle); 255 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 256 } 257 258 TEST(ATT_SERVER, att_server_register_can_send_now_callback){ 259 int status = att_server_register_can_send_now_callback(¬ification_callback, 0x55); 260 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 261 262 att_server_register_packet_handler(&att_event_packet_handler); 263 } 264 265 TEST(ATT_SERVER, opcode_ATT_WRITE_REQUEST){ 266 uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 267 uint8_t buffer[] = {1, 0}; 268 269 uint16_t att_request_len = att_write_request(ATT_WRITE_REQUEST, value_handle, sizeof(buffer), buffer); 270 mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len); 271 } 272 273 TEST(ATT_SERVER, connection_complete_event){ 274 uint8_t buffer[21]; 275 buffer[0] = HCI_EVENT_LE_META; 276 buffer[1] = 19; 277 buffer[2] = HCI_SUBEVENT_LE_CONNECTION_COMPLETE; 278 279 // call with wrong con_handle 280 little_endian_store_16(buffer,4,HCI_CON_HANDLE_INVALID); 281 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 282 283 // call with correct con_handle 284 little_endian_store_16(buffer,4,att_con_handle); 285 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 286 287 // use max MTU > ATT_REQUEST_BUFFER_SIZE 288 mock_l2cap_set_max_mtu(ATT_REQUEST_BUFFER_SIZE + 10); 289 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 290 291 // wrong subevent 292 buffer[2] = 0xFF; 293 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 294 } 295 296 TEST(ATT_SERVER, connection_disconnect_complete_event) { 297 uint8_t buffer[6]; 298 buffer[0] = HCI_EVENT_DISCONNECTION_COMPLETE; 299 buffer[1] = 19; 300 buffer[2] = 0; 301 302 // call with wrong con_handle 303 little_endian_store_16(buffer, 3, HCI_CON_HANDLE_INVALID); 304 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 305 306 // call with correct con_handle 307 little_endian_store_16(buffer, 3, att_con_handle); 308 mock_call_att_packet_handler(HCI_EVENT_PACKET, 0, &buffer[0], sizeof(buffer)); 309 } 310 311 312 int main (int argc, const char * argv[]){ 313 return CommandLineTestRunner::RunAllTests(argc, argv); 314 } 315