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 --- |