How to Access Bluetooth Low Level Functions in Pybluez

How to access Bluetooth low level functions in pybluez?

The simple way to get the exact same functionality would be to just have python scripts invoke hcitool from the command line.

But for the custom solution, you can use pybluez to send the same HCI command packets that those other commands generate. For example, hcitool rssi just causes an HCI Read RSSI command to be sent to the local BT adapter, and parses the result. With pybluez you can open an HCI socket, construct command packets, and parse results yourself. If you don't have access to the BT spec that defines the command packet formats, you can either look at the source code for hcitool to see what they are sending, or you can use hcidump.

To use hcidump, you can run hcidump in a terminal to sniff the local HCI command traffic while you use another terminal to do your other commands via hcitool. With hcidump you will be able to capture the raw packet transactions that you can use as reference for what you want to generate from pybluez.

This example http://code.google.com/p/pybluez/source/browse/trunk/examples/advanced/inquiry-with-rssi.py shows how to deal with HCI sockets for manually forming command packets and parsing results. You just need to customize for the commands you want to use.

How to connect BLE devices using Linux bluetooth C library

This is what the old hci_xxx bluetooth C functions are doing at the lowest level. They probably don't work now because bluez/dbus is getting in the way. The following code works on a Raspberry Pi because it disables bluez first, and could be the basis of a C program - but it would be much easier to use one of the github libraries mentioned in the comments.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

struct sockaddr_hci
{
unsigned short hci_family;
unsigned short hci_dev;
unsigned short hci_channel;
};


struct hci_filter
{
unsigned long type_mask;
unsigned long event_mask[2];
unsigned short opcode;
};

#define BTPROTO_HCI 1
#define SOL_HCI 0
#define HCI_FILTER 2
#define HCIDEVDOWN 0x400448CA

unsigned char eventmask[16] = { 1,1,0x0C,8,0xFF,0xFF,0xFB,0xFF,0x07,0xF8,0xBF,0x3D };
unsigned char lemask[16] = { 0x01,0x01,0x20,0x08,0xBF,0x05,0,0,0,0,0,0 };
unsigned char leopen[30] = {1,0x0D,0x20,0x19,0x60,0,0x60,0,0,0,0x66,0x55,0x44,0x33,0x22,0x11,0,0x18,0,0x28,0,0,0,0x11,0x01,0,0,0,0};

int main()
{
int n,len,dd;
struct sockaddr_hci sa;
struct hci_filter flt;
char buf[256];

// set board address 00:1E:C0:2D:17:7C
leopen[15] = 0x00;
leopen[14] = 0x1E;
leopen[13] = 0xC0;
leopen[12] = 0x2D;
leopen[11] = 0x17;
leopen[10] = 0x7C;

dd = socket(31, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_HCI);

if(dd < 0)
{
printf("Socket open error\n");
return(0);
}

ioctl(dd,HCIDEVDOWN,0); // hci0
close(dd);


// AF_BLUETOOTH=31
dd = socket(31, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, BTPROTO_HCI);

if(dd < 0)
{
printf("Socket open error\n");
return(0);
}

sa.hci_family = 31; // AF_BLUETOOTH;
sa.hci_dev = 0; // hci0/1/2...
sa.hci_channel = 1; // HCI_CHANNEL_USER

if(bind(dd,(struct sockaddr *)&sa,sizeof(sa)) < 0)
{
printf("Bind failed\n");
close(dd);
return(0);
}

write(dd,eventmask,12);
write(dd,lemask,12);

printf("Send hci LE connect\n");
write(dd,leopen,29);

printf("If get reply = 04 3E 13 01 00.. then has connected OK\n");
printf("REPLY =");
for(n = 0 ; n < 10 ; ++ n)
{
len = read(dd,buf,sizeof(buf));
for(n = 0 ; n < len ; ++n)
printf(" %02X",buf[n]);
printf("\n");
sleep(1);
}
printf("\nExit and disconnect\n");
}

Bluetooth protocol and implementing a position system with four devices

I'm sorry, I didn't follow everything you wrote, but I think the first step is to get down to the HCI layer on the fixed stations. That is fairly straight-forward to accomplish and gives you a fair bit of control.

As you mentioned, hcitool is very useful, but it doesn't matter what tool or language you use. You can access HCI commands from any language.

For example, I did something like this with Voyage Linux on an ALIX box. Voyage is debian based so now problem to load BlueZ, PyBluez, and Python. Python made it easy to quickly prototype a solution which you can convert to C++ later if need be. (More here.)

But that's just an example - use whatever stack you are comfortable with as long as you can get at the HCI layer. (Getting past the HCI layer requires you to work with a specific chipset and load code directly into the Bluetooth chipset.)

On the mobile device you might be severely limited: if you are trying for potential real world implementation. If this is just for the lab, you should get rooted Android devices that use the standard Bluez stack and then, like on the fixed devices, you can get at the HCI interface. Android is, after all, just Linux so you can do what you want if you have root.

Low level Bluetooth Programming in C++

http://www.bluez.org/ for Linux

http://inthehand.com/content/32feet.aspx for Windows

Bluetooth Low Energy: listening for notifications/indications in linux

Try this...

Run gatttool -b <MAC Address> --interactive like you did before. You'll get a prompt and then you type connect. You should see a CON in the prompt indicating that you've connected to the device. Then type char-read-uuid 2902. You should get a list of all CCC (Client Characteristic Configuration) attributes on the device. You can try setting them all to 0100 to get notifications, 0200 for indications, 0300 for both, or 0000 for everything off. Type help to see all the commands and their arguments.

EDIT:

The use of the --listen argument requires you to couple it with other commands to turn on the notifications and/or indications. So here's an example that works in Bluez 4.101:

gatttool -b <MAC Address> --char-write-req --handle=0x0031 --value=0100 --listen

Obviously you need to change the handle to the handle of the CCC that you want to turn on notifications for. However, I still find it way easier to just use the interactive mode.



Related Topics



Leave a reply



Submit