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