9

I want to make a bluetooth server that starts and other devices can pair with it.

I can get the code to compile fine, the server starts, but I cannot see the advertisement when I scan for bluetooth devices from android phone.

I think i need to switch on the discoverable mode on.

I tried searching for the function in the hci_lib.h which will make the bluetooth discoverable but couldn't find it.

This is the code I have till now.

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>

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

dev_id = hci_get_route(NULL);
if (dev_id < 0) {
    perror("No Bluetooth Adapter Available");
    exit(1);
}

if (hci_devinfo(dev_id, &dev_info) < 0) {
    perror("Can't get device info");
    exit(1);
}

sock = hci_open_dev( dev_id );
if (sock < 0) {
    perror("HCI device open failed");
    free(info);
    exit(1);
}


// 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));

// put socket into listening mode
listen(s, 1);

// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);

ba2str( &rem_addr.rc_bdaddr, buf );
fprintf(stderr, "accepted connection from %s\n", buf);
memset(buf, 0, sizeof(buf));

// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if( bytes_read > 0 ) {
    printf("received [%s]\n", buf);
}

// close connection
close(client);
close(s);
return 0;
}

What has to be done to set bluetooth discoverable mode on?

Yogesh Ghaturle
  • 307
  • 3
  • 17

3 Answers3

6

Through the BlueZ command line, the command to enable discoverability is achieved through the hciconfig tool as follows:

hciconfig hciX piscan

Where hciX is your HCI device installed on the system, and in most cases will be hci0. You can try the above command and if it doesn't return an error then you should be able to see your Linux machine through your Android device by performing an inquiry. If this does work for you, then the code that you need can be found in the hciconfig source in the link below:-

https://github.com/aguedes/bluez/blob/master/tools/hciconfig.c

And then your starting point will be the following function:-

static void cmd_scan(int ctl, int hdev, char *opt)
{
    struct hci_dev_req dr;

    dr.dev_id  = hdev;
    dr.dev_opt = SCAN_DISABLED;
    if (!strcmp(opt, "iscan"))
        dr.dev_opt = SCAN_INQUIRY;
    else if (!strcmp(opt, "pscan"))
        dr.dev_opt = SCAN_PAGE;
    else if (!strcmp(opt, "piscan"))
        dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;

    if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) {
        fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n",
                        hdev, strerror(errno), errno);
        exit(1);
    }
}

I hope this helps

Youssif Saeed
  • 11,789
  • 4
  • 44
  • 72
1

To take Youssif's answer a step further, here is code you can use

#include <bluetooth/hci.h>
#include <sys/ioctl.h>

int ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
// Open HCI socket
if (ctl < 0) {
    // Can't open HCI socket
}

struct hci_dev_req dr;
dr.dev_id = 0;  // hci0
dr.dev_opt = SCAN_DISABLED;
dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY;

if (ioctl(ctl, HCISETSCAN, (unsigned long)&dr) < 0) {
   // Can't set scan mode
} else {
   // "hci0 is now discoverable
}

close(ctl);

// Normal setup of rfcomm
int socket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
// ....
FrickeFresh
  • 1,688
  • 1
  • 19
  • 31
-1

I believe you want the hci_inquiry() function. It initiates device discovery on the bluetooth adapter.

int hci_inquiry (int adapter_id, int len, int max_rsp,
    const uint8 t *lap, inquiry_info **devs, long flags);

Here is a good tutorial on it: http://people.csail.mit.edu/albert/bluez-intro/c404.html#bzi-choosing

JT Harkey
  • 49
  • 1
  • 6
  • hci_inquiry() function is used to scan other devices. It doesn't make the bluetooth discoverable. – Yogesh Ghaturle Jun 13 '16 at 04:11
  • You're right, I apologize. The api is a bit confusing. You seem to be able to do this with ioctl(), but I feel there should be a better way. Have you tried this: http://stackoverflow.com/questions/30058715/bluez-hci-api-to-make-the-host-discoverable?rq=1 – JT Harkey Jun 14 '16 at 11:07