使用 c 代码使蓝牙可发现

Posted

技术标签:

【中文标题】使用 c 代码使蓝牙可发现【英文标题】:Making bluetooth discoverable using c code 【发布时间】:2016-10-09 06:27:45 【问题描述】:

我想做一个蓝牙服务器,可以启动,其他设备可以与之配对。

我可以正常编译代码,服务器启动,但是当我从安卓手机扫描蓝牙设备时看不到广告。

我想我需要打开可发现模式。

我尝试在 hci_lib.h 中搜索使蓝牙可被发现但找不到的函数。

这是我到现在为止的代码。

#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;

如何设置蓝牙可发现模式?

【问题讨论】:

【参考方案1】:

通过BlueZ命令行,通过hciconfig工具实现启用可发现性的命令如下:

hciconfig hciX piscan

其中 hciX 是您安装在系统上的 HCI 设备,在大多数情况下是 hci0。您可以尝试上述命令,如果它没有返回错误,那么您应该能够通过执行查询通过您的 android 设备看到您的 Linux 机器。如果这对你有用,那么你需要的代码可以在下面链接的 hciconfig 源代码中找到:-

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

然后你的出发点将是以下函数:-

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

希望对你有帮助

【讨论】:

【参考方案2】:

为了让 Youssif 的回答更进一步,这里是您可以使用的代码

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

【讨论】:

【参考方案3】:

我相信你想要 hci_inquiry() 函数。它在蓝牙适配器上启动设备发现。

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

这是一个很好的教程: http://people.csail.mit.edu/albert/bluez-intro/c404.html#bzi-choosing

【讨论】:

hci_inquiry() 函数用于扫描其他设备。它不会让蓝牙被发现。 你是对的,我很抱歉。 api有点混乱。您似乎可以使用 ioctl() 来做到这一点,但我觉得应该有更好的方法。你试过这个:***.com/questions/30058715/…

以上是关于使用 c 代码使蓝牙可发现的主要内容,如果未能解决你的问题,请参考以下文章

Android 蓝牙低功耗配对

查询期间蓝牙设备的可发现性

在Android上禁用蓝牙可发现模式

查看附近所有可发现的蓝牙设备 - Swift iOS XCode

C语言数据通过蓝牙传给APP之后发现问题。C语言中是Unsigned char 类型。安卓通过蓝牙

360发现MacOS蓝牙漏洞 可实现零点击无接触远程利用