gatt_client.c (d8acf2678c74361211216d4d4c57e1065e5a4d42) gatt_client.c (59b5e1571f5da99ee3ef848c85db62a80ffa1972)
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

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

73static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size);
74static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
75static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code);
76
77#ifdef ENABLE_LE_SIGNED_WRITE
78static void att_signed_write_handle_cmac_result(uint8_t hash[8]);
79#endif
80
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

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

73static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size);
74static void gatt_client_event_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
75static void gatt_client_report_error_if_pending(gatt_client_t *gatt_client, uint8_t att_error_code);
76
77#ifdef ENABLE_LE_SIGNED_WRITE
78static void att_signed_write_handle_cmac_result(uint8_t hash[8]);
79#endif
80
81#ifdef ENABLE_GATT_OVER_CLASSIC
82static gatt_client_t * gatt_client_get_context_for_l2cap_cid(uint16_t l2cap_cid);
83static void gatt_client_classic_handle_connected(gatt_client_t * gatt_client, uint8_t status);
84static void gatt_client_classic_handle_disconnected(gatt_client_t * gatt_client);
85#endif
86
81#ifdef ENABLE_GATT_OVER_EATT
82static bool gatt_client_le_enhanced_handle_can_send_query(gatt_client_t * gatt_client);
83#endif
84
85void gatt_client_init(void){
86 gatt_client_connections = NULL;
87
88 // default configuration

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

2096 default:
2097 log_info("ATT Handler, unhandled response type 0x%02x", packet[0]);
2098 break;
2099 }
2100}
2101
2102static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size) {
2103 gatt_client_t *gatt_client;
87#ifdef ENABLE_GATT_OVER_EATT
88static bool gatt_client_le_enhanced_handle_can_send_query(gatt_client_t * gatt_client);
89#endif
90
91void gatt_client_init(void){
92 gatt_client_connections = NULL;
93
94 // default configuration

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

2102 default:
2103 log_info("ATT Handler, unhandled response type 0x%02x", packet[0]);
2104 break;
2105 }
2106}
2107
2108static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size) {
2109 gatt_client_t *gatt_client;
2110 hci_connection_t * hci_connection;
2111 uint8_t status;
2104 if (size < 1u) return;
2112 if (size < 1u) return;
2113 switch (packet_type){
2114 case HCI_EVENT_PACKET:
2115 switch (hci_event_packet_get_type(packet)) {
2116#ifdef ENABLE_GATT_OVER_CLASSIC
2117 case L2CAP_EVENT_CHANNEL_OPENED:
2118 status = l2cap_event_channel_opened_get_status(packet);
2119 gatt_client = gatt_client_get_context_for_l2cap_cid(l2cap_event_channel_opened_get_local_cid(packet));
2120 btstack_assert(gatt_client != NULL);
2121 // if status != 0, gatt_client will be discarded
2122 gatt_client->gatt_client_state = P_READY;
2123 gatt_client->con_handle = l2cap_event_channel_opened_get_handle(packet);
2124 gatt_client->mtu = l2cap_event_channel_opened_get_remote_mtu(packet);
2125 gatt_client_classic_handle_connected(gatt_client, status);
2126 break;
2127 case L2CAP_EVENT_CHANNEL_CLOSED:
2128 gatt_client = gatt_client_get_context_for_l2cap_cid(l2cap_event_channel_closed_get_local_cid(packet));
2129 // clear l2cap cid in hci_connection->att_server
2130 hci_connection = hci_connection_for_handle(gatt_client->con_handle);
2131 hci_connection->att_server.l2cap_cid = 0;
2132 // discard gatt client object
2133 gatt_client_classic_handle_disconnected(gatt_client);
2134 break;
2135#endif
2136 case L2CAP_EVENT_CAN_SEND_NOW:
2137 gatt_client_run();
2138 break;
2139 // att_server has negotiated the mtu for this connection, cache if context exists
2140 case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
2141 if (size < 6u) break;
2142 gatt_client = gatt_client_get_context_for_handle(handle);
2143 if (gatt_client == NULL) break;
2144 gatt_client->mtu = little_endian_read_16(packet, 4);
2145 break;
2146 default:
2147 break;
2148 }
2149 break;
2105
2150
2106 if (packet_type == HCI_EVENT_PACKET) {
2107 switch (packet[0]) {
2108 case L2CAP_EVENT_CAN_SEND_NOW:
2151 case ATT_DATA_PACKET:
2152 // special cases: notifications & indications motivate creating context
2153 switch (packet[0]) {
2154 case ATT_HANDLE_VALUE_NOTIFICATION:
2155 case ATT_HANDLE_VALUE_INDICATION:
2156 gatt_client_provide_context_for_handle(handle, &gatt_client);
2157 break;
2158 default:
2159 gatt_client = gatt_client_get_context_for_handle(handle);
2160 break;
2161 }
2162
2163 if (gatt_client != NULL) {
2164 gatt_client_handle_att_response(gatt_client, packet, size);
2109 gatt_client_run();
2165 gatt_client_run();
2110 break;
2111 // att_server has negotiated the mtu for this connection, cache if context exists
2112 case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
2113 if (size < 6u) break;
2114 gatt_client = gatt_client_get_context_for_handle(handle);
2115 if (gatt_client == NULL) break;
2116 gatt_client->mtu = little_endian_read_16(packet, 4);
2117 break;
2118 default:
2119 break;
2120 }
2121 return;
2122 }
2166 }
2167 break;
2123
2168
2124 if (packet_type != ATT_DATA_PACKET) return;
2125
2126 // special cases: notifications & indications motivate creating context
2127 switch (packet[0]) {
2128 case ATT_HANDLE_VALUE_NOTIFICATION:
2129 case ATT_HANDLE_VALUE_INDICATION:
2130 gatt_client_provide_context_for_handle(handle, &gatt_client);
2169#ifdef ENABLE_GATT_OVER_CLASSIC
2170 case L2CAP_DATA_PACKET:
2171 gatt_client = gatt_client_get_context_for_l2cap_cid(handle);
2172 btstack_assert(gatt_client != NULL);
2173 gatt_client_handle_att_response(gatt_client, packet, size);
2174 gatt_client_run();
2131 break;
2175 break;
2176#endif
2177
2132 default:
2178 default:
2133 gatt_client = gatt_client_get_context_for_handle(handle);
2134 break;
2135 }
2179 break;
2180 }
2136
2137 if (gatt_client != NULL) {
2138 gatt_client_handle_att_response(gatt_client, packet, size);
2139 gatt_client_run();
2140 }
2141}
2142
2143#ifdef ENABLE_LE_SIGNED_WRITE
2144static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
2145 btstack_linked_list_iterator_t it;
2146 btstack_linked_list_iterator_init(&it, &gatt_client_connections);
2147 while (btstack_linked_list_iterator_has_next(&it)){
2148 gatt_client_t * gatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);

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

2862 btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
2863 btstack_memory_gatt_client_free(gatt_client);
2864
2865 uint8_t buffer[20];
2866 uint16_t len = hci_event_create_from_template_and_arguments(buffer, sizeof(buffer), &gatt_client_disconnected, con_handle);
2867 (*callback)(HCI_EVENT_PACKET, 0, buffer, len);
2868}
2869
2181}
2182
2183#ifdef ENABLE_LE_SIGNED_WRITE
2184static void att_signed_write_handle_cmac_result(uint8_t hash[8]){
2185 btstack_linked_list_iterator_t it;
2186 btstack_linked_list_iterator_init(&it, &gatt_client_connections);
2187 while (btstack_linked_list_iterator_has_next(&it)){
2188 gatt_client_t * gatt_client = (gatt_client_t *) btstack_linked_list_iterator_next(&it);

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

2902 btstack_linked_list_remove(&gatt_client_connections, (btstack_linked_item_t *) gatt_client);
2903 btstack_memory_gatt_client_free(gatt_client);
2904
2905 uint8_t buffer[20];
2906 uint16_t len = hci_event_create_from_template_and_arguments(buffer, sizeof(buffer), &gatt_client_disconnected, con_handle);
2907 (*callback)(HCI_EVENT_PACKET, 0, buffer, len);
2908}
2909
2870static void gatt_client_l2cap_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
2871 gatt_client_t * gatt_client = NULL;
2872 uint8_t status;
2873 hci_connection_t * hci_connection;
2874 switch (packet_type){
2875 case HCI_EVENT_PACKET:
2876 switch (hci_event_packet_get_type(packet)) {
2877 case L2CAP_EVENT_CHANNEL_OPENED:
2878 status = l2cap_event_channel_opened_get_status(packet);
2879 gatt_client = gatt_client_get_context_for_l2cap_cid(l2cap_event_channel_opened_get_local_cid(packet));
2880 btstack_assert(gatt_client != NULL);
2881 // if status != 0, gatt_client will be discarded
2882 gatt_client->gatt_client_state = P_READY;
2883 gatt_client->con_handle = l2cap_event_channel_opened_get_handle(packet);
2884 gatt_client->mtu = l2cap_event_channel_opened_get_remote_mtu(packet);
2885 gatt_client_classic_handle_connected(gatt_client, status);
2886 break;
2887 case L2CAP_EVENT_CHANNEL_CLOSED:
2888 gatt_client = gatt_client_get_context_for_l2cap_cid(l2cap_event_channel_closed_get_local_cid(packet));
2889 // clear l2cap cid in hci_connection->att_server
2890 hci_connection = hci_connection_for_handle(gatt_client->con_handle);
2891 hci_connection->att_server.l2cap_cid = 0;
2892 // discard gatt client object
2893 gatt_client_classic_handle_disconnected(gatt_client);
2894 break;
2895 default:
2896 break;
2897 }
2898 break;
2899 case L2CAP_DATA_PACKET:
2900 gatt_client = gatt_client_get_context_for_l2cap_cid(channel);
2901 btstack_assert(gatt_client != NULL);
2902 gatt_client_handle_att_response(gatt_client, packet, size);
2903 gatt_client_run();
2904 break;
2905 default:
2906 break;
2907 }
2908}
2909
2910static void gatt_client_handle_sdp_client_query_attribute_value(gatt_client_t * connection, uint8_t *packet){
2911 des_iterator_t des_list_it;
2912 des_iterator_t prot_it;
2913
2914 if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= sizeof(gatt_client_classic_sdp_buffer)) {
2915 gatt_client_classic_sdp_buffer[sdp_event_query_attribute_byte_get_data_offset(packet)] = sdp_event_query_attribute_byte_get_data(packet);
2916 if ((uint16_t)(sdp_event_query_attribute_byte_get_data_offset(packet)+1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) {
2917 switch(sdp_event_query_attribute_byte_get_attribute_id(packet)) {

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

2974 default:
2975 btstack_assert(false);
2976 return;
2977 }
2978
2979 // done
2980 if (status == ERROR_CODE_SUCCESS){
2981 gatt_client->gatt_client_state = P_W4_L2CAP_CONNECTION;
2910static void gatt_client_handle_sdp_client_query_attribute_value(gatt_client_t * connection, uint8_t *packet){
2911 des_iterator_t des_list_it;
2912 des_iterator_t prot_it;
2913
2914 if (sdp_event_query_attribute_byte_get_attribute_length(packet) <= sizeof(gatt_client_classic_sdp_buffer)) {
2915 gatt_client_classic_sdp_buffer[sdp_event_query_attribute_byte_get_data_offset(packet)] = sdp_event_query_attribute_byte_get_data(packet);
2916 if ((uint16_t)(sdp_event_query_attribute_byte_get_data_offset(packet)+1) == sdp_event_query_attribute_byte_get_attribute_length(packet)) {
2917 switch(sdp_event_query_attribute_byte_get_attribute_id(packet)) {

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

2974 default:
2975 btstack_assert(false);
2976 return;
2977 }
2978
2979 // done
2980 if (status == ERROR_CODE_SUCCESS){
2981 gatt_client->gatt_client_state = P_W4_L2CAP_CONNECTION;
2982 status = l2cap_create_channel(gatt_client_l2cap_handler, gatt_client->addr, gatt_client->l2cap_psm, 0xffff,
2983 &gatt_client->l2cap_cid);
2982 status = att_dispatch_classic_connect(gatt_client->addr, gatt_client->l2cap_psm, &gatt_client->l2cap_cid);
2984 }
2985 if (status != ERROR_CODE_SUCCESS) {
2986 gatt_client_classic_handle_connected(gatt_client, status);
2987 }
2988}
2989
2990static void gatt_client_classic_sdp_start(void * context){
2991 gatt_client_classic_active_sdp_query = (gatt_client_t *) context;

--- 388 unchanged lines hidden ---
2983 }
2984 if (status != ERROR_CODE_SUCCESS) {
2985 gatt_client_classic_handle_connected(gatt_client, status);
2986 }
2987}
2988
2989static void gatt_client_classic_sdp_start(void * context){
2990 gatt_client_classic_active_sdp_query = (gatt_client_t *) context;

--- 388 unchanged lines hidden ---