Working with some bluetooth coding :)

It’s been quite some time since I started poking with bluetooth coding, but didn’t understand it much. But it was quite some moment this afternoon. I was trying to study the rfcomm source code, and finally could able to find out the part of the code responsible for the “bind” option for rfcomm. Had a code already for scanning for nearby bluetooth devices. Edited some of theirs codes, added some lines, and came up with a code in c which scans for nearby bluetooth devices, displays them, asks the users to choose one of the devices to bind, and accordingly binds that device. But for that, the device must be already paired up with the host computer. Here’s the code:

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>

int bt_scan (char baddr_list[][19], char name_list[][248] )
{
inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags;
int i, j;
char addr[19] = {0};
char name[248] = {0};

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

dev_id = hci_get_route(NULL);
sock = hci_open_dev( dev_id);
if (dev_id < 0 || sock < 0){
perror(“opening socket”);
exit(1);
}

len = 8;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));

num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
if( num_rsp < 0 ) perror(“hci_inquiry”);

for (i = 0; i < num_rsp; i++) {
ba2str(&(ii+i)->bdaddr, addr);
memset(name, 0, sizeof(name));
if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name), name, 0) < 0)
strcpy(name, “[unknown]”);
strcpy(name_list[i], name); strcpy(baddr_list[i], addr);
printf(“%d. %s %s\n”, i+1, addr, name);
}

free(ii);
close( sock );
return i;

}

static int create_dev(int ctl, int dev, uint32_t flags, bdaddr_t *bdaddr, char *strba)
{
struct rfcomm_dev_req req;
int err;

memset(&req, 0, sizeof(req));
req.dev_id = dev;
req.flags = flags;
bacpy(&req.src, bdaddr);

str2ba(strba, &req.dst);

req.channel = 1;

err = ioctl(ctl, RFCOMMCREATEDEV, &req);
if (err == EOPNOTSUPP)
fprintf(stderr, “RFCOMM TTY support not available\n”);
else if (err < 0)
perror(“Can’t create device”);

return err;
}

int bind_bt(char *strba)
{
bdaddr_t bdaddr;
int i, opt, ctl, dev_id, show_all = 0, err;

bacpy(&bdaddr, BDADDR_ANY);
ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
if (ctl < 0) {
perror(“Can’t open RFCOMM control socket”);
exit(1);
}

dev_id = atoi (“/dev/rfcomm0”);

err = create_dev(ctl, dev_id, 0, &bdaddr, strba);
close(ctl);

return err;
}

int main (int argc, char *argv[])
{
int count, choice, err;
char name_list[10][248], baddr_list [10][19], strba[19];

count = bt_scan(baddr_list, name_list);
if (count > 0){
x:
printf(“Enter the serial number of the device that you want to connect to : “);
scanf (“%d”, &choice);

if (choice > count){
printf (“Enter proper choice…\n”);
goto x;
}
else{
strcpy(strba, baddr_list[choice-1]);
err = bind_bt(strba);
if (err < 0) printf (“Might be you don’t have sufficient privileges, try running it as root\n”);
}
}
return 0;
}

To compile this code :

gcc foo.c -lbluetooth

Run the a.out file as root because the rfcomm binding operation needs root privileges.

Any suggestions or ways to improve the code are welcome.

How to setup a GPRS internet connection in Linux via bluetooth …

Often I hear questions like this “How do I connect to the internet from linux via my bluetooth mobile phone GPRS?”

Yes, there are ways to do that, but telling a newbie to go to the terminal and do hcitool scan, rfcomm, etc. spooks him out. And also The system-config-network, while setting up a Modem Connection through it, one has to com across port numbers, baud rate, etc. and a user not used to Linux, most of the time finds these things weird, especially the users. These issues need to be looked into and some actions are required to come up with a more user friendly interface in this regard. That’s another topic of discussion though …

Let’s see how to connect to the internet via GPRS over a phone with a Bluetooth Modem :

1. Use the bluetooth-applet to setup your phone if it is not yet paired with your PC. Alternatively you can do this via the terminal

$ bluetooth-applet

and then follow the on – screen instructions.

2. Once done setting up your phone, do the following in the terminal to know your mobile phone’s bluetooth address

$ hcitool scan

In my system, it shows something like this

Scanning …
00:1D:98:78:A2:A1    Nokia 5310 XpressMusic
00:1D:98:78:A2:A1 is the bluetooth address of my mobile phone. Yours will be of similar type.

3. Now as root, do the following

#rfcomm connect rfcomm0 <bluetooth address> 1

Keep this process running

4. Open System->Administration->Network, select New, then select Modem Connection, and enter the following values for the respective field

Modem Device:    /dev/rfcomm0

Baud Rate: 460800

this is the safe limit for most Nokia phones, may vary for different phones.

Then click Forward. Then fill in the requisite details, then click Forward, and accept the default settings, like automatically obtaining IP Address and DNS Information from provider. Then select Apply. And then click on File-> Save to save your new settings.

Then click the Activate button for the modem connection just set up, and enjoy.

4. Every time, you want to connect to the Internet, before activating the connection via Network, you have to connect your phone as a bluetooth modem as in step 3 .

Hope to see a new GUI dedicated to setting up bluetooth internet connection in Linux soon.