10f7fd6c1SMilanka Ringwald #include <stdint.h>
20f7fd6c1SMilanka Ringwald #include <stdio.h>
30f7fd6c1SMilanka Ringwald #include <string.h>
40f7fd6c1SMilanka Ringwald
5af770404SMilanka Ringwald #include "btstack_debug.h"
67e693ad3SMilanka Ringwald #include "bluetooth_gatt.h"
70f7fd6c1SMilanka Ringwald #include "mock_gatt_client.h"
87aa69c24SMatthias Ringwald #include "hci_event_builder.h"
90f7fd6c1SMilanka Ringwald
1043bef108SMatthias Ringwald //#include "CppUTest/TestHarness.h"
1143bef108SMatthias Ringwald //#include "CppUTestExt/MockSupport.h"
120f7fd6c1SMilanka Ringwald
13af770404SMilanka Ringwald static enum {
14af770404SMilanka Ringwald MOCK_QUERY_IDLE = 0,
157dbac955SMatthias Ringwald MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID,
167dbac955SMatthias Ringwald MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID,
177dbac955SMatthias Ringwald MOCK_QUERY_DISCOVER_ALL_CHARACTERISTICS,
1876cdba3eSMilanka Ringwald MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS,
1976cdba3eSMilanka Ringwald MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION,
207e693ad3SMilanka Ringwald MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE,
217e693ad3SMilanka Ringwald MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE
22af770404SMilanka Ringwald } mock_gatt_client_state;
23af770404SMilanka Ringwald
2476cdba3eSMilanka Ringwald static uint16_t mock_gatt_client_att_handle_generator;
2576cdba3eSMilanka Ringwald
26af770404SMilanka Ringwald static uint8_t mock_gatt_client_att_error;
277dbac955SMatthias Ringwald static uint8_t mock_gatt_client_uuid128[16];
2876cdba3eSMilanka Ringwald static uint16_t mock_gatt_client_value_handle;
2976cdba3eSMilanka Ringwald static uint16_t mock_gatt_client_start_handle;
3076cdba3eSMilanka Ringwald static uint16_t mock_gatt_client_end_handle;
3176cdba3eSMilanka Ringwald
32af770404SMilanka Ringwald static gatt_client_t gatt_client;
330f7fd6c1SMilanka Ringwald
347da2c1baSMilanka Ringwald static btstack_linked_list_t mock_gatt_client_services;
357da2c1baSMilanka Ringwald
367da2c1baSMilanka Ringwald static mock_gatt_client_service_t * mock_gatt_client_last_service;
377da2c1baSMilanka Ringwald static mock_gatt_client_characteristic_t * mock_gatt_client_last_characteristic;
387da2c1baSMilanka Ringwald
39ec1a0daeSMilanka Ringwald static uint8_t moc_att_error_code_discover_services;
40ec1a0daeSMilanka Ringwald static uint8_t moc_att_error_code_discover_characteristics;
41ec1a0daeSMilanka Ringwald static uint8_t moc_att_error_code_discover_characteristic_descriptors;
42e92f7a17SMilanka Ringwald static uint8_t moc_att_error_code_read_value_characteristics;
4386d0910fSMilanka Ringwald
44500d8180SMilanka Ringwald static btstack_linked_list_t event_packet_handlers;
45500d8180SMilanka Ringwald
hci_add_event_handler(btstack_packet_callback_registration_t * callback_handler)46500d8180SMilanka Ringwald void hci_add_event_handler(btstack_packet_callback_registration_t * callback_handler){
47500d8180SMilanka Ringwald btstack_linked_list_add_tail(&event_packet_handlers, (btstack_linked_item_t*) callback_handler);
48500d8180SMilanka Ringwald }
49500d8180SMilanka Ringwald
mock_hci_emit_event(uint8_t * packet,uint16_t size)50500d8180SMilanka Ringwald void mock_hci_emit_event(uint8_t * packet, uint16_t size){
51500d8180SMilanka Ringwald // dispatch to all event handlers
52500d8180SMilanka Ringwald btstack_linked_list_iterator_t it;
53500d8180SMilanka Ringwald btstack_linked_list_iterator_init(&it, &event_packet_handlers);
54500d8180SMilanka Ringwald while (btstack_linked_list_iterator_has_next(&it)){
55500d8180SMilanka Ringwald btstack_packet_callback_registration_t * entry = (btstack_packet_callback_registration_t*) btstack_linked_list_iterator_next(&it);
56500d8180SMilanka Ringwald entry->callback(HCI_EVENT_PACKET, 0, packet, size);
57500d8180SMilanka Ringwald }
58500d8180SMilanka Ringwald }
59500d8180SMilanka Ringwald
hci_create_gap_connection_complete_event(const uint8_t * hci_event,uint8_t * gap_event)60500d8180SMilanka Ringwald static void hci_create_gap_connection_complete_event(const uint8_t * hci_event, uint8_t * gap_event) {
61500d8180SMilanka Ringwald gap_event[0] = HCI_EVENT_META_GAP;
62500d8180SMilanka Ringwald gap_event[1] = 36 - 2;
63500d8180SMilanka Ringwald gap_event[2] = GAP_SUBEVENT_LE_CONNECTION_COMPLETE;
64500d8180SMilanka Ringwald switch (hci_event[2]){
65500d8180SMilanka Ringwald case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
66500d8180SMilanka Ringwald memcpy(&gap_event[3], &hci_event[3], 11);
67500d8180SMilanka Ringwald memset(&gap_event[14], 0, 12);
68500d8180SMilanka Ringwald memcpy(&gap_event[26], &hci_event[14], 7);
69500d8180SMilanka Ringwald memset(&gap_event[33], 0xff, 3);
70500d8180SMilanka Ringwald break;
71500d8180SMilanka Ringwald case HCI_SUBEVENT_LE_ENHANCED_CONNECTION_COMPLETE_V1:
72500d8180SMilanka Ringwald memcpy(&gap_event[3], &hci_event[3], 30);
73500d8180SMilanka Ringwald memset(&gap_event[33], 0xff, 3);
74500d8180SMilanka Ringwald break;
75500d8180SMilanka Ringwald case HCI_SUBEVENT_LE_ENHANCED_CONNECTION_COMPLETE_V2:
76500d8180SMilanka Ringwald memcpy(&gap_event[3], &hci_event[3], 33);
77500d8180SMilanka Ringwald break;
78500d8180SMilanka Ringwald default:
79500d8180SMilanka Ringwald btstack_unreachable();
80500d8180SMilanka Ringwald break;
81500d8180SMilanka Ringwald }
82500d8180SMilanka Ringwald }
83500d8180SMilanka Ringwald
mock_hci_emit_le_connection_complete(uint8_t address_type,const bd_addr_t address,hci_con_handle_t con_handle,uint8_t status)84500d8180SMilanka Ringwald void mock_hci_emit_le_connection_complete(uint8_t address_type, const bd_addr_t address, hci_con_handle_t con_handle, uint8_t status){
85500d8180SMilanka Ringwald uint8_t hci_event[21];
86500d8180SMilanka Ringwald hci_event[0] = HCI_EVENT_LE_META;
87500d8180SMilanka Ringwald hci_event[1] = sizeof(hci_event) - 2u;
88500d8180SMilanka Ringwald hci_event[2] = HCI_SUBEVENT_LE_CONNECTION_COMPLETE;
89500d8180SMilanka Ringwald hci_event[3] = status;
90500d8180SMilanka Ringwald little_endian_store_16(hci_event, 4, con_handle);
91500d8180SMilanka Ringwald hci_event[6] = 0; // TODO: role
92500d8180SMilanka Ringwald hci_event[7] = address_type;
93500d8180SMilanka Ringwald reverse_bd_addr(address, &hci_event[8]);
94500d8180SMilanka Ringwald little_endian_store_16(hci_event, 14, 0); // interval
95500d8180SMilanka Ringwald little_endian_store_16(hci_event, 16, 0); // latency
96500d8180SMilanka Ringwald little_endian_store_16(hci_event, 18, 0); // supervision timeout
97500d8180SMilanka Ringwald hci_event[20] = 0; // master clock accuracy
98500d8180SMilanka Ringwald // emit GAP event, too
99500d8180SMilanka Ringwald uint8_t gap_event[36];
100500d8180SMilanka Ringwald hci_create_gap_connection_complete_event(hci_event, gap_event);
101500d8180SMilanka Ringwald mock_hci_emit_event(gap_event, sizeof(gap_event));
102500d8180SMilanka Ringwald }
103500d8180SMilanka Ringwald
mock_hci_emit_connection_encrypted(hci_con_handle_t con_handle,uint8_t encrypted)104500d8180SMilanka Ringwald void mock_hci_emit_connection_encrypted(hci_con_handle_t con_handle, uint8_t encrypted){
105500d8180SMilanka Ringwald uint8_t encryption_complete_event[6] = { HCI_EVENT_ENCRYPTION_CHANGE, 4, 0, 0, 0, 0};
106500d8180SMilanka Ringwald little_endian_store_16(encryption_complete_event, 3, con_handle);
107500d8180SMilanka Ringwald encryption_complete_event[5] = encrypted;
108500d8180SMilanka Ringwald mock_hci_emit_event(encryption_complete_event, sizeof(encryption_complete_event));
109500d8180SMilanka Ringwald }
110500d8180SMilanka Ringwald
mock_hci_emit_disconnection_complete(hci_con_handle_t con_handle,uint8_t reason)111500d8180SMilanka Ringwald void mock_hci_emit_disconnection_complete(hci_con_handle_t con_handle, uint8_t reason){
112500d8180SMilanka Ringwald uint8_t event[6];
113500d8180SMilanka Ringwald event[0] = HCI_EVENT_DISCONNECTION_COMPLETE;
114500d8180SMilanka Ringwald event[1] = sizeof(event) - 2u;
115500d8180SMilanka Ringwald event[2] = 0; // status = OK
116500d8180SMilanka Ringwald little_endian_store_16(event, 3, con_handle);
117500d8180SMilanka Ringwald event[5] = reason;
118500d8180SMilanka Ringwald mock_hci_emit_event(event, sizeof(event));
119500d8180SMilanka Ringwald }
120500d8180SMilanka Ringwald
121500d8180SMilanka Ringwald
122af770404SMilanka Ringwald /**
123af770404SMilanka Ringwald * copied from gatt_client.c - START
124af770404SMilanka Ringwald */
gatt_client_deserialize_service(const uint8_t * packet,int offset,gatt_client_service_t * service)1250f7fd6c1SMilanka Ringwald void gatt_client_deserialize_service(const uint8_t *packet, int offset, gatt_client_service_t * service){
1260f7fd6c1SMilanka Ringwald service->start_group_handle = little_endian_read_16(packet, offset);
1270f7fd6c1SMilanka Ringwald service->end_group_handle = little_endian_read_16(packet, offset + 2);
1280f7fd6c1SMilanka Ringwald reverse_128(&packet[offset + 4], service->uuid128);
1290f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(service->uuid128)){
1300f7fd6c1SMilanka Ringwald service->uuid16 = big_endian_read_32(service->uuid128, 0);
1310f7fd6c1SMilanka Ringwald } else {
1320f7fd6c1SMilanka Ringwald service->uuid16 = 0;
1330f7fd6c1SMilanka Ringwald }
1340f7fd6c1SMilanka Ringwald }
1350f7fd6c1SMilanka Ringwald
gatt_client_deserialize_characteristic(const uint8_t * packet,int offset,gatt_client_characteristic_t * characteristic)1360f7fd6c1SMilanka Ringwald void gatt_client_deserialize_characteristic(const uint8_t * packet, int offset, gatt_client_characteristic_t * characteristic){
1370f7fd6c1SMilanka Ringwald characteristic->start_handle = little_endian_read_16(packet, offset);
1380f7fd6c1SMilanka Ringwald characteristic->value_handle = little_endian_read_16(packet, offset + 2);
1390f7fd6c1SMilanka Ringwald characteristic->end_handle = little_endian_read_16(packet, offset + 4);
1400f7fd6c1SMilanka Ringwald characteristic->properties = little_endian_read_16(packet, offset + 6);
1410f7fd6c1SMilanka Ringwald reverse_128(&packet[offset+8], characteristic->uuid128);
1420f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(characteristic->uuid128)){
1430f7fd6c1SMilanka Ringwald characteristic->uuid16 = big_endian_read_32(characteristic->uuid128, 0);
1440f7fd6c1SMilanka Ringwald } else {
1450f7fd6c1SMilanka Ringwald characteristic->uuid16 = 0;
1460f7fd6c1SMilanka Ringwald }
1470f7fd6c1SMilanka Ringwald }
1480f7fd6c1SMilanka Ringwald
gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet,int offset,gatt_client_characteristic_descriptor_t * descriptor)1490f7fd6c1SMilanka Ringwald void gatt_client_deserialize_characteristic_descriptor(const uint8_t * packet, int offset, gatt_client_characteristic_descriptor_t * descriptor){
1500f7fd6c1SMilanka Ringwald descriptor->handle = little_endian_read_16(packet, offset);
1510f7fd6c1SMilanka Ringwald reverse_128(&packet[offset+2], descriptor->uuid128);
1520f7fd6c1SMilanka Ringwald if (uuid_has_bluetooth_prefix(descriptor->uuid128)){
1530f7fd6c1SMilanka Ringwald descriptor->uuid16 = big_endian_read_32(descriptor->uuid128, 0);
1540f7fd6c1SMilanka Ringwald } else {
1550f7fd6c1SMilanka Ringwald descriptor->uuid16 = 0;
1560f7fd6c1SMilanka Ringwald }
1570f7fd6c1SMilanka Ringwald }
1580f7fd6c1SMilanka Ringwald
emit_event_new(btstack_packet_handler_t callback,uint8_t * packet,uint16_t size)1597aa69c24SMatthias Ringwald static void emit_event_new(btstack_packet_handler_t callback, uint8_t * packet, uint16_t size){
160af770404SMilanka Ringwald if (!callback) return;
161af770404SMilanka Ringwald (*callback)(HCI_EVENT_PACKET, 0, packet, size);
1620f7fd6c1SMilanka Ringwald }
1630f7fd6c1SMilanka Ringwald
emit_gatt_complete_event(gatt_client_t * gatt_client,uint8_t att_status)164af770404SMilanka Ringwald static void emit_gatt_complete_event(gatt_client_t * gatt_client, uint8_t att_status){
1657aa69c24SMatthias Ringwald // @format H122
1667aa69c24SMatthias Ringwald uint8_t packet[9];
1677aa69c24SMatthias Ringwald hci_event_builder_context_t context;
1687aa69c24SMatthias Ringwald hci_event_builder_init(&context, packet, sizeof(packet), GATT_EVENT_QUERY_COMPLETE, 0);
1697aa69c24SMatthias Ringwald hci_event_builder_add_con_handle(&context, gatt_client->con_handle);
1707aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, gatt_client->service_id);
1717aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, gatt_client->connection_id);
1727aa69c24SMatthias Ringwald hci_event_builder_add_08(&context, att_status);
1737aa69c24SMatthias Ringwald emit_event_new(gatt_client->callback, packet, hci_event_builder_get_length(&context));
1740f7fd6c1SMilanka Ringwald }
1750f7fd6c1SMilanka Ringwald
emit_gatt_service_query_result_event(gatt_client_t * gatt_client,uint16_t start_group_handle,uint16_t end_group_handle,const uint8_t * uuid128)1767da2c1baSMilanka Ringwald static void emit_gatt_service_query_result_event(gatt_client_t * gatt_client, uint16_t start_group_handle, uint16_t end_group_handle, const uint8_t * uuid128){
1777aa69c24SMatthias Ringwald // @format H22X
1787aa69c24SMatthias Ringwald uint8_t packet[28];
1797aa69c24SMatthias Ringwald hci_event_builder_context_t context;
1807aa69c24SMatthias Ringwald hci_event_builder_init(&context, packet, sizeof(packet), GATT_EVENT_SERVICE_QUERY_RESULT, 0);
1817aa69c24SMatthias Ringwald hci_event_builder_add_con_handle(&context, gatt_client->con_handle);
1827aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, gatt_client->service_id);
1837aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, gatt_client->connection_id);
1847aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, start_group_handle);
1857aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, end_group_handle);
1867aa69c24SMatthias Ringwald hci_event_builder_add_128(&context, uuid128);
1877aa69c24SMatthias Ringwald emit_event_new(gatt_client->callback, packet, hci_event_builder_get_length(&context));
1887da2c1baSMilanka Ringwald }
1897da2c1baSMilanka Ringwald
emit_gatt_characteristic_query_result_event(gatt_client_t * gatt_client,uint16_t start_handle,uint16_t value_handle,uint16_t end_handle,uint16_t properties,const uint8_t * uuid128)1907da2c1baSMilanka Ringwald static void emit_gatt_characteristic_query_result_event(gatt_client_t * gatt_client, uint16_t start_handle, uint16_t value_handle, uint16_t end_handle,
1917da2c1baSMilanka Ringwald uint16_t properties, const uint8_t * uuid128){
1927aa69c24SMatthias Ringwald // @format H22Y
1937aa69c24SMatthias Ringwald uint8_t packet[32];
1947aa69c24SMatthias Ringwald hci_event_builder_context_t context;
1957aa69c24SMatthias Ringwald hci_event_builder_init(&context, packet, sizeof(packet), GATT_EVENT_CHARACTERISTIC_QUERY_RESULT, 0);
1967aa69c24SMatthias Ringwald hci_event_builder_add_con_handle(&context, gatt_client->con_handle);
1977aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, gatt_client->service_id);
1987aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, gatt_client->connection_id);
1997aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, start_handle);
2007aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, value_handle);
2017aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, end_handle);
2027aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, properties);
2037aa69c24SMatthias Ringwald hci_event_builder_add_128(&context, uuid128);
2047aa69c24SMatthias Ringwald emit_event_new(gatt_client->callback, packet, hci_event_builder_get_length(&context));
2057da2c1baSMilanka Ringwald }
2067da2c1baSMilanka Ringwald
emit_gatt_all_characteristic_descriptors_result_event(gatt_client_t * gatt_client,uint16_t descriptor_handle,const uint8_t * uuid128)20776cdba3eSMilanka Ringwald static void emit_gatt_all_characteristic_descriptors_result_event(
20876cdba3eSMilanka Ringwald gatt_client_t * gatt_client, uint16_t descriptor_handle, const uint8_t * uuid128){
20976cdba3eSMilanka Ringwald // @format HZ
21076cdba3eSMilanka Ringwald uint8_t packet[22];
2117aa69c24SMatthias Ringwald hci_event_builder_context_t context;
2127aa69c24SMatthias Ringwald hci_event_builder_init(&context, packet, sizeof(packet), GATT_EVENT_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY_RESULT, 0);
2137aa69c24SMatthias Ringwald hci_event_builder_add_con_handle(&context, gatt_client->con_handle);
2147aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, gatt_client->service_id);
2157aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, gatt_client->connection_id);
2167aa69c24SMatthias Ringwald hci_event_builder_add_16(&context, descriptor_handle);
2177aa69c24SMatthias Ringwald hci_event_builder_add_128(&context, uuid128);
2187aa69c24SMatthias Ringwald emit_event_new(gatt_client->callback, packet, hci_event_builder_get_length(&context));
21976cdba3eSMilanka Ringwald }
22076cdba3eSMilanka Ringwald
2217e693ad3SMilanka Ringwald static uint8_t event_packet[255];
setup_characteristic_value_packet(uint8_t type,hci_con_handle_t con_handle,uint16_t attribute_handle,uint8_t * value,uint16_t length)22276cdba3eSMilanka Ringwald static uint8_t * setup_characteristic_value_packet(uint8_t type, hci_con_handle_t con_handle, uint16_t attribute_handle, uint8_t * value, uint16_t length){
22376cdba3eSMilanka Ringwald // before the value inside the ATT PDU
2247e693ad3SMilanka Ringwald event_packet[0] = type;
2257aa69c24SMatthias Ringwald event_packet[1] = 10 + length;
2267e693ad3SMilanka Ringwald little_endian_store_16(event_packet, 2, con_handle);
2277aa69c24SMatthias Ringwald little_endian_store_16(event_packet, 4, 0);
2287aa69c24SMatthias Ringwald little_endian_store_16(event_packet, 6, 0);
2297aa69c24SMatthias Ringwald little_endian_store_16(event_packet, 8, attribute_handle);
2307aa69c24SMatthias Ringwald little_endian_store_16(event_packet, 10, length);
2317aa69c24SMatthias Ringwald memcpy(&event_packet[12], value, length);
2327e693ad3SMilanka Ringwald return &event_packet[0];
23376cdba3eSMilanka Ringwald }
23476cdba3eSMilanka Ringwald
mock_gatt_client_send_notification_with_handle(mock_gatt_client_characteristic_t * characteristic,uint16_t value_handle,const uint8_t * value_buffer,uint16_t value_len)2357dbac955SMatthias Ringwald void mock_gatt_client_send_notification_with_handle(mock_gatt_client_characteristic_t * characteristic, uint16_t value_handle, const uint8_t * value_buffer, uint16_t value_len){
2367e693ad3SMilanka Ringwald btstack_assert(characteristic != NULL);
2377e693ad3SMilanka Ringwald btstack_assert(characteristic->notification != NULL);
2387e693ad3SMilanka Ringwald btstack_assert(characteristic->notification->callback != NULL);
2397dbac955SMatthias Ringwald uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_NOTIFICATION, gatt_client.con_handle, value_handle, (uint8_t *) value_buffer, value_len);
2407aa69c24SMatthias Ringwald emit_event_new(characteristic->notification->callback, packet, 2 + packet[1]);
2417e693ad3SMilanka Ringwald }
2427e693ad3SMilanka Ringwald
mock_gatt_client_send_notification(mock_gatt_client_characteristic_t * characteristic,const uint8_t * value_buffer,uint16_t value_len)2437dbac955SMatthias Ringwald void mock_gatt_client_send_notification(mock_gatt_client_characteristic_t * characteristic, const uint8_t * value_buffer, uint16_t value_len){
2447e693ad3SMilanka Ringwald mock_gatt_client_send_notification_with_handle(characteristic, characteristic->value_handle, value_buffer, value_len);
2457e693ad3SMilanka Ringwald }
2467e693ad3SMilanka Ringwald
mock_gatt_client_send_indication_with_handle(mock_gatt_client_characteristic_t * characteristic,uint16_t value_handle,const uint8_t * value_buffer,uint16_t value_len)2477dbac955SMatthias Ringwald void mock_gatt_client_send_indication_with_handle(mock_gatt_client_characteristic_t * characteristic, uint16_t value_handle, const uint8_t * value_buffer, uint16_t value_len){
2487dbac955SMatthias Ringwald btstack_assert(characteristic != NULL);
2497dbac955SMatthias Ringwald btstack_assert(characteristic->notification != NULL);
2507dbac955SMatthias Ringwald btstack_assert(characteristic->notification->callback != NULL);
2517dbac955SMatthias Ringwald uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_INDICATION, gatt_client.con_handle, value_handle, (uint8_t *) value_buffer, value_len);
2527aa69c24SMatthias Ringwald emit_event_new(characteristic->notification->callback, packet, 2 + packet[1]);
2537dbac955SMatthias Ringwald }
2547dbac955SMatthias Ringwald
mock_gatt_client_send_indication(mock_gatt_client_characteristic_t * characteristic,const uint8_t * value_buffer,uint16_t value_len)2557dbac955SMatthias Ringwald void mock_gatt_client_send_indication(mock_gatt_client_characteristic_t * characteristic, const uint8_t * value_buffer, uint16_t value_len){
2567dbac955SMatthias Ringwald mock_gatt_client_send_indication_with_handle(characteristic, characteristic->value_handle, value_buffer, value_len);
2577dbac955SMatthias Ringwald }
2587dbac955SMatthias Ringwald
mock_gatt_client_send_characteristic_value(gatt_client_t * gatt_client,mock_gatt_client_characteristic_t * characteristic)2597e693ad3SMilanka Ringwald static void mock_gatt_client_send_characteristic_value(gatt_client_t * gatt_client, mock_gatt_client_characteristic_t * characteristic){
2607e693ad3SMilanka Ringwald uint8_t * packet = setup_characteristic_value_packet(GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT, gatt_client->con_handle, characteristic->value_handle, characteristic->value_buffer, characteristic->value_len);
2617aa69c24SMatthias Ringwald emit_event_new(gatt_client->callback, packet, 2 + packet[1]);
26276cdba3eSMilanka Ringwald }
26376cdba3eSMilanka Ringwald
264af770404SMilanka Ringwald /**
265af770404SMilanka Ringwald * copied from gatt_client.c - END
266af770404SMilanka Ringwald */
2670f7fd6c1SMilanka Ringwald
2687dbac955SMatthias Ringwald
mock_gatt_client_get_characteristic_for_value_handle(uint16_t value_handle)2697dbac955SMatthias Ringwald static mock_gatt_client_characteristic_t * mock_gatt_client_get_characteristic_for_value_handle(uint16_t value_handle){
2707dbac955SMatthias Ringwald btstack_linked_list_iterator_t service_it;
2717dbac955SMatthias Ringwald btstack_linked_list_iterator_t characteristic_it;
2727dbac955SMatthias Ringwald
2737dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
2747dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){
2757dbac955SMatthias Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
2767dbac955SMatthias Ringwald
2777dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
2787dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){
2797dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
2807dbac955SMatthias Ringwald if (characteristic->value_handle != value_handle) continue;
2817dbac955SMatthias Ringwald return characteristic;
2827dbac955SMatthias Ringwald }
2837dbac955SMatthias Ringwald }
2847dbac955SMatthias Ringwald return NULL;
2857dbac955SMatthias Ringwald }
2867dbac955SMatthias Ringwald
mock_gatt_client_get_characteristic_for_uuid16(uint16_t uuid16)287e92f7a17SMilanka Ringwald static mock_gatt_client_characteristic_t * mock_gatt_client_get_characteristic_for_uuid16(uint16_t uuid16){
288e92f7a17SMilanka Ringwald btstack_linked_list_iterator_t service_it;
289e92f7a17SMilanka Ringwald btstack_linked_list_iterator_t characteristic_it;
290e92f7a17SMilanka Ringwald
291e92f7a17SMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
292e92f7a17SMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){
293e92f7a17SMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
294e92f7a17SMilanka Ringwald
295e92f7a17SMilanka Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
296e92f7a17SMilanka Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){
297e92f7a17SMilanka Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
298e92f7a17SMilanka Ringwald if (characteristic->uuid16 != uuid16) continue;
299e92f7a17SMilanka Ringwald return characteristic;
300e92f7a17SMilanka Ringwald }
301e92f7a17SMilanka Ringwald }
302e92f7a17SMilanka Ringwald return NULL;
303e92f7a17SMilanka Ringwald }
304e92f7a17SMilanka Ringwald
mock_gatt_client_get_characteristic_descriptor_for_handle(uint16_t handle)3057dbac955SMatthias Ringwald static mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_get_characteristic_descriptor_for_handle(uint16_t handle){
3067dbac955SMatthias Ringwald btstack_linked_list_iterator_t service_it;
3077dbac955SMatthias Ringwald btstack_linked_list_iterator_t characteristic_it;
3087dbac955SMatthias Ringwald
3097dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
3107dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){
3117dbac955SMatthias Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
3127dbac955SMatthias Ringwald
3137dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
3147dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){
3157dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
3167dbac955SMatthias Ringwald
3177dbac955SMatthias Ringwald btstack_linked_list_iterator_t desc_it;
3187dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors);
3197dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&desc_it)){
3207dbac955SMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it);
3217dbac955SMatthias Ringwald if (desc->handle != handle) continue;
3227dbac955SMatthias Ringwald return desc;
3237dbac955SMatthias Ringwald }
3247dbac955SMatthias Ringwald }
3257dbac955SMatthias Ringwald }
3267dbac955SMatthias Ringwald return NULL;
3277dbac955SMatthias Ringwald }
3287dbac955SMatthias Ringwald
gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t uuid16)3297dbac955SMatthias Ringwald uint8_t gatt_client_discover_primary_services_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t uuid16){
3307dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID;
3317dbac955SMatthias Ringwald uuid_add_bluetooth_prefix(mock_gatt_client_uuid128, uuid16);
3327dbac955SMatthias Ringwald gatt_client.callback = callback;
3337dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
3347dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
3357dbac955SMatthias Ringwald }
3367dbac955SMatthias Ringwald
gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback,hci_con_handle_t con_handle,const uint8_t * uuid128)3377dbac955SMatthias Ringwald uint8_t gatt_client_discover_primary_services_by_uuid128(btstack_packet_handler_t callback, hci_con_handle_t con_handle, const uint8_t * uuid128){
3387dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID;
3397dbac955SMatthias Ringwald memcpy(mock_gatt_client_uuid128, uuid128, 16);
3407dbac955SMatthias Ringwald gatt_client.callback = callback;
3417dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
3427dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
3437dbac955SMatthias Ringwald }
3447dbac955SMatthias Ringwald
gatt_client_discover_characteristics_for_handle_range_by_uuid16(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t start_handle,uint16_t end_handle,uint16_t uuid16)3457dbac955SMatthias Ringwald uint8_t gatt_client_discover_characteristics_for_handle_range_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16){
3467dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID;
3477dbac955SMatthias Ringwald uuid_add_bluetooth_prefix(mock_gatt_client_uuid128, uuid16);
3487dbac955SMatthias Ringwald mock_gatt_client_start_handle = start_handle;
3497dbac955SMatthias Ringwald mock_gatt_client_end_handle = end_handle;
3507dbac955SMatthias Ringwald
3517dbac955SMatthias Ringwald gatt_client.callback = callback;
3527dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
3537dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
3547dbac955SMatthias Ringwald }
3557dbac955SMatthias Ringwald
gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_service_t * service)3567dbac955SMatthias Ringwald uint8_t gatt_client_discover_characteristics_for_service(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_service_t * service){
3577dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_ALL_CHARACTERISTICS;
3587dbac955SMatthias Ringwald mock_gatt_client_start_handle = service->start_group_handle;
3597dbac955SMatthias Ringwald mock_gatt_client_end_handle = service->end_group_handle;
3607dbac955SMatthias Ringwald gatt_client.callback = callback;
3617dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
3627dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
3637dbac955SMatthias Ringwald }
3647dbac955SMatthias Ringwald
gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_characteristic_t * characteristic)3657dbac955SMatthias Ringwald uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
3667dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS;
3677dbac955SMatthias Ringwald mock_gatt_client_value_handle = characteristic->value_handle;
3687dbac955SMatthias Ringwald
3697dbac955SMatthias Ringwald gatt_client.callback = callback;
3707dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
3717dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
3727dbac955SMatthias Ringwald }
3737dbac955SMatthias Ringwald
gatt_client_listen_for_characteristic_value_updates(gatt_client_notification_t * notification,btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_characteristic_t * characteristic)3747dbac955SMatthias Ringwald void gatt_client_listen_for_characteristic_value_updates(gatt_client_notification_t * notification, btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
3757dbac955SMatthias Ringwald btstack_assert(notification != NULL);
3767dbac955SMatthias Ringwald btstack_assert(&callback != NULL);
3777dbac955SMatthias Ringwald
3787dbac955SMatthias Ringwald notification->callback = callback;
3797dbac955SMatthias Ringwald notification->con_handle = con_handle;
3807dbac955SMatthias Ringwald
3817dbac955SMatthias Ringwald
3827dbac955SMatthias Ringwald if (characteristic == NULL){
3837dbac955SMatthias Ringwald // 'all characteristics': not used yet
3847dbac955SMatthias Ringwald btstack_assert(false);
3857dbac955SMatthias Ringwald } else {
3867dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle);
3877dbac955SMatthias Ringwald btstack_assert(mock_characteristic != NULL);
3887dbac955SMatthias Ringwald
3897dbac955SMatthias Ringwald notification->attribute_handle = characteristic->value_handle;
3907dbac955SMatthias Ringwald mock_characteristic->notification = notification;
3917dbac955SMatthias Ringwald }
3927dbac955SMatthias Ringwald }
3937dbac955SMatthias Ringwald
gatt_client_write_client_characteristic_configuration(btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_characteristic_t * characteristic,uint16_t configuration)3947dbac955SMatthias Ringwald uint8_t gatt_client_write_client_characteristic_configuration(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic, uint16_t configuration){
3957dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle);
3967dbac955SMatthias Ringwald btstack_assert(mock_characteristic != NULL);
3977dbac955SMatthias Ringwald
3987dbac955SMatthias Ringwald if (mock_characteristic->notification_status_code != ERROR_CODE_SUCCESS){
3997dbac955SMatthias Ringwald return mock_characteristic->notification_status_code;
4007dbac955SMatthias Ringwald }
4017dbac955SMatthias Ringwald
4027dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
4037dbac955SMatthias Ringwald
4047dbac955SMatthias Ringwald gatt_client.callback = callback;
4057dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
4067dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
4077dbac955SMatthias Ringwald }
4087dbac955SMatthias Ringwald
gatt_client_read_value_of_characteristics_by_uuid16(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t start_handle,uint16_t end_handle,uint16_t uuid16)409e92f7a17SMilanka Ringwald uint8_t gatt_client_read_value_of_characteristics_by_uuid16(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t start_handle, uint16_t end_handle, uint16_t uuid16){
410e92f7a17SMilanka Ringwald mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE;
411e92f7a17SMilanka Ringwald
412e92f7a17SMilanka Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_uuid16(uuid16);
413e92f7a17SMilanka Ringwald if (mock_characteristic != NULL){
414e92f7a17SMilanka Ringwald mock_gatt_client_value_handle = mock_characteristic->value_handle;
415e92f7a17SMilanka Ringwald gatt_client.callback = callback;
416e92f7a17SMilanka Ringwald gatt_client.con_handle = con_handle;
417e92f7a17SMilanka Ringwald }
418e92f7a17SMilanka Ringwald return ERROR_CODE_SUCCESS;
419e92f7a17SMilanka Ringwald }
420e92f7a17SMilanka Ringwald
gatt_client_read_value_of_characteristic_using_value_handle(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t value_handle)4217dbac955SMatthias Ringwald uint8_t gatt_client_read_value_of_characteristic_using_value_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle){
4227dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE;
4237dbac955SMatthias Ringwald
4247dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(value_handle);
4257dbac955SMatthias Ringwald btstack_assert(mock_characteristic != NULL);
4267dbac955SMatthias Ringwald
4277dbac955SMatthias Ringwald mock_gatt_client_value_handle = mock_characteristic->value_handle;
4287dbac955SMatthias Ringwald gatt_client.callback = callback;
4297dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
4307dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
4317dbac955SMatthias Ringwald }
4327dbac955SMatthias Ringwald
gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback,hci_con_handle_t con_handle,gatt_client_characteristic_t * characteristic)4337dbac955SMatthias Ringwald uint8_t gatt_client_read_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
4347dbac955SMatthias Ringwald btstack_assert(characteristic != NULL);
4357dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE;
4367dbac955SMatthias Ringwald
4377dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(characteristic->value_handle);
4387dbac955SMatthias Ringwald btstack_assert(mock_characteristic != NULL);
4397dbac955SMatthias Ringwald
4407dbac955SMatthias Ringwald gatt_client.callback = callback;
4417dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
4427dbac955SMatthias Ringwald mock_gatt_client_value_handle = mock_characteristic->value_handle;
4437dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
4447dbac955SMatthias Ringwald }
4457dbac955SMatthias Ringwald
gatt_client_read_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t descriptor_handle)4467dbac955SMatthias Ringwald uint8_t gatt_client_read_characteristic_descriptor_using_descriptor_handle(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t descriptor_handle){
4477dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE;
4487dbac955SMatthias Ringwald mock_gatt_client_value_handle = descriptor_handle;
4497dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
4507dbac955SMatthias Ringwald }
4517dbac955SMatthias Ringwald
gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification)4527dbac955SMatthias Ringwald void gatt_client_stop_listening_for_characteristic_value_updates(gatt_client_notification_t * notification){
4537dbac955SMatthias Ringwald }
4547dbac955SMatthias Ringwald
gatt_client_request_to_send_gatt_query(btstack_context_callback_registration_t * callback_registration,hci_con_handle_t con_handle)455*7bf08f64SMatthias Ringwald uint8_t gatt_client_request_to_send_gatt_query(btstack_context_callback_registration_t * callback_registration, hci_con_handle_t con_handle){
456*7bf08f64SMatthias Ringwald // immediate callback, we don't have btstack runloop in most tests
457*7bf08f64SMatthias Ringwald (*callback_registration->callback)(callback_registration->context);
458*7bf08f64SMatthias Ringwald return ERROR_CODE_SUCCESS;
459*7bf08f64SMatthias Ringwald }
460*7bf08f64SMatthias Ringwald
gatt_client_write_value_of_characteristic(btstack_packet_handler_t callback,hci_con_handle_t con_handle,uint16_t value_handle,uint16_t value_length,uint8_t * value)4617dbac955SMatthias Ringwald uint8_t gatt_client_write_value_of_characteristic(btstack_packet_handler_t callback, hci_con_handle_t con_handle, uint16_t value_handle, uint16_t value_length, uint8_t * value){
4627dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * mock_characteristic = mock_gatt_client_get_characteristic_for_value_handle(value_handle);
4637dbac955SMatthias Ringwald btstack_assert(mock_characteristic != NULL);
4647dbac955SMatthias Ringwald
4657dbac955SMatthias Ringwald if (mock_characteristic->notification_status_code != ERROR_CODE_SUCCESS){
4667dbac955SMatthias Ringwald return mock_characteristic->notification_status_code;
4677dbac955SMatthias Ringwald }
4687dbac955SMatthias Ringwald
4697dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
4707dbac955SMatthias Ringwald
4717dbac955SMatthias Ringwald gatt_client.callback = callback;
4727dbac955SMatthias Ringwald gatt_client.con_handle = con_handle;
4737dbac955SMatthias Ringwald return ERROR_CODE_SUCCESS;
4747dbac955SMatthias Ringwald }
4757dbac955SMatthias Ringwald
mock_gatt_client_emit_complete(uint8_t status)4767e693ad3SMilanka Ringwald void mock_gatt_client_emit_complete(uint8_t status){
4777da2c1baSMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_IDLE;
4787da2c1baSMilanka Ringwald emit_gatt_complete_event(&gatt_client, status);
4797da2c1baSMilanka Ringwald }
4800f7fd6c1SMilanka Ringwald
mock_gatt_client_run_once(void)4817e693ad3SMilanka Ringwald void mock_gatt_client_run_once(void){
482af770404SMilanka Ringwald btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE);
48376cdba3eSMilanka Ringwald mock_gatt_client_characteristic_t * characteristic;
48476cdba3eSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * descriptor;
48576cdba3eSMilanka Ringwald
4867da2c1baSMilanka Ringwald btstack_linked_list_iterator_t service_it;
4877da2c1baSMilanka Ringwald btstack_linked_list_iterator_t characteristic_it;
48876cdba3eSMilanka Ringwald btstack_linked_list_iterator_t descriptor_it;
48976cdba3eSMilanka Ringwald
490af770404SMilanka Ringwald switch (mock_gatt_client_state){
4917dbac955SMatthias Ringwald case MOCK_QUERY_DISCOVER_PRIMARY_SERVICES_BY_UUID:
492af770404SMilanka Ringwald // emit GATT_EVENT_SERVICE_QUERY_RESULT for each matching service
493ec1a0daeSMilanka Ringwald if (moc_att_error_code_discover_services != ATT_ERROR_SUCCESS){
494ec1a0daeSMilanka Ringwald mock_gatt_client_emit_complete(moc_att_error_code_discover_services);
495ec1a0daeSMilanka Ringwald return;
496ec1a0daeSMilanka Ringwald }
497ec1a0daeSMilanka Ringwald
4987da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
4997da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){
5007da2c1baSMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
5017dbac955SMatthias Ringwald if (memcmp(service->uuid128, mock_gatt_client_uuid128, 16) != 0) continue;
5027da2c1baSMilanka Ringwald mock_gatt_client_last_service = service;
5037dbac955SMatthias Ringwald emit_gatt_service_query_result_event(&gatt_client, service->start_group_handle, service->end_group_handle, service->uuid128);
5047da2c1baSMilanka Ringwald }
5057da2c1baSMilanka Ringwald // emit GATT_EVENT_QUERY_COMPLETE
5067da2c1baSMilanka Ringwald mock_gatt_client_emit_complete(ATT_ERROR_SUCCESS);
5077da2c1baSMilanka Ringwald break;
5087da2c1baSMilanka Ringwald
5097dbac955SMatthias Ringwald case MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID:
5107dbac955SMatthias Ringwald case MOCK_QUERY_DISCOVER_ALL_CHARACTERISTICS:
5117da2c1baSMilanka Ringwald // emit GATT_EVENT_CHARACTERISTIC_QUERY_RESULT for each matching characteristic
512ec1a0daeSMilanka Ringwald if (moc_att_error_code_discover_characteristics != ATT_ERROR_SUCCESS){
513ec1a0daeSMilanka Ringwald mock_gatt_client_emit_complete(moc_att_error_code_discover_characteristics);
514ec1a0daeSMilanka Ringwald return;
515ec1a0daeSMilanka Ringwald }
516ec1a0daeSMilanka Ringwald
5177da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
5187da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){
5197da2c1baSMilanka Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
5207da2c1baSMilanka Ringwald
5217da2c1baSMilanka Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
5227da2c1baSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){
5237da2c1baSMilanka Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
52476cdba3eSMilanka Ringwald if (characteristic->start_handle < mock_gatt_client_start_handle) continue;
52576cdba3eSMilanka Ringwald if (characteristic->end_handle > mock_gatt_client_end_handle) continue;
5267dbac955SMatthias Ringwald if ((mock_gatt_client_state == MOCK_QUERY_DISCOVER_CHARACTERISTICS_BY_UUID) && (memcmp(characteristic->uuid128, mock_gatt_client_uuid128, 16) != 0)) continue;
52776cdba3eSMilanka Ringwald
52876cdba3eSMilanka Ringwald emit_gatt_characteristic_query_result_event(&gatt_client,
52976cdba3eSMilanka Ringwald characteristic->start_handle, characteristic->value_handle, characteristic->end_handle,
5307dbac955SMatthias Ringwald characteristic->properties, characteristic->uuid128);
5317da2c1baSMilanka Ringwald }
5327da2c1baSMilanka Ringwald }
5337da2c1baSMilanka Ringwald
5347da2c1baSMilanka Ringwald // emit GATT_EVENT_QUERY_COMPLETE
5357da2c1baSMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
536af770404SMilanka Ringwald break;
53776cdba3eSMilanka Ringwald
53876cdba3eSMilanka Ringwald case MOCK_QUERY_DISCOVER_CHARACTERISTIC_DESCRIPTORS:
53976cdba3eSMilanka Ringwald characteristic = mock_gatt_client_get_characteristic_for_value_handle(mock_gatt_client_value_handle);
54076cdba3eSMilanka Ringwald btstack_assert(characteristic != NULL);
54176cdba3eSMilanka Ringwald
542ec1a0daeSMilanka Ringwald if (moc_att_error_code_discover_characteristic_descriptors != ATT_ERROR_SUCCESS){
543ec1a0daeSMilanka Ringwald mock_gatt_client_emit_complete(moc_att_error_code_discover_characteristic_descriptors);
544ec1a0daeSMilanka Ringwald return;
545ec1a0daeSMilanka Ringwald }
546ec1a0daeSMilanka Ringwald
54776cdba3eSMilanka Ringwald btstack_linked_list_iterator_init(&descriptor_it, &characteristic->descriptors);
54876cdba3eSMilanka Ringwald while (btstack_linked_list_iterator_has_next(&descriptor_it)){
54976cdba3eSMilanka Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&descriptor_it);
55076cdba3eSMilanka Ringwald
5517dbac955SMatthias Ringwald emit_gatt_all_characteristic_descriptors_result_event(&gatt_client, desc->handle, desc->uuid128);
55276cdba3eSMilanka Ringwald }
55376cdba3eSMilanka Ringwald
55476cdba3eSMilanka Ringwald // emit GATT_EVENT_QUERY_COMPLETE
55576cdba3eSMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
55676cdba3eSMilanka Ringwald break;
55776cdba3eSMilanka Ringwald
55876cdba3eSMilanka Ringwald case MOCK_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION:
55976cdba3eSMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
56076cdba3eSMilanka Ringwald break;
56176cdba3eSMilanka Ringwald
56276cdba3eSMilanka Ringwald case MOCK_READ_VALUE_OF_CHARACTERISTIC_USING_VALUE_HANDLE:
5637e693ad3SMilanka Ringwald characteristic = mock_gatt_client_get_characteristic_for_value_handle(mock_gatt_client_value_handle);
564e92f7a17SMilanka Ringwald if (moc_att_error_code_read_value_characteristics != ATT_ERROR_SUCCESS){
565e92f7a17SMilanka Ringwald mock_gatt_client_emit_complete(moc_att_error_code_read_value_characteristics);
566e92f7a17SMilanka Ringwald break;
567e92f7a17SMilanka Ringwald }
568e92f7a17SMilanka Ringwald if (characteristic != NULL){
5697e693ad3SMilanka Ringwald mock_gatt_client_send_characteristic_value(&gatt_client, characteristic);
570e92f7a17SMilanka Ringwald }
5717e693ad3SMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
5727e693ad3SMilanka Ringwald break;
5737e693ad3SMilanka Ringwald
5747e693ad3SMilanka Ringwald case MOCK_READ_VALUE_OF_CHARACTERISTIC_DESCRIPTOR_USING_VALUE_HANDLE:
57576cdba3eSMilanka Ringwald descriptor = mock_gatt_client_get_characteristic_descriptor_for_handle(mock_gatt_client_value_handle);
57676cdba3eSMilanka Ringwald btstack_assert(descriptor != NULL);
57776cdba3eSMilanka Ringwald btstack_assert(descriptor->value_buffer != NULL);
57876cdba3eSMilanka Ringwald
57976cdba3eSMilanka Ringwald mock_gatt_client_emit_complete(ERROR_CODE_SUCCESS);
58076cdba3eSMilanka Ringwald break;
58176cdba3eSMilanka Ringwald
582af770404SMilanka Ringwald default:
583af770404SMilanka Ringwald btstack_assert(false);
584af770404SMilanka Ringwald break;
5850f7fd6c1SMilanka Ringwald }
5867da2c1baSMilanka Ringwald }
5877e693ad3SMilanka Ringwald
mock_gatt_client_run(void)5887e693ad3SMilanka Ringwald void mock_gatt_client_run(void){
5897e693ad3SMilanka Ringwald btstack_assert(mock_gatt_client_state != MOCK_QUERY_IDLE);
5907e693ad3SMilanka Ringwald while (mock_gatt_client_state != MOCK_QUERY_IDLE){
5917e693ad3SMilanka Ringwald mock_gatt_client_run_once();
5927e693ad3SMilanka Ringwald }
5937da2c1baSMilanka Ringwald mock_gatt_client_att_error = ERROR_CODE_SUCCESS;
594af770404SMilanka Ringwald mock_gatt_client_state = MOCK_QUERY_IDLE;
5950f7fd6c1SMilanka Ringwald }
5967e693ad3SMilanka Ringwald
mock_gatt_client_emit_dummy_event(void)5977e693ad3SMilanka Ringwald void mock_gatt_client_emit_dummy_event(void){
5987e693ad3SMilanka Ringwald // @format H1
5997e693ad3SMilanka Ringwald uint8_t packet[2];
6007e693ad3SMilanka Ringwald packet[0] = 0;
6017e693ad3SMilanka Ringwald packet[1] = 0;
6027aa69c24SMatthias Ringwald emit_event_new(gatt_client.callback, packet, sizeof(packet));
6037e693ad3SMilanka Ringwald }
6047dbac955SMatthias Ringwald
mock_gatt_client_reset_errors(void)6057dbac955SMatthias Ringwald static void mock_gatt_client_reset_errors(void){
6067dbac955SMatthias Ringwald moc_att_error_code_discover_services = ATT_ERROR_SUCCESS;
6077dbac955SMatthias Ringwald moc_att_error_code_discover_characteristics = ATT_ERROR_SUCCESS;
6087dbac955SMatthias Ringwald moc_att_error_code_discover_characteristic_descriptors = ATT_ERROR_SUCCESS;
609e92f7a17SMilanka Ringwald moc_att_error_code_read_value_characteristics = ATT_ERROR_SUCCESS;
6107dbac955SMatthias Ringwald }
6117dbac955SMatthias Ringwald
mock_gatt_client_reset(void)6127dbac955SMatthias Ringwald void mock_gatt_client_reset(void){
6137dbac955SMatthias Ringwald mock_gatt_client_att_error = 0;
6147dbac955SMatthias Ringwald mock_gatt_client_state = MOCK_QUERY_IDLE;
6157dbac955SMatthias Ringwald mock_gatt_client_att_handle_generator = 0;
6167dbac955SMatthias Ringwald mock_gatt_client_last_service = NULL;
6177dbac955SMatthias Ringwald
6187dbac955SMatthias Ringwald mock_gatt_client_reset_errors();
6197dbac955SMatthias Ringwald
6207dbac955SMatthias Ringwald btstack_linked_list_iterator_t service_it;
6217dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
6227dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){
6237dbac955SMatthias Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
6247dbac955SMatthias Ringwald btstack_linked_list_remove(&mock_gatt_client_services, (btstack_linked_item_t *) service);
6257dbac955SMatthias Ringwald
6267dbac955SMatthias Ringwald btstack_linked_list_iterator_t characteristic_it;
6277dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
6287dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){
6297dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
6307dbac955SMatthias Ringwald btstack_linked_list_remove(&service->characteristics, (btstack_linked_item_t *) characteristic);
6317dbac955SMatthias Ringwald
6327dbac955SMatthias Ringwald btstack_linked_list_iterator_t desc_it;
6337dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors);
6347dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&desc_it)){
6357dbac955SMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it);
6367dbac955SMatthias Ringwald btstack_linked_list_remove(&characteristic->descriptors, (btstack_linked_item_t *) desc);
6377dbac955SMatthias Ringwald free(desc);
6387dbac955SMatthias Ringwald }
6397dbac955SMatthias Ringwald free(characteristic);
6407dbac955SMatthias Ringwald }
6417dbac955SMatthias Ringwald free(service);
6427dbac955SMatthias Ringwald }
6437dbac955SMatthias Ringwald }
6447dbac955SMatthias Ringwald
mock_gatt_client_set_att_error_discover_primary_services(void)6457dbac955SMatthias Ringwald void mock_gatt_client_set_att_error_discover_primary_services(void){
6467dbac955SMatthias Ringwald moc_att_error_code_discover_services = ATT_ERROR_REQUEST_NOT_SUPPORTED;
6477dbac955SMatthias Ringwald }
mock_gatt_client_set_att_error_discover_characteristics(void)6487dbac955SMatthias Ringwald void mock_gatt_client_set_att_error_discover_characteristics(void){
6497dbac955SMatthias Ringwald moc_att_error_code_discover_characteristics = ATT_ERROR_REQUEST_NOT_SUPPORTED;
6507dbac955SMatthias Ringwald }
mock_gatt_client_set_att_error_discover_characteristic_descriptors(void)6517dbac955SMatthias Ringwald void mock_gatt_client_set_att_error_discover_characteristic_descriptors(void){
6527dbac955SMatthias Ringwald moc_att_error_code_discover_characteristic_descriptors = ATT_ERROR_REQUEST_NOT_SUPPORTED;
6537dbac955SMatthias Ringwald }
mock_gatt_client_set_att_error_read_value_characteristics(void)654e92f7a17SMilanka Ringwald void mock_gatt_client_set_att_error_read_value_characteristics(void){
655e92f7a17SMilanka Ringwald moc_att_error_code_read_value_characteristics = ATT_ERROR_REQUEST_NOT_SUPPORTED;
6567dbac955SMatthias Ringwald }
6577dbac955SMatthias Ringwald
mock_gatt_client_enable_notification(mock_gatt_client_characteristic_t * characteristic,bool command_allowed)6587dbac955SMatthias Ringwald void mock_gatt_client_enable_notification(mock_gatt_client_characteristic_t * characteristic, bool command_allowed){
6597dbac955SMatthias Ringwald if (command_allowed){
6607dbac955SMatthias Ringwald characteristic->notification_status_code = ERROR_CODE_SUCCESS;
6617dbac955SMatthias Ringwald } else {
6627dbac955SMatthias Ringwald characteristic->notification_status_code = ERROR_CODE_COMMAND_DISALLOWED;
6637dbac955SMatthias Ringwald }
6647dbac955SMatthias Ringwald }
6657dbac955SMatthias Ringwald
mock_gatt_client_dump_services(void)6667dbac955SMatthias Ringwald void mock_gatt_client_dump_services(void){
6677dbac955SMatthias Ringwald btstack_linked_list_iterator_t service_it;
6687dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&service_it, &mock_gatt_client_services);
6697dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&service_it)){
6707dbac955SMatthias Ringwald mock_gatt_client_service_t * service = (mock_gatt_client_service_t *) btstack_linked_list_iterator_next(&service_it);
6717dbac955SMatthias Ringwald printf("0x%02x: START SERVICE ", service->start_group_handle);
6727dbac955SMatthias Ringwald if (service->uuid16) {
6737dbac955SMatthias Ringwald printf("%04x\n", service->uuid16);
6747dbac955SMatthias Ringwald } else {
6757dbac955SMatthias Ringwald printf("%s\n", uuid128_to_str(service->uuid128));
6767dbac955SMatthias Ringwald }
6777dbac955SMatthias Ringwald
6787dbac955SMatthias Ringwald btstack_linked_list_iterator_t characteristic_it;
6797dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&characteristic_it, &service->characteristics);
6807dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&characteristic_it)){
6817dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * characteristic = (mock_gatt_client_characteristic_t *) btstack_linked_list_iterator_next(&characteristic_it);
6827dbac955SMatthias Ringwald printf("0x%02x: START CHR ", characteristic->start_handle);
6837dbac955SMatthias Ringwald if (characteristic->uuid16) {
6847dbac955SMatthias Ringwald printf("%04x\n", characteristic->uuid16);
6857dbac955SMatthias Ringwald } else {
6867dbac955SMatthias Ringwald printf("%s\n", uuid128_to_str(characteristic->uuid128));
6877dbac955SMatthias Ringwald }
6887dbac955SMatthias Ringwald printf("0x%02x: VALUE HANDLE CHR\n", characteristic->value_handle);
6897dbac955SMatthias Ringwald
6907dbac955SMatthias Ringwald btstack_linked_list_iterator_t desc_it;
6917dbac955SMatthias Ringwald btstack_linked_list_iterator_init(&desc_it, &characteristic->descriptors);
6927dbac955SMatthias Ringwald while (btstack_linked_list_iterator_has_next(&desc_it)){
6937dbac955SMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t *) btstack_linked_list_iterator_next(&desc_it);
6947dbac955SMatthias Ringwald printf("0x%02x: DESC 0x%02x\n", desc->handle, desc->uuid16);
6957dbac955SMatthias Ringwald }
6967dbac955SMatthias Ringwald
6977dbac955SMatthias Ringwald printf("0x%02x: END CHR 0%02x\n", characteristic->end_handle, characteristic->uuid16);
6987dbac955SMatthias Ringwald }
6997dbac955SMatthias Ringwald printf("0x%02x: END SERVICE 0%02x\n", service->end_group_handle, service->uuid16);
7007dbac955SMatthias Ringwald
7017dbac955SMatthias Ringwald }
7027dbac955SMatthias Ringwald }
7037dbac955SMatthias Ringwald
mock_gatt_client_add_primary_service(void)7047dbac955SMatthias Ringwald static void mock_gatt_client_add_primary_service(void){
7057dbac955SMatthias Ringwald // set lsat group handle
7067dbac955SMatthias Ringwald // create new service
7077dbac955SMatthias Ringwald mock_gatt_client_last_service = (mock_gatt_client_service_t * )malloc(sizeof(mock_gatt_client_service_t));
7087dbac955SMatthias Ringwald memset(mock_gatt_client_last_service, 0, sizeof(mock_gatt_client_service_t));
7097dbac955SMatthias Ringwald mock_gatt_client_last_service->start_group_handle = mock_gatt_client_att_handle_generator++;
7107dbac955SMatthias Ringwald mock_gatt_client_last_service->end_group_handle = mock_gatt_client_last_service->start_group_handle;
7117dbac955SMatthias Ringwald btstack_linked_list_add_tail(&mock_gatt_client_services, (btstack_linked_item_t*)mock_gatt_client_last_service);
7127dbac955SMatthias Ringwald mock_gatt_client_last_characteristic = NULL;
7137dbac955SMatthias Ringwald }
7147dbac955SMatthias Ringwald
mock_gatt_client_add_primary_service_uuid16(uint16_t service_uuid)7157dbac955SMatthias Ringwald mock_gatt_client_service_t * mock_gatt_client_add_primary_service_uuid16(uint16_t service_uuid){
7167dbac955SMatthias Ringwald mock_gatt_client_add_primary_service();
7177dbac955SMatthias Ringwald mock_gatt_client_last_service->uuid16 = service_uuid;
7187dbac955SMatthias Ringwald uuid_add_bluetooth_prefix(mock_gatt_client_last_service->uuid128, service_uuid);
7197dbac955SMatthias Ringwald return mock_gatt_client_last_service;
7207dbac955SMatthias Ringwald }
mock_gatt_client_add_primary_service_uuid128(const uint8_t * service_uuid)7217dbac955SMatthias Ringwald mock_gatt_client_service_t * mock_gatt_client_add_primary_service_uuid128(const uint8_t * service_uuid){
7227dbac955SMatthias Ringwald mock_gatt_client_add_primary_service();
7237dbac955SMatthias Ringwald (void) memcpy(mock_gatt_client_last_service->uuid128, service_uuid, 16);
7247dbac955SMatthias Ringwald return mock_gatt_client_last_service;
7257dbac955SMatthias Ringwald }
7267dbac955SMatthias Ringwald
mock_gatt_client_add_characteristic(uint16_t properties)7277dbac955SMatthias Ringwald static void mock_gatt_client_add_characteristic(uint16_t properties){
7287dbac955SMatthias Ringwald btstack_assert(mock_gatt_client_last_service != NULL);
7297dbac955SMatthias Ringwald mock_gatt_client_last_characteristic = (mock_gatt_client_characteristic_t * )malloc(sizeof(mock_gatt_client_characteristic_t));
7307dbac955SMatthias Ringwald memset(mock_gatt_client_last_characteristic, 0, sizeof(mock_gatt_client_characteristic_t));
7317dbac955SMatthias Ringwald mock_gatt_client_last_characteristic->properties = properties;
7327dbac955SMatthias Ringwald mock_gatt_client_last_characteristic->start_handle = mock_gatt_client_att_handle_generator++;
7337dbac955SMatthias Ringwald mock_gatt_client_last_characteristic->value_handle = mock_gatt_client_att_handle_generator++;
7347dbac955SMatthias Ringwald mock_gatt_client_last_characteristic->end_handle = mock_gatt_client_last_characteristic->value_handle;
7357dbac955SMatthias Ringwald btstack_linked_list_add_tail(&mock_gatt_client_last_service->characteristics, (btstack_linked_item_t*)mock_gatt_client_last_characteristic);
7367dbac955SMatthias Ringwald mock_gatt_client_last_service->end_group_handle = mock_gatt_client_att_handle_generator - 1;
7377dbac955SMatthias Ringwald }
7387dbac955SMatthias Ringwald
mock_gatt_client_add_characteristic_uuid16(uint16_t characteristic_uuid,uint16_t properties)7397dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * mock_gatt_client_add_characteristic_uuid16(uint16_t characteristic_uuid, uint16_t properties){
7407dbac955SMatthias Ringwald mock_gatt_client_add_characteristic(properties);
7417dbac955SMatthias Ringwald mock_gatt_client_last_characteristic->uuid16 = characteristic_uuid;
7427dbac955SMatthias Ringwald uuid_add_bluetooth_prefix(mock_gatt_client_last_characteristic->uuid128, characteristic_uuid);
7437dbac955SMatthias Ringwald return mock_gatt_client_last_characteristic;
7447dbac955SMatthias Ringwald }
7457dbac955SMatthias Ringwald
mock_gatt_client_add_characteristic_uuid128(const uint8_t * characteristic_uuid,uint16_t properties)7467dbac955SMatthias Ringwald mock_gatt_client_characteristic_t * mock_gatt_client_add_characteristic_uuid128(const uint8_t * characteristic_uuid, uint16_t properties){
7477dbac955SMatthias Ringwald mock_gatt_client_add_characteristic(properties);
7487dbac955SMatthias Ringwald (void) memcpy(mock_gatt_client_last_characteristic->uuid128, characteristic_uuid, 16);
7497dbac955SMatthias Ringwald return mock_gatt_client_last_characteristic;
7507dbac955SMatthias Ringwald }
7517dbac955SMatthias Ringwald
mock_gatt_client_add_characteristic_descriptor(void)7527dbac955SMatthias Ringwald static mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_add_characteristic_descriptor(void){
7537dbac955SMatthias Ringwald btstack_assert(mock_gatt_client_last_characteristic != NULL);
7547dbac955SMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * desc = (mock_gatt_client_characteristic_descriptor_t * )malloc(sizeof(mock_gatt_client_characteristic_descriptor_t));
7557dbac955SMatthias Ringwald memset(desc, 0, sizeof(mock_gatt_client_characteristic_descriptor_t));
7567dbac955SMatthias Ringwald desc->handle = mock_gatt_client_att_handle_generator++;
7577dbac955SMatthias Ringwald btstack_linked_list_add_tail(&mock_gatt_client_last_characteristic->descriptors, (btstack_linked_item_t*)desc);
7587dbac955SMatthias Ringwald mock_gatt_client_last_characteristic->end_handle = mock_gatt_client_att_handle_generator - 1;
7597dbac955SMatthias Ringwald mock_gatt_client_last_service->end_group_handle = mock_gatt_client_att_handle_generator - 1;
7607dbac955SMatthias Ringwald return desc;
7617dbac955SMatthias Ringwald }
7627dbac955SMatthias Ringwald
mock_gatt_client_add_characteristic_descriptor_uuid16(uint16_t descriptor_uuid)7637dbac955SMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_add_characteristic_descriptor_uuid16(uint16_t descriptor_uuid){
7647dbac955SMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * desc = mock_gatt_client_add_characteristic_descriptor();
7657dbac955SMatthias Ringwald desc->uuid16 = descriptor_uuid;
7667dbac955SMatthias Ringwald uuid_add_bluetooth_prefix(desc->uuid128, descriptor_uuid);
7677dbac955SMatthias Ringwald return desc;
7687dbac955SMatthias Ringwald }
7697dbac955SMatthias Ringwald
mock_gatt_client_add_characteristic_descriptor_uuid128(const uint8_t * descriptor_uuid)7707dbac955SMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * mock_gatt_client_add_characteristic_descriptor_uuid128(const uint8_t * descriptor_uuid){
7717dbac955SMatthias Ringwald mock_gatt_client_characteristic_descriptor_t * desc = mock_gatt_client_add_characteristic_descriptor();
7727dbac955SMatthias Ringwald (void) memcpy(desc->uuid128, descriptor_uuid, 16);
7737dbac955SMatthias Ringwald return desc;
7747dbac955SMatthias Ringwald }
7757dbac955SMatthias Ringwald
mock_gatt_client_set_descriptor_characteristic_value(mock_gatt_client_characteristic_descriptor_t * descriptor,uint8_t * value_buffer,uint16_t value_len)7767dbac955SMatthias Ringwald void mock_gatt_client_set_descriptor_characteristic_value(mock_gatt_client_characteristic_descriptor_t * descriptor, uint8_t * value_buffer, uint16_t value_len){
7777dbac955SMatthias Ringwald btstack_assert(descriptor != NULL);
7787dbac955SMatthias Ringwald descriptor->value_buffer = value_buffer;
7797dbac955SMatthias Ringwald descriptor->value_len = value_len;
7807dbac955SMatthias Ringwald }
7817dbac955SMatthias Ringwald
mock_gatt_client_set_characteristic_value(mock_gatt_client_characteristic_t * characteristic,uint8_t * value_buffer,uint16_t value_len)7827dbac955SMatthias Ringwald void mock_gatt_client_set_characteristic_value(mock_gatt_client_characteristic_t * characteristic, uint8_t * value_buffer, uint16_t value_len){
7837dbac955SMatthias Ringwald btstack_assert(characteristic != NULL);
7847dbac955SMatthias Ringwald characteristic->value_buffer = value_buffer;
7857dbac955SMatthias Ringwald characteristic->value_len = value_len;
7867dbac955SMatthias Ringwald }
7877dbac955SMatthias Ringwald
7887dbac955SMatthias Ringwald // simulate error
mock_gatt_client_simulate_att_error(uint8_t att_error)7897dbac955SMatthias Ringwald void mock_gatt_client_simulate_att_error(uint8_t att_error){
7907dbac955SMatthias Ringwald mock_gatt_client_att_error = att_error;
7917dbac955SMatthias Ringwald }
792