xref: /btstack/test/gatt-service-client/battery_service_client_test.cpp (revision 500d8180fa32d9bb205d49465fb0f7fa20250313)
14902524cSMatthias Ringwald 
24902524cSMatthias Ringwald // *****************************************************************************
34902524cSMatthias Ringwald //
44902524cSMatthias Ringwald // test Battery Service Client
54902524cSMatthias Ringwald //
64902524cSMatthias Ringwald // *****************************************************************************
74902524cSMatthias Ringwald 
84902524cSMatthias Ringwald 
94902524cSMatthias Ringwald #include <stdint.h>
104902524cSMatthias Ringwald #include <stdio.h>
114902524cSMatthias Ringwald #include <stdlib.h>
124902524cSMatthias Ringwald #include <string.h>
134902524cSMatthias Ringwald 
144902524cSMatthias Ringwald #include "CppUTest/TestHarness.h"
154902524cSMatthias Ringwald #include "CppUTest/CommandLineTestRunner.h"
164902524cSMatthias Ringwald #include "CppUTestExt/MockSupport.h"
174902524cSMatthias Ringwald 
184902524cSMatthias Ringwald #include "bluetooth.h"
194902524cSMatthias Ringwald #include "bluetooth_gatt.h"
204902524cSMatthias Ringwald #include "btstack_debug.h"
214902524cSMatthias Ringwald #include "btstack_event.h"
224902524cSMatthias Ringwald #include "btstack_memory.h"
234902524cSMatthias Ringwald #include "btstack_util.h"
244902524cSMatthias Ringwald #include "hci.h"
254902524cSMatthias Ringwald 
264902524cSMatthias Ringwald #include "ble/gatt-service/battery_service_client.h"
274902524cSMatthias Ringwald #include "mock_gatt_client.h"
284902524cSMatthias Ringwald 
294902524cSMatthias Ringwald static const hci_con_handle_t con_handle = 0x01;
304902524cSMatthias Ringwald static bool connected;
314902524cSMatthias Ringwald static uint8_t num_instances = 0;
324902524cSMatthias Ringwald // temp btstack run loop mock
334902524cSMatthias Ringwald 
344902524cSMatthias Ringwald static btstack_timer_source_t * btstack_timer = NULL;
354902524cSMatthias Ringwald static uint8_t  battery_level[10];
364902524cSMatthias Ringwald static uint16_t battery_level_size;
374902524cSMatthias Ringwald 
384902524cSMatthias Ringwald void btstack_run_lopo_deinit(void){
394902524cSMatthias Ringwald         btstack_timer = NULL;
404902524cSMatthias Ringwald }
414902524cSMatthias Ringwald 
424902524cSMatthias Ringwald void btstack_run_loop_add_timer(btstack_timer_source_t * timer){
434902524cSMatthias Ringwald     btstack_timer = timer;
444902524cSMatthias Ringwald }
454902524cSMatthias Ringwald 
464902524cSMatthias Ringwald int btstack_run_loop_remove_timer(btstack_timer_source_t * timer){
474902524cSMatthias Ringwald     btstack_timer = NULL;
484902524cSMatthias Ringwald     return 1;
494902524cSMatthias Ringwald }
504902524cSMatthias Ringwald 
514902524cSMatthias Ringwald void btstack_run_loop_set_timer(btstack_timer_source_t * timer, uint32_t timeout_in_ms){
524902524cSMatthias Ringwald }
534902524cSMatthias Ringwald 
544902524cSMatthias Ringwald void btstack_run_loop_set_timer_handler(btstack_timer_source_t * timer, void (*process)(btstack_timer_source_t * _timer)){
554902524cSMatthias Ringwald     timer->process = process;
564902524cSMatthias Ringwald }
574902524cSMatthias Ringwald 
584902524cSMatthias Ringwald void btstack_run_loop_set_timer_context(btstack_timer_source_t * timer, void * context){
594902524cSMatthias Ringwald     timer->context = context;
604902524cSMatthias Ringwald }
614902524cSMatthias Ringwald 
624902524cSMatthias Ringwald void * btstack_run_loop_get_timer_context(btstack_timer_source_t * timer){
634902524cSMatthias Ringwald     return timer->context;
644902524cSMatthias Ringwald }
654902524cSMatthias Ringwald 
664902524cSMatthias Ringwald void mock_btstack_run_loop_trigger_timer(void){
674902524cSMatthias Ringwald     btstack_assert(btstack_timer != NULL);
684902524cSMatthias Ringwald     (*btstack_timer->process)(btstack_timer);
694902524cSMatthias Ringwald }
704902524cSMatthias Ringwald 
714902524cSMatthias Ringwald // simulate  btstack_memory_battery_service_client_get
724902524cSMatthias Ringwald 
734902524cSMatthias Ringwald static bool mock_btstack_memory_battery_service_client_no_memory;
744902524cSMatthias Ringwald static battery_service_client_t * mock_btstack_memory_battery_service_client_last_alloc;
754902524cSMatthias Ringwald 
764902524cSMatthias Ringwald void btstack_memory_init(void){
774902524cSMatthias Ringwald     mock_btstack_memory_battery_service_client_no_memory = false;
784902524cSMatthias Ringwald     mock_btstack_memory_battery_service_client_last_alloc = NULL;
794902524cSMatthias Ringwald }
804902524cSMatthias Ringwald 
814902524cSMatthias Ringwald void mock_btstack_memory_battery_service_client_simulate_no_memory(void){
824902524cSMatthias Ringwald     mock_btstack_memory_battery_service_client_no_memory = true;
834902524cSMatthias Ringwald }
844902524cSMatthias Ringwald 
854902524cSMatthias Ringwald battery_service_client_t * mock_btstack_memory_battery_service_client_get_last_alloc(void){
864902524cSMatthias Ringwald     btstack_assert(mock_btstack_memory_battery_service_client_last_alloc != NULL);
874902524cSMatthias Ringwald     return mock_btstack_memory_battery_service_client_last_alloc;
884902524cSMatthias Ringwald }
894902524cSMatthias Ringwald 
904902524cSMatthias Ringwald battery_service_client_t * btstack_memory_battery_service_client_get(void){
914902524cSMatthias Ringwald     if (mock_btstack_memory_battery_service_client_no_memory){
924902524cSMatthias Ringwald         return NULL;
934902524cSMatthias Ringwald     }
944902524cSMatthias Ringwald     mock_btstack_memory_battery_service_client_last_alloc =  (battery_service_client_t *) malloc(sizeof(battery_service_client_t));
954902524cSMatthias Ringwald     memset(mock_btstack_memory_battery_service_client_last_alloc, 0, sizeof(battery_service_client_t));
964902524cSMatthias Ringwald     return mock_btstack_memory_battery_service_client_last_alloc;
974902524cSMatthias Ringwald }
984902524cSMatthias Ringwald 
994902524cSMatthias Ringwald void btstack_memory_battery_service_client_free(battery_service_client_t *battery_service_client){
1004902524cSMatthias Ringwald     free(battery_service_client);
1014902524cSMatthias Ringwald }
1024902524cSMatthias Ringwald 
1034902524cSMatthias Ringwald static void gatt_client_event_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
1044902524cSMatthias Ringwald     UNUSED(packet_type);
1054902524cSMatthias Ringwald     UNUSED(channel);
1064902524cSMatthias Ringwald     UNUSED(size);
1074902524cSMatthias Ringwald 
1084902524cSMatthias Ringwald     uint8_t status;
1094902524cSMatthias Ringwald     uint8_t att_status;
1104902524cSMatthias Ringwald 
1114902524cSMatthias Ringwald     if (hci_event_packet_get_type(packet) != HCI_EVENT_GATTSERVICE_META){
1124902524cSMatthias Ringwald         return;
1134902524cSMatthias Ringwald     }
1144902524cSMatthias Ringwald 
1154902524cSMatthias Ringwald     switch (hci_event_gattservice_meta_get_subevent_code(packet)){
1164902524cSMatthias Ringwald         case GATTSERVICE_SUBEVENT_BATTERY_SERVICE_CONNECTED:
1174902524cSMatthias Ringwald             status = gattservice_subevent_battery_service_connected_get_status(packet);
1184902524cSMatthias Ringwald             switch (status){
1194902524cSMatthias Ringwald                 case ERROR_CODE_SUCCESS:
1204902524cSMatthias Ringwald                     num_instances = gattservice_subevent_battery_service_connected_get_num_instances(packet);
1214902524cSMatthias Ringwald                     connected = true;
1224902524cSMatthias Ringwald                     break;
1234902524cSMatthias Ringwald                 default:
1244902524cSMatthias Ringwald                     connected = false;
1254902524cSMatthias Ringwald                     break;
1264902524cSMatthias Ringwald             }
1274902524cSMatthias Ringwald             break;
1284902524cSMatthias Ringwald 
1294902524cSMatthias Ringwald         case GATTSERVICE_SUBEVENT_BATTERY_SERVICE_LEVEL:
1304902524cSMatthias Ringwald             att_status = gattservice_subevent_battery_service_level_get_att_status(packet);
1314902524cSMatthias Ringwald             if (att_status != ATT_ERROR_SUCCESS){
1324902524cSMatthias Ringwald                 // printf("Battery level read failed, ATT Error 0x%02x\n", att_status);
1334902524cSMatthias Ringwald                 break;
1344902524cSMatthias Ringwald             }
1354902524cSMatthias Ringwald 
1364902524cSMatthias Ringwald             // printf("Battery level 0x%02x\n", gattservice_subevent_battery_service_level_get_level(packet));
1374902524cSMatthias Ringwald             CHECK_EQUAL(battery_level[0], gattservice_subevent_battery_service_level_get_level(packet));
1384902524cSMatthias Ringwald             CHECK_EQUAL(0, gattservice_subevent_battery_service_level_get_sevice_index(packet));
1394902524cSMatthias Ringwald             break;
1404902524cSMatthias Ringwald 
1414902524cSMatthias Ringwald         default:
1424902524cSMatthias Ringwald             break;
1434902524cSMatthias Ringwald     }
1444902524cSMatthias Ringwald }
1454902524cSMatthias Ringwald 
1464902524cSMatthias Ringwald TEST_GROUP(BATTERY_SERVICE_CLIENT){
1474902524cSMatthias Ringwald     uint16_t battery_service_cid;
1484902524cSMatthias Ringwald     uint32_t poll_interval_ms;
1494902524cSMatthias Ringwald     mock_gatt_client_service_t * service;
1504902524cSMatthias Ringwald     mock_gatt_client_characteristic_t * characteristic;
1514902524cSMatthias Ringwald     mock_gatt_client_characteristic_descriptor_t * descriptor;
1524902524cSMatthias Ringwald 
1534902524cSMatthias Ringwald     uint8_t  value_buffer[3];
1544902524cSMatthias Ringwald 
1554902524cSMatthias Ringwald     void setup(void){
1564902524cSMatthias Ringwald         battery_service_cid = 1;
1574902524cSMatthias Ringwald         connected = false;
1584902524cSMatthias Ringwald         poll_interval_ms = 2000;
1594902524cSMatthias Ringwald 
1604902524cSMatthias Ringwald         uint16_t i;
1614902524cSMatthias Ringwald         for (i = 0; i < sizeof(value_buffer); i++){
1624902524cSMatthias Ringwald             value_buffer[i] = (i+1)*11;
1634902524cSMatthias Ringwald         }
1644902524cSMatthias Ringwald 
1654902524cSMatthias Ringwald         btstack_memory_init();
1664902524cSMatthias Ringwald         mock_gatt_client_reset();
1674902524cSMatthias Ringwald         battery_service_client_init();
1684902524cSMatthias Ringwald     }
1694902524cSMatthias Ringwald 
1704902524cSMatthias Ringwald     void set_battery_level_of_size(uint16_t value_length){
1714902524cSMatthias Ringwald         battery_level_size = btstack_min(value_length, sizeof(battery_level));
1724902524cSMatthias Ringwald         uint8_t i;
1734902524cSMatthias Ringwald         for (i=0; i<battery_level_size; i++){
1744902524cSMatthias Ringwald             battery_level[i] = i+1;
1754902524cSMatthias Ringwald         }
1764902524cSMatthias Ringwald         mock_gatt_client_set_characteristic_value(characteristic, battery_level, battery_level_size);
1774902524cSMatthias Ringwald     }
1784902524cSMatthias Ringwald 
1794902524cSMatthias Ringwald     void setup_service(bool add_characteristics, bool add_descriptors){
1804902524cSMatthias Ringwald         service = mock_gatt_client_add_primary_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE);
1814902524cSMatthias Ringwald         if (!add_characteristics) return;
1824902524cSMatthias Ringwald 
1834902524cSMatthias Ringwald         characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, ATT_PROPERTY_NOTIFY);
1844902524cSMatthias Ringwald 
1854902524cSMatthias Ringwald         if (!add_descriptors) return;
1864902524cSMatthias Ringwald         descriptor = mock_gatt_client_add_characteristic_descriptor_uuid16(ORG_BLUETOOTH_DESCRIPTOR_GATT_CLIENT_CHARACTERISTIC_CONFIGURATION);
1874902524cSMatthias Ringwald         mock_gatt_client_set_descriptor_characteristic_value(descriptor, value_buffer, sizeof(value_buffer));
1884902524cSMatthias Ringwald 
1894902524cSMatthias Ringwald         // mock_gatt_client_dump_services();
1904902524cSMatthias Ringwald     }
1914902524cSMatthias Ringwald 
1924902524cSMatthias Ringwald     void setup_service_without_notify_capabality(bool add_characteristics, bool add_descriptors){
1934902524cSMatthias Ringwald         service = mock_gatt_client_add_primary_service_uuid16(ORG_BLUETOOTH_SERVICE_BATTERY_SERVICE);
1944902524cSMatthias Ringwald         if (!add_characteristics) return;
1954902524cSMatthias Ringwald 
1964902524cSMatthias Ringwald         characteristic = mock_gatt_client_add_characteristic_uuid16(ORG_BLUETOOTH_CHARACTERISTIC_BATTERY_LEVEL, ATT_PROPERTY_READ);
1974902524cSMatthias Ringwald 
1984902524cSMatthias Ringwald         if (!add_descriptors) return;
1994902524cSMatthias Ringwald         descriptor = mock_gatt_client_add_characteristic_descriptor_uuid16(ORG_BLUETOOTH_DESCRIPTOR_GATT_CLIENT_CHARACTERISTIC_CONFIGURATION);
2004902524cSMatthias Ringwald         mock_gatt_client_set_descriptor_characteristic_value(descriptor, value_buffer, sizeof(value_buffer));
2014902524cSMatthias Ringwald 
2024902524cSMatthias Ringwald         // mock_gatt_client_dump_services();
2034902524cSMatthias Ringwald     }
2044902524cSMatthias Ringwald 
2054902524cSMatthias Ringwald     void connect(void){
2064902524cSMatthias Ringwald         uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid);
2074902524cSMatthias Ringwald         CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
2084902524cSMatthias Ringwald         mock_gatt_client_run();
2094902524cSMatthias Ringwald     }
2104902524cSMatthias Ringwald 
2114902524cSMatthias Ringwald     void teardown(void){
2124902524cSMatthias Ringwald         battery_service_client_deinit();
2134902524cSMatthias Ringwald     }
2144902524cSMatthias Ringwald };
2154902524cSMatthias Ringwald 
2164902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, unhandled_gatt_event){
2174902524cSMatthias Ringwald     mock_gatt_client_emit_dummy_event();
2184902524cSMatthias Ringwald }
2194902524cSMatthias Ringwald 
2204902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, gatt_event_in_wrong_state){
2214902524cSMatthias Ringwald     uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, NULL);
2224902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
2234902524cSMatthias Ringwald     // mock_gatt_client_run_once();
2244902524cSMatthias Ringwald     // mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
2254902524cSMatthias Ringwald }
2264902524cSMatthias Ringwald 
2274902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_no_memory){
2284902524cSMatthias Ringwald     mock_btstack_memory_battery_service_client_simulate_no_memory();
2294902524cSMatthias Ringwald     uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, NULL);
2304902524cSMatthias Ringwald     CHECK_EQUAL(BTSTACK_MEMORY_ALLOC_FAILED, status);
2314902524cSMatthias Ringwald }
2324902524cSMatthias Ringwald 
2334902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_no_cid){
2344902524cSMatthias Ringwald     uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, NULL);
2354902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
2364902524cSMatthias Ringwald 
2374902524cSMatthias Ringwald     mock_gatt_client_run();
2384902524cSMatthias Ringwald     CHECK_EQUAL(false, connected);
2394902524cSMatthias Ringwald }
2404902524cSMatthias Ringwald 
2414902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_no_service){
2424902524cSMatthias Ringwald     uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid);
2434902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
2444902524cSMatthias Ringwald 
2454902524cSMatthias Ringwald     mock_gatt_client_run();
2464902524cSMatthias Ringwald     CHECK_EQUAL(false, connected);
2474902524cSMatthias Ringwald }
2484902524cSMatthias Ringwald 
2494902524cSMatthias Ringwald 
2504902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_with_service_no_chr_no_desc){
2514902524cSMatthias Ringwald     setup_service(false, false);
2524902524cSMatthias Ringwald     connect();
2534902524cSMatthias Ringwald     CHECK_EQUAL(false, connected);
2544902524cSMatthias Ringwald }
2554902524cSMatthias Ringwald 
2564902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_with_service_and_chr_no_desc){
2574902524cSMatthias Ringwald     setup_service(true, false);
2584902524cSMatthias Ringwald     connect();
2594902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
2604902524cSMatthias Ringwald }
2614902524cSMatthias Ringwald 
2624902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_with_service_and_chr_and_desc){
2634902524cSMatthias Ringwald     setup_service(true, true);
2644902524cSMatthias Ringwald     connect();
2654902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
2664902524cSMatthias Ringwald }
2674902524cSMatthias Ringwald 
2684902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_with_one_invalid_and_one_valid_service){
2694902524cSMatthias Ringwald     setup_service(false, false);
2704902524cSMatthias Ringwald     setup_service(true, true);
2714902524cSMatthias Ringwald     connect();
2724902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
2734902524cSMatthias Ringwald }
2744902524cSMatthias Ringwald 
2754902524cSMatthias Ringwald 
2764902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, double_connect){
2774902524cSMatthias Ringwald     setup_service(true, true);
2784902524cSMatthias Ringwald     connect();
2794902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
2804902524cSMatthias Ringwald     uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid);
2814902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_COMMAND_DISALLOWED, status);
2824902524cSMatthias Ringwald }
2834902524cSMatthias Ringwald 
2844902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_discover_primary_service_error){
2854902524cSMatthias Ringwald     mock_gatt_client_set_att_error_discover_primary_services();
2864902524cSMatthias Ringwald     setup_service(true, true);
2874902524cSMatthias Ringwald     connect();
2884902524cSMatthias Ringwald     CHECK_EQUAL(false, connected);
2894902524cSMatthias Ringwald }
2904902524cSMatthias Ringwald 
2914902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_discover_characteristics_error){
2924902524cSMatthias Ringwald     mock_gatt_client_set_att_error_discover_characteristics();
2934902524cSMatthias Ringwald     setup_service(true, true);
2944902524cSMatthias Ringwald     connect();
2954902524cSMatthias Ringwald     CHECK_EQUAL(false, connected);
2964902524cSMatthias Ringwald }
2974902524cSMatthias Ringwald 
2984902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_discover_characteristic_descriptors_error){
2994902524cSMatthias Ringwald     mock_gatt_client_set_att_error_discover_characteristic_descriptors();
3004902524cSMatthias Ringwald     setup_service(true, true);
3014902524cSMatthias Ringwald     connect();
3024902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
3034902524cSMatthias Ringwald }
3044902524cSMatthias Ringwald 
3054902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, connect_ignore_too_many_service){
3064902524cSMatthias Ringwald     uint8_t i;
3074902524cSMatthias Ringwald     for (i = 0; i < MAX_NUM_BATTERY_SERVICES + 2; i++){
3084902524cSMatthias Ringwald         setup_service(true, true);
3094902524cSMatthias Ringwald     }
3104902524cSMatthias Ringwald     setup_service(true, true);
3114902524cSMatthias Ringwald     connect();
3124902524cSMatthias Ringwald 
3134902524cSMatthias Ringwald     CHECK_EQUAL(num_instances, MAX_NUM_BATTERY_SERVICES);
3144902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
3154902524cSMatthias Ringwald }
3164902524cSMatthias Ringwald 
3174902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, disconnect_not_connected){
3184902524cSMatthias Ringwald     uint8_t status;
3194902524cSMatthias Ringwald 
3204902524cSMatthias Ringwald     status = battery_service_client_disconnect(battery_service_cid);
3214902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
3224902524cSMatthias Ringwald }
3234902524cSMatthias Ringwald 
3244902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, double_disconnect){
3254902524cSMatthias Ringwald     uint8_t status;
3264902524cSMatthias Ringwald 
3274902524cSMatthias Ringwald     setup_service(true, true);
3284902524cSMatthias Ringwald     connect();
3294902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
3304902524cSMatthias Ringwald 
3314902524cSMatthias Ringwald     status = battery_service_client_disconnect(battery_service_cid);
3324902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
3334902524cSMatthias Ringwald 
3344902524cSMatthias Ringwald     status = battery_service_client_disconnect(battery_service_cid);
3354902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
3364902524cSMatthias Ringwald }
3374902524cSMatthias Ringwald 
3384902524cSMatthias Ringwald 
3394902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_invalid_0){
3404902524cSMatthias Ringwald     setup_service(true, true);
3414902524cSMatthias Ringwald     connect();
3424902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
3434902524cSMatthias Ringwald 
3444902524cSMatthias Ringwald     set_battery_level_of_size(0);
3454902524cSMatthias Ringwald     mock_gatt_client_send_notification(characteristic, battery_level, battery_level_size);
3464902524cSMatthias Ringwald     // TODO: check battery level was not received
3474902524cSMatthias Ringwald }
3484902524cSMatthias Ringwald 
3494902524cSMatthias Ringwald 
3504902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_invalid_5){
3514902524cSMatthias Ringwald     setup_service(true, true);
3524902524cSMatthias Ringwald     connect();
3534902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
3544902524cSMatthias Ringwald 
3554902524cSMatthias Ringwald     set_battery_level_of_size(5);
3564902524cSMatthias Ringwald     mock_gatt_client_send_notification(characteristic, battery_level, battery_level_size);
3574902524cSMatthias Ringwald     // TODO: check battery level was not received
3584902524cSMatthias Ringwald }
3594902524cSMatthias Ringwald 
3604902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_wrong_handle){
3614902524cSMatthias Ringwald     setup_service(true, true);
3624902524cSMatthias Ringwald     connect();
3634902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
3644902524cSMatthias Ringwald 
3654902524cSMatthias Ringwald     set_battery_level_of_size(1);
3664902524cSMatthias Ringwald     mock_gatt_client_send_notification_with_handle(characteristic, 0x1234, battery_level, battery_level_size);
3674902524cSMatthias Ringwald     // TODO: check battery level was not received
3684902524cSMatthias Ringwald }
3694902524cSMatthias Ringwald 
3704902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_wrong_handle_multiple){
3714902524cSMatthias Ringwald     setup_service(true, true);
3724902524cSMatthias Ringwald     setup_service(true, true);
3734902524cSMatthias Ringwald     connect();
3744902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
3754902524cSMatthias Ringwald 
3764902524cSMatthias Ringwald     set_battery_level_of_size(1);
3774902524cSMatthias Ringwald     mock_gatt_client_send_notification_with_handle(characteristic, 0x1234, battery_level, battery_level_size);
3784902524cSMatthias Ringwald     // TODO: check battery level was not received
3794902524cSMatthias Ringwald }
3804902524cSMatthias Ringwald 
3814902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, notify_battery_value_valid){
3824902524cSMatthias Ringwald     setup_service(true, true);
3834902524cSMatthias Ringwald     connect();
3844902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
3854902524cSMatthias Ringwald 
3864902524cSMatthias Ringwald     set_battery_level_of_size(1);
3874902524cSMatthias Ringwald     mock_gatt_client_send_notification(characteristic, battery_level, battery_level_size);
3884902524cSMatthias Ringwald     // TODO: check battery level was received
3894902524cSMatthias Ringwald }
3904902524cSMatthias Ringwald 
3914902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, multiple_connection){
3924902524cSMatthias Ringwald     battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid);
3934902524cSMatthias Ringwald     battery_service_client_connect(con_handle+1, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid);
3944902524cSMatthias Ringwald     battery_service_client_read_battery_level(10, 0);
3954902524cSMatthias Ringwald }
3964902524cSMatthias Ringwald 
3974902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, read_battery_level_wrong_cid){
3984902524cSMatthias Ringwald     uint8_t status = battery_service_client_read_battery_level(10, 0);
3994902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
4004902524cSMatthias Ringwald }
4014902524cSMatthias Ringwald 
4024902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, read_battery_level_wrong_state){
4034902524cSMatthias Ringwald     // without calling mock_gatt_client_run(), state remains in BATTERY_SERVICE_CLIENT_STATE_W2_QUERY_SERVICE
4044902524cSMatthias Ringwald     uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, poll_interval_ms, &battery_service_cid);
4054902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
4064902524cSMatthias Ringwald     CHECK_EQUAL(false, connected);
4074902524cSMatthias Ringwald 
4084902524cSMatthias Ringwald     status = battery_service_client_read_battery_level(battery_service_cid, 0);
4094902524cSMatthias Ringwald     CHECK_EQUAL(GATT_CLIENT_IN_WRONG_STATE, status);
4104902524cSMatthias Ringwald }
4114902524cSMatthias Ringwald 
4124902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, read_battery_level_wrong_state_in_packet_handler){
4134902524cSMatthias Ringwald     setup_service(true, true);
4144902524cSMatthias Ringwald     connect();
4154902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
4164902524cSMatthias Ringwald     mock_btstack_memory_battery_service_client_get_last_alloc()->state = BATTERY_SERVICE_CLIENT_STATE_IDLE;
4174902524cSMatthias Ringwald     mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
4184902524cSMatthias Ringwald }
4194902524cSMatthias Ringwald 
4204902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, read_battery_level_wrong_service_index){
4214902524cSMatthias Ringwald     setup_service(true, true);
4224902524cSMatthias Ringwald     connect();
4234902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
4244902524cSMatthias Ringwald 
4254902524cSMatthias Ringwald     uint8_t status = battery_service_client_read_battery_level(battery_service_cid, 10);
4264902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE, status);
4274902524cSMatthias Ringwald }
4284902524cSMatthias Ringwald 
4294902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_invalid){
4304902524cSMatthias Ringwald     setup_service(true, true);
4314902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, false);
4324902524cSMatthias Ringwald     set_battery_level_of_size(5);
4334902524cSMatthias Ringwald 
4344902524cSMatthias Ringwald 
4354902524cSMatthias Ringwald     connect();
4364902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
4374902524cSMatthias Ringwald 
4384902524cSMatthias Ringwald     uint8_t status = battery_service_client_read_battery_level(battery_service_cid, 0);
4394902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
4404902524cSMatthias Ringwald }
4414902524cSMatthias Ringwald 
4424902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value){
4434902524cSMatthias Ringwald     setup_service(true, true);
4444902524cSMatthias Ringwald     set_battery_level_of_size(1);
4454902524cSMatthias Ringwald 
4464902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, false);
4474902524cSMatthias Ringwald 
4484902524cSMatthias Ringwald     connect();
4494902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
4504902524cSMatthias Ringwald 
4514902524cSMatthias Ringwald     uint8_t status = battery_service_client_read_battery_level(battery_service_cid, 0);
4524902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
4534902524cSMatthias Ringwald }
4544902524cSMatthias Ringwald 
4554902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_with_error){
4564902524cSMatthias Ringwald     setup_service(true, true);
4574902524cSMatthias Ringwald     set_battery_level_of_size(1);
4584902524cSMatthias Ringwald 
4594902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, false);
4604902524cSMatthias Ringwald 
4614902524cSMatthias Ringwald     connect();
4624902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
4634902524cSMatthias Ringwald 
4644902524cSMatthias Ringwald     uint8_t status = battery_service_client_read_battery_level(battery_service_cid, 0);
4654902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
4664902524cSMatthias Ringwald     mock_gatt_client_emit_complete(1);
4674902524cSMatthias Ringwald }
4684902524cSMatthias Ringwald 
4694902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_zero_poll_interval){
4704902524cSMatthias Ringwald     setup_service(true, true);
4714902524cSMatthias Ringwald     set_battery_level_of_size(1);
4724902524cSMatthias Ringwald 
4734902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, false);
4744902524cSMatthias Ringwald 
4754902524cSMatthias Ringwald     uint8_t status = battery_service_client_connect(con_handle, &gatt_client_event_handler, 0, &battery_service_cid);
4764902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
4774902524cSMatthias Ringwald     mock_gatt_client_run();
4784902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
4794902524cSMatthias Ringwald 
4804902524cSMatthias Ringwald     status = battery_service_client_read_battery_level(battery_service_cid, 0);
4814902524cSMatthias Ringwald     CHECK_EQUAL(ERROR_CODE_SUCCESS, status);
4824902524cSMatthias Ringwald }
4834902524cSMatthias Ringwald 
4844902524cSMatthias Ringwald 
4854902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_trigger_timer){
4864902524cSMatthias Ringwald     setup_service(true, true);
4874902524cSMatthias Ringwald     set_battery_level_of_size(1);
4884902524cSMatthias Ringwald 
4894902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, false);
4904902524cSMatthias Ringwald 
4914902524cSMatthias Ringwald     connect();
4924902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
4934902524cSMatthias Ringwald     mock_btstack_run_loop_trigger_timer();
4944902524cSMatthias Ringwald     mock_gatt_client_run();
4954902524cSMatthias Ringwald }
4964902524cSMatthias Ringwald 
4974902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, poll_battery_value_trigger_timer_unxpected_complete){
4984902524cSMatthias Ringwald     setup_service(true, true);
4994902524cSMatthias Ringwald     set_battery_level_of_size(1);
5004902524cSMatthias Ringwald 
5014902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, false);
5024902524cSMatthias Ringwald 
5034902524cSMatthias Ringwald     connect();
5044902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
5054902524cSMatthias Ringwald     mock_btstack_run_loop_trigger_timer();
5064902524cSMatthias Ringwald     mock_gatt_client_run();
5074902524cSMatthias Ringwald 
5084902524cSMatthias Ringwald     // polling done, emit another complete event
5094902524cSMatthias Ringwald     mock_gatt_client_emit_complete(0);
5104902524cSMatthias Ringwald }
5114902524cSMatthias Ringwald 
5124902524cSMatthias Ringwald 
5134902524cSMatthias Ringwald TEST(BATTERY_SERVICE_CLIENT, mixed_poll_and_notify_battery_value){
5144902524cSMatthias Ringwald     setup_service(true, true);
5154902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, true);
5164902524cSMatthias Ringwald 
5174902524cSMatthias Ringwald     setup_service(true, true);
5184902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, false);
5194902524cSMatthias Ringwald 
5204902524cSMatthias Ringwald     setup_service(true, true);
5214902524cSMatthias Ringwald     mock_gatt_client_enable_notification(characteristic, true);
5224902524cSMatthias Ringwald 
5234902524cSMatthias Ringwald     connect();
5244902524cSMatthias Ringwald     CHECK_EQUAL(true, connected);
5254902524cSMatthias Ringwald }
5264902524cSMatthias Ringwald 
527*500d8180SMilanka Ringwald TEST(BATTERY_SERVICE_CLIENT, disconnect){
528*500d8180SMilanka Ringwald     setup_service(true, true);
529*500d8180SMilanka Ringwald     connect();
530*500d8180SMilanka Ringwald     CHECK_EQUAL(true, connected);
531*500d8180SMilanka Ringwald 
532*500d8180SMilanka Ringwald     uint8_t status;
533*500d8180SMilanka Ringwald 
534*500d8180SMilanka Ringwald     // send unexpected event
535*500d8180SMilanka Ringwald     mock_hci_emit_connection_encrypted(con_handle, 0);
536*500d8180SMilanka Ringwald 
537*500d8180SMilanka Ringwald     mock_hci_emit_disconnection_complete(con_handle, 0);
538*500d8180SMilanka Ringwald     status = battery_service_client_disconnect(battery_service_cid);
539*500d8180SMilanka Ringwald     CHECK_EQUAL(ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER, status);
540*500d8180SMilanka Ringwald 
541*500d8180SMilanka Ringwald     // send event with wrong con handle
542*500d8180SMilanka Ringwald     mock_hci_emit_disconnection_complete(HCI_CON_HANDLE_INVALID, 0);
543*500d8180SMilanka Ringwald }
544*500d8180SMilanka Ringwald 
545*500d8180SMilanka Ringwald 
5464902524cSMatthias Ringwald int main (int argc, const char * argv[]){
5474902524cSMatthias Ringwald     return CommandLineTestRunner::RunAllTests(argc, argv);
5484902524cSMatthias Ringwald }
549