Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

patch to make obexapp work with BSD iconv(3)

8 views
Skip to first unread message

Matthias Drochner

unread,
Dec 1, 2009, 6:50:54 AM12/1/09
to Maksim Yevmenkin, freebsd-...@freebsd.org, plu...@netbsd.org

Here is a patch which removes the GNU iconv dependency from obexapp.
I've successfully tested it by sending vcards with strange names;
the resulting files were identical.
The relevant changes are:
-just use the result of nl_langinfo(CODESET) as input of
iconv_open(3), this is more robust than trying to interpret
the locale string
-remove iconvctl(ICONV_SET_DISCARD_ILSEQ) -- BSD doesn't
have this and it should be unneeded because it only
compensates for some non-standard behaviour of GNU iconv.
(The bsdxml->expat part is unrelated.)

best regards
Matthias

Matthias Drochner

unread,
Dec 1, 2009, 7:52:39 AM12/1/09
to Maksim Yevmenkin, freebsd-...@freebsd.org, plu...@netbsd.org

On Tue, 1 Dec 2009 12:50:54 +0100
Matthias Drochner <m.dro...@gmail.com> wrote:
> Here is a patch

Oops, this time for real.
best regards
Matthias

patch-ac

Maksim Yevmenkin

unread,
Dec 1, 2009, 1:28:40 PM12/1/09
to Matthias Drochner, freebsd-...@freebsd.org, plu...@netbsd.org
Matthias,

> Here is a patch which removes the GNU iconv dependency from obexapp.
> I've successfully tested it by sending vcards with strange names;
> the resulting files were identical.

thanks for the patch!

could you please tell me which bsd flavor you tested this on?

> The relevant changes are:
> -just use the result of nl_langinfo(CODESET) as input of
> iconv_open(3), this is more robust than trying to interpret
> the locale string
> -remove iconvctl(ICONV_SET_DISCARD_ILSEQ) -- BSD doesn't
> have this and it should be unneeded because it only
> compensates for some non-standard behaviour of GNU iconv.
> (The bsdxml->expat part is unrelated.)

i dont really have any objections to those, just wanted to get some
clarification.

thanks
max

Iain Hibbert

unread,
Dec 1, 2009, 2:15:48 PM12/1/09
to Matthias Drochner, freebsd-...@freebsd.org
On Tue, 1 Dec 2009, Matthias Drochner wrote:

> iconv_open(3), this is more robust than trying to interpret
> the locale string

btw nl_langinfo(3) is defined to always return a valid pointer, so the

if (locale == NULL)
return (-1);

is not required..

also, the locale variable can be private to obexapp_util_locale_init() as
it is not used elsewhere

regards,
iain


Iain Hibbert

unread,
Dec 1, 2009, 2:31:13 PM12/1/09
to freebsd-...@freebsd.org
Hi,

while on the subject of obexapp, I have a patch to remove some annoying
'type punning' compilation errors that gcc spits out that I'm not totally
sure are valid, but see below anyway..

I don't understand the OBEX protocol or libopenobex enough to know if it
is possible, but the last case also removes a potential NULL dereference -
if the OBEX_ObjectGetNonHdrData() fails to recover a proper data, an error
is logged but it carries on and hdr->flags might cause a segfault?

iain

--- ~client.c 2009-04-10 00:16:31.000000000 +0100
+++ client.c 2009-12-01 16:44:49.000000000 +0000
@@ -1219,10 +1219,10 @@ obexapp_client_request_connect_done(obex
int obex_rsp)
{
context_p context = (context_p) OBEX_GetUserData(handle);
- obex_connect_hdr_t *hdr = NULL;
obex_headerdata_t hv;
uint8_t hi;
uint32_t hlen;
+ uint8_t *data = NULL;

log_debug("%s(): Connect completed, response %#x", __func__, obex_rsp);

@@ -1232,10 +1232,12 @@ obexapp_client_request_connect_done(obex
if (obex_rsp != OBEX_RSP_SUCCESS)
return (obex_rsp);

- if (OBEX_ObjectGetNonHdrData(object, (uint8_t **) &hdr) == sizeof(*hdr))
+ if (OBEX_ObjectGetNonHdrData(object, &data) == sizeof(obex_connect_hdr_t))
log_debug("%s(): OBEX connect header: " \
"version=%#x, flags=%#x, mtu=%d", __func__,
- hdr->version, hdr->flags, ntohs(hdr->mtu));
+ ((obex_connect_hdr_t *)data)->version,
+ ((obex_connect_hdr_t *)data)->flags,
+ ntohs(((obex_connect_hdr_t *)data)->mtu));
else
log_err("%s(): Invalid OBEX connect header?!", __func__);

--- ~server.c 2009-08-20 22:57:18.000000000 +0100
+++ server.c 2009-12-01 16:57:08.000000000 +0000
@@ -471,19 +471,21 @@ static int
obexapp_server_request_connect(obex_t *handle, obex_object_t *object,
__unused int obex_rsp)
{
- obex_connect_hdr_t *hdr = NULL;
obex_headerdata_t hv;
uint8_t hi;
uint32_t hlen;
uint8_t const *target = NULL;
int target_len = 0;
+ uint8_t *data = NULL;

log_debug("%s()", __func__);

- if (OBEX_ObjectGetNonHdrData(object, (uint8_t **) &hdr) == sizeof(*hdr))
+ if (OBEX_ObjectGetNonHdrData(object, &data) == sizeof(obex_connect_hdr_t))
log_debug("%s(): OBEX connect header: version=%#x, " \
- "flags=%#x, mtu=%d", __func__, hdr->version, hdr->flags,
- ntohs(hdr->mtu));
+ "flags=%#x, mtu=%d", __func__,
+ ((obex_connect_hdr_t *)data)->version,
+ ((obex_connect_hdr_t *)data)->flags,
+ ntohs(((obex_connect_hdr_t *)data)->mtu));
else
log_err("%s(): Invalid OBEX connect header?!", __func__);

@@ -1086,20 +1088,22 @@ obexapp_server_request_setpath(obex_t *h
__unused int obex_rsp)
{
context_p context = (context_p) OBEX_GetUserData(handle);
- obex_setpath_hdr_t *hdr = NULL;
obex_headerdata_t hv;
uint8_t hi;
uint32_t hlen;
int got_name = 0;
+ uint8_t *data = NULL;
+ uint8_t flags = 0;

log_debug("%s()", __func__);

context->file[0] = '\0';

- if (OBEX_ObjectGetNonHdrData(object, (uint8_t **) &hdr) == sizeof(*hdr))
+ if (OBEX_ObjectGetNonHdrData(object, &data) == sizeof(obex_setpath_hdr_t)) {
+ flags = ((obex_setpath_hdr_t *)data)->flags;
log_debug("%s(): OBEX setpath header: flags=%#x, constants=%d",
- __func__, hdr->flags, hdr->constants);
- else
+ __func__, flags, ((obex_setpath_hdr_t *)data)->constants);
+ } else
log_err("%s(): Invalid OBEX setpath header?!", __func__);

while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) {
@@ -1145,15 +1149,14 @@ obexapp_server_request_setpath(obex_t *h
}

if (!got_name) {
-
/*
* No name and flags == 0x3 (back up one level + don't create
* directory) means "cd ..". Everything else is forbidden.
*/

- if (hdr->flags != 0x3) {
+ if (flags != 0x3) {
log_err("%s(): Invalid flags for 'cd ..', flags=%#x",
- __func__, hdr->flags);
+ __func__, flags);

return (OBEXAPP_PACK_RSP_CODES(OBEX_RSP_FORBIDDEN,
OBEX_RSP_FORBIDDEN));
@@ -1169,9 +1172,9 @@ obexapp_server_request_setpath(obex_t *h
* 'cd /'. Everything else is forbidden
*/

- if (hdr->flags != 0x2) {
+ if (flags != 0x2) {
log_err("%s(): Invalid flags for 'cd /', flags=%#x",
- __func__, hdr->flags);
+ __func__, flags);

return (OBEXAPP_PACK_RSP_CODES(OBEX_RSP_FORBIDDEN,
OBEX_RSP_FORBIDDEN));
@@ -1180,7 +1183,7 @@ obexapp_server_request_setpath(obex_t *h
strlcpy(context->file, context->root, PATH_MAX);
}

- if (hdr->flags == 0) {
+ if (flags == 0) {
if (mkdir(context->file, 0755) < 0 && errno != EEXIST) {
log_err("%s(): mkdir(%s) failed. %s (%d)",
__func__, context->file,


Maksim Yevmenkin

unread,
Dec 1, 2009, 6:25:55 PM12/1/09
to Iain Hibbert, freebsd-...@freebsd.org
On Tue, Dec 1, 2009 at 11:31 AM, Iain Hibbert <plu...@rya-online.net> wrote:
> Hi,
>
> while on the subject of obexapp, I have a patch to remove some annoying
> 'type punning' compilation errors that gcc spits out that I'm not totally
> sure are valid, but see below anyway..

that is why i had -fno-strict-aliasing in makefile :)

> I don't understand the OBEX protocol or libopenobex enough to know if it
> is possible, but the last case also removes a potential NULL dereference -
> if the OBEX_ObjectGetNonHdrData() fails to recover a proper data, an error
> is logged but it carries on and hdr->flags might cause a segfault?

yes, i think those are good. combined patch went out in the previous email.

thanks,
max

Iain Hibbert

unread,
Dec 7, 2009, 1:39:48 PM12/7/09
to Maksim Yevmenkin, freebsd-...@freebsd.org
On Tue, 1 Dec 2009, Maksim Yevmenkin wrote:

> ok, so, combined patch would look something like the attached.
>
> could you please give it a try and see if it still works?

seems fine to me

iain


Iain Hibbert

unread,
Dec 8, 2009, 10:21:12 AM12/8/09
to Maksim Yevmenkin, freebsd-...@freebsd.org
Hi Max,

one more thing with obexapp - I have it running in server mode here,
command line:

/usr/pkg/bin/obexapp -s -S -C 10 -r /home/plunky/obex -u plunky

which works well - I can copy files to and from my obex directory as I
like locally and remotely. A thing I recently noticed is that when my
phone connects, I get

obexapp[134]: /etc/pwd.db: No such file or directory

in the system log. Naturally, this is because obexapp is running in a
chroot and there is no password database inside.. I'm not sure if this is
new behaviour but I don't recall seeing it previously.

I guess this relates to getpwnam or getpwuid in server.c, is it a problem?

iain

PS there is also a fork()/daemon() cascade in transport.c I think you
removed the unnecessary fork() from main previously?

PPS sorry no time to investigate this stuff here just now but I thought
I'd let you know :)


Maksim Yevmenkin

unread,
Dec 8, 2009, 6:48:27 PM12/8/09
to Iain Hibbert, freebsd-...@freebsd.org
Iain,

> one more thing with obexapp - I have it running in server mode here,
> command line:
>
> /usr/pkg/bin/obexapp -s -S -C 10 -r /home/plunky/obex -u plunky
>
> which works well - I can copy files to and from my obex directory as I
> like locally and remotely. A thing I recently noticed is that when my
> phone connects, I get
>
> obexapp[134]: /etc/pwd.db: No such file or directory
>
> in the system log. Naturally, this is because obexapp is running in a
> chroot and there is no password database inside.. I'm not sure if this is
> new behaviour but I don't recall seeing it previously.
>
> I guess this relates to getpwnam or getpwuid in server.c, is it a problem?

ahh... i see what the problem is.

obexapp_server_request_get_folder_object() wants to call
getpwuid()/getgrgid() to put user/group name into xml, but, obviously,
it can not. i guess this is the case where "less is more" :) i will
fix this.

> PS there is also a fork()/daemon() cascade in transport.c I think you
> removed the unnecessary fork() from main previously?

yeah, this was me being too lazy :) i just wanted to make sure child
gets completely detached no matter how parent is running :) i will fix
it too

> PPS sorry no time to investigate this stuff here just now but I thought
> I'd let you know :)

thanks!

max

Iain Hibbert

unread,
Dec 15, 2009, 2:36:37 PM12/15/09
to freebsd-...@freebsd.org
Hi,

While obexapp is the subject, I wonder what kind of transfer speeds people
get? Normally I use obexapp to copy files to and from my phone but they
are not much big files and I've never bothered with speed tests.. I have
been working some long hours at a tedious job lately and thought I would
listen to some music off my phone.

However, transferring tracks is tedious. I have calculated (see attached
program) that I'm getting about 12-15 kbytes/second by using windows
mobile bluetooth explorer in suck mode (navigate to my laptop, then copy
and paste the directory to the sd card)

using obexapp to push files seemed to go faster, about 15-20 kbytes/second
initially but obexapp doesn't handle sending complete directories so I had
to write a wrapper script and then when I left this going overnight it
only transferred about 15 tracks (I think a resource leak in the phone,
which needed a reboot afterwards)

So, my question is what kind of speeds should we normally expect with
OBEX? I thought bluetooth should be faster than that but I don't really
know what version my phone has (laptop has Broadcom BCM2045B 2.0+EDR and
specs I found on the web says HTC Elf has 2.0 but I don't know about EDR)
and I only have a single computer so while a speed test would be possible
with two dongles, there could be interference in the stack. Has anybody
done anything like that in the past?

I read some comments previously on the list and have raised the MTU to
8192 bytes as suggested for an older obexapp but that hasn't improved the
speed much. Any other ideas?

regards,
iain

btstat.c

Maksim Yevmenkin

unread,
Dec 15, 2009, 5:40:01 PM12/15/09
to Iain Hibbert, freebsd-...@freebsd.org

have you tried obexapp client to obexapp server transfer? i.e. pc to
pc. i suspect that mobile devices just not being able to process data
fast enough.

thanks,
max

Alexandre "Sunny" Kovalenko

unread,
Dec 16, 2009, 12:04:52 PM12/16/09
to Maksim Yevmenkin, freebsd-...@freebsd.org
> _______________________________________________
> freebsd-...@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth
> To unsubscribe, send any mail to "freebsd-blueto...@freebsd.org"

Not very scientific (I took 43 MByte file and transferred it once and
did not discount time spent on manually accepting transfer on the
receiving end)...

Source of the transfer is ThinkPad X60:
FreeBSD 8.0-STABLE #0 r200413
ubt0: <Broadcom Corp BCM2045B, class 224/1, rev 2.00/1.00, addr 2> on
usbus3
obexapp-1.4.12
No special tuning of the stack or obexapp.

Sent to:
* Motorola Razor V3xx ~85 KBytes/sec
* Nokia N810 ~120 KBytes/sec
* ThinkPad T500 (running Windows) ~150 KBytes/sec

HTH,

--
Alexandre Kovalenko (Олександр Коваленко)


Iain Hibbert

unread,
Dec 17, 2009, 2:34:47 PM12/17/09
to freebsd-...@freebsd.org
On Wed, 16 Dec 2009, Alexandre "Sunny" Kovalenko wrote:

> On Tue, 2009-12-15 at 14:40 -0800, Maksim Yevmenkin wrote:
> > have you tried obexapp client to obexapp server transfer? i.e. pc to
> > pc. i suspect that mobile devices just not being able to process data
> > fast enough.

No, as I only have one computer.. actually, I can plug in a couple of
devices and run tests in the loop but I thought there could be self
interference influences..

> Sent to:
> * Motorola Razor V3xx ~85 KBytes/sec
> * Nokia N810 ~120 KBytes/sec
> * ThinkPad T500 (running Windows) ~150 KBytes/sec

Yes, these are much more realistic figures than mine thanks.. I note that
the Bluetooth page on wikipedia lists a HTC device that has 2.0 but not
EDR and I wonder if that is the case for my phone too (HTC Elf). I will do
some more research next week when I might have some time..

iain


Iain Hibbert

unread,
Jan 3, 2010, 11:13:00 AM1/3/10
to freebsd-...@freebsd.org

Ok, some more research.. My slowness seems to be a combination of several
issues. To start with, using the same system but with a CSR 2.0+EDR dongle
rather than the inbuilt BCM2045B device I get 40-50KBytes/sec (about 3x
before).

But, capturing the transfer of a 1Mb datafile shows that windows mobile
itself is not very clever at sending RFCOMM flow-control credits in what
is basically a one-sided connection (data is only flowing out). It seems
to have space for about 55 packets in its buffer but doesn't send credits
until it has [just about] run out, sigh. So I get the following scenario:

< ACL data: handle 12 flags 0x02 dlen 135
L2CAP(d): cid 0x0070 len 131 [psm 3]
RFCOMM(d): UIH: cr 1 dlci 8 pf 0 ilen 127 fcs 0x5a
< ACL data: handle 12 flags 0x02 dlen 135
L2CAP(d): cid 0x0070 len 131 [psm 3]
RFCOMM(d): UIH: cr 1 dlci 8 pf 0 ilen 127 fcs 0x5a
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 12 packets 2

that repeats for a while, sending, sending..

> HCI Event: Number of Completed Packets (0x13) plen 5
handle 12 packets 2
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 12 packets 2
> HCI Event: Number of Completed Packets (0x13) plen 5
handle 12 packets 2

and runs out of steam..

> ACL data: handle 12 flags 0x02 dlen 9
L2CAP(d): cid 0x0041 len 5 [psm 3]
RFCOMM(d): UIH: cr 0 dlci 8 pf 1 ilen 0 fcs 0x9c credits 51

until the credits arrive and we may start sending again.

Doubling the RFCOMM frame size or altering the OBEX mtu made small
differences but not very significant.

Setting up transfers with my NetBSD laptop and obexapp at each end using
different dongles showed that the BCM2045B itself is pretty slow, in that
it never really got much over 20KBytes/sec whereas two CSR 2.0+EDR dongles
managed a solid 60KBytes/sec with the more regular credit flow.

The rates are still less than Sunny so I guess there could also be
improvements to be made in the stack itself, and it would probably be
easier to test if I had more hardware or could compare the same equipment
with a different OS.

iain


0 new messages