public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [Bluez-devel] Proposed DTD
@ 2006-10-23  0:25 Denis KENZIOR
  2006-10-23  3:13 ` Marcel Holtmann
  0 siblings, 1 reply; 23+ messages in thread
From: Denis KENZIOR @ 2006-10-23  0:25 UTC (permalink / raw)
  To: bluez-devel

[-- Attachment #1: Type: text/plain, Size: 820 bytes --]

Marcel,

Here's the proposed DTD for SDP over XML.  It closely follows the SDP profile 
doc.  I wasn't sure whether sequences can be empty (which makes no sense to 
me), so I required at least one element in a sequence.    The sizes for Text, 
URLs and Sequences was dropped.  It can easily be inferred from parsing the 
document.  

I'd like to get some feedback as to how to manage things like Record Handle, 
and RFCOMM/L2Cap channels, etc.  For record handle I think it is easy, just 
remove that particular attribute and let the SDP server figure it out.  For 
RFCOMM channel, etc it is more tricky.  Should we use a magic value or just 
override it behind the scenes?  We can always rely on the user to pick a 
correct channel as well (and fail registration if they pick a channel that is 
already in use)

-Denis

[-- Attachment #2: sdprecord.dtd --]
[-- Type: text/plain, Size: 998 bytes --]

<!ELEMENT SdpRecord (Attribute)*>
<!ELEMENT Attribute (Sequence|Alternate|UUID16|UUID32|UUID128|UINT8|UINT16|UINT32|UINT64|UINT128|INT8|INT16|INT32|INT64|INT128|BOOL|Text|URL|NIL)>
<!ATTLIST Attribute id CDATA #REQUIRED>
<!ELEMENT Sequence (Sequence|Alternate|UUID16|UUID32|UUID128|UINT8|UINT16|UINT32|UINT64|UINT128|INT8|INT16|INT32|INT64|INT128|BOOL|Text|URL|NIL)+>
<!ELEMENT Alternate (Sequence|Alternate|UUID16|UUID32|UUID128|UINT8|UINT16|UINT32|UINT64|UINT128|INT8|INT16|INT32|INT64|INT128|BOOL|Text|URL|NIL)+>
<!ELEMENT UUID16 (#PCDATA)>
<!ELEMENT UUID32 (#PCDATA)>
<!ELEMENT UUID128 (#PCDATA)>
<!ELEMENT UINT8 (#PCDATA)>
<!ELEMENT UINT16 (#PCDATA)>
<!ELEMENT UINT32 (#PCDATA)>
<!ELEMENT UINT64 (#PCDATA)>
<!ELEMENT UINT128 (#PCDATA)>
<!ELEMENT INT8 (#PCDATA)>
<!ELEMENT INT16 (#PCDATA)>
<!ELEMENT INT32 (#PCDATA)>
<!ELEMENT INT64 (#PCDATA)>
<!ELEMENT INT128 (#PCDATA)>
<!ELEMENT BOOL (#PCDATA)>
<!ELEMENT URL (#PCDATA)>
<!ELEMENT Text (#PCDATA)>
<!ATTLIST Text type (data|string) "string">


[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-23  0:25 [Bluez-devel] Proposed DTD Denis KENZIOR
@ 2006-10-23  3:13 ` Marcel Holtmann
  2006-10-23  3:59   ` Denis KENZIOR
  0 siblings, 1 reply; 23+ messages in thread
From: Marcel Holtmann @ 2006-10-23  3:13 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> Here's the proposed DTD for SDP over XML.  It closely follows the SDP profile 
> doc.  I wasn't sure whether sequences can be empty (which makes no sense to 
> me), so I required at least one element in a sequence.    The sizes for Text, 
> URLs and Sequences was dropped.  It can easily be inferred from parsing the 
> document.  

since it is XML, keep everything lower-case and no extra "sdp" prefix.
It should be enough to call the root element "record". And I think it is
better and easier to use something like:

	<data type="uuid16" value="0x1002"/>

And to be fully in sync with the specification we need to differentiate
between text8, text16 and text32 (and of course for url, too). For
convenience we can then have all data types without the size value and
then the server will determine the most appropriate one by itself.

> I'd like to get some feedback as to how to manage things like Record Handle, 
> and RFCOMM/L2Cap channels, etc.  For record handle I think it is easy, just 
> remove that particular attribute and let the SDP server figure it out.  For 
> RFCOMM channel, etc it is more tricky.  Should we use a magic value or just 
> override it behind the scenes?  We can always rely on the user to pick a 
> correct channel as well (and fail registration if they pick a channel that is 
> already in use)

Actually at the moment you have to let the server pick the record
handle, because specifying the handle doesn't work. It should work, but
I never found the actual bug in the code that prevents it.

Using the proposed way of the "data" element, we can have special values
for "value" like "%channel" etc. that can be filled in by the server.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-23  3:13 ` Marcel Holtmann
@ 2006-10-23  3:59   ` Denis KENZIOR
  2006-10-23  4:11     ` Marcel Holtmann
  0 siblings, 1 reply; 23+ messages in thread
From: Denis KENZIOR @ 2006-10-23  3:59 UTC (permalink / raw)
  To: BlueZ development

Marcel,

On Monday 23 October 2006 13:13, Marcel Holtmann wrote:
> Hi Denis,
>
> > Here's the proposed DTD for SDP over XML.  It closely follows the SDP
> > profile doc.  I wasn't sure whether sequences can be empty (which makes
> > no sense to me), so I required at least one element in a sequence.    The
> > sizes for Text, URLs and Sequences was dropped.  It can easily be
> > inferred from parsing the document.
>
> since it is XML, keep everything lower-case and no extra "sdp" prefix.
> It should be enough to call the root element "record". And I think it is
> better and easier to use something like:
>
> 	<data type="uuid16" value="0x1002"/>
>

I can see your point on being lower case, so this is something I agree with.

I don't really like using the single data tag for everything.  I think I 
prefer the e.g. <uuid16>0x1002</uuid16> syntax.  However, since this is XML 
there's no right or wrong way to do this.  Perhaps others can chime in?

> And to be fully in sync with the specification we need to differentiate
> between text8, text16 and text32 (and of course for url, too). For
> convenience we can then have all data types without the size value and
> then the server will determine the most appropriate one by itself.
>

Why though?  This is something that can be easily computed while parsing the 
XML structure and creating the internal data representation.  The user should 
not have to deal with this implementation detail.  I suppose I'm open to 
adding text8, text16 and text32 tags in "expert" mode.  But how will we 
handle sequences and alternatives in this case?  

For me I'd rather let the underlying system pick whatever is optimal.  If I 
want to deal with such low level details, I'll program in the low-level API.  
Isn't the goal to be as user-friendly as possible?

> > I'd like to get some feedback as to how to manage things like Record
> > Handle, and RFCOMM/L2Cap channels, etc.  For record handle I think it is
> > easy, just remove that particular attribute and let the SDP server figure
> > it out.  For RFCOMM channel, etc it is more tricky.  Should we use a
> > magic value or just override it behind the scenes?  We can always rely on
> > the user to pick a correct channel as well (and fail registration if they
> > pick a channel that is already in use)
>
> Actually at the moment you have to let the server pick the record
> handle, because specifying the handle doesn't work. It should work, but
> I never found the actual bug in the code that prevents it.
>
> Using the proposed way of the "data" element, we can have special values
> for "value" like "%channel" etc. that can be filled in by the server.

I think this can be accomplished easily by using a hint attribute or a special 
value, e.g.

<uint16 type="auto_rfcomm_channel">0x0000</uint16>

or

<uint16>AUTO_RFCOMM_CHANNEL</uint16>

>
> Regards
>
> Marcel
>

-Denis

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-23  3:59   ` Denis KENZIOR
@ 2006-10-23  4:11     ` Marcel Holtmann
  2006-10-23  4:31       ` Denis KENZIOR
  0 siblings, 1 reply; 23+ messages in thread
From: Marcel Holtmann @ 2006-10-23  4:11 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > > Here's the proposed DTD for SDP over XML.  It closely follows the SDP
> > > profile doc.  I wasn't sure whether sequences can be empty (which makes
> > > no sense to me), so I required at least one element in a sequence.    The
> > > sizes for Text, URLs and Sequences was dropped.  It can easily be
> > > inferred from parsing the document.
> >
> > since it is XML, keep everything lower-case and no extra "sdp" prefix.
> > It should be enough to call the root element "record". And I think it is
> > better and easier to use something like:
> >
> > 	<data type="uuid16" value="0x1002"/>
> >
> 
> I can see your point on being lower case, so this is something I agree with.
> 
> I don't really like using the single data tag for everything.  I think I 
> prefer the e.g. <uuid16>0x1002</uuid16> syntax.  However, since this is XML 
> there's no right or wrong way to do this.  Perhaps others can chime in?

my main reason is that the D-Bus Introspection goes this way. And I
personally find this way simpler and more intuitive.

> > And to be fully in sync with the specification we need to differentiate
> > between text8, text16 and text32 (and of course for url, too). For
> > convenience we can then have all data types without the size value and
> > then the server will determine the most appropriate one by itself.
> >
> 
> Why though?  This is something that can be easily computed while parsing the 
> XML structure and creating the internal data representation.  The user should 
> not have to deal with this implementation detail.  I suppose I'm open to 
> adding text8, text16 and text32 tags in "expert" mode.  But how will we 
> handle sequences and alternatives in this case?  

If you specify the DTD the size is not important. Say for example it is
a UUID and the server can detect if it is a UUID-128, UUID-32 or UUID-16
and so the actual application programmer can use the convenient way to
specify the record with thinking about the actual sizes. The server will
do the right thing.

However this only works for "uuid", "text" and "url", because all others
might be used with special meaning from profile to profile.

Having the sized version around and retrieving a record from a remote
server gives you the chance to see the actual record how it is stored on
the remote side. For example some implementation use UUID-32 for no real
reason. Even if a UUID-16 would have been enough. I wanna see these
differences.

> For me I'd rather let the underlying system pick whatever is optimal.  If I 
> want to deal with such low level details, I'll program in the low-level API.  
> Isn't the goal to be as user-friendly as possible?

The problem with SDP is that you can't make it really simple. So far we
tried four times and nothing simple came around. This protocol and data
representation is simply messed up.

> > > I'd like to get some feedback as to how to manage things like Record
> > > Handle, and RFCOMM/L2Cap channels, etc.  For record handle I think it is
> > > easy, just remove that particular attribute and let the SDP server figure
> > > it out.  For RFCOMM channel, etc it is more tricky.  Should we use a
> > > magic value or just override it behind the scenes?  We can always rely on
> > > the user to pick a correct channel as well (and fail registration if they
> > > pick a channel that is already in use)
> >
> > Actually at the moment you have to let the server pick the record
> > handle, because specifying the handle doesn't work. It should work, but
> > I never found the actual bug in the code that prevents it.
> >
> > Using the proposed way of the "data" element, we can have special values
> > for "value" like "%channel" etc. that can be filled in by the server.
> 
> I think this can be accomplished easily by using a hint attribute or a special 
> value, e.g.
> 
> <uint16 type="auto_rfcomm_channel">0x0000</uint16>
> 
> or
> 
> <uint16>AUTO_RFCOMM_CHANNEL</uint16>

I prefer the "%channel" way. Most people with programming skills will
understand what it means.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-23  4:11     ` Marcel Holtmann
@ 2006-10-23  4:31       ` Denis KENZIOR
  2006-10-23  7:27         ` Marcel Holtmann
  0 siblings, 1 reply; 23+ messages in thread
From: Denis KENZIOR @ 2006-10-23  4:31 UTC (permalink / raw)
  To: BlueZ development

Marcel,

> >
> > I can see your point on being lower case, so this is something I agree
> > with.
> >
> > I don't really like using the single data tag for everything.  I think I
> > prefer the e.g. <uuid16>0x1002</uuid16> syntax.  However, since this is
> > XML there's no right or wrong way to do this.  Perhaps others can chime
> > in?
>
> my main reason is that the D-Bus Introspection goes this way. And I
> personally find this way simpler and more intuitive.

Ok in this case, agreed.  I will make the necessary changes.

> > Why though?  This is something that can be easily computed while parsing
> > the XML structure and creating the internal data representation.  The
> > user should not have to deal with this implementation detail.  I suppose
> > I'm open to adding text8, text16 and text32 tags in "expert" mode.  But
> > how will we handle sequences and alternatives in this case?
>
> If you specify the DTD the size is not important. Say for example it is
> a UUID and the server can detect if it is a UUID-128, UUID-32 or UUID-16
> and so the actual application programmer can use the convenient way to
> specify the record with thinking about the actual sizes. The server will
> do the right thing.
>

Yep, I prefer this.  See next.  

> However this only works for "uuid", "text" and "url", because all others
> might be used with special meaning from profile to profile.

Yep, hence I made the int8..128 and uint8..128.  I think this is unavoidable.  
This is also the reason why I explicitly specify uuid16..128.  Do you think 
the uuid one is unnecessary?

>
> Having the sized version around and retrieving a record from a remote
> server gives you the chance to see the actual record how it is stored on
> the remote side. For example some implementation use UUID-32 for no real
> reason. Even if a UUID-16 would have been enough. I wanna see these
> differences.

I understand, but this is more of a developer thing.  Can sdptool be made to 
fill this gap?  It already has this functionality.  I think the XML format 
should be kept as simple as possible, unless extra complexity is unavoidable.

Perhaps two dtds are in order.  One that is "explicit" (you specify sizes for 
all elements, including Sequences and Alternates, Text, URL and UUID) and one 
that is not?

> The problem with SDP is that you can't make it really simple. So far we
> tried four times and nothing simple came around. This protocol and data
> representation is simply messed up.

I completely agree with the last sentence :)

> > > Actually at the moment you have to let the server pick the record
> > > handle, because specifying the handle doesn't work. It should work, but
> > > I never found the actual bug in the code that prevents it.
> > >
> > > Using the proposed way of the "data" element, we can have special
> > > values for "value" like "%channel" etc. that can be filled in by the
> > > server.
> >
> > I think this can be accomplished easily by using a hint attribute or a
> > special value, e.g.
> >
> > <uint16 type="auto_rfcomm_channel">0x0000</uint16>
> >
> > or
> >
> > <uint16>AUTO_RFCOMM_CHANNEL</uint16>
>
> I prefer the "%channel" way. Most people with programming skills will
> understand what it means.
>

Something that occurred to me is that I think in the real implementation it 
would be a lot easier to specify the l2cap and rfcomm channels separately and 
just override the parsed SDP record.  Don't know if this is good though.  
E.g. 
	RegisterXMLRecordRFCOMM(byte[] xml, int rfcomm_channel)
	RegisterXMLRecordL2CAP...

> Regards
>
> Marcel
>

Thanks,
-Denis

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-23  4:31       ` Denis KENZIOR
@ 2006-10-23  7:27         ` Marcel Holtmann
  2006-10-24  5:47           ` Denis KENZIOR
  0 siblings, 1 reply; 23+ messages in thread
From: Marcel Holtmann @ 2006-10-23  7:27 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > > I can see your point on being lower case, so this is something I agree
> > > with.
> > >
> > > I don't really like using the single data tag for everything.  I think I
> > > prefer the e.g. <uuid16>0x1002</uuid16> syntax.  However, since this is
> > > XML there's no right or wrong way to do this.  Perhaps others can chime
> > > in?
> >
> > my main reason is that the D-Bus Introspection goes this way. And I
> > personally find this way simpler and more intuitive.
> 
> Ok in this case, agreed.  I will make the necessary changes.

Great.

> > However this only works for "uuid", "text" and "url", because all others
> > might be used with special meaning from profile to profile.
> 
> Yep, hence I made the int8..128 and uint8..128.  I think this is unavoidable.  
> This is also the reason why I explicitly specify uuid16..128.  Do you think 
> the uuid one is unnecessary?

It actually is, because the UUID-128 has a well defined representation
and it is simple to distinguish between UUID-16 and UUID-32. However if
someone wants to force another UUID, then we might should have them in
case.

> > Having the sized version around and retrieving a record from a remote
> > server gives you the chance to see the actual record how it is stored on
> > the remote side. For example some implementation use UUID-32 for no real
> > reason. Even if a UUID-16 would have been enough. I wanna see these
> > differences.
> 
> I understand, but this is more of a developer thing.  Can sdptool be made to 
> fill this gap?  It already has this functionality.  I think the XML format 
> should be kept as simple as possible, unless extra complexity is unavoidable.

I am not sure. For example if you wanna auto detect some special
devices, you might wanna have this extra bit of information. This can
become handy with all the special devices using the serial port profile
and are something special like a blood pressure device etc.

> Perhaps two dtds are in order.  One that is "explicit" (you specify sizes for 
> all elements, including Sequences and Alternates, Text, URL and UUID) and one 
> that is not?

No. Two DTDs will make it too complex. We can have both ways within one
DTD and the registering application can use the simple one, while the
server will always hand out the detailed one. Leave the rest to the XML
parser.

> Something that occurred to me is that I think in the real implementation it 
> would be a lot easier to specify the l2cap and rfcomm channels separately and 
> just override the parsed SDP record.  Don't know if this is good though.  
> E.g. 
> 	RegisterXMLRecordRFCOMM(byte[] xml, int rfcomm_channel)
> 	RegisterXMLRecordL2CAP...

I am against putting too much information into the methods itself. This
never gave us any advantage in the past. The Bluetooth SIG is inventing
new records all the time and in case of HCRP and HID you have two L2CAP
PSMs which makes this more complicated.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-23  7:27         ` Marcel Holtmann
@ 2006-10-24  5:47           ` Denis KENZIOR
  2006-10-24  8:13             ` Marcel Holtmann
  0 siblings, 1 reply; 23+ messages in thread
From: Denis KENZIOR @ 2006-10-24  5:47 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 99 bytes --]

Marcel,

Based on your feedback a new DTD specification.  Hopefully it is getting 
closer.

-Denis

[-- Attachment #2: record.dtd --]
[-- Type: text/html, Size: 2723 bytes --]

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-24  8:13             ` Marcel Holtmann
@ 2006-10-24  6:47               ` Denis KENZIOR
  2006-10-24  9:16                 ` Marcel Holtmann
  2006-10-30 13:27                 ` Marcel Holtmann
  2006-10-24  7:08               ` Denis KENZIOR
  1 sibling, 2 replies; 23+ messages in thread
From: Denis KENZIOR @ 2006-10-24  6:47 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 1659 bytes --]

Marcel,

On Tuesday 24 October 2006 18:13, Marcel Holtmann wrote:
> Hi Denis,
>
> > Based on your feedback a new DTD specification.  Hopefully it is getting
> > closer.
>
> looks good. However the text about hex encoded is not needed. All number
> based values can be either in hex or decimal or whatever. We will use
> the standard encoding to detect it. For example if it starts with 0x
> then it is hex, otherwise it is decimal.

Yes, the encoding is only relevant for the <text[8,16,32]> fields.  The rest 
of the attributes should not have it (this is hard to express in a DTD.)

>
> I am also not sure that the encoding attribute is needed. If you wanna
> encode binary data in text elements (at the moment only HID does this)
> then you can use \000 style encoding to do so.

This does not seem to be supported by expat, unless I'm missing something.  I 
also want to expand encoding to eventually have a base64 option, for space 
saving.  

How would this work, do you mean to just recognize if a character starts with 
\0xxx - Octal
\xx - Hex?

>
> Can also provide an example XML record for a really simple serial port
> profile. This will help to see how it looks like.
>
> Anyone willing to write a really specific and simple XML parser to
> convert these XML files into sdp_record_t structures. And or course a
> function that converts this structure back to XML.

Attached is a sample of OPUSH profile.  Attached also is the code to generate 
one of these and parse one of these as well (you can use attached sdptool 
patch to play with it)

The code is still pretty raw, but it should at least get us started.

>
> Regards
>
> Marcel
>

-Denis

[-- Attachment #2: OPUSH.xml --]
[-- Type: text/xml, Size: 1213 bytes --]

<record>
	<attribute id="0x0000">
		<data type="uint32" value="0x00010000" />
	</attribute>
	<attribute id="0x0001">
		<sequence8>
			<data type="uuid16" value="0x1105" />
		</sequence8>
	</attribute>
	<attribute id="0x0004">
		<sequence8>
			<sequence8>
				<data type="uuid16" value="0x0100" />
			</sequence8>
			<sequence8>
				<data type="uuid16" value="0x0003" />
				<data type="uint8" value="0x09" />
			</sequence8>
			<sequence8>
				<data type="uuid16" value="0x0008" />
			</sequence8>
		</sequence8>
	</attribute>
	<attribute id="0x0005">
		<sequence8>
			<data type="uuid16" value="0x1002" />
		</sequence8>
	</attribute>
	<attribute id="0x0009">
		<sequence8>
			<sequence8>
				<data type="uuid16" value="0x1105" />
				<data type="uint16" value="0x0100" />
			</sequence8>
		</sequence8>
	</attribute>
	<attribute id="0x0100">
		<data type="text8" value="OBEX Object Push" />
	</attribute>
	<attribute id="0x0303">
		<sequence8>
			<data type="uint8" value="0x01" />
			<data type="uint8" value="0x02" />
			<data type="uint8" value="0x03" />
			<data type="uint8" value="0x04" />
			<data type="uint8" value="0x05" />
			<data type="uint8" value="0x06" />
		</sequence8>
	</attribute>
</record>

[-- Attachment #3: sdp-xml.c --]
[-- Type: text/x-csrc, Size: 26808 bytes --]

#include "sdp-xml.h"

#include <stdio.h>
#include <string.h>
#include <bluetooth/sdp_lib.h>
#include <malloc.h>
#include <limits.h>

#define STRBUFSIZE 256
#define MAXINDENT 64

static void convert_raw_data_to_xml(sdp_data_t * data, int indentLevel,
				    void *userData,
				    void (*appendFunc) (void *, const char *))
{
	int i, hex;
	char buf[STRBUFSIZE];
	char indent[MAXINDENT];
	char indentPlusOne[MAXINDENT];

	if (!data)
		return;

	if (indentLevel >= MAXINDENT)
		indentLevel = MAXINDENT - 2;

	for (i = 0; i < indentLevel; i++) {
		indent[i] = '\t';
		indentPlusOne[i] = '\t';
	}

	indent[i] = '\0';
	indentPlusOne[i] = '\t';
	indentPlusOne[i + 1] = '\0';

	buf[STRBUFSIZE - 1] = '\0';

	switch (data->dtd) {
	case SDP_DATA_NIL:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"nil\" value=\"\" />\n");
		break;
	case SDP_BOOL:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"bool\" value=\"");
		appendFunc(userData, data->val.uint8 ? "True" : "False");
		appendFunc(userData, "\" />\n");
		break;
	case SDP_UINT8:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"uint8\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%02x", data->val.uint8);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_UINT16:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"uint16\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%04x", data->val.uint16);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_UINT32:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"uint32\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%08x", data->val.uint32);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_UINT64:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"uint64\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%016jx", data->val.uint64);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_UINT128:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"uint128\" value=\"");

		for (i = 0; i < 16; i++) {
			sprintf(&buf[i * 2], "%02x",
				(unsigned char) data->val.uint128.data[i]);
		}

		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_INT8:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"int8\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "%d", data->val.int8);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_INT16:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"int16\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "%d", data->val.int16);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_INT32:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"int32\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "%d", data->val.int32);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_INT64:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"int64\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "%jd", data->val.int64);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_INT128:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"int128\" value=\"");

		for (i = 0; i < 16; i++) {
			sprintf(&buf[i * 2], "%02x",
				(unsigned char) data->val.int128.data[i]);
		}
		appendFunc(userData, buf);

		appendFunc(userData, "\" />\n");
		break;
	case SDP_UUID16:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"uuid16\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%04x",
			 data->val.uuid.value.uuid16);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_UUID32:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"uuid32\" value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%08x",
			 data->val.uuid.value.uuid32);
		appendFunc(userData, buf);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_UUID128:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"uuid128\" value=\"");

		snprintf(buf, STRBUFSIZE - 1,
			 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[0],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[1],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[2],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[3],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[4],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[5],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[6],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[7],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[8],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[9],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[10],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[11],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[12],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[13],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[14],
			 (unsigned char) data->val.uuid.value.
			 uuid128.data[15]);

		appendFunc(userData, "\" />\n");
		break;
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
	case SDP_TEXT_STR32:
	{
		hex = 0;
		
		for (i = 0; i < data->unitSize; i++) {
			if (i == (data->unitSize - 1)
			    && data->val.str[i] == '\0')
				break;
			if (!isalnum(data->val.str[i])
			    && (data->val.str[i] != ' ')) {
				hex = 1;
				break;
			}
		}
		
		appendFunc(userData, indent);

		appendFunc(userData, "<data ");

		switch (data->dtd) {
			case SDP_TEXT_STR8:
				appendFunc(userData, "type=\"text8\" ");
				break;
			case SDP_TEXT_STR16:
				appendFunc(userData, "type=\"text16\" ");
				break;
			case SDP_TEXT_STR32:
				appendFunc(userData, "type=\"text32\" ");
				break;
		};

		char *strBuf = 0;

		if (hex) {
			appendFunc(userData, "encoding=\"hex\" ");
			strBuf = (char *) malloc(sizeof(char)
						 * (data->unitSize * 2 + 1));

			// Unit Size seems to include the size for dtd
			// It is thus off by 1
			// This is safe for Normal strings, but not
			// hex encoded data
			for (i = 0; i < (data->unitSize-1); i++)
				sprintf(&strBuf[i * sizeof (char) * 2],
					"%02x",
					(unsigned char) data->val.str[i]);

			strBuf[data->unitSize * 2] = '\0';
		}
		else {
			strBuf = (char *)
				malloc(sizeof(char) * (data->unitSize + 1));
			memcpy(strBuf, data->val.str, data->unitSize);
			strBuf[data->unitSize] = '\0';
		}

		appendFunc(userData, "value=\"");
		appendFunc(userData, strBuf);
		appendFunc(userData, "\" />\n");
		free(strBuf);
		break;
	}
	case SDP_URL_STR8:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"url8\" value=\"");
		appendFunc(userData, data->val.str);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_URL_STR16:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"url16\" value=\"");
		appendFunc(userData, data->val.str);
		appendFunc(userData, "\" />\n");
	case SDP_URL_STR32:
		appendFunc(userData, indent);
		appendFunc(userData, "<data type=\"url32\" value=\"");
		appendFunc(userData, data->val.str);
		appendFunc(userData, "\" />\n");
		break;
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		appendFunc(userData, indent);
		switch(data->dtd) {
			case SDP_SEQ8:
				appendFunc(userData, "<sequence8>\n");
				break;
			case SDP_SEQ16:
				appendFunc(userData, "<sequence16>\n");
				break;
			case SDP_SEQ32:
				appendFunc(userData, "<sequence32>\n");
				break;
		};

		convert_raw_data_to_xml(data->val.dataseq,
					indentLevel + 1, userData,
					appendFunc);
					
		appendFunc(userData, indent);
		switch(data->dtd) {
			case SDP_SEQ8:
				appendFunc(userData, "</sequence8>\n");
				break;
			case SDP_SEQ16:
				appendFunc(userData, "</sequence16>\n");
				break;
			case SDP_SEQ32:
				appendFunc(userData, "</sequence32>\n");
				break;
		};
		
		break;
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
		appendFunc(userData, indent);

		switch(data->dtd) {
			case SDP_ALT8:
				appendFunc(userData, "<alternate8>\n");
				break;
			case SDP_ALT16:
				appendFunc(userData, "<alternate16>\n");
				break;
			case SDP_ALT32:
				appendFunc(userData, "<alternate32>\n");
				break;
		};

		convert_raw_data_to_xml(data->val.dataseq,
					indentLevel + 1, userData,
					appendFunc);
		appendFunc(userData, indent);

		switch(data->dtd) {
			case SDP_ALT8:
				appendFunc(userData, "</alternate8>\n");
				break;
			case SDP_ALT16:
				appendFunc(userData, "</alternate16>\n");
				break;
			case SDP_ALT32:
				appendFunc(userData, "</alternate32>\n");
				break;
		};
	       
		break;
	default:
		break;
	}

	convert_raw_data_to_xml(data->next, indentLevel, userData,
				appendFunc);
}

struct conversion_data
{
	void *userData;
	void (*appendFunc) (void *userData, const char *);
};

static void convert_raw_attr_to_xml_func(void *value, void *userData)
{
	struct conversion_data *cd = (struct conversion_data *) userData;
	sdp_data_t *data = (sdp_data_t *) value;
	char buf[STRBUFSIZE];

	buf[STRBUFSIZE - 1] = '\0';
	snprintf(buf, STRBUFSIZE - 1, "\t<attribute id=\"0x%04x\">\n",
		 data->attrId);
	cd->appendFunc(cd->userData, buf);

	if (data)
		convert_raw_data_to_xml(data, 2, cd->userData,
					cd->appendFunc);
	else
		cd->appendFunc(cd->userData, "\t\tNULL\n");

	cd->appendFunc(cd->userData, "\t</attribute>\n");
}

/*
    Will convert the sdp record to XML.  The appendFunc and userData can be used
    to control where to output the record (e.g. file or a data buffer).  The
    appendFunc will be called repeatedly with userData and the character buffer
    (containing parts of the generated XML) to append.
*/
void convert_sdp_record_to_xml(sdp_record_t * rec,
			       void *userData,
			       void (*appendFunc) (void *, const char *))
{
	struct conversion_data data;

	data.userData = userData;
	data.appendFunc = appendFunc;

	if (rec && rec->attrlist) {
		appendFunc(userData, "<record>\n");
		sdp_list_foreach(rec->attrlist,
				 convert_raw_attr_to_xml_func, &data);
		appendFunc(userData, "</record>\n");
	}
}

#define DEFAULT_XML_DATA_SIZE 64

static sdp_xml_data_t *sdp_xml_data_alloc()
{
	sdp_xml_data_t *elem;

	elem = (sdp_xml_data_t *) malloc(sizeof(sdp_xml_data_t));

	/* Null terminate the text */
	elem->size = DEFAULT_XML_DATA_SIZE;
	elem->text = (char *) malloc(sizeof(char) * DEFAULT_XML_DATA_SIZE);
	elem->text[0] = '\0';

	elem->next = 0;
	elem->data = 0;

	elem->type = 0;

	return elem;
}

static void sdp_xml_data_free(sdp_xml_data_t * elem)
{
	if (elem->data)
		sdp_data_free(elem->data);

	free(elem->text);
	free(elem);
}

static sdp_xml_data_t *sdp_xml_data_expand(sdp_xml_data_t * elem)
{
	char *newbuf;

	newbuf = (char *) malloc(elem->size * 2);
	if (!newbuf)
		return NULL;

	memcpy(newbuf, elem->text, elem->size);
	elem->size *= 2;
	free(elem->text);

	elem->text = newbuf;

	return elem;
}

static void sdp_xml_parse_uuid16(sdp_xml_context * data)
{
	uint16_t val;

	val = strtol(data->stack_head->text, 0, 16);

	data->stack_head->data = sdp_data_alloc(SDP_UUID16, &val);
}

static void sdp_xml_parse_uuid32(sdp_xml_context * data)
{
	uint32_t val;

	val = strtoll(data->stack_head->text, 0, 16);
	data->stack_head->data = sdp_data_alloc(SDP_UUID32, &val);
}

static void sdp_xml_parse_uuid128(sdp_xml_context * data)
{
	uint128_t val;
	int i;
	int j;

	char buf[3];

	buf[2] = '\0';

	for (j = 0, i = 0; i < strlen(data->stack_head->text); j++) {
		if (data->stack_head->text[i] == '-') {
			i++;
			continue;
		}

		buf[0] = data->stack_head->text[i];
		buf[1] = data->stack_head->text[i + 1];

		val.data[i] = strtoul(buf, 0, 16);
		i += 2;
	}

	data->stack_head->data = sdp_data_alloc(SDP_UUID128, &val);
}

static void sdp_xml_parse_uuid(sdp_xml_context *data)
{
	int len;

	len = strlen(data->stack_head->text);

	if (len == 36) {
		sdp_xml_parse_uuid128(data);
	}
	else {
		uint32_t val;

		val = strtoll(data->stack_head->text, 0, 16);

		if (val > USHRT_MAX) {
			data->stack_head->data =
				sdp_data_alloc(SDP_UUID32, &val);
		}
		else {
			uint16_t val2 = val;
			data->stack_head->data =
				sdp_data_alloc(SDP_UUID16, &val2);
		}
	}
}

static void sdp_xml_parse_int(sdp_xml_context * data, uint8_t dtd)
{
	switch (dtd) {
	case SDP_BOOL:
	{
		uint8_t val = 0;

		if (!strcmp("True", data->stack_head->text)) {
			val = 1;
		}
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_INT8:
	{
		int8_t val = strtoul(data->stack_head->text, 0,
				     10);
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_UINT8:
	{
		uint8_t val = strtoul(data->stack_head->text, 0,
					      16);
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_INT16:
	{
		int16_t val = strtoul(data->stack_head->text, 0,
				      10);
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_UINT16:
	{
		uint16_t val = strtoul(data->stack_head->text, 0,
				       16);
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_INT32:
	{
		int32_t val = strtoul(data->stack_head->text, 0,
				      10);
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_UINT32:
	{
		uint32_t val = strtoul(data->stack_head->text, 0,
				       16);
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_INT64:
	{
		int64_t val = strtoull(data->stack_head->text, 0,
				       10);
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_UINT64:
	{
		uint64_t val = strtoull(data->stack_head->text, 0,
					16);
		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	case SDP_INT128:
	case SDP_UINT128:
	{
		uint128_t val;
		int i = 0;
		char buf[3];

		buf[2] = '\0';

		for (; i < 32; i += 2) {
			buf[0] = data->stack_head->text[i];
			buf[1] = data->stack_head->text[i + 1];

			val.data[i] = strtoul(buf, 0, 16);
		}

		data->stack_head->data = sdp_data_alloc(dtd, &val);
		break;
	}

	};
}

static void sdp_xml_parse_url_with_size(sdp_xml_context * data, uint8_t dtd)
{
	data->stack_head->data = sdp_data_alloc(dtd, data->stack_head->text);
}

static void sdp_xml_parse_url(sdp_xml_context * data)
{
	uint8_t dtd = SDP_URL_STR8;

	if (strlen(data->stack_head->text) > UCHAR_MAX) {
		dtd = SDP_URL_STR16;
	}

	sdp_xml_parse_url_with_size(data, dtd);
}

static char * sdp_xml_parse_text_decode(sdp_xml_context *data,
					char *shouldFree,
					uint32_t *length)
{
	char *text;

	if (data->stack_head->type == 0) {
		text = data->stack_head->text;
		*length = strlen(text);
	}
	else {
		int len = strlen(data->stack_head->text);
		char buf[3];
		int i;
		char *decoded =
			(char *) malloc(sizeof(char) * ((len >> 1) + 1));

		fprintf(stderr,
			"Got a stack_head->text len of: %d(%s)\n",
			len, data->stack_head->text);
		fprintf(stderr, "len >> 1 = %d\n", len >> 1);

		buf[2] = '\0';

		for (i = 0; i < len; i += 2) {
			buf[0] = data->stack_head->text[i];
			buf[1] = data->stack_head->text[i + 1];

			decoded[i >> 1] = strtoul(buf, 0, 16);
			fprintf(stderr, "Putting at %d\n", i>>1);
		}

		decoded[len >> 1] = '\0';
		text = decoded;
		*shouldFree = 1;
		*length = len >> 1;
	}

	return text;
}

static void sdp_xml_parse_text_with_size(sdp_xml_context * data, uint8_t dtd)
{
	char shouldFree = 0;
	char *text;
	uint32_t length;

	text = sdp_xml_parse_text_decode(data, &shouldFree, &length);
	data->stack_head->data = sdp_data_alloc_with_length(dtd, text, length);

	fprintf(stderr, "Got text of length %d: -->%s<--\n", length,
		text);
	fprintf(stderr, "Unit size was: %d\n",
		data->stack_head->data->unitSize);

	if (shouldFree)
		free(text);
}

static void sdp_xml_parse_text(sdp_xml_context * data)
{
	uint8_t dtd = SDP_TEXT_STR8;
	char shouldFree = 0;
	char *text;
	uint32_t length;

	text = sdp_xml_parse_text_decode(data, &shouldFree, &length);

	if (length > UCHAR_MAX) {
		dtd = SDP_TEXT_STR16;
	}

	fprintf(stderr, "Got text of length %d: -->%s<--\n", length,
		text);
	fprintf(stderr, "Unit size was: %d\n",
		data->stack_head->data->unitSize);

	data->stack_head->data = sdp_data_alloc(dtd, text);

	if (shouldFree)
		free(text);
}

static void sdp_xml_parse_nil(sdp_xml_context * data)
{
	data->stack_head->data = sdp_data_alloc(SDP_DATA_NIL, 0);
}

static void sdp_xml_parse_datatype(sdp_xml_context * context, const char *el)
{
	if (!strcmp(el, "bool")) {
		sdp_xml_parse_int(context, SDP_BOOL);
	}

	else if (!strcmp(el, "uint8")) {
		sdp_xml_parse_int(context, SDP_UINT8);
	}
	else if (!strcmp(el, "uint16")) {
		sdp_xml_parse_int(context, SDP_UINT16);
	}

	else if (!strcmp(el, "uint32")) {
		sdp_xml_parse_int(context, SDP_UINT32);
	}

	else if (!strcmp(el, "uint64")) {
		sdp_xml_parse_int(context, SDP_UINT64);
	}

	else if (!strcmp(el, "uint128")) {
		sdp_xml_parse_int(context, SDP_UINT128);
	}

	else if (!strcmp(el, "int8")) {
		sdp_xml_parse_int(context, SDP_INT8);
	}

	else if (!strcmp(el, "int16")) {
		sdp_xml_parse_int(context, SDP_INT16);
	}

	else if (!strcmp(el, "int32")) {
		sdp_xml_parse_int(context, SDP_INT32);
	}

	else if (!strcmp(el, "int64")) {
		sdp_xml_parse_int(context, SDP_INT64);
	}

	else if (!strcmp(el, "int128")) {
		sdp_xml_parse_int(context, SDP_INT128);
	}

	else if (!strcmp(el, "uuid16")) {
		sdp_xml_parse_uuid16(context);
	}

	else if (!strcmp(el, "uuid32")) {
		sdp_xml_parse_uuid32(context);

	}

	else if (!strcmp(el, "uuid128")) {
		sdp_xml_parse_uuid128(context);
	}

	else if (!strcmp(el, "uuid")) {
		sdp_xml_parse_uuid(context);
	}

	else if (!strcmp(el, "url")) {
		sdp_xml_parse_url(context);
	}

	else if (!strcmp(el, "url8")) {
		sdp_xml_parse_url_with_size(context, SDP_URL_STR8);
	}

	else if (!strcmp(el, "url16")) {
		sdp_xml_parse_url_with_size(context, SDP_URL_STR16);
	}

	else if (!strcmp(el, "url32")) {
		sdp_xml_parse_url_with_size(context, SDP_URL_STR32);
	}

	else if (!strcmp(el, "text")) {
		sdp_xml_parse_text(context);
	}

	else if (!strcmp(el, "text8")) {
		sdp_xml_parse_text_with_size(context, SDP_TEXT_STR8);
	}

	else if (!strcmp(el, "text16")) {
		sdp_xml_parse_text_with_size(context, SDP_TEXT_STR16);
	}

	else if (!strcmp(el, "text32")) {
		sdp_xml_parse_text_with_size(context, SDP_TEXT_STR32);
	}

	else if (!strcmp(el, "nil")) {
		sdp_xml_parse_nil(context);
	}

	else {
		printf("Can't parse element: %s\n", el);
		printf("Gathered data: %s\n", context->stack_head->text);
	}
}

static void convert_xml_to_sdp_start(void *data, const char *el,
				     const char **attr)
{
	int i;
	sdp_xml_context *context = (sdp_xml_context *) data;

	if (!strcmp(el, "record"))
		return;

	if (!strcmp(el, "attribute")) {
		/* Get the ID */
		for (i = 0; attr[i]; i += 1) {
			if (!strcmp(attr[i], "id")) {
				context->attrId = strtol(attr[i + 1], 0, 0);
				break;
			}
		}

		return;
	}

	/* Assume every other tag is an element of some sort */
	if (context->stack_head) {
		sdp_xml_data_t *newElem = sdp_xml_data_alloc();
		newElem->next = context->stack_head;
		context->stack_head = newElem;
	}
	else {
		context->stack_head = sdp_xml_data_alloc();
		context->stack_head->next = 0;
	}

	if (!strcmp(el, "sequence")) {
		context->stack_head->data = sdp_data_alloc(SDP_SEQ8, NULL);
	}

        else if (!strcmp(el, "sequence8")) {
		context->stack_head->data = sdp_data_alloc(SDP_SEQ8, NULL);
	}

	else if (!strcmp(el, "sequence16")) {
		context->stack_head->data = sdp_data_alloc(SDP_SEQ16, NULL);
	}
	
        else if (!strcmp(el, "sequence32")) {
		context->stack_head->data = sdp_data_alloc(SDP_SEQ32, NULL);
	}

	else if (!strcmp(el, "alternate")) {
		context->stack_head->data = sdp_data_alloc(SDP_ALT8, NULL);
	}

	else if (!strcmp(el, "alternate8")) {
		context->stack_head->data = sdp_data_alloc(SDP_ALT8, NULL);
	}

	else {
		const char *type;
		/* Parse value, datatype, encoding */
		for (i = 0; attr[i]; i += 2) {
			if (!strcmp(attr[i], "type")) {
				type = attr[i+1];
			}

			if (!strcmp(attr[i], "value")) {
				int curlen = strlen(context->stack_head->text);
				int attrlen = strlen(attr[i+1]);

				/* Ensure we're big enough */
				while ((curlen + 1 + attrlen) >
				       context->stack_head->size) {
					fprintf(stderr, "Growing text\n");
					sdp_xml_data_expand(context->stack_head);
				}

				memcpy(&context->stack_head->text[curlen],
				       attr[i+1], attrlen);
				context->stack_head->text[curlen + attrlen] = '\0';
				fprintf(stderr, "Text is now: -->%s<--\n",
					context->stack_head->text);
			}

			if (!strcmp(attr[i], "encoding")) {
				if (!strcmp(attr[i+1], "hex"))
					context->stack_head->type = 1;
			}
			
		}

		sdp_xml_parse_datatype(context, type);
	}
}

static int compute_seq_size(sdp_data_t *data)
{
	int unitSize = data->unitSize;
	sdp_data_t *seq = data->val.dataseq;

	fprintf(stderr, "seq unitSize is: %d\n",
		unitSize);

	for (; seq; seq = seq->next)
		unitSize += seq->unitSize;

	fprintf(stderr, "seq unitSize is now: %d\n",
		unitSize);

	return unitSize;
}

static void convert_xml_to_sdp_end(void *data, const char *el)
{
	sdp_xml_context *context = (sdp_xml_context *) data;
	sdp_xml_data_t *elem;

	if (!strcmp(el, "record"))
		return;

	if (!strcmp(el, "attribute")) {
		if (context->stack_head && context->stack_head->data) {
			int ret = sdp_attr_add(context->sdprec,
					       context->attrId,
					       context->stack_head->data);
			if (ret == -1)
				fprintf(stderr, "Trouble adding attribute\n");

			context->stack_head->data = 0;
			sdp_xml_data_free(context->stack_head);
			context->stack_head = 0;
		}
		else {
			fprintf(stderr,
				"No Data for attribute: %d\n",
				context->attrId);
		}

		return;
	}
	else if (!strcmp(el, "sequence")) {
		context->stack_head->data->unitSize =
			compute_seq_size(context->stack_head->data);
	
		if (context->stack_head->data->unitSize > USHRT_MAX) {
			context->stack_head->data->unitSize +=
				sizeof(uint32_t);
			context->stack_head->data->dtd = SDP_SEQ32;
		}
		else if (context->stack_head->data->unitSize > UCHAR_MAX) {
			context->stack_head->data->unitSize +=
				sizeof(uint16_t);
			context->stack_head->data->dtd = SDP_SEQ16;
		}
		else {
			context->stack_head->data->unitSize += sizeof(uint8_t);
		}
	}

	else if (!strcmp(el, "sequence8")) {
		context->stack_head->data->unitSize =
			compute_seq_size(context->stack_head->data);

		context->stack_head->data->unitSize += sizeof(uint8_t);
	}

	else if (!strcmp(el, "sequence16")) {
		context->stack_head->data->unitSize =
			compute_seq_size(context->stack_head->data);

		context->stack_head->data->unitSize += sizeof(uint16_t);
	}

	else if (!strcmp(el, "sequence32")) {
		context->stack_head->data->unitSize =
			compute_seq_size(context->stack_head->data);

		context->stack_head->data->unitSize += sizeof(uint32_t);
	}

	else if (!strcmp(el, "alternate")) {
		context->stack_head->data->unitSize =
			compute_seq_size(context->stack_head->data);
		
		if (context->stack_head->data->unitSize > USHRT_MAX) {
			context->stack_head->data->unitSize +=
				sizeof(uint32_t);
			context->stack_head->data->dtd = SDP_ALT32;
		}
		else if (context->stack_head->data->unitSize > UCHAR_MAX) {
			context->stack_head->data->unitSize +=
				sizeof(uint16_t);
			context->stack_head->data->dtd = SDP_ALT16;
		}
		else {
			context->stack_head->data->unitSize += sizeof(uint8_t);
		}
	}

	else if (!strcmp(el, "alternate8")) {
		context->stack_head->data->unitSize =
			compute_seq_size(context->stack_head->data);

		context->stack_head->data->unitSize += sizeof(uint8_t);

	}

	else if (!strcmp(el, "alternate16")) {
		context->stack_head->data->unitSize =
			compute_seq_size(context->stack_head->data);

		context->stack_head->data->unitSize += sizeof(uint16_t);
	}

	else if (!strcmp(el, "alternate32")) {
		context->stack_head->data->unitSize =
			compute_seq_size(context->stack_head->data);

		context->stack_head->data->unitSize += sizeof(uint32_t);
	}

	/* If we're not inside a seq or alt, then we're inside an attribute
	   which will be taken care of later
	 */
	if (context->stack_head->next &&
	    context->stack_head->data && context->stack_head->next->data) {
		switch (context->stack_head->next->data->dtd) {
		case SDP_SEQ8:
		case SDP_SEQ16:
		case SDP_SEQ32:
		case SDP_ALT8:
		case SDP_ALT16:
		case SDP_ALT32:
			context->stack_head->next->data->val.
				dataseq =
				sdp_seq_append(context->
					       stack_head->
					       next->data->
					       val.dataseq,
					       context->stack_head->data);
			context->stack_head->data = 0;
			break;
		}

		elem = context->stack_head;
		context->stack_head = context->stack_head->next;

		sdp_xml_data_free(elem);
	}
}

sdp_xml_context *sdp_xml_init_context()
{
	sdp_xml_context *context = 0;

	context = (sdp_xml_context *) malloc(sizeof(sdp_xml_context));

	if (!context)
		return NULL;

	context->parser = 0;
	context->sdprec = 0;
	context->stack_head = 0;

	context->parser = XML_ParserCreate(NULL);
	XML_SetElementHandler(context->parser, convert_xml_to_sdp_start,
			      convert_xml_to_sdp_end);
	XML_SetUserData(context->parser, context);

	if (!context->parser)
		goto fail;

	context->sdprec = sdp_record_alloc();

	if (!context->sdprec)
		goto fail;

	return context;

fail:
	fprintf(stderr, "Failed to allocated context\n");

	if (context->parser)
		free(context->parser);

	if (context->sdprec)
		sdp_record_free(context->sdprec);

	if (context)
		free(context);

	return NULL;
}

/*
    Should be called after sdp_xml_parse_chunk has been called with the
    final flag set

    Returns the resulting sdp_record_t.  The returned value will need to
    be freed by the caller by usig sdp_record_free.
*/
sdp_record_t *sdp_xml_get_record(sdp_xml_context * context)
{
	sdp_record_t *rec = context->sdprec;

	context->sdprec = 0;

	return rec;
}

/*
    Frees all data except the sdp_record if the sdp_xml_get_record was called.
    Otherwise everything is freed.
*/
void sdp_xml_free_context(sdp_xml_context * context)
{
	sdp_xml_data_t *elem;

	/* Free the stack */
	while (context->stack_head) {
		elem = context->stack_head;
		context->stack_head = elem->next;
		sdp_xml_data_free(elem);
	}

	if (context->sdprec)
		sdp_record_free(context->sdprec);
	XML_ParserFree(context->parser);
	free(context);
}

/*
    parses an XML chunk.  Returns -1 if a parse error occured, and 0
    if successful pass final as 1 if the chunk is the final chunk
*/
int sdp_xml_parse_chunk(sdp_xml_context * context, const char *data, int size,
			int final)
{
	if (!XML_Parse(context->parser, data, size, final)) {
		fprintf(stderr, "Parse error at line %d:\n%s\n",
			XML_GetCurrentLineNumber(context->parser),
			XML_ErrorString(XML_GetErrorCode(context->parser)));
		return -1;
	}

	return 0;
}

[-- Attachment #4: sdp-xml.h --]
[-- Type: text/x-chdr, Size: 1100 bytes --]

#ifndef __SDP_XML_H__
#define __SDP_XML_H__

#include <ctype.h>
#include <bluetooth/sdp.h>
#include <expat.h>

typedef struct _sdp_xml_data sdp_xml_data_t;
struct _sdp_xml_data
{
	char *text;			/* Pointer to the current buffer */
	int size;			/* Size of the current buffer */
	sdp_data_t *data;		/* The current item being built */
	sdp_xml_data_t *next;		/* Next item on the stack */
	char type;			/* 0 = Text or Hexadecimal */
};

typedef struct
{
	XML_Parser parser;		/* Parser object being used */
	sdp_record_t *sdprec;		/* SDP Record being built */
	sdp_xml_data_t *stack_head;	/* Top of the stack of attributes */
	int attrId;			/* Id of the most recently processed attribute */
} sdp_xml_context;

sdp_xml_context *sdp_xml_init_context (void);
int sdp_xml_parse_chunk(sdp_xml_context * context,
			const char *data, int size, int final);
sdp_record_t *sdp_xml_get_record(sdp_xml_context * context);
void sdp_xml_free_context(sdp_xml_context * context);

void convert_sdp_record_to_xml(sdp_record_t * rec,
			       void *userData,
			       void (*appendFunc) (void *, const char *));

#endif

[-- Attachment #5: sdptool.patch --]
[-- Type: text/x-diff, Size: 6947 bytes --]

Index: sdptool.c
===================================================================
RCS file: /cvsroot/bluez/utils/tools/sdptool.c,v
retrieving revision 1.61
diff -u -5 -r1.61 sdptool.c
--- sdptool.c	15 Oct 2006 13:07:47 -0000	1.61
+++ sdptool.c	24 Oct 2006 06:43:13 -0000
@@ -43,10 +43,12 @@
 #include <bluetooth/sdp.h>
 #include <bluetooth/sdp_lib.h>
 
 #include <netinet/in.h>
 
+#include "sdp-xml.h"
+
 #ifndef APPLE_AGENT_SVCLASS_ID
 #define APPLE_AGENT_SVCLASS_ID 0x2112
 #endif
 
 #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1)
@@ -65,10 +67,11 @@
 }
 
 #define DEFAULT_VIEW	0	/* Display only known attribute */
 #define TREE_VIEW	1	/* Display full attribute tree */
 #define RAW_VIEW	2	/* Display raw tree */
+#define XML_VIEW        3       /* Display xml tree */
 
 /* Pass args to the inquiry/search handler */
 struct search_context {
 	char		*svc;		/* Service */
 	uuid_t		group;		/* Browse group */
@@ -3168,10 +3234,78 @@
 	sdp_close(sess);
 
 	return ret;
 }
 
+#define BUFFSIZE 256
+
+static int add_xml_service(bdaddr_t *bdaddr, svc_info_t *si)
+{
+	sdp_session_t *sess;
+	int ret = -1;
+	FILE *fp;
+	char buf[BUFFSIZE];
+	sdp_xml_context *context = 0;
+	sdp_record_t *rec = 0;
+
+	if (!si->name)
+		return -1;
+
+	fp = fopen(si->name, "r");
+	if (!fp) {
+		fprintf(stderr, "Couldn't open %s\n", si->name);
+		return -1;
+	}
+
+	context = sdp_xml_init_context();
+	if (!context) {
+		fprintf(stderr, "Couldn't allocate context\n");
+		return -1;
+	}
+
+	for (;;) {
+		int done;
+		int len;
+
+		len = fread(buf, 1, BUFFSIZE, fp);
+
+		if (ferror(fp)) {
+			return -1;
+		}
+		done = feof(fp);
+
+		if (sdp_xml_parse_chunk(context, buf, len, done) != 0) {
+			return -1;
+		}
+
+		if (done)
+			break;
+	}
+
+	rec = sdp_xml_get_record(context);
+	sdp_xml_free_context(context);
+	
+	sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
+	if (!sess)
+		return -1;	
+
+	rec->handle = si->handle;
+	/* Remove the record handle attribute so SDP server assigns a new one */
+	sdp_attr_remove(rec, 0x0);
+	
+	if (sdp_record_register(sess, rec, SDP_RECORD_PERSIST) < 0)
+		fprintf(stderr, "Registration failed\n");
+
+done:
+	sdp_record_free(rec);
+		
+	free(si->name);
+	sdp_close(sess);
+
+	return ret;
+}
+
 static struct option add_options[] = {
 	{ "help",	0, 0, 'h' },
 	{ "handle",	1, 0, 'r' },
 	{ "psm",	1, 0, 'p' },
 	{ "channel",	1, 0, 'c' },
@@ -3234,10 +3368,55 @@
 	si.name = strdup(argv[0]);
 
 	return add_service(0, &si);
 }
 
+static struct option addxml_options[] = {
+	{ "help",	0, 0, 'h' },
+	{ "handle",	1, 0, 'r' },
+	{ 0, 0, 0, 0 }
+};
+
+static char *addxml_help = 
+	"Usage:\n"
+	"\tadd [--handle=RECORD_HANDLE] xmlfile\n";
+
+static int cmd_addxml(int argc, char **argv)
+{
+	svc_info_t si;
+	int opt;
+
+	memset(&si, 0, sizeof(si));
+	si.handle = 0xffffffff;
+
+	for_each_opt(opt, addxml_options, 0) {
+		switch (opt) {
+		case 'r':
+			if (strncasecmp(optarg, "0x", 2))
+				si.handle = atoi(optarg);
+			else
+				si.handle = strtol(optarg + 2, NULL, 16);
+			break;
+		default:
+			printf(addxml_help);
+			return -1;
+		}
+	}
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc < 1) {
+		printf(add_help);
+		return -1;
+	}
+
+	si.name = strdup(argv[0]);
+
+	return add_xml_service(0, &si);
+}
+
 /* Delete local service */
 static int del_service(bdaddr_t *bdaddr, void *arg)
 {
 	uint32_t handle, range = 0x0000ffff;
 	sdp_list_t *attr;
@@ -3327,10 +3506,15 @@
 
 	for (i = 0; i < count; i++)
 		handler(&ii[i].bdaddr, arg);
 }
 
+static void doprintf(void *data, const char *str)
+{
+	printf(str);
+}
+
 /*
  * Search for a specific SDP service
  */
 static int do_search(bdaddr_t *bdaddr, struct search_context *context)
 {
@@ -3381,12 +3565,15 @@
 		case TREE_VIEW:
 			/* Display full tree */
 			print_tree_attr(rec);
 			printf("\n");
 			break;
+		case XML_VIEW:
+			/* Display raw XML tree */
+			convert_sdp_record_to_xml(rec, 0, doprintf);
+			break;
 		default:
-			/* Display raw tree */
 			print_raw_attr(rec);
 			break;
 		}
 
 		if (sdp_get_group_id(rec, &sub_context.group) != -1) {
@@ -3407,10 +3594,11 @@
 
 static struct option browse_options[] = {
 	{ "help",	0, 0, 'h' },
 	{ "tree",	0, 0, 't' },
 	{ "raw",	0, 0, 'r' },
+	{ "xml",        0, 0, 'x' },
 	{ "uuid",	1, 0, 'u' },
 	{ "l2cap",	0, 0, 'l' },
 	{ 0, 0, 0, 0 }
 };
 
@@ -3438,10 +3626,13 @@
 			context.view = TREE_VIEW;
 			break;
 		case 'r':
 			context.view = RAW_VIEW;
 			break;
+		case 'x':
+			context.view = XML_VIEW;
+			break;
 		case 'u':
 			if (sscanf(optarg, "%i", &num) != 1 || num < 0 || num > 0xffff) {
 				printf("Invalid uuid %s\n", optarg);
 				return -1;
 			}
@@ -3471,10 +3662,11 @@
 static struct option search_options[] = {
 	{ "help",	0, 0, 'h' },
 	{ "bdaddr",	1, 0, 'b' },
 	{ "tree",	0, 0, 't' },
 	{ "raw",	0, 0, 'r' },
+	{ "xml",        0, 0, 'x' },
 	{ 0, 0, 0, 0}
 };
 
 static char *search_help = 
 	"Usage:\n"
@@ -3512,10 +3704,13 @@
 			context.view = TREE_VIEW;
 			break;
 		case 'r':
 			context.view = RAW_VIEW;
 			break;
+		case 'x':
+			context.view = XML_VIEW;
+			break;
 		default:
 			printf(search_help);
 			return -1;
 		}
 	}
@@ -3608,10 +3803,14 @@
 	case TREE_VIEW:
 		/* Display full tree */
 		print_tree_attr(rec);
 		printf("\n");
 		break;
+	case XML_VIEW:
+		/* Display raw XML tree */
+		convert_sdp_record_to_xml(rec, 0, doprintf);
+		break;
 	default:
 		/* Display raw tree */
 		print_raw_attr(rec);
 		break;
 	}
@@ -3622,10 +3821,11 @@
 
 static struct option records_options[] = {
 	{ "help",	0, 0, 'h' },
 	{ "tree",	0, 0, 't' },
 	{ "raw",	0, 0, 'r' },
+	{ "xml",        0, 0, 'x' },
 	{ 0, 0, 0, 0 }
 };
 
 static char *records_help = 
 	"Usage:\n"
@@ -3650,10 +3850,14 @@
 			context.view = TREE_VIEW;
 			break;
 		case 'r':
 			context.view = RAW_VIEW;
 			break;
+
+		case 'x':
+			context.view = XML_VIEW;
+			break;
 		default:
 			printf(records_help);
 			return -1;
 		}
 	}
@@ -3684,10 +3888,11 @@
 static struct option get_options[] = {
 	{ "help",	0, 0, 'h' },
 	{ "bdaddr",	1, 0, 'b' },
 	{ "tree",	0, 0, 't' },
 	{ "raw",	0, 0, 'r' },
+	{ "xml",        0, 0, 'x' },
 	{ 0, 0, 0, 0 }
 };
 
 static char *get_help = 
 	"Usage:\n"
@@ -3716,10 +3921,13 @@
 			context.view = TREE_VIEW;
 			break;
 		case 'r':
 			context.view = RAW_VIEW;
 			break;
+		case 'x':
+			context.view = XML_VIEW;
+			break;
 		default:
 			printf(get_help);
 			return -1;
 		}
 	}
@@ -3749,10 +3957,11 @@
 	{ "add",     cmd_add,         "Add local service"             },
 	{ "del",     cmd_del,         "Delete local service"          },
 	{ "get",     cmd_get,         "Get local service"             },
 	{ "setattr", cmd_setattr,     "Set/Add attribute to a SDP record"          },
 	{ "setseq",  cmd_setseq,      "Set/Add attribute sequence to a SDP record" },
+	{ "addxml",  cmd_addxml,      "Add local service (XML format)" },
 	{ 0, 0, 0 }
 };
 
 static void usage(void)
 {

[-- Attachment #6: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #7: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-24  8:13             ` Marcel Holtmann
  2006-10-24  6:47               ` Denis KENZIOR
@ 2006-10-24  7:08               ` Denis KENZIOR
  2006-10-24  9:13                 ` Marcel Holtmann
  1 sibling, 1 reply; 23+ messages in thread
From: Denis KENZIOR @ 2006-10-24  7:08 UTC (permalink / raw)
  To: BlueZ development

Marcel,

> I am also not sure that the encoding attribute is needed. If you wanna
> encode binary data in text elements (at the moment only HID does this)
> then you can use \000 style encoding to do so.

Perhaps you mean the '&#00;' style escapes?  This is feasible, except that 
expat assumes attributes do not contain raw data (it returns an array of 
const char * and assumes it is null terminated).  Thus we would need to 
switch text* (and perhaps url*?) elements to be something like:

<!ELEMENT text (#PCDATA)>

or find another parser.  

-Denis

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-24  9:16                 ` Marcel Holtmann
@ 2006-10-24  8:09                   ` Denis KENZIOR
  2006-10-24 10:17                     ` Marcel Holtmann
  0 siblings, 1 reply; 23+ messages in thread
From: Denis KENZIOR @ 2006-10-24  8:09 UTC (permalink / raw)
  To: BlueZ development

Marcel,

> > Yes, the encoding is only relevant for the <text[8,16,32]> fields.  The
> > rest of the attributes should not have it (this is hard to express in a
> > DTD.)
>
> then don't express it at all. Leave it out. An XML file can be valid
> based on its DTD, but still be rejected when stuff is not passing the
> semantic requirements.

I'd rather leave it, encoding attribute is optional anyway, and as you said 
it'll only happen for HID profile.  Might as well treat the entire thing as a 
data blob.  

> If I can get an XML parser that only deals with this specific DTD and is
> not using expat at all, I am willing to include it right away and make
> sdptool use it.

Cool.  I will be unable to work on this for a few weeks, so if nobody steps up 
till then I'll see what I can do.  In the interest of getting something 
working quickly and generating feedback, would you be willing to introduce a 
dependency on expat for hcid? The XML infrastructure really belongs in the 
new dbus API anyway.   

-Denis

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-24  5:47           ` Denis KENZIOR
@ 2006-10-24  8:13             ` Marcel Holtmann
  2006-10-24  6:47               ` Denis KENZIOR
  2006-10-24  7:08               ` Denis KENZIOR
  0 siblings, 2 replies; 23+ messages in thread
From: Marcel Holtmann @ 2006-10-24  8:13 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> Based on your feedback a new DTD specification.  Hopefully it is getting 
> closer.

looks good. However the text about hex encoded is not needed. All number
based values can be either in hex or decimal or whatever. We will use
the standard encoding to detect it. For example if it starts with 0x
then it is hex, otherwise it is decimal.

I am also not sure that the encoding attribute is needed. If you wanna
encode binary data in text elements (at the moment only HID does this)
then you can use \000 style encoding to do so.

Can also provide an example XML record for a really simple serial port
profile. This will help to see how it looks like.

Anyone willing to write a really specific and simple XML parser to
convert these XML files into sdp_record_t structures. And or course a
function that converts this structure back to XML.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-24  7:08               ` Denis KENZIOR
@ 2006-10-24  9:13                 ` Marcel Holtmann
  0 siblings, 0 replies; 23+ messages in thread
From: Marcel Holtmann @ 2006-10-24  9:13 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > I am also not sure that the encoding attribute is needed. If you wanna
> > encode binary data in text elements (at the moment only HID does this)
> > then you can use \000 style encoding to do so.
> 
> Perhaps you mean the '&#00;' style escapes?  This is feasible, except that 
> expat assumes attributes do not contain raw data (it returns an array of 
> const char * and assumes it is null terminated).  Thus we would need to 
> switch text* (and perhaps url*?) elements to be something like:
> 
> <!ELEMENT text (#PCDATA)>
> 
> or find another parser.  

we do the parsing of the string by ourself. You only have to do that for
binary strings anyway. And they are expected only in the HID profile so
far. So that shouldn't be that big problem.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-24  6:47               ` Denis KENZIOR
@ 2006-10-24  9:16                 ` Marcel Holtmann
  2006-10-24  8:09                   ` Denis KENZIOR
  2006-10-30 13:27                 ` Marcel Holtmann
  1 sibling, 1 reply; 23+ messages in thread
From: Marcel Holtmann @ 2006-10-24  9:16 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > > Based on your feedback a new DTD specification.  Hopefully it is getting
> > > closer.
> >
> > looks good. However the text about hex encoded is not needed. All number
> > based values can be either in hex or decimal or whatever. We will use
> > the standard encoding to detect it. For example if it starts with 0x
> > then it is hex, otherwise it is decimal.
> 
> Yes, the encoding is only relevant for the <text[8,16,32]> fields.  The rest 
> of the attributes should not have it (this is hard to express in a DTD.)

then don't express it at all. Leave it out. An XML file can be valid
based on its DTD, but still be rejected when stuff is not passing the
semantic requirements.

> > I am also not sure that the encoding attribute is needed. If you wanna
> > encode binary data in text elements (at the moment only HID does this)
> > then you can use \000 style encoding to do so.
> 
> This does not seem to be supported by expat, unless I'm missing something.  I 
> also want to expand encoding to eventually have a base64 option, for space 
> saving.  
> 
> How would this work, do you mean to just recognize if a character starts with 
> \0xxx - Octal
> \xx - Hex?

Use the same logic as printf() is using for example.

> > Can also provide an example XML record for a really simple serial port
> > profile. This will help to see how it looks like.
> >
> > Anyone willing to write a really specific and simple XML parser to
> > convert these XML files into sdp_record_t structures. And or course a
> > function that converts this structure back to XML.
> 
> Attached is a sample of OPUSH profile.  Attached also is the code to generate 
> one of these and parse one of these as well (you can use attached sdptool 
> patch to play with it)
> 
> The code is still pretty raw, but it should at least get us started.

If I can get an XML parser that only deals with this specific DTD and is
not using expat at all, I am willing to include it right away and make
sdptool use it.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-24  8:09                   ` Denis KENZIOR
@ 2006-10-24 10:17                     ` Marcel Holtmann
  0 siblings, 0 replies; 23+ messages in thread
From: Marcel Holtmann @ 2006-10-24 10:17 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > > Yes, the encoding is only relevant for the <text[8,16,32]> fields.  The
> > > rest of the attributes should not have it (this is hard to express in a
> > > DTD.)
> >
> > then don't express it at all. Leave it out. An XML file can be valid
> > based on its DTD, but still be rejected when stuff is not passing the
> > semantic requirements.

I prefer to leave it out now and then add it later if really needed. It
is simpler to add something than to remove it.

> I'd rather leave it, encoding attribute is optional anyway, and as you said 
> it'll only happen for HID profile.  Might as well treat the entire thing as a 
> data blob.  
> 
> > If I can get an XML parser that only deals with this specific DTD and is
> > not using expat at all, I am willing to include it right away and make
> > sdptool use it.
> 
> Cool.  I will be unable to work on this for a few weeks, so if nobody steps up 
> till then I'll see what I can do.  In the interest of getting something 
> working quickly and generating feedback, would you be willing to introduce a 
> dependency on expat for hcid? The XML infrastructure really belongs in the 
> new dbus API anyway.   

Having a temporary expat dependency is not an option am willing to go
for. However removing the code from sdptool and only put some XML
templates in a shared place seems like a good option.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-24  6:47               ` Denis KENZIOR
  2006-10-24  9:16                 ` Marcel Holtmann
@ 2006-10-30 13:27                 ` Marcel Holtmann
  2006-11-09  1:49                   ` Denis KENZIOR
  1 sibling, 1 reply; 23+ messages in thread
From: Marcel Holtmann @ 2006-10-30 13:27 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > Can also provide an example XML record for a really simple serial port
> > profile. This will help to see how it looks like.
> >
> > Anyone willing to write a really specific and simple XML parser to
> > convert these XML files into sdp_record_t structures. And or course a
> > function that converts this structure back to XML.
> 
> Attached is a sample of OPUSH profile.  Attached also is the code to generate 
> one of these and parse one of these as well (you can use attached sdptool 
> patch to play with it)
> 
> The code is still pretty raw, but it should at least get us started.

to get this started, I like to see the method

string GetRemoteServiceRecordAsXML(string address, uint32 handle)

from the org.bluez.Adapter interface gets implemented and make it using
the simple service-record.dtd I put into the CVS.

I choose to simplify the DTD a lot. After having a discussion about XML
and binary representation from the SDP part of the specification, I am
pretty certain, that we should support both. The binary representation
will cover all tasks ever possible with SDP and it is the default. For
convenience we will additionally support XML as record description, but
it will only cover up to 90% of all cases, but it will be simpler to use
and easier to understand and that should be fine.

This means that all length fields are not represented in XML. They will
be chosen automatically as needed. The same applies to the UUID. So it
leaves only int* and uint* where the actual size will be taken care of
as part of the type name.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-10-30 13:27                 ` Marcel Holtmann
@ 2006-11-09  1:49                   ` Denis KENZIOR
  2006-11-10 18:09                     ` Claudio Takahasi
  2006-11-13  6:37                     ` Marcel Holtmann
  0 siblings, 2 replies; 23+ messages in thread
From: Denis KENZIOR @ 2006-11-09  1:49 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 2428 bytes --]

Marcel,

On Monday 30 October 2006 23:27, Marcel Holtmann wrote:
> Hi Denis,
>
>
> to get this started, I like to see the method
>
> string GetRemoteServiceRecordAsXML(string address, uint32 handle)
>
> from the org.bluez.Adapter interface gets implemented and make it using
> the simple service-record.dtd I put into the CVS.

Here's a patch that imlements 

string GetRemoteServiceRecordAsXML(string address, uint32 handle)

>
> I choose to simplify the DTD a lot. After having a discussion about XML

Yes, I saw this.  I have made some changes to the DTD however.  Mainly I've 
added the int* data types and have removed the 'data' type since it was not 
used anywhere anymore.

> and binary representation from the SDP part of the specification, I am
> pretty certain, that we should support both. The binary representation
> will cover all tasks ever possible with SDP and it is the default. For
> convenience we will additionally support XML as record description, but
> it will only cover up to 90% of all cases, but it will be simpler to use
> and easier to understand and that should be fine.
>

I'm concerned about this.  BlueZ dbus developers have explicitly and 
repeatedly stated that their intent is to make the dbus interface as 
high-level as possible.  This is why the interface is so nice and easy to 
use, particularly from languages other than C.  Binary SDP record 
representation/registration just does not fit.  I would strongly encourage 
that we adopt an XML format for both view and registration of SDP records, 
and that it should be the default.

There's also the issue of GPL.  Anybody who wants to create such binary 
records and cannot link against the GPL'd libbluetooth would need to spend 
(perhaps considerable) time duplicating what is already there in order to 
produce such data structures.

> This means that all length fields are not represented in XML. They will
> be chosen automatically as needed. The same applies to the UUID. So it
> leaves only int* and uint* where the actual size will be taken care of
> as part of the type name.

I totally agree with this and this was my original thought as well.  Hopefully 
the dtd is getting closer to being finalized.  This reminds me, do you still 
want to base sdptool on XML if an appropriate (no external dependency) parser 
is written?  I don't want to spend time on this unless it is wanted and the 
DTD is stabilized.

Regards,
Denis

[-- Attachment #2: sdpxml.patch --]
[-- Type: text/x-diff, Size: 10375 bytes --]

Index: Makefile.am
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/Makefile.am,v
retrieving revision 1.59
diff --unified=5 -r1.59 Makefile.am
--- Makefile.am	1 Nov 2006 12:58:31 -0000	1.59
+++ Makefile.am	9 Nov 2006 01:11:23 -0000
@@ -23,11 +23,12 @@
 		dbus-hci.h dbus-hci.c dbus-common.c dbus-common.h \
 		dbus-error.c dbus-error.h dbus-manager.c dbus-manager.h \
 		dbus-adapter.c dbus-adapter.h \
 		dbus-device.c dbus-device.h dbus-service.c dbus-service.h \
 		dbus-security.c dbus-security.h dbus-test.c dbus-test.h \
-		dbus-sdp.c dbus-sdp.h dbus-rfcomm.c dbus-rfcomm.h
+		dbus-sdp.c dbus-sdp.h dbus-rfcomm.c dbus-rfcomm.h \
+		sdp-xml.c sdp-xml.h
 
 hcid_LDADD = @DBUS_LIBS@ @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a
 
 passkey_agent_SOURCES = passkey-agent.c
 
Index: dbus-adapter.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-adapter.c,v
retrieving revision 1.135
diff --unified=5 -r1.135 dbus-adapter.c
--- dbus-adapter.c	7 Nov 2006 20:36:10 -0000	1.135
+++ dbus-adapter.c	9 Nov 2006 01:11:24 -0000
@@ -1059,28 +1059,17 @@
 }
 
 static DBusHandlerResult adapter_get_remote_svc(DBusConnection *conn,
 						DBusMessage *msg, void *data)
 {
-	return get_remote_svc_rec(conn, msg, data);
+	return get_remote_svc_rec(conn, msg, data, SDP_FORMAT_BINARY);
 }
 
 static DBusHandlerResult adapter_get_remote_svc_xml(DBusConnection *conn,
 						DBusMessage *msg, void *data)
 {
-	DBusMessage *reply;
-	const char *result = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
-				"<record></record>";
-
-	reply = dbus_message_new_method_return(msg);
-	if (!reply)
-		return DBUS_HANDLER_RESULT_NEED_MEMORY;
-
-	dbus_message_append_args(reply, DBUS_TYPE_STRING, &result,
-					DBUS_TYPE_INVALID);
-
-	return send_message_and_unref(conn, reply);
+	return get_remote_svc_rec(conn, msg, data, SDP_FORMAT_XML);
 }
 
 static DBusHandlerResult adapter_get_remote_svc_handles(DBusConnection *conn,
 							DBusMessage *msg,
 							void *data)
Index: dbus-sdp.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.c,v
retrieving revision 1.54
diff --unified=5 -r1.54 dbus-sdp.c
--- dbus-sdp.c	1 Nov 2006 12:58:31 -0000	1.54
+++ dbus-sdp.c	9 Nov 2006 01:11:25 -0000
@@ -55,10 +55,11 @@
 #include "dbus-adapter.h"
 #include "dbus-error.h"
 #include "dbus-sdp.h"
 
 #define MAX_IDENTIFIER_LEN	29	/* "XX:XX:XX:XX:XX:XX/0xYYYYYYYY\0" */
+#define DEFAULT_XML_BUFFER_SIZE 1024
 
 struct service_provider {
 	char *owner;	/* null for remote services or unique name if local */
 	char *prov;	/* remote Bluetooth address that provides the service */
 	struct slist *lrec;
@@ -96,10 +97,37 @@
 	char            *name;
 	uint16_t        class;
 	char            *info_name;
 } sdp_service_t;
 
+typedef struct {
+	int size;
+	char *str;
+} string_t;
+
+static void append_and_grow_string(void *data, const char *str)
+{
+	string_t *string = (string_t *)data;
+	char *newbuf;
+
+	int oldlen = strlen(string->str);
+	int newlen = strlen(str);
+	
+	if ((oldlen + newlen + 1) > string->size) {
+		newbuf = (char *) malloc(string->size * 2);
+		if (!newbuf)
+			return;
+
+		memcpy(newbuf, string->str, oldlen+1);
+		string->size *= 2;
+		free(string->str);
+		string->str = newbuf;		
+	}
+
+	strcat(string->str, str);
+}
+
 /* FIXME:  move to a common file */
 sdp_service_t sdp_service[] = {
 	{ "vcp",	VIDEO_CONF_SVCLASS_ID,		"Video Conference"	},
 	{ "map",	0,				NULL			},
 	{ "pbap",	PBAP_SVCLASS_ID,		"Phone Book Access"	},
@@ -608,10 +636,80 @@
 	send_message_and_unref(ctxt->conn, reply);
 failed:
 	transaction_context_free(ctxt);
 }
 
+static void remote_svc_rec_completed_xml_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata)
+{
+	struct transaction_context *ctxt = udata;
+	sdp_record_t *rec = NULL;
+	DBusMessage *reply;
+	const char *dst;
+	int scanned;
+	string_t result;
+	
+	if (!ctxt)
+		return;
+
+	if (err == 0xffff) {
+		/* Check for protocol error or I/O error */
+		int sdp_err = sdp_get_error(ctxt->session);
+		if (sdp_err < 0) {
+			error("search failed: Invalid session!");
+			error_failed(ctxt->conn, ctxt->rq, EINVAL);
+			goto failed;
+		}
+
+		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
+		error_failed(ctxt->conn, ctxt->rq, sdp_err);
+		goto failed;
+	}
+
+	if (type == SDP_ERROR_RSP) {
+		error_sdp_failed(ctxt->conn, ctxt->rq, err);
+		goto failed;
+	}
+
+	/* check response PDU ID */
+	if (type != SDP_SVC_ATTR_RSP) {
+		error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
+		error_failed(ctxt->conn, ctxt->rq, EPROTO);
+		goto failed;
+	}
+
+	dbus_message_get_args(ctxt->rq, NULL,
+			DBUS_TYPE_STRING, &dst,
+			DBUS_TYPE_INVALID);
+
+	reply = dbus_message_new_method_return(ctxt->rq);
+
+	result.str = 0;
+	
+	rec = sdp_extract_pdu(rsp, &scanned);
+	if (rec == NULL) {
+		error("SVC REC is null");
+		goto done;
+	}
+
+	result.str = malloc(sizeof(char) * DEFAULT_XML_BUFFER_SIZE);
+	result.size = DEFAULT_XML_BUFFER_SIZE;
+	
+	sdp_cache_append(NULL, dst, rec);
+
+	convert_sdp_record_to_xml(rec, &result, append_and_grow_string);
+
+	dbus_message_append_args(reply,
+		DBUS_TYPE_STRING, &result.str,
+		DBUS_TYPE_INVALID);
+
+done:
+	send_message_and_unref(ctxt->conn, reply);
+	free(result.str);
+failed:
+	transaction_context_free(ctxt);
+}
+
 static void remote_svc_handles_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata)
 {
 	struct transaction_context *ctxt = udata;
 	DBusMessage *reply;
 	DBusMessageIter iter, array_iter;
@@ -898,28 +996,65 @@
 		sdp_list_free(attrids, NULL);
 
 	return err;
 }
 
-DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data)
+static int remote_svc_rec_conn_xml_cb(struct transaction_context *ctxt)
+{
+	sdp_list_t *attrids = NULL;
+	uint32_t range = 0x0000ffff;
+	const char *dst;
+	uint32_t handle;
+	int err = 0;
+
+	if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_xml_cb, ctxt) < 0) {
+		err = -EINVAL;
+		goto fail;
+	}
+
+	dbus_message_get_args(ctxt->rq, NULL,
+			DBUS_TYPE_STRING, &dst,
+			DBUS_TYPE_UINT32, &handle,
+			DBUS_TYPE_INVALID);
+
+	attrids = sdp_list_append(NULL, &range);
+	/* Create/send the search request and set the callback to indicate the request completion */
+	if (sdp_service_attr_async(ctxt->session, handle, SDP_ATTR_REQ_RANGE, attrids) < 0) {
+		err = -sdp_get_error(ctxt->session);
+		goto fail;
+	}
+
+fail:
+	if (attrids)
+		sdp_list_free(attrids, NULL);
+
+	return err;
+}
+
+DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data, sdp_format_t format)
 {
 	struct adapter *adapter = data;
 	const char *dst;
 	uint32_t handle;
 	int err = 0;
+	connect_cb_t *cb;
 
 	if (!dbus_message_get_args(msg, NULL,
 			DBUS_TYPE_STRING, &dst,
 			DBUS_TYPE_UINT32, &handle,
 			DBUS_TYPE_INVALID))
 		return error_invalid_arguments(conn, msg);
 
 	if (find_pending_connect(dst))
 		return error_service_search_in_progress(conn, msg);
 
+	cb = remote_svc_rec_conn_cb;
+	if (format == SDP_FORMAT_XML)
+		cb = remote_svc_rec_conn_xml_cb;
+
 	if (!connect_request(conn, msg, adapter->dev_id,
-				dst, remote_svc_rec_conn_cb, &err)) {
+				dst, cb, &err)) {
 		error("Search request failed: %s (%d)", strerror(err), err);
 		return error_failed(conn, msg, err);
 	}
 
 	return DBUS_HANDLER_RESULT_HANDLED;
Index: dbus-sdp.h
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.h,v
retrieving revision 1.1
diff --unified=5 -r1.1 dbus-sdp.h
--- dbus-sdp.h	30 Oct 2006 18:39:38 -0000	1.1
+++ dbus-sdp.h	9 Nov 2006 01:11:25 -0000
@@ -28,15 +28,20 @@
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/sdp.h>
 
 #define SDP_INTERFACE "org.bluez.SDP"
 
+typedef enum {
+	SDP_FORMAT_XML,
+	SDP_FORMAT_BINARY
+} sdp_format_t;
+
 DBusHandlerResult handle_sdp_method(DBusConnection *conn, DBusMessage *msg, void *data);
 
 DBusHandlerResult get_remote_svc_handles(DBusConnection *conn, DBusMessage *msg, void *data);
 
-DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data);
+DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data, sdp_format_t format);
 
 uint16_t sdp_str2svclass(const char *str);
 
 typedef void get_record_cb_t(sdp_record_t *rec, void *data, int err);
 
Index: service-record.dtd
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/service-record.dtd,v
retrieving revision 1.2
diff --unified=5 -r1.2 service-record.dtd
--- service-record.dtd	30 Oct 2006 14:11:16 -0000	1.2
+++ service-record.dtd	9 Nov 2006 01:11:25 -0000
@@ -1,16 +1,17 @@
 <!ELEMENT record (attribute)*>
 
-<!ELEMENT attribute (sequence|alternate|text|url|uuid|boolean|uint8|uint16|uint32|uint64|nil|data)+>
+<!ELEMENT attribute (sequence|alternate|text|url|uuid|boolean|uint8|uint16|uint32|uint64|nil)+>
 <!ATTLIST attribute id CDATA #REQUIRED>
 
-<!ELEMENT sequence (sequence|alternate|text|url|uuid|boolean|uint8|uint16|uint32|uint64|nil|data)+>
+<!ELEMENT sequence (sequence|alternate|text|url|uuid|boolean|uint8|uint16|uint32|uint64|uint128|int8|int16|int32|int64|int128|nil)+>
 
-<!ELEMENT alternate (sequence|alternate|text|url|uuid|boolean|uint8|uint16|uint32|uint64|nil|data)+>
+<!ELEMENT alternate (sequence|alternate|text|url|uuid|boolean|uint8|uint16|uint32|uint64|uint128|int8|int16|int32|int64|int128|nil)+>
 
 <!ELEMENT text EMPTY>
 <!ATTLIST text value CDATA #REQUIRED>
+<!ATTLIST text encoding (normal|hex) "normal">
 
 <!ELEMENT url EMPTY>
 <!ATTLIST url value CDATA #REQUIRED>
 
 <!ELEMENT uuid EMPTY>
@@ -29,10 +30,24 @@
 <!ATTLIST uint32 value CDATA #REQUIRED>
 
 <!ELEMENT uint64 EMPTY>
 <!ATTLIST uint64 value CDATA #REQUIRED>
 
-<!ELEMENT nil EMPTY>
+<!ELEMENT uint128 EMPTY>
+<!ATTLIST uint128 value CDATA #REQUIRED>
+
+<!ELEMENT int8 EMPTY>
+<!ATTLIST int8 value CDATA #REQUIRED>
+
+<!ELEMENT int16 EMPTY>
+<!ATTLIST int16 value CDATA #REQUIRED>
+
+<!ELEMENT int32 EMPTY>
+<!ATTLIST int32 value CDATA #REQUIRED>
 
-<!ELEMENT data EMPTY>
-<!ATTLIST data type CDATA #REQUIRED>
-<!ATTLIST data value CDATA #REQUIRED>
+<!ELEMENT int64 EMPTY>
+<!ATTLIST int64 value CDATA #REQUIRED>
+
+<!ELEMENT int128 EMPTY>
+<!ATTLIST int128 value CDATA #REQUIRED>
+
+<!ELEMENT nil EMPTY>

[-- Attachment #3: sdp-xml.h --]
[-- Type: text/x-chdr, Size: 231 bytes --]

#ifndef __SDP_XML_H__
#define __SDP_XML_H__

#include <ctype.h>
#include <bluetooth/sdp.h>

void convert_sdp_record_to_xml(sdp_record_t * rec,
			       void *userData,
			       void (*appendFunc) (void *, const char *));

#endif

[-- Attachment #4: sdp-xml.c --]
[-- Type: text/x-csrc, Size: 9038 bytes --]

#include "sdp-xml.h"

#include <stdio.h>
#include <string.h>
#include <bluetooth/sdp_lib.h>
#include <malloc.h>
#include <limits.h>

#define STRBUFSIZE 256
#define MAXINDENT 64

static void convert_raw_data_to_xml(sdp_data_t *value, int indent_level,
				    void *data,
				    void (*appender) (void *, const char *))
{
	int i, hex;
	char buf[STRBUFSIZE];
	char indent[MAXINDENT];
	char next_indent[MAXINDENT];

	if (!value)
		return;

	if (indent_level >= MAXINDENT)
		indent_level = MAXINDENT - 2;

	for (i = 0; i < indent_level; i++) {
		indent[i] = '\t';
		next_indent[i] = '\t';
	}

	indent[i] = '\0';
	next_indent[i] = '\t';
	next_indent[i + 1] = '\0';

	buf[STRBUFSIZE - 1] = '\0';

	switch (value->dtd) {
	case SDP_DATA_NIL:
		appender(data, indent);
		appender(data, "<nil/>\n");
		break;
	case SDP_BOOL:
		appender(data, indent);
		appender(data, "<boolean value=\"");
		appender(data, value->val.uint8 ? "true" : "false");
		appender(data, "\" />\n");
		break;
	case SDP_UINT8:
		appender(data, indent);
		appender(data, "<uint8 value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%02x", value->val.uint8);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_UINT16:
		appender(data, indent);
		appender(data, "<uint16 value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%04x", value->val.uint16);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_UINT32:
		appender(data, indent);
		appender(data, "<uint32 value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%08x", value->val.uint32);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_UINT64:
		appender(data, indent);
		appender(data, "<uint64 value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%016jx", value->val.uint64);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_UINT128:
		appender(data, indent);
		appender(data, "<uint128 value=\"");

		for (i = 0; i < 16; i++) {
			sprintf(&buf[i * 2], "%02x",
				(unsigned char) value->val.uint128.data[i]);
		}

		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_INT8:
		appender(data, indent);
		appender(data, "<int8 value=\"");
		snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int8);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_INT16:
		appender(data, indent);
		appender(data, "<int16 value=\"");
		snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int16);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_INT32:
		appender(data, indent);
		appender(data, "<int32 value=\"");
		snprintf(buf, STRBUFSIZE - 1, "%d", value->val.int32);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_INT64:
		appender(data, indent);
		appender(data, "<int64 value=\"");
		snprintf(buf, STRBUFSIZE - 1, "%jd", value->val.int64);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_INT128:
		appender(data, indent);
		appender(data, "<int128 value=\"");

		for (i = 0; i < 16; i++) {
			sprintf(&buf[i * 2], "%02x",
				(unsigned char) value->val.int128.data[i]);
		}
		appender(data, buf);

		appender(data, "\" />\n");
		break;
	case SDP_UUID16:
		appender(data, indent);
		appender(data, "<uuid value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%04x",
			 value->val.uuid.value.uuid16);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_UUID32:
		appender(data, indent);
		appender(data, "<uuid value=\"");
		snprintf(buf, STRBUFSIZE - 1, "0x%08x",
			 value->val.uuid.value.uuid32);
		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_UUID128:
		appender(data, indent);
		appender(data, "<uuid value=\"");

		snprintf(buf, STRBUFSIZE - 1,
			 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[0],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[1],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[2],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[3],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[4],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[5],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[6],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[7],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[8],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[9],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[10],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[11],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[12],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[13],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[14],
			 (unsigned char) value->val.uuid.value.
			 uuid128.data[15]);

		appender(data, buf);
		appender(data, "\" />\n");
		break;
	case SDP_TEXT_STR8:
	case SDP_TEXT_STR16:
	case SDP_TEXT_STR32:
	{
		hex = 0;

		int num_chars_to_escape = 0;
		
		for (i = 0; i < value->unitSize; i++) {
			if (i == (value->unitSize - 1)
			    && value->val.str[i] == '\0')
				break;
			if (!isprint(value->val.str[i])) {
				hex = 1;
				break;
			}
			
			/* XML is evil, must do this... */
			if ((value->val.str[i] == '<') ||
			    (value->val.str[i] == '>') ||
			    (value->val.str[i] == '"') ||
			    (value->val.str[i] == '&'))
			    num_chars_to_escape++;
			
		}
		
		appender(data, indent);

		appender(data, "<text ");

		char *strBuf = 0;

		if (hex) {
			appender(data, "encoding=\"hex\" ");
			strBuf = (char *) malloc(sizeof(char)
						 * (value->unitSize * 2 + 1));

			/* Unit Size seems to include the size for dtd
			   It is thus off by 1
			   This is safe for Normal strings, but not
			   hex encoded data */
			for (i = 0; i < (value->unitSize-1); i++)
				sprintf(&strBuf[i * sizeof (char) * 2],
					"%02x",
					(unsigned char) value->val.str[i]);

			strBuf[value->unitSize * 2] = '\0';
		}
		else {
			int j;
			/* escape the XML disallowed chars */
			strBuf = (char *)
				malloc(sizeof(char) *
				(value->unitSize + 1 + num_chars_to_escape * 4));
			for (i = 0, j = 0; i < value->unitSize; i++) {
				if (value->val.str[i] == '&') {
					strBuf[j++] = '&';
					strBuf[j++] = 'a';
					strBuf[j++] = 'm';
					strBuf[j++] = 'p';
				}
				else if (value->val.str[i] == '<') {
					strBuf[j++] = '&';
					strBuf[j++] = 'l';
					strBuf[j++] = 't';
				}
				else if (value->val.str[i] == '>') {
					strBuf[j++] = '&';
					strBuf[j++] = 'g';
					strBuf[j++] = 't';
				}
				else if (value->val.str[i] == '"') {
					strBuf[j++] = '&';
					strBuf[j++] = 'q';
					strBuf[j++] = 'u';
					strBuf[j++] = 'o';
					strBuf[j++] = 't';
				}
				else {
					strBuf[j++] = value->val.str[i];
				}
			}

			strBuf[j] = '\0';
		}

		appender(data, "value=\"");
		appender(data, strBuf);
		appender(data, "\" />\n");
		free(strBuf);
		break;
	}
	case SDP_URL_STR8:
	case SDP_URL_STR16:
	case SDP_URL_STR32:
		appender(data, indent);
		appender(data, "<url value=\"");
		appender(data, value->val.str);
		appender(data, "\" />\n");
		break;
	case SDP_SEQ8:
	case SDP_SEQ16:
	case SDP_SEQ32:
		appender(data, indent);
		appender(data, "<sequence>\n");

		convert_raw_data_to_xml(value->val.dataseq,
					indent_level + 1, data,
					appender);
					
		appender(data, indent);
		appender(data, "</sequence>\n");
		
		break;
	case SDP_ALT8:
	case SDP_ALT16:
	case SDP_ALT32:
		appender(data, indent);

		appender(data, "<alternate>\n");

		convert_raw_data_to_xml(value->val.dataseq,
					indent_level + 1, data,
					appender);
		appender(data, indent);

		appender(data, "</alternate>\n");
	       
		break;
	default:
		break;
	}

	convert_raw_data_to_xml(value->next, indent_level, data,
				appender);
}

struct conversion_data
{
	void *data;
	void (*appender) (void *data, const char *);
};

static void convert_raw_attr_to_xml_func(void *val, void *data)
{
	struct conversion_data *cd = (struct conversion_data *) data;
	sdp_data_t *value = (sdp_data_t *) val;
	char buf[STRBUFSIZE];

	buf[STRBUFSIZE - 1] = '\0';
	snprintf(buf, STRBUFSIZE - 1, "\t<attribute id=\"0x%04x\">\n",
		 value->attrId);
	cd->appender(cd->data, buf);

	if (data)
		convert_raw_data_to_xml(value, 2, cd->data,
					cd->appender);
	else
		cd->appender(cd->data, "\t\tNULL\n");

	cd->appender(cd->data, "\t</attribute>\n");
}

/*
    Will convert the sdp record to XML.  The appender and data can be used
    to control where to output the record (e.g. file or a data buffer).  The
    appender will be called repeatedly with data and the character buffer
    (containing parts of the generated XML) to append.
*/
void convert_sdp_record_to_xml(sdp_record_t *rec,
			       void *data,
			       void (*appender) (void *, const char *))
{
	struct conversion_data cd;

	cd.data = data;
	cd.appender = appender;

	if (rec && rec->attrlist) {
		appender(data, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n");
		appender(data, "<record>\n");
		sdp_list_foreach(rec->attrlist,
				 convert_raw_attr_to_xml_func, &cd);
		appender(data, "</record>\n");
	}
}

[-- Attachment #5: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #6: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-11-09  1:49                   ` Denis KENZIOR
@ 2006-11-10 18:09                     ` Claudio Takahasi
  2006-11-10 21:38                       ` Claudio Takahasi
  2006-11-13  6:37                     ` Marcel Holtmann
  1 sibling, 1 reply; 23+ messages in thread
From: Claudio Takahasi @ 2006-11-10 18:09 UTC (permalink / raw)
  To: BlueZ development

On 11/8/06, Denis KENZIOR <denis.kenzior@trolltech.com> wrote:
> Marcel,
>
> On Monday 30 October 2006 23:27, Marcel Holtmann wrote:
> > Hi Denis,
> >
> >
> > to get this started, I like to see the method
> >
> > string GetRemoteServiceRecordAsXML(string address, uint32 handle)
> >
> > from the org.bluez.Adapter interface gets implemented and make it using
> > the simple service-record.dtd I put into the CVS.
>
> Here's a patch that imlements
>
> string GetRemoteServiceRecordAsXML(string address, uint32 handle)
>
> >
> > I choose to simplify the DTD a lot. After having a discussion about XML
>
> Yes, I saw this.  I have made some changes to the DTD however.  Mainly I've
> added the int* data types and have removed the 'data' type since it was not
> used anywhere anymore.
>
> > and binary representation from the SDP part of the specification, I am
> > pretty certain, that we should support both. The binary representation
> > will cover all tasks ever possible with SDP and it is the default. For
> > convenience we will additionally support XML as record description, but
> > it will only cover up to 90% of all cases, but it will be simpler to use
> > and easier to understand and that should be fine.
> >
>
> I'm concerned about this.  BlueZ dbus developers have explicitly and
> repeatedly stated that their intent is to make the dbus interface as
> high-level as possible.  This is why the interface is so nice and easy to
> use, particularly from languages other than C.  Binary SDP record
> representation/registration just does not fit.  I would strongly encourage
> that we adopt an XML format for both view and registration of SDP records,
> and that it should be the default.
>
> There's also the issue of GPL.  Anybody who wants to create such binary
> records and cannot link against the GPL'd libbluetooth would need to spend
> (perhaps considerable) time duplicating what is already there in order to
> produce such data structures.
>
> > This means that all length fields are not represented in XML. They will
> > be chosen automatically as needed. The same applies to the UUID. So it
> > leaves only int* and uint* where the actual size will be taken care of
> > as part of the type name.
>
> I totally agree with this and this was my original thought as well.  Hopefully
> the dtd is getting closer to being finalized.  This reminds me, do you still
> want to base sdptool on XML if an appropriate (no external dependency) parser
> is written?  I don't want to spend time on this unless it is wanted and the
> DTD is stabilized.
>
> Regards,
> Denis
>
>
> -------------------------------------------------------------------------
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job easier
> Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
>
> _______________________________________________
> Bluez-devel mailing list
> Bluez-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/bluez-devel
>
>
>
>

Hi Denis,

the patch is in cvs now!

The sdp-xml.* were moved to common directory.

Some points to be improved:
1. append_and_grow_string: avoid a lot of strlen calls and string copy
2. Analyze if it is possible use sdp_buf_t instead of string_t
3. I got some system bus disconnection messages when calling
GetRemoteServiceRecordAsXML consecutively. We need fix this bug.

BR,
Claudio.
-- 
---------------------------------------------------------
Claudio Takahasi
Instituto Nokia de Tecnologia - INdT

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-11-10 18:09                     ` Claudio Takahasi
@ 2006-11-10 21:38                       ` Claudio Takahasi
  2006-11-13  1:14                         ` Denis KENZIOR
  0 siblings, 1 reply; 23+ messages in thread
From: Claudio Takahasi @ 2006-11-10 21:38 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 4076 bytes --]

On 11/10/06, Claudio Takahasi <cktakahasi@gmail.com> wrote:
> On 11/8/06, Denis KENZIOR <denis.kenzior@trolltech.com> wrote:
> > Marcel,
> >
> > On Monday 30 October 2006 23:27, Marcel Holtmann wrote:
> > > Hi Denis,
> > >
> > >
> > > to get this started, I like to see the method
> > >
> > > string GetRemoteServiceRecordAsXML(string address, uint32 handle)
> > >
> > > from the org.bluez.Adapter interface gets implemented and make it using
> > > the simple service-record.dtd I put into the CVS.
> >
> > Here's a patch that imlements
> >
> > string GetRemoteServiceRecordAsXML(string address, uint32 handle)
> >
> > >
> > > I choose to simplify the DTD a lot. After having a discussion about XML
> >
> > Yes, I saw this.  I have made some changes to the DTD however.  Mainly I've
> > added the int* data types and have removed the 'data' type since it was not
> > used anywhere anymore.
> >
> > > and binary representation from the SDP part of the specification, I am
> > > pretty certain, that we should support both. The binary representation
> > > will cover all tasks ever possible with SDP and it is the default. For
> > > convenience we will additionally support XML as record description, but
> > > it will only cover up to 90% of all cases, but it will be simpler to use
> > > and easier to understand and that should be fine.
> > >
> >
> > I'm concerned about this.  BlueZ dbus developers have explicitly and
> > repeatedly stated that their intent is to make the dbus interface as
> > high-level as possible.  This is why the interface is so nice and easy to
> > use, particularly from languages other than C.  Binary SDP record
> > representation/registration just does not fit.  I would strongly encourage
> > that we adopt an XML format for both view and registration of SDP records,
> > and that it should be the default.
> >
> > There's also the issue of GPL.  Anybody who wants to create such binary
> > records and cannot link against the GPL'd libbluetooth would need to spend
> > (perhaps considerable) time duplicating what is already there in order to
> > produce such data structures.
> >
> > > This means that all length fields are not represented in XML. They will
> > > be chosen automatically as needed. The same applies to the UUID. So it
> > > leaves only int* and uint* where the actual size will be taken care of
> > > as part of the type name.
> >
> > I totally agree with this and this was my original thought as well.  Hopefully
> > the dtd is getting closer to being finalized.  This reminds me, do you still
> > want to base sdptool on XML if an appropriate (no external dependency) parser
> > is written?  I don't want to spend time on this unless it is wanted and the
> > DTD is stabilized.
> >
> > Regards,
> > Denis
> >
> >
> > -------------------------------------------------------------------------
> > Using Tomcat but need to do more? Need to support web services, security?
> > Get stuff done quickly with pre-integrated technology to make your job easier
> > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> >
> > _______________________________________________
> > Bluez-devel mailing list
> > Bluez-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/bluez-devel
> >
> >
> >
> >
>
> Hi Denis,
>
> the patch is in cvs now!
>
> The sdp-xml.* were moved to common directory.
>
> Some points to be improved:
> 1. append_and_grow_string: avoid a lot of strlen calls and string copy
> 2. Analyze if it is possible use sdp_buf_t instead of string_t
> 3. I got some system bus disconnection messages when calling
> GetRemoteServiceRecordAsXML consecutively. We need fix this bug.
>
> BR,
> Claudio.
> --

Hi Marcel, Denis,

this patch replaces string_t by sdp_buf_t and fix system bus
disconnection problem. Check if this patch make sense or if it is
better keep  string_t.

BR,
Claudio
-- 
---------------------------------------------------------
Claudio Takahasi
Instituto Nokia de Tecnologia - INdT

[-- Attachment #2: remove_string_t.patch --]
[-- Type: text/x-patch, Size: 2532 bytes --]

Index: hcid/dbus-sdp.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.c,v
retrieving revision 1.55
diff -u -r1.55 dbus-sdp.c
--- hcid/dbus-sdp.c	10 Nov 2006 17:59:15 -0000	1.55
+++ hcid/dbus-sdp.c	10 Nov 2006 21:21:03 -0000
@@ -58,7 +58,6 @@
 #include "sdp-xml.h"
 
 #define MAX_IDENTIFIER_LEN	29	/* "XX:XX:XX:XX:XX:XX/0xYYYYYYYY\0" */
-#define DEFAULT_XML_BUFFER_SIZE 1024
 
 struct service_provider {
 	char *owner;	/* null for remote services or unique name if local */
@@ -100,31 +99,26 @@
 	char            *info_name;
 } sdp_service_t;
 
-typedef struct {
-	int size;
-	char *str;
-} string_t;
-
 static void append_and_grow_string(void *data, const char *str)
 {
-	string_t *string = (string_t *)data;
-	char *newbuf;
+	sdp_buf_t *buff = (sdp_buf_t *) data;
+	int len;
 
-	int oldlen = strlen(string->str);
-	int newlen = strlen(str);
-	
-	if ((oldlen + newlen + 1) > string->size) {
-		newbuf = (char *) malloc(string->size * 2);
-		if (!newbuf)
-			return;
+	len = strlen(str);
 
-		memcpy(newbuf, string->str, oldlen+1);
-		string->size *= 2;
-		free(string->str);
-		string->str = newbuf;		
+	if (buff->buf_size < (buff->data_size + len + 1)) {
+		if (!buff->buf_size)
+			buff->buf_size = 1;
+
+		buff->buf_size += len;
+		buff->data = realloc(buff->data, buff->buf_size);
+		if (!buff->data)
+			return;
 	}
 
-	strcat(string->str, str);
+	/* Include the NULL character */
+	memcpy(buff->data + buff->data_size, str, len + 1);
+	buff->data_size += len;
 }
 
 /* FIXME:  move to a common file */
@@ -648,8 +642,8 @@
 	DBusMessage *reply;
 	const char *dst;
 	int scanned;
-	string_t result;
-	
+	sdp_buf_t result;
+
 	if (!ctxt)
 		return;
 
@@ -685,7 +679,6 @@
 
 	reply = dbus_message_new_method_return(ctxt->rq);
 
-	result.str = 0;
 	
 	rec = sdp_extract_pdu(rsp, &scanned);
 	if (rec == NULL) {
@@ -693,20 +686,21 @@
 		goto done;
 	}
 
-	result.str = malloc(sizeof(char) * DEFAULT_XML_BUFFER_SIZE);
-	result.size = DEFAULT_XML_BUFFER_SIZE;
-	
+	memset(&result, 0, sizeof(sdp_buf_t));
+
 	sdp_cache_append(NULL, dst, rec);
 
 	convert_sdp_record_to_xml(rec, &result, append_and_grow_string);
 
-	dbus_message_append_args(reply,
-		DBUS_TYPE_STRING, &result.str,
-		DBUS_TYPE_INVALID);
+	if (result.data) {
+		dbus_message_append_args(reply,
+				DBUS_TYPE_STRING, &result.data,
+				DBUS_TYPE_INVALID);
 
+		free(result.data);
+	}
 done:
 	send_message_and_unref(ctxt->conn, reply);
-	free(result.str);
 failed:
 	transaction_context_free(ctxt);
 }

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-11-10 21:38                       ` Claudio Takahasi
@ 2006-11-13  1:14                         ` Denis KENZIOR
  2006-11-13  6:21                           ` Marcel Holtmann
  0 siblings, 1 reply; 23+ messages in thread
From: Denis KENZIOR @ 2006-11-13  1:14 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 1001 bytes --]

Claudio,

> >
> > Hi Denis,
> >
> > the patch is in cvs now!
> >
> > The sdp-xml.* were moved to common directory.
> >
> > Some points to be improved:
> > 1. append_and_grow_string: avoid a lot of strlen calls and string copy
> > 2. Analyze if it is possible use sdp_buf_t instead of string_t
> > 3. I got some system bus disconnection messages when calling
> > GetRemoteServiceRecordAsXML consecutively. We need fix this bug.
> >
> > BR,
> > Claudio.
> > --
>
> Hi Marcel, Denis,
>
> this patch replaces string_t by sdp_buf_t and fix system bus
> disconnection problem. Check if this patch make sense or if it is
> better keep  string_t.

I agree we should replace string_t by sdp_buf_t since this avoids an extra 
strlen.  However, I think that the buffer should be grown by factors.  Your  
proposed solution would call realloc many times, as the append function is 
called quite frequently with small strings, but this is no biggie.

Would the attached patch be better?

>
> BR,
> Claudio

-Denis

[-- Attachment #2: remove_string_t_2.patch --]
[-- Type: text/x-diff, Size: 3329 bytes --]

Index: dbus-sdp.c
===================================================================
RCS file: /cvsroot/bluez/utils/hcid/dbus-sdp.c,v
retrieving revision 1.55
diff -u -5 -r1.55 dbus-sdp.c
--- dbus-sdp.c	10 Nov 2006 17:59:15 -0000	1.55
+++ dbus-sdp.c	13 Nov 2006 00:54:20 -0000
@@ -56,11 +56,11 @@
 #include "dbus-error.h"
 #include "dbus-sdp.h"
 #include "sdp-xml.h"
 
 #define MAX_IDENTIFIER_LEN	29	/* "XX:XX:XX:XX:XX:XX/0xYYYYYYYY\0" */
-#define DEFAULT_XML_BUFFER_SIZE 1024
+#define DEFAULT_XML_BUF_SIZE	1024
 
 struct service_provider {
 	char *owner;	/* null for remote services or unique name if local */
 	char *prov;	/* remote Bluetooth address that provides the service */
 	struct slist *lrec;
@@ -98,35 +98,37 @@
 	char            *name;
 	uint16_t        class;
 	char            *info_name;
 } sdp_service_t;
 
-typedef struct {
-	int size;
-	char *str;
-} string_t;
-
 static void append_and_grow_string(void *data, const char *str)
 {
-	string_t *string = (string_t *)data;
-	char *newbuf;
+	sdp_buf_t *buff = (sdp_buf_t *) data;
+	int len;
 
-	int oldlen = strlen(string->str);
-	int newlen = strlen(str);
-	
-	if ((oldlen + newlen + 1) > string->size) {
-		newbuf = (char *) malloc(string->size * 2);
-		if (!newbuf)
+	len = strlen(str);
+
+	if (!buff->data) {
+		buff->buf_size = DEFAULT_XML_BUF_SIZE;
+		buff->data = realloc(buff->data, buff->buf_size);
+		if (!buff->data)
 			return;
+	}
+
+	/* Grow string */
+	while (buff->buf_size < (buff->data_size + len + 1)) {
+		/* Grow buffer by a factor of 2 */
+		buff->buf_size = (buff->buf_size << 1);
 
-		memcpy(newbuf, string->str, oldlen+1);
-		string->size *= 2;
-		free(string->str);
-		string->str = newbuf;		
+		buff->data = realloc(buff->data, buff->buf_size);
+		if (!buff->data)
+			return;
 	}
 
-	strcat(string->str, str);
+	/* Include the NULL character */
+	memcpy(buff->data + buff->data_size, str, len + 1);
+	buff->data_size += len;
 }
 
 /* FIXME:  move to a common file */
 sdp_service_t sdp_service[] = {
 	{ "vcp",	VIDEO_CONF_SVCLASS_ID,		"Video Conference"	},
@@ -646,12 +648,12 @@
 	struct transaction_context *ctxt = udata;
 	sdp_record_t *rec = NULL;
 	DBusMessage *reply;
 	const char *dst;
 	int scanned;
-	string_t result;
-	
+	sdp_buf_t result;
+
 	if (!ctxt)
 		return;
 
 	if (err == 0xffff) {
 		/* Check for protocol error or I/O error */
@@ -683,32 +685,32 @@
 			DBUS_TYPE_STRING, &dst,
 			DBUS_TYPE_INVALID);
 
 	reply = dbus_message_new_method_return(ctxt->rq);
 
-	result.str = 0;
 	
 	rec = sdp_extract_pdu(rsp, &scanned);
 	if (rec == NULL) {
 		error("SVC REC is null");
 		goto done;
 	}
 
-	result.str = malloc(sizeof(char) * DEFAULT_XML_BUFFER_SIZE);
-	result.size = DEFAULT_XML_BUFFER_SIZE;
-	
+	memset(&result, 0, sizeof(sdp_buf_t));
+
 	sdp_cache_append(NULL, dst, rec);
 
 	convert_sdp_record_to_xml(rec, &result, append_and_grow_string);
 
-	dbus_message_append_args(reply,
-		DBUS_TYPE_STRING, &result.str,
-		DBUS_TYPE_INVALID);
+	if (result.data) {
+		dbus_message_append_args(reply,
+				DBUS_TYPE_STRING, &result.data,
+				DBUS_TYPE_INVALID);
 
+		free(result.data);
+	}
 done:
 	send_message_and_unref(ctxt->conn, reply);
-	free(result.str);
 failed:
 	transaction_context_free(ctxt);
 }
 
 static void remote_svc_handles_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata)

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-11-13  1:14                         ` Denis KENZIOR
@ 2006-11-13  6:21                           ` Marcel Holtmann
  0 siblings, 0 replies; 23+ messages in thread
From: Marcel Holtmann @ 2006-11-13  6:21 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > this patch replaces string_t by sdp_buf_t and fix system bus
> > disconnection problem. Check if this patch make sense or if it is
> > better keep  string_t.
> 
> I agree we should replace string_t by sdp_buf_t since this avoids an extra 
> strlen.  However, I think that the buffer should be grown by factors.  Your  
> proposed solution would call realloc many times, as the append function is 
> called quite frequently with small strings, but this is no biggie.
> 
> Would the attached patch be better?

looks good to me.

Claudio, please review it and then commit this to the CVS.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-11-09  1:49                   ` Denis KENZIOR
  2006-11-10 18:09                     ` Claudio Takahasi
@ 2006-11-13  6:37                     ` Marcel Holtmann
  2006-11-13  7:03                       ` Denis KENZIOR
  1 sibling, 1 reply; 23+ messages in thread
From: Marcel Holtmann @ 2006-11-13  6:37 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > to get this started, I like to see the method
> >
> > string GetRemoteServiceRecordAsXML(string address, uint32 handle)
> >
> > from the org.bluez.Adapter interface gets implemented and make it using
> > the simple service-record.dtd I put into the CVS.
> 
> Here's a patch that imlements 
> 
> string GetRemoteServiceRecordAsXML(string address, uint32 handle)
> 
> >
> > I choose to simplify the DTD a lot. After having a discussion about XML
> 
> Yes, I saw this.  I have made some changes to the DTD however.  Mainly I've 
> added the int* data types and have removed the 'data' type since it was not 
> used anywhere anymore.

I simply was too lazy to do the full conversion. Thanks for fixing my
laziness ;)

The only thing that I am not fully agree with is the encoding attribute
for string. I have to check up on the best way to achieve the support of
binary strings.

> > and binary representation from the SDP part of the specification, I am
> > pretty certain, that we should support both. The binary representation
> > will cover all tasks ever possible with SDP and it is the default. For
> > convenience we will additionally support XML as record description, but
> > it will only cover up to 90% of all cases, but it will be simpler to use
> > and easier to understand and that should be fine.
> >
> 
> I'm concerned about this.  BlueZ dbus developers have explicitly and 
> repeatedly stated that their intent is to make the dbus interface as 
> high-level as possible.  This is why the interface is so nice and easy to 
> use, particularly from languages other than C.  Binary SDP record 
> representation/registration just does not fit.  I would strongly encourage 
> that we adopt an XML format for both view and registration of SDP records, 
> and that it should be the default.

The current XML format is for both, but it makes some assumptions and
simplifications. In 99% of the use cases this is enough and for the
other 1% you have to deal with the binary format. And this is totally
fine in case of easy use.

> There's also the issue of GPL.  Anybody who wants to create such binary 
> records and cannot link against the GPL'd libbluetooth would need to spend 
> (perhaps considerable) time duplicating what is already there in order to 
> produce such data structures.

You can pre-calculate these binary blobs. And yes, in case you really
need to have full control you have to obey to the GPL or re-write the
binary SDP parser from scratch. I have no problem with that and actually
I don't care. The support of binary only software is definitely not my
top priority.

> > This means that all length fields are not represented in XML. They will
> > be chosen automatically as needed. The same applies to the UUID. So it
> > leaves only int* and uint* where the actual size will be taken care of
> > as part of the type name.
> 
> I totally agree with this and this was my original thought as well.  Hopefully 
> the dtd is getting closer to being finalized.  This reminds me, do you still 
> want to base sdptool on XML if an appropriate (no external dependency) parser 
> is written?  I don't want to spend time on this unless it is wanted and the 
> DTD is stabilized.

Actually it should be enough to have support for libexpat and libxml2
since one of these is required by D-Bus anyway. So I would start with
libexpat for now. It should be common/sdp-expat.c and I will create the
autoconf magic around it.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-11-13  6:37                     ` Marcel Holtmann
@ 2006-11-13  7:03                       ` Denis KENZIOR
  2006-11-13  7:17                         ` Marcel Holtmann
  0 siblings, 1 reply; 23+ messages in thread
From: Denis KENZIOR @ 2006-11-13  7:03 UTC (permalink / raw)
  To: BlueZ development

Marcel,

> I simply was too lazy to do the full conversion. Thanks for fixing my
> laziness ;)
>
> The only thing that I am not fully agree with is the encoding attribute
> for string. I have to check up on the best way to achieve the support of
> binary strings.
>

>>From what I read, this is the preferred way, but I'm definitely open to 
suggestions.

> The current XML format is for both, but it makes some assumptions and
> simplifications. In 99% of the use cases this is enough and for the
> other 1% you have to deal with the binary format. And this is totally
> fine in case of easy use.

Ok, cool.  I'm just worried about code duplication and maintenance of multiple 
formats.  E.g. looking at the new service framework (which is something that 
we're very interested in for instance), it takes a binary formatted sdp 
record.  Would there also be a version for XML?  

> Actually it should be enough to have support for libexpat and libxml2
> since one of these is required by D-Bus anyway. So I would start with
> libexpat for now. It should be common/sdp-expat.c and I will create the
> autoconf magic around it.

Ok, I will work on a parser based on expat.

Regards,
-Denis

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Bluez-devel] Proposed DTD
  2006-11-13  7:03                       ` Denis KENZIOR
@ 2006-11-13  7:17                         ` Marcel Holtmann
  0 siblings, 0 replies; 23+ messages in thread
From: Marcel Holtmann @ 2006-11-13  7:17 UTC (permalink / raw)
  To: BlueZ development

Hi Denis,

> > The current XML format is for both, but it makes some assumptions and
> > simplifications. In 99% of the use cases this is enough and for the
> > other 1% you have to deal with the binary format. And this is totally
> > fine in case of easy use.
> 
> Ok, cool.  I'm just worried about code duplication and maintenance of multiple 
> formats.  E.g. looking at the new service framework (which is something that 
> we're very interested in for instance), it takes a binary formatted sdp 
> record.  Would there also be a version for XML?  

yes, there will be a XML version for registering SDP records. However
someone has to write it.

> > Actually it should be enough to have support for libexpat and libxml2
> > since one of these is required by D-Bus anyway. So I would start with
> > libexpat for now. It should be common/sdp-expat.c and I will create the
> > autoconf magic around it.
> 
> Ok, I will work on a parser based on expat.

Add the function prototypes to common/sdp-xml.h and the actual
implementation to common/sdp-expat.c and an implementation that returns
an error to common/sdp-dummy.c to make it compile with systems where the
Expat library is not available.

Regards

Marcel



-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2006-11-13  7:17 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-23  0:25 [Bluez-devel] Proposed DTD Denis KENZIOR
2006-10-23  3:13 ` Marcel Holtmann
2006-10-23  3:59   ` Denis KENZIOR
2006-10-23  4:11     ` Marcel Holtmann
2006-10-23  4:31       ` Denis KENZIOR
2006-10-23  7:27         ` Marcel Holtmann
2006-10-24  5:47           ` Denis KENZIOR
2006-10-24  8:13             ` Marcel Holtmann
2006-10-24  6:47               ` Denis KENZIOR
2006-10-24  9:16                 ` Marcel Holtmann
2006-10-24  8:09                   ` Denis KENZIOR
2006-10-24 10:17                     ` Marcel Holtmann
2006-10-30 13:27                 ` Marcel Holtmann
2006-11-09  1:49                   ` Denis KENZIOR
2006-11-10 18:09                     ` Claudio Takahasi
2006-11-10 21:38                       ` Claudio Takahasi
2006-11-13  1:14                         ` Denis KENZIOR
2006-11-13  6:21                           ` Marcel Holtmann
2006-11-13  6:37                     ` Marcel Holtmann
2006-11-13  7:03                       ` Denis KENZIOR
2006-11-13  7:17                         ` Marcel Holtmann
2006-10-24  7:08               ` Denis KENZIOR
2006-10-24  9:13                 ` Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox