gatt_client.c (4c7c987f92f21ab881ce714862f6b9a6f8eb6a11) gatt_client.c (544a5845c296932954981242900572b1856bf7e1)
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

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

63
64// L2CAP Test Spec p35 defines a minimum of 100 ms, but PTS might indicate an error if we sent after 100 ms
65#define GATT_CLIENT_COLLISION_BACKOFF_MS 150
66
67static btstack_linked_list_t gatt_client_connections;
68static btstack_linked_list_t gatt_client_value_listeners;
69static btstack_packet_callback_registration_t hci_event_callback_registration;
70static btstack_packet_callback_registration_t sm_event_callback_registration;
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

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

63
64// L2CAP Test Spec p35 defines a minimum of 100 ms, but PTS might indicate an error if we sent after 100 ms
65#define GATT_CLIENT_COLLISION_BACKOFF_MS 150
66
67static btstack_linked_list_t gatt_client_connections;
68static btstack_linked_list_t gatt_client_value_listeners;
69static btstack_packet_callback_registration_t hci_event_callback_registration;
70static btstack_packet_callback_registration_t sm_event_callback_registration;
71static btstack_context_callback_registration_t gatt_client_deferred_event_emit;
71
72// GATT Client Configuration
73static bool gatt_client_mtu_exchange_enabled;
74static gap_security_level_t gatt_client_required_security_level;
75
76static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size);
77static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
78static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code);

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

1449 btstack_unreachable();
1450 break;
1451 }
1452
1453
1454 }
1455}
1456
72
73// GATT Client Configuration
74static bool gatt_client_mtu_exchange_enabled;
75static gap_security_level_t gatt_client_required_security_level;
76
77static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size);
78static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
79static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code);

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

1450 btstack_unreachable();
1451 break;
1452 }
1453
1454
1455 }
1456}
1457
1458// emit complete event, used to avoid emitting event from API call
1459static void gatt_client_emit_events(void * context){
1460 UNUSED(context);
1461 btstack_linked_item_t *it;
1462 for (it = (btstack_linked_item_t *) gatt_client_connections; it != NULL; it = it->next) {
1463 gatt_client_t *gatt_client = (gatt_client_t *) it;
1464 if (gatt_client->state == P_W2_EMIT_QUERY_COMPLETE_EVENT){
1465 gatt_client->state = P_READY;
1466 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
1467 }
1468 }
1469}
1470
1457static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code) {
1458 if (is_ready(gatt_client)) return;
1459 gatt_client_handle_transaction_complete(gatt_client, att_error_code);
1460}
1461
1462static void gatt_client_handle_reencryption_complete(const uint8_t * packet){
1463 hci_con_handle_t con_handle = sm_event_reencryption_complete_get_handle(packet);
1464 gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);

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

2379
2380uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
2381 gatt_client_t * gatt_client;
2382 uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2383 if (status != ERROR_CODE_SUCCESS){
2384 return status;
2385 }
2386
1471static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code) {
1472 if (is_ready(gatt_client)) return;
1473 gatt_client_handle_transaction_complete(gatt_client, att_error_code);
1474}
1475
1476static void gatt_client_handle_reencryption_complete(const uint8_t * packet){
1477 hci_con_handle_t con_handle = sm_event_reencryption_complete_get_handle(packet);
1478 gatt_client_t * gatt_client = gatt_client_get_context_for_handle(con_handle);

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

2393
2394uint8_t gatt_client_discover_characteristic_descriptors(btstack_packet_handler_t callback, hci_con_handle_t con_handle, gatt_client_characteristic_t * characteristic){
2395 gatt_client_t * gatt_client;
2396 uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2397 if (status != ERROR_CODE_SUCCESS){
2398 return status;
2399 }
2400
2387 if (characteristic->value_handle == characteristic->end_handle){
2388 emit_gatt_complete_event(gatt_client, ATT_ERROR_SUCCESS);
2389 return ERROR_CODE_SUCCESS;
2401 // check if there is space for characteristics descriptors
2402 if (characteristic->end_handle > characteristic->value_handle){
2403 gatt_client->callback = callback;
2404 gatt_client->start_group_handle = characteristic->value_handle + 1u;
2405 gatt_client->end_group_handle = characteristic->end_handle;
2406 gatt_client->state = P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY;
2407 gatt_client_run();
2408 } else {
2409 // schedule gatt complete event on next run loop iteration otherwise
2410 gatt_client->state = P_W2_EMIT_QUERY_COMPLETE_EVENT;
2411 gatt_client_deferred_event_emit.callback = gatt_client_emit_events;
2412 btstack_run_loop_execute_on_main_thread(&gatt_client_deferred_event_emit);
2390 }
2413 }
2391 gatt_client->callback = callback;
2392 gatt_client->start_group_handle = characteristic->value_handle + 1u;
2393 gatt_client->end_group_handle = characteristic->end_handle;
2394 gatt_client->state = P_W2_SEND_ALL_CHARACTERISTIC_DESCRIPTORS_QUERY;
2395 gatt_client_run();
2396 return ERROR_CODE_SUCCESS;
2397}
2398
2399uint8_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){
2400 gatt_client_t * gatt_client;
2401 uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2402 if (status != ERROR_CODE_SUCCESS){
2403 return status;

--- 1076 unchanged lines hidden ---
2414 return ERROR_CODE_SUCCESS;
2415}
2416
2417uint8_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){
2418 gatt_client_t * gatt_client;
2419 uint8_t status = gatt_client_provide_context_for_request(con_handle, &gatt_client);
2420 if (status != ERROR_CODE_SUCCESS){
2421 return status;

--- 1076 unchanged lines hidden ---