sdp_client.c (0d6cebf8ee59e5b421d706dc7ae0b442d880a493) sdp_client.c (e094740e060c70e12af6cf8e9e2f7e7eb2b4eeb8)
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

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

111static uint16_t sdp_cid = 0x40;
112static const uint8_t * service_search_pattern;
113static const uint8_t * attribute_id_list;
114static uint16_t transactionID = 0;
115static uint8_t continuationState[16];
116static uint8_t continuationStateLen;
117static sdp_client_state_t sdp_client_state = INIT;
118static SDP_PDU_ID_t PDU_ID = SDP_Invalid;
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

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

111static uint16_t sdp_cid = 0x40;
112static const uint8_t * service_search_pattern;
113static const uint8_t * attribute_id_list;
114static uint16_t transactionID = 0;
115static uint8_t continuationState[16];
116static uint8_t continuationStateLen;
117static sdp_client_state_t sdp_client_state = INIT;
118static SDP_PDU_ID_t PDU_ID = SDP_Invalid;
119
120// Query registration
121static btstack_linked_list_t sdp_client_query_requests;
122
119#ifdef ENABLE_SDP_EXTRA_QUERIES
120static uint32_t serviceRecordHandle;
121static uint32_t record_handle;
122#endif
123
124// DES Parser
125void de_state_init(de_state_t * de_state){
126 de_state->in_state_GET_DE_HEADER_LENGTH = 1;

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

302 little_endian_store_16(event, 2, total_count);
303 little_endian_store_16(event, 4, record_counter);
304 little_endian_store_32(event, 6, record_handle);
305 (*sdp_parser_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
306 }
307}
308#endif
309
123#ifdef ENABLE_SDP_EXTRA_QUERIES
124static uint32_t serviceRecordHandle;
125static uint32_t record_handle;
126#endif
127
128// DES Parser
129void de_state_init(de_state_t * de_state){
130 de_state->in_state_GET_DE_HEADER_LENGTH = 1;

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

306 little_endian_store_16(event, 2, total_count);
307 little_endian_store_16(event, 4, record_counter);
308 little_endian_store_32(event, 6, record_handle);
309 (*sdp_parser_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
310 }
311}
312#endif
313
314static void sdp_client_notify_callbacks(void){
315 if (!sdp_client_ready) {
316 return;
317 }
318 btstack_context_callback_registration_t * callback = btstack_linked_list_pop(&sdp_client_query_requests);
319 if (callback == NULL) {
320 return;
321 }
322 (*callback->callback)(callback->callback);
323}
324
310void sdp_parser_handle_done(uint8_t status){
325void sdp_parser_handle_done(uint8_t status){
326 // reset state
327 sdp_client_state = INIT;
328
329 // emit query complete event
311 uint8_t event[3];
312 event[0] = SDP_EVENT_QUERY_COMPLETE;
313 event[1] = 1;
314 event[2] = status;
315 (*sdp_parser_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
330 uint8_t event[3];
331 event[0] = SDP_EVENT_QUERY_COMPLETE;
332 event[1] = 1;
333 event[2] = status;
334 (*sdp_parser_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
335
336 // trigger next query if pending
337 sdp_client_notify_callbacks();
316}
317
318// SDP Client
319
320// TODO: inline if not needed (des(des))
321
322static void sdp_client_parse_attribute_lists(uint8_t* packet, uint16_t length){
323 sdp_parser_handle_chunk(packet, length);

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

442 if (packet_type != HCI_EVENT_PACKET) return;
443
444 switch(hci_event_packet_get_type(packet)){
445 case L2CAP_EVENT_CHANNEL_OPENED:
446 if (sdp_client_state != W4_CONNECT) break;
447 // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16)
448 if (packet[2]) {
449 log_info("SDP Client Connection failed, status 0x%02x.", packet[2]);
338}
339
340// SDP Client
341
342// TODO: inline if not needed (des(des))
343
344static void sdp_client_parse_attribute_lists(uint8_t* packet, uint16_t length){
345 sdp_parser_handle_chunk(packet, length);

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

464 if (packet_type != HCI_EVENT_PACKET) return;
465
466 switch(hci_event_packet_get_type(packet)){
467 case L2CAP_EVENT_CHANNEL_OPENED:
468 if (sdp_client_state != W4_CONNECT) break;
469 // data: event (8), len(8), status (8), address(48), handle (16), psm (16), local_cid(16), remote_cid (16), local_mtu(16), remote_mtu(16)
470 if (packet[2]) {
471 log_info("SDP Client Connection failed, status 0x%02x.", packet[2]);
450 sdp_client_state = INIT;
451 sdp_parser_handle_done(packet[2]);
452 break;
453 }
454 sdp_cid = channel;
455 mtu = little_endian_read_16(packet, 17);
456 // handle = little_endian_read_16(packet, 9);
457 log_debug("SDP Client Connected, cid %x, mtu %u.", sdp_cid, mtu);
458

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

467 break;
468 case L2CAP_EVENT_CHANNEL_CLOSED: {
469 if (sdp_cid != little_endian_read_16(packet, 2)) {
470 // log_info("Received L2CAP_EVENT_CHANNEL_CLOSED for cid %x, current cid %x\n", little_endian_read_16(packet, 2),sdp_cid);
471 break;
472 }
473 log_info("SDP Client disconnected.");
474 uint8_t status = (sdp_client_state == QUERY_COMPLETE) ? 0 : SDP_QUERY_INCOMPLETE;
472 sdp_parser_handle_done(packet[2]);
473 break;
474 }
475 sdp_cid = channel;
476 mtu = little_endian_read_16(packet, 17);
477 // handle = little_endian_read_16(packet, 9);
478 log_debug("SDP Client Connected, cid %x, mtu %u.", sdp_cid, mtu);
479

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

488 break;
489 case L2CAP_EVENT_CHANNEL_CLOSED: {
490 if (sdp_cid != little_endian_read_16(packet, 2)) {
491 // log_info("Received L2CAP_EVENT_CHANNEL_CLOSED for cid %x, current cid %x\n", little_endian_read_16(packet, 2),sdp_cid);
492 break;
493 }
494 log_info("SDP Client disconnected.");
495 uint8_t status = (sdp_client_state == QUERY_COMPLETE) ? 0 : SDP_QUERY_INCOMPLETE;
475 sdp_client_state = INIT;
476 sdp_parser_handle_done(status);
477 break;
478 }
479 default:
480 break;
481 }
482}
483

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

681}
682
683// Public API
684
685int sdp_client_ready(void){
686 return sdp_client_state == INIT;
687}
688
496 sdp_parser_handle_done(status);
497 break;
498 }
499 default:
500 break;
501 }
502}
503

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

701}
702
703// Public API
704
705int sdp_client_ready(void){
706 return sdp_client_state == INIT;
707}
708
709uint8_t sdp_client_register_query_callback(btstack_context_callback_registration_t * callback_registration){
710 bool added = btstack_linked_list_add_tail(&sdp_client_query_requests, (btstack_linked_item_t*) callback_registration);
711 if (!added) return ERROR_CODE_COMMAND_DISALLOWED;
712 sdp_client_notify_callbacks();
713 return ERROR_CODE_SUCCESS;
714}
715
689uint8_t sdp_client_query(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * des_service_search_pattern, const uint8_t * des_attribute_id_list){
690 if (!sdp_client_ready()) return SDP_QUERY_BUSY;
691
692 sdp_parser_init(callback);
693 service_search_pattern = des_service_search_pattern;
694 attribute_id_list = des_attribute_id_list;
695 continuationStateLen = 0;
696 PDU_ID = SDP_ServiceSearchAttributeResponse;

--- 45 unchanged lines hidden ---
716uint8_t sdp_client_query(btstack_packet_handler_t callback, bd_addr_t remote, const uint8_t * des_service_search_pattern, const uint8_t * des_attribute_id_list){
717 if (!sdp_client_ready()) return SDP_QUERY_BUSY;
718
719 sdp_parser_init(callback);
720 service_search_pattern = des_service_search_pattern;
721 attribute_id_list = des_attribute_id_list;
722 continuationStateLen = 0;
723 PDU_ID = SDP_ServiceSearchAttributeResponse;

--- 45 unchanged lines hidden ---