1*4902524cSMatthias Ringwald 2*4902524cSMatthias Ringwald // ***************************************************************************** 3*4902524cSMatthias Ringwald // 4*4902524cSMatthias Ringwald // test Battery Service Client 5*4902524cSMatthias Ringwald // 6*4902524cSMatthias Ringwald // ***************************************************************************** 7*4902524cSMatthias Ringwald 8*4902524cSMatthias Ringwald 9*4902524cSMatthias Ringwald #include <stdint.h> 10*4902524cSMatthias Ringwald #include <stdio.h> 11*4902524cSMatthias Ringwald #include <stdlib.h> 12*4902524cSMatthias Ringwald #include <string.h> 13*4902524cSMatthias Ringwald 14*4902524cSMatthias Ringwald #include "CppUTest/TestHarness.h" 15*4902524cSMatthias Ringwald #include "CppUTest/CommandLineTestRunner.h" 16*4902524cSMatthias Ringwald #include "CppUTestExt/MockSupport.h" 17*4902524cSMatthias Ringwald 18*4902524cSMatthias Ringwald #include "bluetooth.h" 19*4902524cSMatthias Ringwald #include "bluetooth_gatt.h" 20*4902524cSMatthias Ringwald #include "btstack_debug.h" 21*4902524cSMatthias Ringwald #include "btstack_event.h" 22*4902524cSMatthias Ringwald #include "btstack_memory.h" 23*4902524cSMatthias Ringwald #include "btstack_util.h" 24*4902524cSMatthias Ringwald #include "hci.h" 25*4902524cSMatthias Ringwald 26*4902524cSMatthias Ringwald #include "ble/gatt-service/battery_service_client.h" 27*4902524cSMatthias Ringwald #include "mock_gatt_client.h" 28*4902524cSMatthias Ringwald 29*4902524cSMatthias Ringwald static const hci_con_handle_t con_handle = 0x01; 30*4902524cSMatthias Ringwald static bool connected; 31*4902524cSMatthias Ringwald static uint8_t num_instances = 0; 32*4902524cSMatthias Ringwald // temp btstack run loop mock 33*4902524cSMatthias Ringwald 34*4902524cSMatthias Ringwald static btstack_timer_source_t * btstack_timer = NULL; 35*4902524cSMatthias Ringwald static uint8_t battery_level[10]; 36*4902524cSMatthias Ringwald static uint16_t battery_level_size; 37*4902524cSMatthias Ringwald 38*4902524cSMatthias Ringwald void btstack_run_lopo_deinit(void){ 39*4902524cSMatthias Ringwald btstack_timer = NULL; 40*4902524cSMatthias Ringwald } 41*4902524cSMatthias Ringwald 42*4902524cSMatthias Ringwald void btstack_run_loop_add_timer(btstack_timer_source_t * timer){ 43*4902524cSMatthias Ringwald btstack_timer = timer; 44*4902524cSMatthias Ringwald } 45*4902524cSMatthias Ringwald 46*4902524cSMatthias Ringwald int btstack_run_loop_remove_timer(btstack_timer_source_t * timer){ 47*4902524cSMatthias Ringwald btstack_timer = NULL; 48*4902524cSMatthias Ringwald return 1; 49*4902524cSMatthias Ringwald } 50*4902524cSMatthias Ringwald 51*4902524cSMatthias Ringwald void btstack_run_loop_set_timer(btstack_timer_source_t * timer, uint32_t timeout_in_ms){ 52*4902524cSMatthias Ringwald } 53*4902524cSMatthias Ringwald 54*4902524cSMatthias Ringwald void btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer, void (*process)(btstack_timer_source_t * _timer)){ 55*4902524cSMatthias Ringwald timer->process = process; 56*4902524cSMatthias Ringwald } 57*4902524cSMatthias Ringwald 58*4902524cSMatthias Ringwald void btstack_run_loop_set_timer_context(btstack_timer_source_t * timer, void * context){ 59*4902524cSMatthias Ringwald timer->context = context; 60*4902524cSMatthias Ringwald } 61*4902524cSMatthias Ringwald 62*4902524cSMatthias Ringwald void * btstack_run_loop_get_timer_context(btstack_timer_source_t * timer){ 63*4902524cSMatthias Ringwald return timer->context; 64*4902524cSMatthias Ringwald } 65*4902524cSMatthias Ringwald 66*4902524cSMatthias Ringwald void mock_btstack_run_loop_trigger_timer(void){ 67*4902524cSMatthias Ringwald btstack_assert(btstack_timer != NULL); 68*4902524cSMatthias Ringwald (*btstack_timer->process)(btstack_timer); 69*4902524cSMatthias Ringwald } 70*4902524cSMatthias Ringwald 71*4902524cSMatthias Ringwald // simulate btstack_memory_battery_service_client_get 72*4902524cSMatthias Ringwald 73*4902524cSMatthias Ringwald static bool mock_btstack_memory_battery_service_client_no_memory; 74*4902524cSMatthias Ringwald static battery_service_client_t * mock_btstack_memory_battery_service_client_last_alloc; 75*4902524cSMatthias Ringwald 76*4902524cSMatthias Ringwald void btstack_memory_init(void){ 77*4902524cSMatthias Ringwald mock_btstack_memory_battery_service_client_no_memory = false; 78*4902524cSMatthias Ringwald mock_btstack_memory_battery_service_client_last_alloc = NULL; 79*4902524cSMatthias Ringwald } 80*4902524cSMatthias Ringwald 81*4902524cSMatthias Ringwald void mock_btstack_memory_battery_service_client_simulate_no_memory(void){ 82*4902524cSMatthias Ringwald mock_btstack_memory_battery_service_client_no_memory = true; 83*4902524cSMatthias Ringwald } 84*4902524cSMatthias Ringwald 85*4902524cSMatthias Ringwald battery_service_client_t * mock_btstack_memory_battery_service_client_get_last_alloc(void){ 86*4902524cSMatthias Ringwald btstack_assert(mock_btstack_memory_battery_service_client_last_alloc != NULL); 87*4902524cSMatthias Ringwald return mock_btstack_memory_battery_service_client_last_alloc; 88*4902524cSMatthias Ringwald } 89*4902524cSMatthias Ringwald 90*4902524cSMatthias Ringwald battery_service_client_t * btstack_memory_battery_service_client_get(void){ 91*4902524cSMatthias Ringwald if (mock_btstack_memory_battery_service_client_no_memory){ 92*4902524cSMatthias Ringwald return NULL; 93*4902524cSMatthias Ringwald } 94*4902524cSMatthias Ringwald mock_btstack_memory_battery_service_client_last_alloc = (battery_service_client_t *) malloc(sizeof(battery_service_client_t)); 95*4902524cSMatthias Ringwald memset(mock_btstack_memory_battery_service_client_last_alloc, 0, sizeof(battery_service_client_t)); 96*4902524cSMatthias Ringwald return mock_btstack_memory_battery_service_client_last_alloc; 97*4902524cSMatthias Ringwald } 98*4902524cSMatthias Ringwald 99*4902524cSMatthias Ringwald void btstack_memory_battery_service_client_free(battery_service_client_t *battery_service_client){ 100*4902524cSMatthias Ringwald free(battery_service_client); 101*4902524cSMatthias Ringwald } 102*4902524cSMatthias Ringwald 103*4902524cSMatthias Ringwald static void gatt_client_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 104*4902524cSMatthias Ringwald UNUSED(packet_type); 105*4902524cSMatthias Ringwald UNUSED(channel); 106*4902524cSMatthias Ringwald UNUSED(size); 107*4902524cSMatthias Ringwald 108*4902524cSMatthias Ringwald uint8_t status; 109*4902524cSMatthias Ringwald uint8_t att_status; 110*4902524cSMatthias Ringwald 111*4902524cSMatthias Ringwald if (hci_event_packet_get_type(packet) != HCI_EVENT_GATTSERVICE_META){ 112*4902524cSMatthias Ringwald return; 113*4902524cSMatthias Ringwald } 114*4902524cSMatthias Ringwald 115*4902524cSMatthias Ringwald switch (hci_event_gattservice_meta_get_subevent_code(packet)){ 116*4902524cSMatthias Ringwald case GATTSERVICE_SUBEVENT_BATTERY_SERVICE_CONNECTED: 117*4902524cSMatthias Ringwald status = gattservice_subevent_battery_service_connected_get_status(packet); 118*4902524cSMatthias Ringwald switch (status){ 119*4902524cSMatthias Ringwald case ERROR_CODE_SUCCESS: 120*4902524cSMatthias Ringwald num_instances = gattservice_subevent_battery_service_connected_get_num_instances(packet); 121*4902524cSMatthias Ringwald connected = true; 122*4902524cSMatthias Ringwald break; 123*4902524cSMatthias Ringwald default: 124*4902524cSMatthias Ringwald connected = false; 125*4902524cSMatthias Ringwald break; 126*4902524cSMatthias Ringwald } 127*4902524cSMatthias Ringwald break; 128*4902524cSMatthias Ringwald 129*4902524cSMatthias Ringwald case GATTSERVICE_SUBEVENT_BATTERY_SERVICE_LEVEL: 130*4902524cSMatthias Ringwald att_status = gattservice_subevent_battery_service_level_get_att_status(packet); 131*4902524cSMatthias Ringwald if (att_status != ATT_ERROR_SUCCESS){ 132*4902524cSMatthias Ringwald // printf("Battery level read failed, ATT Error 0x%02x\n", att_status); 133*4902524cSMatthias Ringwald break; 134*4902524cSMatthias Ringwald } 135*4902524cSMatthias Ringwald 136*4902524cSMatthias Ringwald // printf("Battery level 0x%02x\n", gattservice_subevent_battery_service_level_get_level(packet)); 137*4902524cSMatthias Ringwald CHECK_EQUAL(battery_level[0], gattservice_subevent_battery_service_level_get_level(packet)); 138*4902524cSMatthias Ringwald CHECK_EQUAL(0, gattservice_subevent_battery_service_level_get_sevice_index(packet)); 139*4902524cSMatthias Ringwald break; 140*4902524cSMatthias Ringwald 141*4902524cSMatthias Ringwald default: 142*4902524cSMatthias Ringwald break; 143*4902524cSMatthias Ringwald } 144*4902524cSMatthias Ringwald } 145*4902524cSMatthias Ringwald 146*4902524cSMatthias Ringwald TEST_GROUP(BATTERY_SERVICE_CLIENT){ 147*4902524cSMatthias Ringwald uint16_t battery_service_cid; 148*4902524cSMatthias Ringwald uint32_t poll_interval_ms; 149*4902524cSMatthias Ringwald mock_gatt_client_service_t * service; 150*4902524cSMatthias Ringwald mock_gatt_client_characteristic_t * characteristic; 151*4902524cSMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * descriptor; 152*4902524cSMatthias Ringwald 153*4902524cSMatthias Ringwald uint8_t value_buffer[3]; 154*4902524cSMatthias Ringwald 155*4902524cSMatthias Ringwald void setup(void){ 156*4902524cSMatthias Ringwald battery_service_cid = 1; 157*4902524cSMatthias Ringwald connected = false; 158*4902524cSMatthias Ringwald poll_interval_ms = 2000; 159*4902524cSMatthias Ringwald 160*4902524cSMatthias Ringwald uint16_t i; 161*4902524cSMatthias Ringwald for (i = 0; i < sizeof(value_buffer); i++){ 162*4902524cSMatthias Ringwald value_buffer[i] = (i+1)*11; 163*4902524cSMatthias Ringwald } 164*4902524cSMatthias Ringwald 165*4902524cSMatthias Ringwald btstack_memory_init(); 166*4902524cSMatthias Ringwald mock_gatt_client_reset(); 167*4902524cSMatthias Ringwald battery_service_client_init(); 168*4902524cSMatthias Ringwald } 169*4902524cSMatthias Ringwald 170*4902524cSMatthias Ringwald void set_battery_level_of_size(uint16_t value_length){ 171*4902524cSMatthias Ringwald battery_level_size = btstack_min(value_length, sizeof(battery_level)); 172*4902524cSMatthias Ringwald uint8_t i; 173*4902524cSMatthias Ringwald for (i=0; i<battery_level_size; i++){ 174*4902524cSMatthias Ringwald battery_level[i] = i+1; 175*4902524cSMatthias Ringwald } 176*4902524cSMatthias Ringwald mock_gatt_client_set_characteristic_value(characteristic, battery_level, battery_level_size); 177*4902524cSMatthias Ringwald } 178*4902524cSMatthias Ringwald 179*4902524cSMatthias Ringwald void setup_service(bool add_characteristics, bool add_descriptors){ 180*4902524cSMatthias Ringwald service = mock_gatt_client_add_primary_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE); 181*4902524cSMatthias Ringwald if (!add_characteristics) return; 182*4902524cSMatthias Ringwald 183*4902524cSMatthias Ringwald characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, ATT_PROPERTY_NOTIFY); 184*4902524cSMatthias Ringwald 185*4902524cSMatthias Ringwald if (!add_descriptors) return; 186*4902524cSMatthias Ringwald descriptor = mock_gatt_client_add_characteristic_descriptor_uuid16(ORG_BLUETOOTH_DESCRIPTOR_GATT_CLIENT_CHARACTERISTIC_CONFIGURATION); 187*4902524cSMatthias Ringwald mock_gatt_client_set_descriptor_characteristic_value(descriptor, value_buffer, sizeof(value_buffer)); 188*4902524cSMatthias Ringwald 189*4902524cSMatthias Ringwald // mock_gatt_client_dump_services(); 190*4902524cSMatthias Ringwald } 191*4902524cSMatthias Ringwald 192*4902524cSMatthias Ringwald void setup_service_without_notify_capabality(bool add_characteristics, bool add_descriptors){ 193*4902524cSMatthias Ringwald service = mock_gatt_client_add_primary_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE); 194*4902524cSMatthias Ringwald if (!add_characteristics) return; 195*4902524cSMatthias Ringwald 196*4902524cSMatthias Ringwald characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, ATT_PROPERTY_READ); 197*4902524cSMatthias Ringwald 198*4902524cSMatthias Ringwald if (!add_descriptors) return; 199*4902524cSMatthias Ringwald descriptor = mock_gatt_client_add_characteristic_descriptor_uuid16(ORG_BLUETOOTH_DESCRIPTOR_GATT_CLIENT_CHARACTERISTIC_CONFIGURATION); 200*4902524cSMatthias Ringwald mock_gatt_client_set_descriptor_characteristic_value(descriptor, value_buffer, sizeof(value_buffer)); 201*4902524cSMatthias Ringwald 202*4902524cSMatthias Ringwald // mock_gatt_client_dump_services(); 203*4902524cSMatthias Ringwald } 204*4902524cSMatthias Ringwald 205*4902524cSMatthias Ringwald void connect(void){ 206*4902524cSMatthias Ringwald uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid); 207*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 208*4902524cSMatthias Ringwald mock_gatt_client_run(); 209*4902524cSMatthias Ringwald } 210*4902524cSMatthias Ringwald 211*4902524cSMatthias Ringwald void teardown(void){ 212*4902524cSMatthias Ringwald battery_service_client_deinit(); 213*4902524cSMatthias Ringwald } 214*4902524cSMatthias Ringwald }; 215*4902524cSMatthias Ringwald 216*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, unhandled_gatt_event){ 217*4902524cSMatthias Ringwald mock_gatt_client_emit_dummy_event(); 218*4902524cSMatthias Ringwald } 219*4902524cSMatthias Ringwald 220*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, gatt_event_in_wrong_state){ 221*4902524cSMatthias Ringwald uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, NULL); 222*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 223*4902524cSMatthias Ringwald // mock_gatt_client_run_once(); 224*4902524cSMatthias Ringwald // mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 225*4902524cSMatthias Ringwald } 226*4902524cSMatthias Ringwald 227*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_no_memory){ 228*4902524cSMatthias Ringwald mock_btstack_memory_battery_service_client_simulate_no_memory(); 229*4902524cSMatthias Ringwald uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, NULL); 230*4902524cSMatthias Ringwald CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status); 231*4902524cSMatthias Ringwald } 232*4902524cSMatthias Ringwald 233*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_no_cid){ 234*4902524cSMatthias Ringwald uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, NULL); 235*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 236*4902524cSMatthias Ringwald 237*4902524cSMatthias Ringwald mock_gatt_client_run(); 238*4902524cSMatthias Ringwald CHECK_EQUAL(false, connected); 239*4902524cSMatthias Ringwald } 240*4902524cSMatthias Ringwald 241*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_no_service){ 242*4902524cSMatthias Ringwald uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid); 243*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 244*4902524cSMatthias Ringwald 245*4902524cSMatthias Ringwald mock_gatt_client_run(); 246*4902524cSMatthias Ringwald CHECK_EQUAL(false, connected); 247*4902524cSMatthias Ringwald } 248*4902524cSMatthias Ringwald 249*4902524cSMatthias Ringwald 250*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_with_service_no_chr_no_desc){ 251*4902524cSMatthias Ringwald setup_service(false, false); 252*4902524cSMatthias Ringwald connect(); 253*4902524cSMatthias Ringwald CHECK_EQUAL(false, connected); 254*4902524cSMatthias Ringwald } 255*4902524cSMatthias Ringwald 256*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_with_service_and_chr_no_desc){ 257*4902524cSMatthias Ringwald setup_service(true, false); 258*4902524cSMatthias Ringwald connect(); 259*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 260*4902524cSMatthias Ringwald } 261*4902524cSMatthias Ringwald 262*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_with_service_and_chr_and_desc){ 263*4902524cSMatthias Ringwald setup_service(true, true); 264*4902524cSMatthias Ringwald connect(); 265*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 266*4902524cSMatthias Ringwald } 267*4902524cSMatthias Ringwald 268*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_with_one_invalid_and_one_valid_service){ 269*4902524cSMatthias Ringwald setup_service(false, false); 270*4902524cSMatthias Ringwald setup_service(true, true); 271*4902524cSMatthias Ringwald connect(); 272*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 273*4902524cSMatthias Ringwald } 274*4902524cSMatthias Ringwald 275*4902524cSMatthias Ringwald 276*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, double_connect){ 277*4902524cSMatthias Ringwald setup_service(true, true); 278*4902524cSMatthias Ringwald connect(); 279*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 280*4902524cSMatthias Ringwald uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid); 281*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status); 282*4902524cSMatthias Ringwald } 283*4902524cSMatthias Ringwald 284*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_discover_primary_service_error){ 285*4902524cSMatthias Ringwald mock_gatt_client_set_att_error_discover_primary_services(); 286*4902524cSMatthias Ringwald setup_service(true, true); 287*4902524cSMatthias Ringwald connect(); 288*4902524cSMatthias Ringwald CHECK_EQUAL(false, connected); 289*4902524cSMatthias Ringwald } 290*4902524cSMatthias Ringwald 291*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_discover_characteristics_error){ 292*4902524cSMatthias Ringwald mock_gatt_client_set_att_error_discover_characteristics(); 293*4902524cSMatthias Ringwald setup_service(true, true); 294*4902524cSMatthias Ringwald connect(); 295*4902524cSMatthias Ringwald CHECK_EQUAL(false, connected); 296*4902524cSMatthias Ringwald } 297*4902524cSMatthias Ringwald 298*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_discover_characteristic_descriptors_error){ 299*4902524cSMatthias Ringwald mock_gatt_client_set_att_error_discover_characteristic_descriptors(); 300*4902524cSMatthias Ringwald setup_service(true, true); 301*4902524cSMatthias Ringwald connect(); 302*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 303*4902524cSMatthias Ringwald } 304*4902524cSMatthias Ringwald 305*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_ignore_too_many_service){ 306*4902524cSMatthias Ringwald uint8_t i; 307*4902524cSMatthias Ringwald for (i = 0; i < MAX_NUM_BATTERY_SERVICES + 2; i++){ 308*4902524cSMatthias Ringwald setup_service(true, true); 309*4902524cSMatthias Ringwald } 310*4902524cSMatthias Ringwald setup_service(true, true); 311*4902524cSMatthias Ringwald connect(); 312*4902524cSMatthias Ringwald 313*4902524cSMatthias Ringwald CHECK_EQUAL(num_instances, MAX_NUM_BATTERY_SERVICES); 314*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 315*4902524cSMatthias Ringwald } 316*4902524cSMatthias Ringwald 317*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, disconnect_not_connected){ 318*4902524cSMatthias Ringwald uint8_t status; 319*4902524cSMatthias Ringwald 320*4902524cSMatthias Ringwald status = battery_service_client_disconnect(battery_service_cid); 321*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 322*4902524cSMatthias Ringwald } 323*4902524cSMatthias Ringwald 324*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, double_disconnect){ 325*4902524cSMatthias Ringwald uint8_t status; 326*4902524cSMatthias Ringwald 327*4902524cSMatthias Ringwald setup_service(true, true); 328*4902524cSMatthias Ringwald connect(); 329*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 330*4902524cSMatthias Ringwald 331*4902524cSMatthias Ringwald status = battery_service_client_disconnect(battery_service_cid); 332*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 333*4902524cSMatthias Ringwald 334*4902524cSMatthias Ringwald status = battery_service_client_disconnect(battery_service_cid); 335*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 336*4902524cSMatthias Ringwald } 337*4902524cSMatthias Ringwald 338*4902524cSMatthias Ringwald 339*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_invalid_0){ 340*4902524cSMatthias Ringwald setup_service(true, true); 341*4902524cSMatthias Ringwald connect(); 342*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 343*4902524cSMatthias Ringwald 344*4902524cSMatthias Ringwald set_battery_level_of_size(0); 345*4902524cSMatthias Ringwald mock_gatt_client_send_notification(characteristic, battery_level, battery_level_size); 346*4902524cSMatthias Ringwald // TODO: check battery level was not received 347*4902524cSMatthias Ringwald } 348*4902524cSMatthias Ringwald 349*4902524cSMatthias Ringwald 350*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_invalid_5){ 351*4902524cSMatthias Ringwald setup_service(true, true); 352*4902524cSMatthias Ringwald connect(); 353*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 354*4902524cSMatthias Ringwald 355*4902524cSMatthias Ringwald set_battery_level_of_size(5); 356*4902524cSMatthias Ringwald mock_gatt_client_send_notification(characteristic, battery_level, battery_level_size); 357*4902524cSMatthias Ringwald // TODO: check battery level was not received 358*4902524cSMatthias Ringwald } 359*4902524cSMatthias Ringwald 360*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_wrong_handle){ 361*4902524cSMatthias Ringwald setup_service(true, true); 362*4902524cSMatthias Ringwald connect(); 363*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 364*4902524cSMatthias Ringwald 365*4902524cSMatthias Ringwald set_battery_level_of_size(1); 366*4902524cSMatthias Ringwald mock_gatt_client_send_notification_with_handle(characteristic, 0x1234, battery_level, battery_level_size); 367*4902524cSMatthias Ringwald // TODO: check battery level was not received 368*4902524cSMatthias Ringwald } 369*4902524cSMatthias Ringwald 370*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_wrong_handle_multiple){ 371*4902524cSMatthias Ringwald setup_service(true, true); 372*4902524cSMatthias Ringwald setup_service(true, true); 373*4902524cSMatthias Ringwald connect(); 374*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 375*4902524cSMatthias Ringwald 376*4902524cSMatthias Ringwald set_battery_level_of_size(1); 377*4902524cSMatthias Ringwald mock_gatt_client_send_notification_with_handle(characteristic, 0x1234, battery_level, battery_level_size); 378*4902524cSMatthias Ringwald // TODO: check battery level was not received 379*4902524cSMatthias Ringwald } 380*4902524cSMatthias Ringwald 381*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_valid){ 382*4902524cSMatthias Ringwald setup_service(true, true); 383*4902524cSMatthias Ringwald connect(); 384*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 385*4902524cSMatthias Ringwald 386*4902524cSMatthias Ringwald set_battery_level_of_size(1); 387*4902524cSMatthias Ringwald mock_gatt_client_send_notification(characteristic, battery_level, battery_level_size); 388*4902524cSMatthias Ringwald // TODO: check battery level was received 389*4902524cSMatthias Ringwald } 390*4902524cSMatthias Ringwald 391*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, multiple_connection){ 392*4902524cSMatthias Ringwald battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid); 393*4902524cSMatthias Ringwald battery_service_client_connect(con_handle+1, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid); 394*4902524cSMatthias Ringwald battery_service_client_read_battery_level(10, 0); 395*4902524cSMatthias Ringwald } 396*4902524cSMatthias Ringwald 397*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, read_battery_level_wrong_cid){ 398*4902524cSMatthias Ringwald uint8_t status = battery_service_client_read_battery_level(10, 0); 399*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status); 400*4902524cSMatthias Ringwald } 401*4902524cSMatthias Ringwald 402*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, read_battery_level_wrong_state){ 403*4902524cSMatthias Ringwald // without calling mock_gatt_client_run(), state remains in BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE 404*4902524cSMatthias Ringwald uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid); 405*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 406*4902524cSMatthias Ringwald CHECK_EQUAL(false, connected); 407*4902524cSMatthias Ringwald 408*4902524cSMatthias Ringwald status = battery_service_client_read_battery_level(battery_service_cid, 0); 409*4902524cSMatthias Ringwald CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status); 410*4902524cSMatthias Ringwald } 411*4902524cSMatthias Ringwald 412*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, read_battery_level_wrong_state_in_packet_handler){ 413*4902524cSMatthias Ringwald setup_service(true, true); 414*4902524cSMatthias Ringwald connect(); 415*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 416*4902524cSMatthias Ringwald mock_btstack_memory_battery_service_client_get_last_alloc()->state = BATTERY_SERVICE_CLIENT_STATE_IDLE; 417*4902524cSMatthias Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS); 418*4902524cSMatthias Ringwald } 419*4902524cSMatthias Ringwald 420*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, read_battery_level_wrong_service_index){ 421*4902524cSMatthias Ringwald setup_service(true, true); 422*4902524cSMatthias Ringwald connect(); 423*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 424*4902524cSMatthias Ringwald 425*4902524cSMatthias Ringwald uint8_t status = battery_service_client_read_battery_level(battery_service_cid, 10); 426*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE, status); 427*4902524cSMatthias Ringwald } 428*4902524cSMatthias Ringwald 429*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_invalid){ 430*4902524cSMatthias Ringwald setup_service(true, true); 431*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, false); 432*4902524cSMatthias Ringwald set_battery_level_of_size(5); 433*4902524cSMatthias Ringwald 434*4902524cSMatthias Ringwald 435*4902524cSMatthias Ringwald connect(); 436*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 437*4902524cSMatthias Ringwald 438*4902524cSMatthias Ringwald uint8_t status = battery_service_client_read_battery_level(battery_service_cid, 0); 439*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 440*4902524cSMatthias Ringwald } 441*4902524cSMatthias Ringwald 442*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value){ 443*4902524cSMatthias Ringwald setup_service(true, true); 444*4902524cSMatthias Ringwald set_battery_level_of_size(1); 445*4902524cSMatthias Ringwald 446*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, false); 447*4902524cSMatthias Ringwald 448*4902524cSMatthias Ringwald connect(); 449*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 450*4902524cSMatthias Ringwald 451*4902524cSMatthias Ringwald uint8_t status = battery_service_client_read_battery_level(battery_service_cid, 0); 452*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 453*4902524cSMatthias Ringwald } 454*4902524cSMatthias Ringwald 455*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_with_error){ 456*4902524cSMatthias Ringwald setup_service(true, true); 457*4902524cSMatthias Ringwald set_battery_level_of_size(1); 458*4902524cSMatthias Ringwald 459*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, false); 460*4902524cSMatthias Ringwald 461*4902524cSMatthias Ringwald connect(); 462*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 463*4902524cSMatthias Ringwald 464*4902524cSMatthias Ringwald uint8_t status = battery_service_client_read_battery_level(battery_service_cid, 0); 465*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 466*4902524cSMatthias Ringwald mock_gatt_client_emit_complete(1); 467*4902524cSMatthias Ringwald } 468*4902524cSMatthias Ringwald 469*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_zero_poll_interval){ 470*4902524cSMatthias Ringwald setup_service(true, true); 471*4902524cSMatthias Ringwald set_battery_level_of_size(1); 472*4902524cSMatthias Ringwald 473*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, false); 474*4902524cSMatthias Ringwald 475*4902524cSMatthias Ringwald uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, 0, &battery_service_cid); 476*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 477*4902524cSMatthias Ringwald mock_gatt_client_run(); 478*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 479*4902524cSMatthias Ringwald 480*4902524cSMatthias Ringwald status = battery_service_client_read_battery_level(battery_service_cid, 0); 481*4902524cSMatthias Ringwald CHECK_EQUAL(ERROR_CODE_SUCCESS, status); 482*4902524cSMatthias Ringwald } 483*4902524cSMatthias Ringwald 484*4902524cSMatthias Ringwald 485*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_trigger_timer){ 486*4902524cSMatthias Ringwald setup_service(true, true); 487*4902524cSMatthias Ringwald set_battery_level_of_size(1); 488*4902524cSMatthias Ringwald 489*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, false); 490*4902524cSMatthias Ringwald 491*4902524cSMatthias Ringwald connect(); 492*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 493*4902524cSMatthias Ringwald mock_btstack_run_loop_trigger_timer(); 494*4902524cSMatthias Ringwald mock_gatt_client_run(); 495*4902524cSMatthias Ringwald } 496*4902524cSMatthias Ringwald 497*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_trigger_timer_unxpected_complete){ 498*4902524cSMatthias Ringwald setup_service(true, true); 499*4902524cSMatthias Ringwald set_battery_level_of_size(1); 500*4902524cSMatthias Ringwald 501*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, false); 502*4902524cSMatthias Ringwald 503*4902524cSMatthias Ringwald connect(); 504*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 505*4902524cSMatthias Ringwald mock_btstack_run_loop_trigger_timer(); 506*4902524cSMatthias Ringwald mock_gatt_client_run(); 507*4902524cSMatthias Ringwald 508*4902524cSMatthias Ringwald // polling done, emit another complete event 509*4902524cSMatthias Ringwald mock_gatt_client_emit_complete(0); 510*4902524cSMatthias Ringwald } 511*4902524cSMatthias Ringwald 512*4902524cSMatthias Ringwald 513*4902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, mixed_poll_and_notify_battery_value){ 514*4902524cSMatthias Ringwald setup_service(true, true); 515*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, true); 516*4902524cSMatthias Ringwald 517*4902524cSMatthias Ringwald setup_service(true, true); 518*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, false); 519*4902524cSMatthias Ringwald 520*4902524cSMatthias Ringwald setup_service(true, true); 521*4902524cSMatthias Ringwald mock_gatt_client_enable_notification(characteristic, true); 522*4902524cSMatthias Ringwald 523*4902524cSMatthias Ringwald connect(); 524*4902524cSMatthias Ringwald CHECK_EQUAL(true, connected); 525*4902524cSMatthias Ringwald } 526*4902524cSMatthias Ringwald 527*4902524cSMatthias Ringwald int main (int argc, const char * argv[]){ 528*4902524cSMatthias Ringwald return CommandLineTestRunner::RunAllTests(argc, argv); 529*4902524cSMatthias Ringwald } 530