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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "sdp_client_rfcomm.c" 39 40 /* 41 * sdp_rfcomm_query.c 42 */ 43 44 #include <stdint.h> 45 #include <string.h> 46 47 #include "bluetooth_sdp.h" 48 #include "btstack_debug.h" 49 #include "btstack_event.h" 50 #include "classic/core.h" 51 #include "classic/sdp_client.h" 52 #include "classic/sdp_client_rfcomm.h" 53 #include "classic/sdp_util.h" 54 #include "hci_cmd.h" 55 56 // called by test/sdp_client 57 void sdp_client_query_rfcomm_init(void); 58 59 typedef enum { 60 GET_PROTOCOL_LIST_LENGTH = 1, 61 GET_PROTOCOL_LENGTH, 62 GET_PROTOCOL_ID_HEADER_LENGTH, 63 GET_PROTOCOL_ID, 64 GET_PROTOCOL_VALUE_LENGTH, 65 GET_PROTOCOL_VALUE 66 } pdl_state_t; 67 68 69 // higher layer query - get rfcomm channel and name 70 71 // All attributes: 0x0001 - 0x0100 72 static const uint8_t des_attributeIDList[] = { 0x35, 0x05, 0x0A, 0x00, 0x01, 0x01, 0x00}; 73 74 static uint8_t sdp_service_name[SDP_SERVICE_NAME_LEN+1]; 75 static uint8_t sdp_service_name_len = 0; 76 static uint8_t sdp_rfcomm_channel_nr = 0; 77 static uint8_t sdp_service_name_header_size; 78 79 static pdl_state_t pdl_state = GET_PROTOCOL_LIST_LENGTH; 80 static int protocol_value_bytes_received = 0; 81 static uint16_t protocol_id = 0; 82 static int protocol_offset; 83 static int protocol_size; 84 static int protocol_id_bytes_to_read; 85 static int protocol_value_size; 86 static de_state_t de_header_state; 87 static de_state_t sn_de_header_state; 88 static btstack_packet_handler_t sdp_app_callback; 89 // 90 91 static void sdp_rfcomm_query_emit_service(void){ 92 uint8_t event[3+SDP_SERVICE_NAME_LEN+1]; 93 event[0] = SDP_EVENT_QUERY_RFCOMM_SERVICE; 94 event[1] = sdp_service_name_len + 1; 95 event[2] = sdp_rfcomm_channel_nr; 96 (void)memcpy(&event[3], sdp_service_name, sdp_service_name_len); 97 event[3+sdp_service_name_len] = 0; 98 (*sdp_app_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event)); 99 sdp_rfcomm_channel_nr = 0; 100 } 101 102 static void sdp_client_query_rfcomm_handle_protocol_descriptor_list_data(uint32_t attribute_value_length, uint32_t data_offset, uint8_t data){ 103 UNUSED(attribute_value_length); 104 105 // init state on first byte 106 if (data_offset == 0){ 107 pdl_state = GET_PROTOCOL_LIST_LENGTH; 108 } 109 110 111 switch(pdl_state){ 112 113 case GET_PROTOCOL_LIST_LENGTH: 114 if (!de_state_size(data, &de_header_state)) break; 115 116 pdl_state = GET_PROTOCOL_LENGTH; 117 break; 118 119 case GET_PROTOCOL_LENGTH: 120 // check size 121 if (!de_state_size(data, &de_header_state)) break; 122 123 // cache protocol info 124 protocol_offset = de_header_state.de_offset; 125 protocol_size = de_header_state.de_size; 126 127 pdl_state = GET_PROTOCOL_ID_HEADER_LENGTH; 128 break; 129 130 case GET_PROTOCOL_ID_HEADER_LENGTH: 131 protocol_offset++; 132 if (!de_state_size(data, &de_header_state)) break; 133 134 protocol_id = 0; 135 protocol_id_bytes_to_read = de_header_state.de_size; 136 pdl_state = GET_PROTOCOL_ID; 137 138 break; 139 140 case GET_PROTOCOL_ID: 141 protocol_offset++; 142 143 protocol_id = (protocol_id << 8) | data; 144 protocol_id_bytes_to_read--; 145 if (protocol_id_bytes_to_read > 0) break; 146 147 148 if (protocol_offset >= protocol_size){ 149 pdl_state = GET_PROTOCOL_LENGTH; 150 break; 151 } 152 153 pdl_state = GET_PROTOCOL_VALUE_LENGTH; 154 protocol_value_bytes_received = 0; 155 break; 156 157 case GET_PROTOCOL_VALUE_LENGTH: 158 protocol_offset++; 159 160 if (!de_state_size(data, &de_header_state)) break; 161 162 protocol_value_size = de_header_state.de_size; 163 pdl_state = GET_PROTOCOL_VALUE; 164 sdp_rfcomm_channel_nr = 0; 165 break; 166 167 case GET_PROTOCOL_VALUE: 168 protocol_offset++; 169 protocol_value_bytes_received++; 170 171 if (protocol_value_bytes_received < protocol_value_size) break; 172 173 if (protocol_id == BLUETOOTH_PROTOCOL_RFCOMM){ 174 // log_info("\n\n ******* Data ***** %02x\n\n", data); 175 sdp_rfcomm_channel_nr = data; 176 } 177 178 if (protocol_offset >= protocol_size) { 179 pdl_state = GET_PROTOCOL_LENGTH; 180 break; 181 182 } 183 pdl_state = GET_PROTOCOL_ID_HEADER_LENGTH; 184 break; 185 default: 186 break; 187 } 188 } 189 190 static void sdp_client_query_rfcomm_handle_service_name_data(uint32_t attribute_value_length, uint32_t data_offset, uint8_t data){ 191 192 // Get Header Len 193 if (data_offset == 0){ 194 de_state_size(data, &sn_de_header_state); 195 sdp_service_name_header_size = sn_de_header_state.addon_header_bytes + 1; 196 return; 197 } 198 199 // Get Header 200 if (data_offset < sdp_service_name_header_size){ 201 de_state_size(data, &sn_de_header_state); 202 return; 203 } 204 205 // Process payload 206 int name_len = attribute_value_length - sdp_service_name_header_size; 207 int name_pos = data_offset - sdp_service_name_header_size; 208 209 if (name_pos < SDP_SERVICE_NAME_LEN){ 210 sdp_service_name[name_pos] = data; 211 name_pos++; 212 213 // terminate if name complete 214 if (name_pos >= name_len){ 215 sdp_service_name[name_pos] = 0; 216 sdp_service_name_len = name_pos; 217 } 218 219 // terminate if buffer full 220 if (name_pos == SDP_SERVICE_NAME_LEN){ 221 sdp_service_name[name_pos] = 0; 222 sdp_service_name_len = name_pos; 223 } 224 } 225 226 // notify on last char 227 if ((data_offset == (attribute_value_length - 1)) && (sdp_rfcomm_channel_nr!=0)){ 228 sdp_rfcomm_query_emit_service(); 229 } 230 } 231 232 static void sdp_client_query_rfcomm_handle_sdp_parser_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 233 UNUSED(packet_type); 234 UNUSED(channel); 235 236 switch (hci_event_packet_get_type(packet)){ 237 case SDP_EVENT_QUERY_SERVICE_RECORD_HANDLE: 238 // handle service without a name 239 if (sdp_rfcomm_channel_nr){ 240 sdp_rfcomm_query_emit_service(); 241 } 242 243 // prepare for new record 244 sdp_rfcomm_channel_nr = 0; 245 sdp_service_name[0] = 0; 246 break; 247 case SDP_EVENT_QUERY_ATTRIBUTE_VALUE: 248 switch (sdp_event_query_attribute_byte_get_attribute_id(packet)){ 249 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST: 250 // find rfcomm channel 251 sdp_client_query_rfcomm_handle_protocol_descriptor_list_data(sdp_event_query_attribute_byte_get_attribute_length(packet), 252 sdp_event_query_attribute_byte_get_data_offset(packet), 253 sdp_event_query_attribute_byte_get_data(packet)); 254 break; 255 case 0x0100: 256 // get service name 257 sdp_client_query_rfcomm_handle_service_name_data(sdp_event_query_attribute_byte_get_attribute_length(packet), 258 sdp_event_query_attribute_byte_get_data_offset(packet), 259 sdp_event_query_attribute_byte_get_data(packet)); 260 break; 261 default: 262 // give up 263 return; 264 } 265 break; 266 case SDP_EVENT_QUERY_COMPLETE: 267 // handle service without a name 268 if (sdp_rfcomm_channel_nr){ 269 sdp_rfcomm_query_emit_service(); 270 } 271 (*sdp_app_callback)(HCI_EVENT_PACKET, 0, packet, size); 272 break; 273 default: 274 break; 275 } 276 } 277 278 void sdp_client_query_rfcomm_init(void){ 279 // init 280 de_state_init(&de_header_state); 281 de_state_init(&sn_de_header_state); 282 pdl_state = GET_PROTOCOL_LIST_LENGTH; 283 protocol_offset = 0; 284 sdp_rfcomm_channel_nr = 0; 285 sdp_service_name[0] = 0; 286 } 287 288 // Public API 289 290 uint8_t sdp_client_query_rfcomm_channel_and_name_for_search_pattern(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * service_search_pattern){ 291 if (!sdp_client_ready()) return SDP_QUERY_BUSY; 292 293 sdp_app_callback = callback; 294 sdp_client_query_rfcomm_init(); 295 return sdp_client_query(&sdp_client_query_rfcomm_handle_sdp_parser_event, remote, service_search_pattern, (uint8_t*)&des_attributeIDList[0]); 296 } 297 298 uint8_t sdp_client_query_rfcomm_channel_and_name_for_uuid(btstack_packet_handler_t callback, bd_addr_t remote, uint16_t uuid16){ 299 if (!sdp_client_ready()) return SDP_QUERY_BUSY; 300 return sdp_client_query_rfcomm_channel_and_name_for_search_pattern(callback, remote, sdp_service_search_pattern_for_uuid16(uuid16)); 301 } 302 303 uint8_t sdp_client_query_rfcomm_channel_and_name_for_uuid128(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * uuid128){ 304 if (!sdp_client_ready()) return SDP_QUERY_BUSY; 305 return sdp_client_query_rfcomm_channel_and_name_for_search_pattern(callback, remote, sdp_service_search_pattern_for_uuid128(uuid128)); 306 } 307