1*1ca3442bSMatthias RingwaldSDP for BTstack 2*1ca3442bSMatthias Ringwald 3*1ca3442bSMatthias RingwaldGeneral: 4*1ca3442bSMatthias Ringwald * Protocol: request/response, half-duplex 5*1ca3442bSMatthias Ringwald * Endianess = BIG/Network! not little endian as usual 6*1ca3442bSMatthias Ringwald * Server maintains a list of service records 7*1ca3442bSMatthias Ringwald * service (record) is instance of a service class 8*1ca3442bSMatthias Ringwald * a service record = list of service attributes 9*1ca3442bSMatthias Ringwald * service attribute = { attribute ID, attribute value } 10*1ca3442bSMatthias Ringwald * service record handle: 32 bit number (used internally) 11*1ca3442bSMatthias Ringwald * service record handle 12*1ca3442bSMatthias Ringwald * 0x00000000 used for SDP server, 13*1ca3442bSMatthias Ringwald * 0x00000001-0x0000FFFF reserved 14*1ca3442bSMatthias Ringwald * attribute ID: 16 bit (pre-defined), data element 15*1ca3442bSMatthias Ringwald * attribute value: var length field, data element 16*1ca3442bSMatthias Ringwald * service class: UUID (128 bit) stored as ServiceClassIDList attribute 17*1ca3442bSMatthias Ringwald * service classes form an inheritance tree, which each subclass specifying more attributes 18*1ca3442bSMatthias Ringwald * Bluetooth Base UUID: 00000000-0000-1000-8000- 00805F9B34FB 19*1ca3442bSMatthias Ringwald * 16 bit UUID => Bluetooth Base UUID + 16_bit_value * 2^96 20*1ca3442bSMatthias Ringwald * 32 bit UUID => Bluetooth Base UUID + 32_bit_value * 2^96 21*1ca3442bSMatthias Ringwald * Service Search Pattern: list of UUIDs required in a service record to be present for a match 22*1ca3442bSMatthias Ringwald * Browse Group UUID: all top-level services contain browse group UUID in the BrowseGroupList attribute 23*1ca3442bSMatthias Ringwald * Service Browsing Hierarchy is possible - not supported by BTstack for now 24*1ca3442bSMatthias Ringwald * Data representation: like XML 25*1ca3442bSMatthias Ringwald * PDU: PDU ID(1), Transaction ID(2), Param length(2), params* 26*1ca3442bSMatthias Ringwald * ServiceSearchRequest/ServiceSearchResponse: list of UUIDs to be matched by service record -> list of service record handles 27*1ca3442bSMatthias Ringwald * ServiceAttributeRequest/ServiceAttributeResponse: get list of attributes for a given service record handle 28*1ca3442bSMatthias Ringwald * Service SearchAttributeRequest/SearchAtrributeResponse: for all service records that match ServiceSearchPattern: return list of attributes that match AttributeIDList 29*1ca3442bSMatthias Ringwald * Transaction ID of response = ID of request 30*1ca3442bSMatthias Ringwald * param lengh in bytes 31*1ca3442bSMatthias Ringwald * Continuation state parameter: send to client to denote further data (max 16 bytes) 32*1ca3442bSMatthias Ringwald * To get RFCOMM channel, we use SDP_ServiceSearchAttributeRequest(RFCOMM service, RFCOMM type) 33*1ca3442bSMatthias Ringwald 34*1ca3442bSMatthias RingwaldImplementation: 35*1ca3442bSMatthias Ringwald * DataElement creation API - no extra memory 36*1ca3442bSMatthias Ringwald * helper functions: 37*1ca3442bSMatthias Ringwald * attribute ID in AttributeIDList 38*1ca3442bSMatthias Ringwald * get attributes specified by AttributeIDList 39*1ca3442bSMatthias Ringwald * service record contains UUID 40*1ca3442bSMatthias Ringwald * does service search pattern matches record 41*1ca3442bSMatthias Ringwald * get attribute value (DE) for attribute ID 42*1ca3442bSMatthias Ringwald * create service record handle (incl. ServiceRecordHandle management) 43*1ca3442bSMatthias Ringwald * visitor pattern for DES traversal 44*1ca3442bSMatthias Ringwald * call handler on every element: int handle_element(uint8_t element, void *context) - done? 45*1ca3442bSMatthias Ringwald * Dispatch packets for protocols implemented by BTdaemon 46*1ca3442bSMatthias Ringwald * add packet_handler to l2cap_service_t and l2cap_channel_t 47*1ca3442bSMatthias Ringwald * pass acl/event handler to l2cap_register_service_internal 48*1ca3442bSMatthias Ringwald * copy acl/event handler to l2cap_channel_t 49*1ca3442bSMatthias Ringwald * if specified, call custom packet_handler instead of general one 50*1ca3442bSMatthias Ringwald * acl -> l2cap -> l2cap_channel -> acl/event handler OR daemon 51*1ca3442bSMatthias Ringwald * LinkedList of service records 52*1ca3442bSMatthias Ringwald * alloc { linked_list_item_t ; ServiceRecord } 53*1ca3442bSMatthias Ringwald * add service record: service record -> service record handle or 0 54*1ca3442bSMatthias Ringwald * remove service record: service record handle (32bit) 55*1ca3442bSMatthias Ringwald * SDP as part of stack itself 56*1ca3442bSMatthias Ringwald * Register SDP PSM=0x0001 57*1ca3442bSMatthias Ringwald * Accept incoming connections 58*1ca3442bSMatthias Ringwald * Define all SDP requests/response PDU-IDs 59*1ca3442bSMatthias Ringwald * Handle all three SDP requests by denying 60*1ca3442bSMatthias Ringwald * ServiceSearchRequest 61*1ca3442bSMatthias Ringwald * ServiceAttributeRequest 62*1ca3442bSMatthias Ringwald * ServiceSearchAttributeRequest 63*1ca3442bSMatthias Ringwald * Dynamically create denial 64*1ca3442bSMatthias Ringwald * Handle ServiceSearchAttributeRequest 65*1ca3442bSMatthias Ringwald * Handle ServiceSearchRequest 66*1ca3442bSMatthias Ringwald * Handle ServiceAttributeRequest 67*1ca3442bSMatthias Ringwald * Extract sdp_create_error_response 68*1ca3442bSMatthias Ringwald * call sdp_create_error_response when service record handle is invalid 69*1ca3442bSMatthias Ringwald * Define and implement client commands & events for SDP registry 70*1ca3442bSMatthias Ringwald * Store client connection in service record item 71*1ca3442bSMatthias Ringwald * Unregister service when client disconnects 72*1ca3442bSMatthias Ringwald * Send SDP_ErrorResponse for invalid records 73*1ca3442bSMatthias Ringwald * Implement Continuation: limited nr of ServiceRecordHandles or AttributeList(s)ByteCount 74*1ca3442bSMatthias Ringwald * ServiceSearchRequest: Iterate over all records - use record index as cont. 75*1ca3442bSMatthias Ringwald * ServiceAttributeRequest: Iterate over all attributes - use attribute index as cont. 76*1ca3442bSMatthias Ringwald * ServiceSearchAttributeRequest: Iterate over all records and attributes. Use {record, attribute} index 77*1ca3442bSMatthias Ringwald * Test continuation for all three commands 78*1ca3442bSMatthias Ringwald * add 2 records, get all data back with limited result size 79*1ca3442bSMatthias Ringwald * sdp_handle_service_search_attribute_request 80*1ca3442bSMatthias Ringwald* implement SDP_sequence_traversal -> simplify traversing 81*1ca3442bSMatthias Ringwald 82*1ca3442bSMatthias Ringwald * keep track of remote incoming MTU during l2cap establishment 83*1ca3442bSMatthias Ringwald * segment l2cap packets according to MTU size 84*1ca3442bSMatthias Ringwald 85*1ca3442bSMatthias Ringwald * Packet for HID is shortened - bluez uses 0x0096 as MTU - segment packets 86*1ca3442bSMatthias Ringwald * String Handling in Linux SDP/sdptool probably buggy 87*1ca3442bSMatthias Ringwald 88*1ca3442bSMatthias Ringwald 89*1ca3442bSMatthias Ringwald