libbluetooth.so

2,844 views
Skip to first unread message

mike digioia

unread,
Jun 26, 2012, 9:22:43 PM6/26/12
to andro...@googlegroups.com
Hi

Looked at the archives but hard to see anything on my issues with using the bluetooth adapter on my android device.

The problem is that the standard socket call for RFCOMM keeps failing with an error code of "1". Iti is as if the adapter is not initialized. Socket handle does not return a real handle and is < 1. If I change the socket call to any normal (non-bluetooth) call it works but can bind of course.

{
struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read;
socklen_t opt = sizeof(rem_addr);

// allocate socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

// bind socket to port 1 of the first available
// local bluetooth adapter
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = *BDADDR_ANY;
loc_addr.rc_channel = (uint8_t) 1;
bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr
*************************

The Java activity based code uses this to initialize the BT device through the adapter and enables it -

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}

if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult
(enableBtIntent, REQUEST_ENABLE_BT);
}

How can I do this in native code, since my java wrapper is just a call into this code base.

thanks,

/mpd


Philippe Simons

unread,
Jun 27, 2012, 7:29:54 AM6/27/12
to andro...@googlegroups.com
Short answer: You can't.

blutooth API are only available from Java not from native code.


--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.

mike digioia

unread,
Jun 27, 2012, 12:07:01 PM6/27/12
to andro...@googlegroups.com
Hi Philippe,

Thanks for your reply.

I may have not been too clear in my email. But I know one can't write java code from native C-code. My questions were more related to what can be done to make it work, that is, have the RFCOMM socket call return a socket handle. If someone knows the java api above and the related HAL code used to access the bluetooth adapter, then it can be replicated in my native code.

Has anyone included the above java code inside a java wrapper (like I have) to enable the bluetooth adapter, then issued the socket call in C successfully?

what other options exists?

thanks.

/mpd

Philippe Simons

unread,
Jun 27, 2012, 2:39:28 PM6/27/12
to andro...@googlegroups.com
Forget it, you'll never get an RFCOMM socket.
Bluetooth devices are not accessible directly from C/C++, you could be able to hack something using the system libraries on your device, but there is no guarantee those libraries/API will be available on an other device.

You need to call the api from package android.bluetooth using JNI.

mike digioia

unread,
Jun 27, 2012, 2:55:40 PM6/27/12
to andro...@googlegroups.com

Ok. While I don't understand the details of why it is not possi ble, since the bluetooth driver is accessable from linux with c code. Guess you may not know why either. If anyone knows what to change, let me know.

If I use the java api to enable the device and get a handle, will this allow me to move packet data to my native code space with un managed memory buffers?

Philippe Simons

unread,
Jun 27, 2012, 3:05:17 PM6/27/12
to andro...@googlegroups.com
Yup! That's the way to go.

David Turner

unread,
Jun 28, 2012, 9:21:51 AM6/28/12
to andro...@googlegroups.com
On Wed, Jun 27, 2012 at 8:55 PM, mike digioia <mpd...@gmail.com> wrote:

Ok. While I don't understand the details of why it is not possi ble, since the bluetooth driver is accessable from linux with c code. Guess you may not know why either. If anyone knows what to change, let me know.

For one, an Android application process may not be allowed to open() the driver's device file

Second, which driver is being used, and which user-level Bluetooth stack is being used on a device is very variable. E.g. various OEMs have replaced bluez (used by default in AOSP) with something completely different. Also, bluez was completely removed from JellyBean, iirc.

In other words, the high-level Bluetooth Java API are the only stable ones that application developers should use if they don't want to face weird compatibility issues.

If I use the java api to enable the device and get a handle, will this allow me to move packet data to my native code space with un managed memory buffers?

I don't think it's possible to get a native file descriptor from an android.bluetooth.BluetoothSocket object. Whether this object encapsulate a real file descriptor or something else is a platform implementation details.

mike digioia

unread,
Jun 28, 2012, 1:30:48 PM6/28/12
to andro...@googlegroups.com
Thanks David.


>> For one, an Android application process may not be allowed to open() the driver's device file

Anything prevents me from using setuid/setgid to root and then issue the socket call. All other parameters I used for the socket call worked without using any for bluetooth.

>> various OEMs have replaced bluez (used by default in AOSP) with something completely different.

I suspect this since the target device is samsung Nexus S and one phone does not have RFCOMM but the other one does.


>> I don't think it's possible to get a native file descriptor from an android.bluetooth. BluetoothSocket object.

Made these changes last night but has not worked yet.

thanks

/mpd

David Given

unread,
Jul 2, 2012, 8:56:50 AM7/2/12
to andro...@googlegroups.com
Philippe Simons wrote:
> Forget it, you'll never get an RFCOMM socket.
> Bluetooth devices are not accessible directly from C/C++...
[...]

Could you expand on this?

With regard to basic RFCOMM and L2CAP connections, Linux simply exposes
them as sockets of type AF_BLUETOOTH, so creating a connection is as
simple as socket()+connect() and you're done. e.g.:

http://people.csail.mit.edu/albert/bluez-intro/x502.html

Does Android not allow this?

(I'm aware that doing anything high-level such as device discovery will
require going via Java, but I don't really care about that.)

--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│ "Parents let children ride bicycles on the street. But parents do not
│ allow children to hear vulgar words. Therefore we can deduce that
│ cursing is more dangerous than being hit by a car." --- Scott Adams



signature.asc

Philippe Simons

unread,
Jul 2, 2012, 9:02:15 AM7/2/12
to andro...@googlegroups.com
the issue in your sample is
#include <bluetooth/rfcomm.h>
you can't assue this file exists on a device.

David Given

unread,
Jul 2, 2012, 11:05:06 AM7/2/12
to andro...@googlegroups.com
Philippe Simons wrote:
> the issue in your sample is
>
> #include <bluetooth/rfcomm.h>
>
> you can't assue this file exists on a device.

Well, no, it's a header... and, in fact, it doesn't appear in the NDK,
but the values are all well-defined and don't change across platforms,
so it would be easy to bodge up myself.
signature.asc

Philippe Simons

unread,
Jul 2, 2012, 11:28:41 AM7/2/12
to andro...@googlegroups.com
Sorry, I'll state it differently

<bluetooth/rfcomm.h> is part of blueZ library, and you can't assume this library is available on all devices.

Or, if it's not part of the NDK, you need to include the library yourself.
Of course, a library like bluez is a system/device lib, and including it in your apk is pointless.

mike digioia

unread,
Jul 4, 2012, 12:53:13 PM7/4/12
to andro...@googlegroups.com
I understand that bluetooth is implemented differently from one chipset to another. Even on my two samsung nexus S phones, one has RFCOMM and the other does not (using hcitool scan). So one can't expect to have the same capabilities everywhere. But if one phone has RFCOMM, then one would expect to be able to use SOCKET calls with this device. Correct?  If not, what steps may one take to allow the socket call to work?

David Given

unread,
Jul 31, 2012, 9:52:55 AM7/31/12
to andro...@googlegroups.com
mike digioia wrote:
> I understand that bluetooth is implemented differently from one chipset
> to another. Even on my two samsung nexus S phones, one has RFCOMM and
> the other does not (using hcitool scan). So one can't expect to have the
> same capabilities everywhere. But if one phone has RFCOMM, then one
> would expect to be able to use SOCKET calls with this device. Correct?
> If not, what steps may one take to allow the socket call to work?

Sorry for the necropost, but I've just been looking into this and
thought it was worth reporting that it all works fine.

The NDK doesn't have the bluetooth/rfcomm.h and bluetooth/bluetooth.h
headers, but the kernel interface is well-defined and it's trivial to
define yourself:

---snip---
#define BTPROTO_RFCOMM 3

#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
#define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})

typedef struct
{
uint8_t b[6];
} __attribute__((packed)) bdaddr_t;

struct sockaddr_rc
{
sa_family_t rc_family;
bdaddr_t rc_bdaddr;
uint8_t rc_channel;
};
---snip---

Now I can just create Bluetooth RFCOMM sockets, connect them, listen to
them, etc. Of course, anything SDP related still has to go through Java.

I have the BLUETOOTH and BLUETOOTH_ADMIN permissions; I haven't tried
this without them but I expect it wouldn't work.
signature.asc

Philippe Simons

unread,
Jul 31, 2012, 10:47:17 AM7/31/12
to andro...@googlegroups.com
And what happens if a kernel update changes those structs / defines...

crash...

Once again, if it's not part of the NDK stable API, you cant rely on system API implementations.

mike digioia

unread,
Jul 31, 2012, 12:33:09 PM7/31/12
to andro...@googlegroups.com, jun...@huawei.com
Thanks David and Philippe, I put this project on hold since it was
just not allow me to setup the socket. But now I will attempt to make
these defines as shown above.

This is just a research project so I am not too much concerned about
the kernel being changed as I would if it was production code to be
released.

The prior answer given that it is not possible unless the java
activity is used was obviously wrong, as I suspected,

So where are the above defines made inside the NDK directory?

thanks,

/mpd

David Given

unread,
Jul 31, 2012, 12:43:35 PM7/31/12
to andro...@googlegroups.com
Philippe Simons wrote:
> And what happens if a kernel update changes those structs / defines...

It won't. They're public APIs.
signature.asc

David Given

unread,
Jul 31, 2012, 5:12:24 PM7/31/12
to andro...@googlegroups.com
On 31/07/12 17:33, mike digioia wrote:
[...]
> The prior answer given that it is not possible unless the java
> activity is used was obviously wrong, as I suspected,
>
> So where are the above defines made inside the NDK directory?

They're not --- the include files they belong to are missing. An
oversight, I presume. I just added a header header containing the quoted
definitions to my local project.

This is quite safe; there are no additional APIs, and the sockets
interface is explicitly designed to cope safely with varying different
types of sockaddr. The very worst that can happen --- even if the Linux
kernel people decide to break ABI compatibility with all existing code
and change the structures --- is that the sockaddr will be
misinterpreted and it'll simply stop working.

--
┌─── dg@cowlark.com ───── http://www.cowlark.com ─────

│ life←{ ↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ }
│ --- Conway's Game Of Life, in one line of APL

signature.asc

mike digioia

unread,
Jul 31, 2012, 7:54:48 PM7/31/12
to andro...@googlegroups.com

What header do I need to add to my ndk directory and where do they go inside the ndk?

Reply all
Reply to author
Forward
0 new messages