1 2 // ***************************************************************************** 3 // 4 // test Battery Service Client 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 #include "CppUTestExt/MockSupport.h" 17 18 #include "bluetooth.h" 19 #include "bluetooth_gatt.h" 20 #include "btstack_debug.h" 21 #include "btstack_event.h" 22 #include "btstack_memory.h" 23 #include "btstack_util.h" 24 #include "hci.h" 25 26 #include "ble/gatt-service/device_information_service_client.h" 27 #include "mock_gatt_client.h" 28 29 static const hci_con_handle_t con_handle = 0x01; 30 static bool connected; 31 32 // temp btstack run loop mock 33 34 static btstack_timer_source_t * btstack_timer = NULL; 35 36 static bool manufacturer_name = false; 37 static bool model_number = false; 38 static bool serial_number = false; 39 static bool hardware_revision = false; 40 static bool firmware_revision = false; 41 static bool software_revision = false; 42 static bool system_id = false; 43 static bool ieee_regulatory_certification = false; 44 static bool pnp_id = false; 45 46 static bool mock_wrong_hci_event_packet_type = false; 47 48 extern "C" void device_information_service_client_set_invalid_state(void); 49 50 void btstack_run_lopo_deinit(void){ 51 btstack_timer = NULL; 52 } 53 54 void btstack_run_loop_add_timer(btstack_timer_source_t * timer){ 55 btstack_timer = timer; 56 } 57 58 int btstack_run_loop_remove_timer(btstack_timer_source_t * timer){ 59 btstack_timer = NULL; 60 return 1; 61 } 62 63 void btstack_run_loop_set_timer(btstack_timer_source_t * timer, uint32_t timeout_in_ms){ 64 } 65 66 void btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer, void (*process)(btstack_timer_source_t * _timer)){ 67 timer->process = process; 68 } 69 70 void btstack_run_loop_set_timer_context(btstack_timer_source_t * timer, void * context){ 71 timer->context = context; 72 } 73 74 void * btstack_run_loop_get_timer_context(btstack_timer_source_t * timer){ 75 return timer->context; 76 } 77 78 void mock_btstack_run_loop_trigger_timer(void){ 79 btstack_assert(btstack_timer != NULL); 80 (*btstack_timer->process)(btstack_timer); 81 } 82 83 // simulate btstack_memory_battery_service_client_get 84 85 static bool mock_btstack_memory_battery_service_client_no_memory; 86 static battery_service_client_t * mock_btstack_memory_battery_service_client_last_alloc; 87 88 void btstack_memory_init(void){ 89 mock_btstack_memory_battery_service_client_no_memory = false; 90 mock_btstack_memory_battery_service_client_last_alloc = NULL; 91 } 92 93 void mock_btstack_memory_battery_service_client_simulate_no_memory(void){ 94 mock_btstack_memory_battery_service_client_no_memory = true; 95 } 96 97 battery_service_client_t * mock_btstack_memory_battery_service_client_get_last_alloc(void){ 98 btstack_assert(mock_btstack_memory_battery_service_client_last_alloc != NULL); 99 return mock_btstack_memory_battery_service_client_last_alloc; 100 } 101 102 battery_service_client_t * btstack_memory_battery_service_client_get(void){ 103 if (mock_btstack_memory_battery_service_client_no_memory){ 104 return NULL; 105 } 106 mock_btstack_memory_battery_service_client_last_alloc = (battery_service_client_t *) malloc(sizeof(battery_service_client_t)); 107 memset(mock_btstack_memory_battery_service_client_last_alloc, 0, sizeof(battery_service_client_t)); 108 return mock_btstack_memory_battery_service_client_last_alloc; 109 } 110 111 void btstack_memory_battery_service_client_free(battery_service_client_t *battery_service_client){ 112 free(battery_service_client); 113 } 114 115 static void gatt_client_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 116 UNUSED(packet_type); 117 UNUSED(channel); 118 UNUSED(size); 119 120 uint8_t status; 121 // uint8_t att_status; 122 123 if (hci_event_packet_get_type(packet) != HCI_EVENT_GATTSERVICE_META){ 124 return; 125 } 126 127 switch (hci_event_gattservice_meta_get_subevent_code(packet)){ 128 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_DONE: 129 status = gattservice_subevent_device_information_done_get_att_status(packet); 130 switch (status){ 131 case ATT_ERROR_SUCCESS: 132 connected = true; 133 break; 134 default: 135 connected = false; 136 break; 137 } 138 break; 139 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_MANUFACTURER_NAME: 140 manufacturer_name = true; 141 break; 142 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_MODEL_NUMBER: 143 model_number = true; 144 break; 145 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SERIAL_NUMBER: 146 serial_number = true; 147 break; 148 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_HARDWARE_REVISION: 149 hardware_revision = true; 150 break; 151 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_FIRMWARE_REVISION: 152 firmware_revision = true; 153 break; 154 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SOFTWARE_REVISION: 155 software_revision = true; 156 break; 157 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_SYSTEM_ID: 158 system_id = true; 159 break; 160 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_IEEE_REGULATORY_CERTIFICATION: 161 ieee_regulatory_certification = true; 162 break; 163 case GATTSERVICE_SUBEVENT_DEVICE_INFORMATION_PNP_ID: 164 pnp_id = true; 165 break; 166 167 default: 168 break; 169 } 170 } 171 172 TEST_GROUP(DEVICE_INFORMATION_SERVICE_CLIENT){ 173 mock_gatt_client_service_t * service; 174 mock_gatt_client_characteristic_t * characteristic; 175 176 void setup(void){ 177 mock_wrong_hci_event_packet_type = false; 178 manufacturer_name = false; 179 model_number = false; 180 serial_number = false; 181 hardware_revision = false; 182 firmware_revision = false; 183 software_revision = false; 184 system_id = false; 185 ieee_regulatory_certification = false; 186 pnp_id = false; 187 188 device_information_service_client_init(); 189 mock_gatt_client_reset(); 190 } 191 192 void setup_service(bool add_characteristic){ 193 uint8_t buffer[] = {0x01, 0x02}; 194 service = mock_gatt_client_add_primary_service_uuid16(ORG_BLUETOOTH_SERVICE_DEVICE_INFORMATION); 195 196 if (!add_characteristic) return; 197 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_MANUFACTURER_NAME_STRING, ATT_PROPERTY_READ); 198 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer)); 199 } 200 201 void setup_full_service(void){ 202 static uint8_t buffer[] = {0x01, 0x02}; 203 static uint8_t system_id_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; 204 static uint8_t ieee_buffer[] = {0x01, 0x02, 0x03, 0x04}; 205 static uint8_t pnp_id_buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; 206 207 service = mock_gatt_client_add_primary_service_uuid16(ORG_BLUETOOTH_SERVICE_DEVICE_INFORMATION); 208 209 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_MANUFACTURER_NAME_STRING, ATT_PROPERTY_READ); 210 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer)); 211 212 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_MODEL_NUMBER_STRING , ATT_PROPERTY_READ); 213 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer)); 214 215 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_SERIAL_NUMBER_STRING , ATT_PROPERTY_READ); 216 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer)); 217 218 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_HARDWARE_REVISION_STRING, ATT_PROPERTY_READ); 219 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer)); 220 221 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_FIRMWARE_REVISION_STRING, ATT_PROPERTY_READ); 222 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer)); 223 224 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_SOFTWARE_REVISION_STRING, ATT_PROPERTY_READ); 225 mock_gatt_client_set_characteristic_value(characteristic, buffer, sizeof(buffer)); 226 227 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_SYSTEM_ID, ATT_PROPERTY_READ); 228 mock_gatt_client_set_characteristic_value(characteristic, system_id_buffer, sizeof(system_id_buffer)); 229 230 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_IEEE_11073_20601_REGULATORY_CERTIFICATION_DATA_LIST, ATT_PROPERTY_READ); 231 mock_gatt_client_set_characteristic_value(characteristic, ieee_buffer, sizeof(ieee_buffer)); 232 233 characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_PNP_ID, ATT_PROPERTY_READ); 234 mock_gatt_client_set_characteristic_value(characteristic, pnp_id_buffer, sizeof(pnp_id_buffer)); 235 } 236 237 void teardown(void){ 238 device_information_service_client_deinit(); 239 } 240 }; 241 242 243 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, double_query){ 244 uint8_t status; 245 246 status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 247 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 248 249 status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 250 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 251 252 status = device_information_service_client_query(HCI_CON_HANDLE_INVALID, &gatt_client_event_handler); 253 CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 254 } 255 256 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_no_service){ 257 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 258 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 259 260 mock_gatt_client_run(); 261 CHECK_EQUAL(false, connected); 262 } 263 264 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_no_caharacteristic){ 265 setup_service(false); 266 267 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 268 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 269 270 mock_gatt_client_run(); 271 CHECK_EQUAL(false, connected); 272 } 273 274 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_att_error){ 275 setup_service(false); 276 mock_gatt_client_set_att_error_discover_primary_services(); 277 278 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 279 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 280 281 mock_gatt_client_run(); 282 CHECK_EQUAL(false, connected); 283 } 284 285 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_one_chr){ 286 setup_service(true); 287 288 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 289 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 290 291 mock_gatt_client_run(); 292 CHECK_EQUAL(true, connected); 293 } 294 295 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_one_chr_att_error){ 296 setup_service(true); 297 mock_gatt_client_set_att_error_read_value_characteristics(); 298 // mock_gatt_client_dump_services(); 299 300 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 301 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 302 303 mock_gatt_client_run(); 304 CHECK_EQUAL(true, connected); 305 } 306 307 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, query_service_full_setup_no_error){ 308 setup_full_service(); 309 310 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 311 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 312 313 mock_gatt_client_run(); 314 CHECK_EQUAL(true, connected); 315 316 CHECK_EQUAL(true, manufacturer_name); 317 CHECK_EQUAL(true, model_number); 318 CHECK_EQUAL(true, serial_number); 319 CHECK_EQUAL(true, hardware_revision); 320 CHECK_EQUAL(true, firmware_revision); 321 CHECK_EQUAL(true, software_revision); 322 323 CHECK_EQUAL(true, system_id); 324 CHECK_EQUAL(true, ieee_regulatory_certification); 325 CHECK_EQUAL(true, pnp_id); 326 } 327 328 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, unhandled_gatt_event_when_connected){ 329 setup_service(true); 330 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 331 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 332 mock_gatt_client_run(); 333 CHECK_EQUAL(true, connected); 334 335 mock_gatt_client_emit_dummy_event(); 336 CHECK_EQUAL(true, connected); 337 } 338 339 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, unhandled_gatt_event_when_not_connected){ 340 setup_service(true); 341 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 342 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 343 344 CHECK_EQUAL(false, connected); 345 346 mock_gatt_client_emit_dummy_event(); 347 CHECK_EQUAL(false, connected); 348 349 mock_gatt_client_run(); 350 CHECK_EQUAL(true, connected); 351 } 352 353 354 TEST(DEVICE_INFORMATION_SERVICE_CLIENT, client_in_wrong_state){ 355 setup_service(true); 356 uint8_t status = device_information_service_client_query(con_handle, &gatt_client_event_handler); 357 CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 358 359 device_information_service_client_set_invalid_state(); 360 mock_gatt_client_run(); 361 CHECK_EQUAL(false, connected); 362 } 363 364 int main (int argc, const char * argv[]){ 365 return CommandLineTestRunner::RunAllTests(argc, argv); 366 } 367