使用两个适配器在一台机器上运行两个蓝牙程序 新帖子旧帖子

问题描述

新帖子

我现在更好地理解了我的问题,而不是创建一个新线程,我将对其进行更新。

因此使用hci_open_dev是错误的,因为它仅打开本地BT适配器的套接字。这对我建立与远程设备的连接没有帮助。

总而言之-我的笔记本电脑中有一个内置的BT适配器,我已经购买了一个USB BT适配器,并将其插入同一台笔记本电脑中。现在,我想在一台可以通信的机器上运行两个程序。为此,他们需要使用不同的适配器。

bind的第二个参数是struct sockaddr*,我只需将先前的struct sockaddr_rc*强制转换为。 侦听套接字的bdaddr_t的{​​{1}}字段指定要使用的BT适配器,我可以这样做:

struct sockaddr

但是,对于传出连接,我不确定如何指定要使用的适配器。代码大致如下:

struct sockaddr_rc loc_addr = { 0 },rem_addr = { 0 };
// address of the built in BT adapter on my machine
const char* adapter = "60:F2:62:1B:9C:74";
// converting it to a bdaddr_t*
bdaddr_t* adapterbdadd = strtoba(adapter);

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

// bind socket to port 1
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = *adapterbdadd;
loc_addr.rc_channel = (uint8_t) 1;
bind(s,(struct sockaddr *)&loc_addr,sizeof(loc_addr));

// set the socket to listening mode
listen(s,1);

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

// convert the bdaddr to a char* (just assume buf is defined elsewhere)
ba2str( &rem_addr.rc_bdaddr,buf );
fprintf(stderr,"accepted connection from %s\n",buf);

// free socket resources
close(client);
close(s);

如上所述,我只能指定要连接到哪个设备,要使用哪个设备。当我先启动监听程序,然后再启动客户端时,从不建立连接。运行struct sockaddr_rc addr = { 0 }; // This is the same address that should be used by the listening program above char dest[18] = "60:F2:62:1B:9C:74"; // allocate a socket int s = socket(AF_BLUETOOTH,BTPROTO_RFCOMM); // set the connection parameters. Want to connect to the listening program // and connect through port 1. If I change both programs to use port 0 I // get an Invalid Argument error from this program. addr.rc_family = AF_BLUETOOTH; addr.rc_channel = (uint8_t) 1; str2ba( dest,&addr.rc_bdaddr ); // connect to listening program int status = connect(s,(struct sockaddr *)&addr,sizeof(addr)); // This program never reaches beyond this point if( status == 0 ) { printf("successfully connected\n"); } else { perror("error connecting"); } close(s); 的输出如下所示:

hciconfig

我不是BT专家,但是我在这里看不到任何警告的信息。还有其他人吗? 如果有人能指出我为什么这两个程序不能互相交谈,我将非常感激


旧帖子

我正在笔记本电脑上开发一些蓝牙(BT)(普通蓝牙,而不是低功耗蓝牙)软件,为了在一台计算机上进行测试,我购买了第二个BT适配器(华硕USB-BT400)。插入后,我可以立即使用hci1: Type: Primary Bus: USB BD Address: 60:F2:62:1B:9C:74 ACL MTU: 1021:4 SCO MTU: 96:6 UP RUNNING RX bytes:16967 acl:0 sco:0 events:2751 errors:0 TX bytes:678007 acl:0 sco:0 commands:2749 errors:0 hci0: Type: Primary Bus: USB BD Address: 5C:F3:70:9D:BC:07 ACL MTU: 1021:8 SCO MTU: 64:1 UP RUNNING RX bytes:1016 acl:0 sco:0 events:57 errors:0 TX bytes:3679 acl:0 sco:0 commands:57 errors:0 看到它。

我试图调整程序以使用适当的适配器,但是它不起作用,我不确定为什么。我是BT编程的新手,所以我可能误会了一些东西。要使程序A使用地址为hciconfig的适配器,我运行了

addr1

其中int dev_id = hci_devid("60:F2:62:1B:9C:74"); int err = hci_open_dev(dev_id); if(err < 0) { printf("error opening adapter device\n"); } "60:F2:62:1B:9C:74"。配套程序执行相同的操作,但是使用了其他适配器地址。

当我运行这两个程序时,不会打印错误(是否成功选择了适配器?),但是这些程序什么也不做。稍后,客户端程序将打印addr1如果有人能解释我在选择适配器时做错了什么,我将非常感谢。我还尝试在一台笔记本电脑上运行服务器,而另一台笔记本电脑上运行客户端,但是那里也没有任何反应。在那种情况下,我没有明确选择BT适配器,因为我希望它默认为唯一可用的适配器。我没有考虑到示例代码可能是错误的,但是如果有人看到任何错误,请指出来。

完整的代码如下。我试图通过服务器和客户端之间的RFCOMM连接运行一个简单的示例。该示例是从Albert S. Huang和Larry Rudolph借的《面向程序员的蓝牙基础知识》一书中借来的,之后我尝试对其进行修改。


服务器程序

Uh Oh! The Host is Down

客户端程序

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.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;
    socklen_t opt = sizeof(rem_addr);

    int dev_id = hci_devid("60:F2:62:1B:9C:74");
    int err = hci_open_dev(dev_id);    
    if(err < 0) {
        printf("error opening laptop device\n");
    }


    // allocate socket
    s = socket(AF_BLUETOOTH,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,sizeof(loc_addr));

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

    // accept one connection
    client = accept(s,&opt);

    ba2str( &rem_addr.rc_bdaddr,buf );
    fprintf(stderr,buf);
    memset(buf,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;
}

解决方法

好的,所以我在@phy和@sjanc用户的Zephyr闲置频道中获得了一些帮助。有些事情我不得不改变。首先,我对strtoba的用法已更改为str2bastrtoba进行了一些奇怪的交换。

第二,即使客户端程序也可以通过bind指定要使用哪个BT适配器,这与服务器程序的操作类似。就我而言,我首先启动服务器,然后将为客户端分配免费的适配器。我不需要明确说明。

最后但绝对是最重要的,事实证明,您必须指示Linux使BT适配器可被发现。我通过运行hciconfig hci0 piscanhciconfig hci1 piscan来做到这一点。

最后完成程序:

客户

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

int main(int argc,char **argv)
{
    struct sockaddr_rc addr = { 0 },laddr = {0};
    int s,status;
    char dest[18]       = "60:F2:62:1B:9C:74";

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

    // set the connection parameters (who to connect to)
    addr.rc_family = AF_BLUETOOTH;
    addr.rc_channel = (uint8_t) 1;
    str2ba( dest,&addr.rc_bdaddr );

    // connect to server
    status = connect(s,(struct sockaddr *)&addr,sizeof(addr));

    // send a message
    if( status == 0 ) {
        printf("successfully connected\n");
    }

    close(s);
    return 0;
}

服务器

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.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;
    socklen_t opt = sizeof(rem_addr);

    // I want to use the built in BT adapter
    const char* adapter = "60:F2:62:1B:9C:74";

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

    // bind socket to port 1 of the first available 
    // local bluetooth adapter
    loc_addr.rc_family = AF_BLUETOOTH;
    str2ba(adapter,&loc_addr.rc_bdaddr);
    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,sizeof(buf));

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...