You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
HCI Bluetooth socket bind error on an arm crosscompiled environment #67632
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2015-02-11.15:50:15.557>labels= ['extension-modules', 'type-bug']
title='HCI Bluetooth socket bind error on an arm crosscompiled environment'updated_at=<Date2015-02-11.16:05:05.047>user='https://bugs.python.org/ThomasChiroux'
This bug bellow occurs only on my crosscompiled environment on arm (marvell armada 166): arm-pxa168-linux-gnueabi
It does not seems to be a cross-compile issue: python compiles without problem and all unittests pass on the target device.
description and first clues
---------------------------
The problem is easyly reproducted using this script:
So on my box if PyArg_ParseTuple write on &addr->hci_dev if write 4 bytes from &addr->hci_family which is 2 bytes BEFORE &addr->hci_dev
At this time I can not understand how it's possible.
Remarks and patch
-----------------
Now I have several remarks and a working patch.
remark/question 1: why does PyArg_ParseTuple parse an int when addr->hci_dev is an unsigned short ?
even in normal situation, when it works, writing on &addr->hci_dev overflow on the next two bytes which are btw addr->channel (more on that later)
remark/question 2: i've tried to dig more deeply inside PyArg_ParseTuple and found another odd thing, but I did not try to change it without knowing what I do:
in Python/getargs.c, in convertsimple, int parsing result is not casted before returned:
(ival is a long). In all other cases (short, unsigned short, char, usigned char), they are casted before return.
[disclosure: i've tested to add the cast and relaunched my bind test, it did not change anything, but it's still strange for me]
Now a working patch: here below and attached a working patch which results on a good socket bind, but now completely satisfiying:
in short: I parse now an unsigned short instead of parsing an int which gives me a two bytes long elements which is stored well
on addr->hci_dev without overloading addr->hci_family.
But this modification alone is not enough: addr->hci_channel needed a good value.
that's why i added _BT_HCI_MEMB(addr, channel) = HCI_CHANNEL_RAW;
which sets addr->hci_channel to zero.
(without this line, any value could be here)
And that led me to another question/problem: how is hci_channel normally handled ?
It does not seems to be a valid parameter of bind; behaviour without the patch will
erase hci_channel while storing int value in hci_dev, so theorically we can assign
a well defined int value in our bind method to both assign the wanted value in
hci_dev and hci_channel, but it does not seems to be a proper way to do it.
changed the title [-]HCI Bluetooth socket bind error on an arm crosscompiler environment[/-][+]HCI Bluetooth socket bind error on an arm crosscompiled environment[/+]on Feb 11, 2015
Activity
thomaschiroux commentedon Feb 11, 2015
This bug bellow occurs only on my crosscompiled environment on arm (marvell armada 166): arm-pxa168-linux-gnueabi
It does not seems to be a cross-compile issue: python compiles without problem and all unittests pass on the target device.
description and first clues
---------------------------
The problem is easyly reproducted using this script:
which raises the following exception when run on the target device:
Traceback (most recent call last): File "./test_bt.py", line 4, in <module> sock.bind((0,)) OSError: [Errno 22] Invalid argumentThis does not give much clues, but strace does (i've filtered to display the
two significant parts of strace)
(on a working environment, including arm, like a raspberry pi, strace gives the following result (and no traceback of course):
So, on the armada166, between the socket creation and the bind we lost the socket family (AF_UNSPEC instead of AF_BLUETOOTH).
And That's why bind returns invalid argument.
socketmodule and PyArg_ParseTuple
---------------------------------
Now let's look at Modules/socketmodule.c:
After some digging, i've found that the problem is in getsockaddrarg, in the AF_BLUETOOTH / BTPROTO_HCI case
and more precisely on this line:
reproducted here:
When we execute the PyArg_ParseTuple, the addr->hci_family is crunched (by zeros with my previous python sample).
At this same place, i've done the following test:
and the result is:
(WTF ??)
in a working environnement (tested on raspberry B+ / python 3.4.2 locally compiled) result is what we should expect:
So on my box if PyArg_ParseTuple write on &addr->hci_dev if write 4 bytes from &addr->hci_family which is 2 bytes BEFORE &addr->hci_dev
At this time I can not understand how it's possible.
Remarks and patch
-----------------
Now I have several remarks and a working patch.
remark/question 1: why does PyArg_ParseTuple parse an int when addr->hci_dev is an unsigned short ?
even in normal situation, when it works, writing on &addr->hci_dev overflow on the next two bytes which are btw addr->channel (more on that later)
remark/question 2: i've tried to dig more deeply inside PyArg_ParseTuple and found another odd thing, but I did not try to change it without knowing what I do:
in Python/getargs.c, in convertsimple, int parsing result is not casted before returned:
here: https://hg.python.org/cpython/file/ab2c023a9432/Python/getargs.c#l690
(ival is a long). In all other cases (short, unsigned short, char, usigned char), they are casted before return.
[disclosure: i've tested to add the cast and relaunched my bind test, it did not change anything, but it's still strange for me]
in short: I parse now an unsigned short instead of parsing an int which gives me a two bytes long elements which is stored well
on addr->hci_dev without overloading addr->hci_family.
But this modification alone is not enough: addr->hci_channel needed a good value.
that's why i added _BT_HCI_MEMB(addr, channel) = HCI_CHANNEL_RAW;
which sets addr->hci_channel to zero.
(without this line, any value could be here)
And that led me to another question/problem: how is hci_channel normally handled ?
It does not seems to be a valid parameter of bind; behaviour without the patch will
erase hci_channel while storing int value in hci_dev, so theorically we can assign
a well defined int value in our bind method to both assign the wanted value in
hci_dev and hci_channel, but it does not seems to be a proper way to do it.
[-]HCI Bluetooth socket bind error on an arm crosscompiler environment[/-][+]HCI Bluetooth socket bind error on an arm crosscompiled environment[/+]serhiy-storchaka commentedon Apr 1, 2025
It should be fixed by #131668.