From owner-freebsd-bluetooth@FreeBSD.ORG Mon Jun 19 17:19:45 2006 Return-Path: X-Original-To: freebsd-bluetooth@freebsd.org Delivered-To: freebsd-bluetooth@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DA7B016A47D for ; Mon, 19 Jun 2006 17:19:45 +0000 (UTC) (envelope-from maksim.yevmenkin@savvis.net) Received: from mailgate1b.savvis.net (mailgate1b.savvis.net [216.91.182.6]) by mx1.FreeBSD.org (Postfix) with ESMTP id ABF6C43D6E for ; Mon, 19 Jun 2006 17:19:38 +0000 (GMT) (envelope-from maksim.yevmenkin@savvis.net) Received: from localhost (localhost.localdomain [127.0.0.1]) by mailgate1b.savvis.net (Postfix) with ESMTP id B9F3F3BF27; Mon, 19 Jun 2006 12:19:37 -0500 (CDT) Received: from mailgate1b.savvis.net ([127.0.0.1]) by localhost (mailgate1b.savvis.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 19112-01-29; Mon, 19 Jun 2006 12:19:37 -0500 (CDT) Received: from [10.254.186.111] (sntc04ep01.savvis.net [64.14.1.106]) by mailgate1b.savvis.net (Postfix) with ESMTP id 29AA93BF09; Mon, 19 Jun 2006 12:19:37 -0500 (CDT) Message-ID: <4496DCA8.2070405@savvis.net> Date: Mon, 19 Jun 2006 10:19:36 -0700 From: Maksim Yevmenkin User-Agent: Thunderbird 1.5.0.2 (X11/20060603) MIME-Version: 1.0 To: Iain Hibbert References: <1150200307.649295.228.nullmailer@galant.ukfsn.org> <44904A60.6080105@savvis.net> <1150322381.757072.1713.nullmailer@galant.ukfsn.org> <4492E9FA.2030708@savvis.net> <1150486990.380039.25644.nullmailer@galant.ukfsn.org> <44931C12.7020805@savvis.net> <1150571287.231614.2893.nullmailer@galant.ukfsn.org> In-Reply-To: <1150571287.231614.2893.nullmailer@galant.ukfsn.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: amavisd-new at savvis.net Cc: freebsd-bluetooth@freebsd.org Subject: Re: SDP X-BeenThere: freebsd-bluetooth@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Using Bluetooth in FreeBSD environments List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Jun 2006 17:19:45 -0000 Iain, >> i'm not sure why is it required to parse all the data and re-pack it into the >> linked list, just to have another api that would search and extract data from >> the linked list. > > I agree, and I dont like the plethora of functions that they use. Better > I think to have a generic function and pass it an argument telling it what > to look for, that way its easily extensible. after thinking about it, i'm somewhat confused by your statement "...telling it what to look for...". please read below for the specific example. >> i had a chance to work with csr bluelab sdk recently and develop the > > I guess this is a proprietary system, but do they have a public API? yes it is a proprietary system. i'm not aware of any public api, however, i will describe my ideas at the end of this email. like i said before, those ideas have common points with csr api. > My thought for a parse function would be to pass an array of some kind, > describing the attributes and possible values that are wanted, plus the > address of the storage location, so to find the HID control and interrupt > PSM values you just go something like this: > > uint16_t control_psm, interrupt_psm; > > sdp_parse_t values[] = { > { > SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST, > { UUID, SDP_UUID_PROTOCOL_L2CAP }, > { UINT16, &control_psm } > }, > { > SDP_ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST, > { UUID, SDP_UUID_PROTOCOL_L2CAP }, > { UINT16, &interrupt_psm } > } > }; > > nvalues = 2; > control_psm = 0; > interrupt_psm = 0; > > err = sdp_parse(pdu, &values, nvalues); > > if (err || control_psm == 0 || interrupt_psm == 0) > ... > > and this should be easily extensible for whatever you want to extract. The > array can be static and const. It could be that you could specify > mandatory/optional values and have the sdp_parse fail if mandatory fields > are not accounted for. i see. this is one way of doing it. few comments. 1) i do not think that sdp_parse_t array could be static (and/or const) unless all the pointers to data holders are also static. also both sdp_data_t array and data pointers would have to be defined in the scope. not that it is an issue - one can wrap up sdp_parse() into another function that accepts data pointers and creates sdp_parse_t array on the stack 2) from what i understand, libsdp(3) must know how to parse attribute given in sdp_parse_t. in other words, libsdp(3) must know that SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST is a sequence in a specific format, etc. i think this means that if there is a new attribute and/or value format libsdp(3) needs modification. it all boils down to what do we think libsdp(3) is. is it a) a generic library that only operates inside the sdp protocol scope, i.e. it is only aware of sdp data elements and their types and *NOT* of the meaning of these data elements to the end user application or b) a library that has complete awareness of all currently defined (in all bluetooth profile documents) sdp attributes, their data types, format and values > I didnt think about it too deeply, just the general concept. There can no > doubt be a bunch of complications.. and thinking about it, if the same > concept could be used to *construct* a PDU I would be especially pleased.. right, please let me briefly describe what i had in mind for libsdp(3) parsing. this would correspond to the item (a) from above. there is a new auxiliary data type that represents a part of the original buffer (with sdp pdu). lets call it a "chunk". a chunk could be just 2 pointers to beginning and end. each chunk contains only one sdp data element. sdp data element could be simple, i.e. bool, int8,16,32 etc. or complex, i.e. seq8,16,32,alt8,etc. for example, uint16 chunk containing 0x0000 data value would have 3 bytes, i.e. "0x09 0x00 0x00". each chunk obviously "knows" about its type and length. access methods: 1) int32_t sdp_chunk_next(void const *pdu, void const *pdu_end, chunk_t *chunk); can be used to iterate through all chunks in the pdu, i.e. === chunk_t chunk; int32_t result; for (result = sdp_chunk_next(pdu, pdu_end, &chunk); result > 0; result = sdp_chunk_next(chunk.end + 1, pdu_end, &chunk)) { ... } === 2) uint8_t sdp_chunk_type(chunk_t *chunk) { return (chunk.begin[0]); } can be used to get chunk type. 3) for "simple" chunks, there are data extraction methods, i.e. int32_t sdp_chunk_get_{u}int{8,16,32}(chunk_t *chunk, {u}int{8,16,32} *value); you can also image the reverse api to build chunks, i.e. sdp_chunk_put_XXX() and sdp_chunk_advance() etc. obviously libsdp(3) can (and probably should) include more high-level functions to parse "well-known" attributes and their values. thanks, max