gatt_client.c (1b9be2e8d27cdda8e4ec6c17a6c75ebf262a671d) gatt_client.c (197b4dd334e478ceaf939f8f152295ee6dfabbf3)
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 625 unchanged lines hidden (view full) ---

634static void send_gatt_execute_write_request(gatt_client_t * gatt_client){
635 att_execute_write_request(gatt_client, ATT_EXECUTE_WRITE_REQUEST, 1);
636}
637
638static void send_gatt_cancel_prepared_write_request(gatt_client_t * gatt_client){
639 att_execute_write_request(gatt_client, ATT_EXECUTE_WRITE_REQUEST, 0);
640}
641
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright

--- 625 unchanged lines hidden (view full) ---

634static void send_gatt_execute_write_request(gatt_client_t * gatt_client){
635 att_execute_write_request(gatt_client, ATT_EXECUTE_WRITE_REQUEST, 1);
636}
637
638static void send_gatt_cancel_prepared_write_request(gatt_client_t * gatt_client){
639 att_execute_write_request(gatt_client, ATT_EXECUTE_WRITE_REQUEST, 0);
640}
641
642#ifndef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
643static void send_gatt_read_client_characteristic_configuration_request(gatt_client_t * gatt_client){
644 att_read_by_type_or_group_request_for_uuid16(gatt_client, ATT_READ_BY_TYPE_REQUEST,
645 GATT_CLIENT_CHARACTERISTICS_CONFIGURATION,
646 gatt_client->start_group_handle, gatt_client->end_group_handle);
647}
648#endif
649
642static void send_gatt_read_characteristic_descriptor_request(gatt_client_t * gatt_client){
643 att_read_request(gatt_client, ATT_READ_REQUEST, gatt_client->attribute_handle);
644}
645
646#ifdef ENABLE_LE_SIGNED_WRITE
647static void send_gatt_signed_write_request(gatt_client_t * gatt_client, uint32_t sign_counter){
648 att_signed_write_request(gatt_client, ATT_SIGNED_WRITE_COMMAND, gatt_client->attribute_handle,
649 gatt_client->attribute_length, gatt_client->attribute_value, sign_counter,

--- 903 unchanged lines hidden (view full) ---

1553 send_gatt_cancel_prepared_write_request(gatt_client);
1554 break;
1555
1556 case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH:
1557 gatt_client->state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT;
1558 send_gatt_cancel_prepared_write_request(gatt_client);
1559 break;
1560
650static void send_gatt_read_characteristic_descriptor_request(gatt_client_t * gatt_client){
651 att_read_request(gatt_client, ATT_READ_REQUEST, gatt_client->attribute_handle);
652}
653
654#ifdef ENABLE_LE_SIGNED_WRITE
655static void send_gatt_signed_write_request(gatt_client_t * gatt_client, uint32_t sign_counter){
656 att_signed_write_request(gatt_client, ATT_SIGNED_WRITE_COMMAND, gatt_client->attribute_handle,
657 gatt_client->attribute_length, gatt_client->attribute_value, sign_counter,

--- 903 unchanged lines hidden (view full) ---

1561 send_gatt_cancel_prepared_write_request(gatt_client);
1562 break;
1563
1564 case P_W2_CANCEL_PREPARED_WRITE_DATA_MISMATCH:
1565 gatt_client->state = P_W4_CANCEL_PREPARED_WRITE_DATA_MISMATCH_RESULT;
1566 send_gatt_cancel_prepared_write_request(gatt_client);
1567 break;
1568
1561 case P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
1569#ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
1570 case P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
1562 // use Find Information
1563 gatt_client->state = P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
1564 send_gatt_characteristic_descriptor_request(gatt_client);
1571 // use Find Information
1572 gatt_client->state = P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
1573 send_gatt_characteristic_descriptor_request(gatt_client);
1574#else
1575 case P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY:
1576 // Use Read By Type
1577 gatt_client->state = P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT;
1578 send_gatt_read_client_characteristic_configuration_request(gatt_client);
1579#endif
1565 break;
1566
1567 case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY:
1568 gatt_client->state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT;
1569 send_gatt_read_characteristic_descriptor_request(gatt_client);
1570 break;
1571
1572 case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY:

--- 385 unchanged lines hidden (view full) ---

1958 }
1959
1960 trigger_next_included_service_query(gatt_client,
1961 get_last_result_handle_from_included_services_list(packet,
1962 size));
1963 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1964 break;
1965 }
1580 break;
1581
1582 case P_W2_SEND_READ_CHARACTERISTIC_DESCRIPTOR_QUERY:
1583 gatt_client->state = P_W4_READ_CHARACTERISTIC_DESCRIPTOR_RESULT;
1584 send_gatt_read_characteristic_descriptor_request(gatt_client);
1585 break;
1586
1587 case P_W2_SEND_READ_BLOB_CHARACTERISTIC_DESCRIPTOR_QUERY:

--- 385 unchanged lines hidden (view full) ---

1973 }
1974
1975 trigger_next_included_service_query(gatt_client,
1976 get_last_result_handle_from_included_services_list(packet,
1977 size));
1978 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
1979 break;
1980 }
1981#ifndef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
1982 case P_W4_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT:
1983 gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, 2);
1984 gatt_client->state = P_W2_WRITE_CLIENT_CHARACTERISTIC_CONFIGURATION;
1985 break;
1986#endif
1966 case P_W4_READ_BY_TYPE_RESPONSE: {
1967 uint16_t pair_size = packet[1];
1968 // set last result handle to last valid handle, only used if pair_size invalid
1969 uint16_t last_result_handle = 0xffff;
1970 if (pair_size > 2) {
1971 uint16_t offset;
1972 for (offset = 2; offset < size; offset += pair_size) {
1973 uint16_t value_handle = little_endian_read_16(packet, offset);

--- 127 unchanged lines hidden (view full) ---

2101 if (packet[1u] == 2u) {
2102 pair_size = 18;
2103 }
2104 uint16_t offset = 2;
2105
2106 if (size < (pair_size + offset)) break;
2107 uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size);
2108
1987 case P_W4_READ_BY_TYPE_RESPONSE: {
1988 uint16_t pair_size = packet[1];
1989 // set last result handle to last valid handle, only used if pair_size invalid
1990 uint16_t last_result_handle = 0xffff;
1991 if (pair_size > 2) {
1992 uint16_t offset;
1993 for (offset = 2; offset < size; offset += pair_size) {
1994 uint16_t value_handle = little_endian_read_16(packet, offset);

--- 127 unchanged lines hidden (view full) ---

2122 if (packet[1u] == 2u) {
2123 pair_size = 18;
2124 }
2125 uint16_t offset = 2;
2126
2127 if (size < (pair_size + offset)) break;
2128 uint16_t last_descriptor_handle = little_endian_read_16(packet, size - pair_size);
2129
2130#ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
2109 log_info("ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY, state %x", gatt_client->state);
2110 if (gatt_client->state == P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT){
2111 // iterate over descriptors looking for CCC
2112 if (pair_size == 4){
2113 while ((offset + 4) <= size){
2114 uint16_t uuid16 = little_endian_read_16(packet, offset + 2);
2115 if (uuid16 == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION){
2116 gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, offset);

--- 8 unchanged lines hidden (view full) ---

2125
2126 } else {
2127 // next
2128 gatt_client->start_group_handle = last_descriptor_handle + 1;
2129 gatt_client->state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2130 }
2131 break;
2132 }
2131 log_info("ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY, state %x", gatt_client->state);
2132 if (gatt_client->state == P_W4_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY_RESULT){
2133 // iterate over descriptors looking for CCC
2134 if (pair_size == 4){
2135 while ((offset + 4) <= size){
2136 uint16_t uuid16 = little_endian_read_16(packet, offset + 2);
2137 if (uuid16 == GATT_CLIENT_CHARACTERISTICS_CONFIGURATION){
2138 gatt_client->client_characteristic_configuration_handle = little_endian_read_16(packet, offset);

--- 8 unchanged lines hidden (view full) ---

2147
2148 } else {
2149 // next
2150 gatt_client->start_group_handle = last_descriptor_handle + 1;
2151 gatt_client->state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2152 }
2153 break;
2154 }
2155#endif
2133 report_gatt_all_characteristic_descriptors(gatt_client, &packet[2], size - 2u, pair_size);
2134 trigger_next_characteristic_descriptor_query(gatt_client, last_descriptor_handle);
2135 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
2136 break;
2137 }
2138
2139 case ATT_WRITE_RESPONSE:
2140 gatt_client_handle_att_write_response(gatt_client);

--- 816 unchanged lines hidden (view full) ---

2957
2958 gatt_client->callback = callback;
2959 gatt_client->service_id = service_id;
2960 gatt_client->connection_id = connection_id;
2961 gatt_client->start_group_handle = characteristic->value_handle;
2962 gatt_client->end_group_handle = characteristic->end_handle;
2963 little_endian_store_16(gatt_client->client_characteristic_configuration_value, 0, configuration);
2964
2156 report_gatt_all_characteristic_descriptors(gatt_client, &packet[2], size - 2u, pair_size);
2157 trigger_next_characteristic_descriptor_query(gatt_client, last_descriptor_handle);
2158 // GATT_EVENT_QUERY_COMPLETE is emitted by trigger_next_xxx when done
2159 break;
2160 }
2161
2162 case ATT_WRITE_RESPONSE:
2163 gatt_client_handle_att_write_response(gatt_client);

--- 816 unchanged lines hidden (view full) ---

2980
2981 gatt_client->callback = callback;
2982 gatt_client->service_id = service_id;
2983 gatt_client->connection_id = connection_id;
2984 gatt_client->start_group_handle = characteristic->value_handle;
2985 gatt_client->end_group_handle = characteristic->end_handle;
2986 little_endian_store_16(gatt_client->client_characteristic_configuration_value, 0, configuration);
2987
2988#ifdef ENABLE_GATT_FIND_INFORMATION_FOR_CCC_DISCOVERY
2965 gatt_client->state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2989 gatt_client->state = P_W2_SEND_FIND_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2990#else
2991 gatt_client->state = P_W2_SEND_READ_CLIENT_CHARACTERISTIC_CONFIGURATION_QUERY;
2992#endif
2966 gatt_client_run();
2967 return ERROR_CODE_SUCCESS;
2968}
2969
2970uint8_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){
2971 return gatt_client_write_client_characteristic_configuration_with_context(callback, con_handle, characteristic, configuration, 0, 0);
2972}
2973

--- 908 unchanged lines hidden ---
2993 gatt_client_run();
2994 return ERROR_CODE_SUCCESS;
2995}
2996
2997uint8_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){
2998 return gatt_client_write_client_characteristic_configuration_with_context(callback, con_handle, characteristic, configuration, 0, 0);
2999}
3000

--- 908 unchanged lines hidden ---