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 att_init_connection(uint16_t con_handle); 35 36 static uint8_t att_request[255]; 37 static uint16_t att_write_request(uint16_t request_type, uint16_t attribute_handle, uint16_t value_length, const uint8_t * value){ 38 att_request[0] = request_type; 39 little_endian_store_16(att_request, 1, attribute_handle); 40 (void)memcpy(&att_request[3], value, value_length); 41 return 3 + value_length; 42 } 43 44 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){ 45 UNUSED(connection_handle); 46 UNUSED(att_handle); 47 UNUSED(offset); 48 UNUSED(buffer); 49 UNUSED(buffer_size); 50 51 return 0; 52 } 53 54 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){ 55 UNUSED(connection_handle); 56 UNUSED(att_handle); 57 UNUSED(transaction_mode); 58 UNUSED(offset); 59 UNUSED(buffer); 60 UNUSED(buffer_size); 61 62 return 0; 63 } 64 65 static void att_client_indication_callback(void * context){ 66 } 67 68 TEST_GROUP(ATT_SERVER){ 69 uint16_t att_con_handle; 70 mock_btstack_tlv_t tlv_context; 71 const btstack_tlv_t * tlv_impl; 72 73 void setup(void){ 74 att_con_handle = 0x00; 75 76 att_init_connection(att_con_handle); 77 tlv_impl = mock_btstack_tlv_init_instance(&tlv_context); 78 btstack_tlv_set_instance(tlv_impl, &tlv_context); 79 80 l2cap_can_send_fixed_channel_packet_now_set_status(1); 81 82 // init att db util and add a service and characteristic 83 att_db_util_init(); 84 // 0x180F 85 att_db_util_add_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE); 86 // 0x2A19 87 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); 88 // 0x2A1B 89 att_db_util_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL_STATE, ATT_PROPERTY_NOTIFY, ATT_SECURITY_NONE, ATT_SECURITY_NONE, &battery_level, 1); 90 // 0x2A1A 91 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); 92 // 0x2A49 93 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); 94 // 0x2A35 95 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); 96 97 98 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); 99 // 0x2A38btstack_tlv_set_instance 100 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); 101 102 103 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); 104 // 0x2AAB 105 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); 106 // 0x2A5C 107 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); 108 // setup ATT server 109 att_server_init(att_db_util_get_address(), att_read_callback, att_write_callback); 110 } 111 112 void teardown(void) { 113 mock_btstack_tlv_deinit(&tlv_context); 114 } 115 }; 116 117 118 TEST(ATT_SERVER, gatt_server_get_value_handle_for_characteristic_with_uuid16){ 119 // att_dump_attributes(); 120 uint16_t value_handle; 121 122 // start handle > value handle 123 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0xf000, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 124 CHECK_EQUAL(0, value_handle); 125 126 // end handle < value handle 127 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0x02, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 128 CHECK_EQUAL(0, value_handle); 129 130 // search value handle for unknown UUID 131 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xffff); 132 CHECK_EQUAL(0, value_handle); 133 134 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0); 135 CHECK_EQUAL(0, value_handle); 136 137 // search value handle after one with uuid128_no_bluetooth_base 138 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BODY_SENSOR_LOCATION); 139 CHECK_EQUAL(0x0014, value_handle); 140 141 // search value handle after one with uuid128_with_bluetooth_base 142 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_CGM_SESSION_RUN_TIME); 143 CHECK_EQUAL(0x001a, value_handle); 144 145 // search value handle registered with bluetooth_base 146 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, 0xbbbb); 147 CHECK_EQUAL(0x0017, value_handle); 148 149 // correct read 150 value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 151 CHECK_EQUAL(0x03, value_handle); 152 } 153 154 155 TEST(ATT_SERVER, att_server_indicate){ 156 static uint8_t value[] = {0x55}; 157 uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 158 uint8_t status; 159 160 // invalid connection handle 161 status = att_server_indicate(0x50, value_handle, &value[0], 0); 162 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 163 164 // L2CAP cannot send 165 l2cap_can_send_fixed_channel_packet_now_set_status(0); 166 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 167 CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status); 168 l2cap_can_send_fixed_channel_packet_now_set_status(1); 169 170 // correct command 171 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 172 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 173 174 // already in progress 175 status = att_server_indicate(att_con_handle, value_handle, &value[0], 0); 176 CHECK_EQUAL(ATT_HANDLE_VALUE_INDICATION_IN_PROGRESS, status); 177 } 178 179 TEST(ATT_SERVER, att_server_notify){ 180 static uint8_t value[] = {0x55}; 181 uint16_t value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 182 uint8_t status; 183 184 // invalid connection handle 185 status = att_server_notify(0x50, value_handle, &value[0], 0); 186 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 187 188 // L2CAP cannot send 189 l2cap_can_send_fixed_channel_packet_now_set_status(0); 190 status = att_server_notify(att_con_handle, value_handle, &value[0], 0); 191 CHECK_EQUAL(BTSTACK_ACL_BUFFERS_FULL, status); 192 l2cap_can_send_fixed_channel_packet_now_set_status(1); 193 194 // correct command 195 status = att_server_notify(att_con_handle, value_handle, &value[0], 0); 196 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 197 } 198 199 TEST(ATT_SERVER, att_server_get_mtu){ 200 // invalid connection handle 201 uint8_t mtu = att_server_get_mtu(0x50); 202 CHECK_EQUAL(0, mtu); 203 204 mtu = att_server_get_mtu(att_con_handle); 205 CHECK_EQUAL(23, mtu); 206 } 207 208 TEST(ATT_SERVER, att_server_request_can_send_now_event){ 209 att_server_request_can_send_now_event(att_con_handle); 210 211 } 212 213 TEST(ATT_SERVER, att_server_can_send_packet_now){ 214 int status = att_server_can_send_packet_now(att_con_handle); 215 CHECK_EQUAL(1, status); 216 217 status = att_server_can_send_packet_now(0x50); 218 CHECK_EQUAL(0, status); 219 } 220 221 static btstack_context_callback_registration_t indication_callback; 222 223 TEST(ATT_SERVER, att_server_request_to_send_indication){ 224 225 indication_callback.callback = &att_client_indication_callback; 226 int status = att_server_request_to_send_indication(&indication_callback, 0x55); 227 CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 228 229 l2cap_can_send_fixed_channel_packet_now_set_status(0); 230 231 status = att_server_request_to_send_indication(&indication_callback, att_con_handle); 232 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 233 234 status = att_server_request_to_send_indication(&indication_callback, att_con_handle); 235 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 236 } 237 238 TEST(ATT_SERVER, opcode_ATT_WRITE_REQUEST){ 239 uint16_t value_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(0, 0xffff, ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL); 240 uint8_t buffer[] = {1, 0}; 241 uint16_t att_request_len = att_write_request(ATT_WRITE_REQUEST, value_handle, sizeof(buffer), buffer); 242 mock_call_att_server_packet_handler(ATT_DATA_PACKET, att_con_handle, &att_request[0], att_request_len); 243 } 244 245 int main (int argc, const char * argv[]){ 246 return CommandLineTestRunner::RunAllTests(argc, argv); 247 } 248