最近需要在某个开发板上面通过蓝牙和手机蓝牙连接,并通过RFCOMM通信。还没有做过蓝牙RFCOMM相关工作,因此先在linux PC上面调试一下流程,并在此记录调试过程。

一、说明

RFCOMM协议基于L2CAP协议的串行(9针RS-232)仿真。

本文中实现了RFCOMM server和client通信。

二、设备

linux主机(Ubuntu-14.04)、linux虚拟机(Ubuntu-14.04)、Android手机一台、不知名蓝牙dongle_1(controller)、CSR 蓝牙dongle_2(controller)。

Linux主机+dongle_1作为server端; linux虚拟机+dongle_2作为client端;Android手机作为client端。

三、环境搭建

Server端:

1. 安装bluez协议栈

2. 查看bluetoothd进程是否启动:ps -ef|grep blue

root      1891     1  0  5月19 ?      00:00:00 /usr/sbin/bluetoothd

如果没有启动,执行:/usr/sbin/bluetoothd -C &

注:经过测试,该过程不是必须的。可能是因为server端程序是socket通信,不需要bluetoothd。

3. 查看bluetooth service是否存在:service --status-all | grep blue

如果不存在,执行:service bluetooth start

注:该步骤经过测试也可以不需要。执行service bluetooth stop,也可以正常通信。可能是因为server端程序是socket通信,不需要bluetooth service。

4. 将dongle_1插入linux主机端;并配置。

1> 执行:hciconfig,观察dongle状态是否为UP RUNNING,如果不为UP RUNNING,则执行:hciconfig hci0 UP

注:hci0是根据hciconfig打印的BD Address来确定的。如果有两个dongle,有可能是hci1。

2> 使蓝牙设备可见(可被其他蓝牙设备扫描到,如手机)

执行命令:hciconfig piscan

然后执行hciconfig,观察状态是否为UP RUNNING PSCAN ISCAN

3> 添加SPP服务

sdptool add SP

也可以执行添加所有服务:

sdptool add --channel=1 DID SP DUN LAN FAX OPUSH FTP HS HF SAP NAP GN PANU HID CIP CTP A2SRC A2SNK SYNCML NOKID PCSUITE SR1

4> 关闭pin码验证

hciconfig hci0 noauth;

5. 编写并编译测试程序

gcc -o rfcomm_server rfcomm_server.c

Client端(linux虚拟机):

1. 安装bluez协议栈

2. 查看bluetoothd进程是否启动:ps -ef|grep blue,如果没有启动,则启动该进程。(非必须)

3. 查看bluetooth service是否存在:service --status-all | grep blue  (非必须)

如果不存在,执行:service bluetooth start

4. 添加SPP服务,关闭pin码验证。

5. 创建RFCOMM设备节点:mknod /dev/rfcomm0 c 216 0

chmod 666 /dev/rfcomm0

6. 绑定server端蓝牙mac地址

rfcomm bind 0 00:19:86:00:2B:BD 1 //0表示rfcomm0, 00:19:86:00:2B:BD为server端的蓝牙地址,1为通道

7. 编写并编译rfcomm_client

Client端(Android手机)

下载蓝牙串口SPP应用程序

四、测试

1. Server + client(linux虚拟机)

1> 在server端执行rfcomm_server

2> 在client端执行rfcomm_client

可以在两端观察到写入和读出的数据

2. Server + Android手机

1> 在server端执行rfcomm_server

2> Client端,打开蓝牙SPP应用,扫描到server端的蓝牙设备,连接。即可和server端进行通信

rfcomm_server.c

#include #include#include#include#include

int str2ba(const char *str, bdaddr_t *ba)

{

uint8_t b[6];const char *ptr =str;inti;for (i = 0; i < 6; i++)

{

b[i]= (uint8_t) strtol(ptr, NULL, 16);if (i != 5 && !(ptr = strchr(ptr, ':')))

ptr= ":00:00:00:00:00";

ptr++;

}

}void baswap(bdaddr_t *dst, const bdaddr_t *src)

{

unsignedchar *d = (unsigned char *) dst;const unsigned char *s = (const unsigned char *) src;inti;for (i = 0; i < 6; i++)

d[i]= s[5-i];

}int ba2str(const bdaddr_t *ba, char *str)

{

uint8_t b[6];

baswap((bdaddr_t*) b, ba);return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",

b[0], b[1], b[2], b[3], b[4], b[5]);

}int main(int argc, char **argv)

{struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0};char buf[1024] = { 0};ints, client, bytes_read;

socklen_t opt= sizeof(rem_addr);char write_buf[1204]="hello world";char flag = 1;char count=0;//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);while( flag )

{

memset(buf,0, sizeof(buf));#if 0

//read data from the client

bytes_read = read(client, buf, sizeof(buf));if( bytes_read > 0)

{

printf("[rcv]:%s\n", buf);if(!strcmp(buf,"exit"))

{

flag= 0;

}//write( client,write_buf,16 );

}

usleep(5000);#endif

#if 1

//write data to client

strcpy( buf, "abcdefgh");

bytes_read= 9;

write( client,buf,bytes_read );

usleep(50000);#endif}//close connection

close(client);

close(s);return 0;

}

rfcomm_client.c

#include#include#include#include#include#include

int main( int argc, char **argv )

{intfd ;

unsignedchar buff[64] = "hello";char read_buff[128] = {0};intread_n;intwrite_n;

fd= open( "/dev/rfcomm0",O_RDWR);if( fd<0)

printf("open rfcomm0 error\n");while(1)

{#if 0

//printf( "write hello to rfcomm\n" );

write_n = write( fd, buff, 64);if( write_n<0)

printf("write error\n");else if(write_n==0)

printf("write nothing\n");elseprintf("write %d byte\n",write_n );//sleep(1);

#endif

#if 1memset( read_buff,0, sizeof(read_buff) );

read_n= read( fd, read_buff, sizeof(read_buff) );if( read_n > 0)

{

printf("[receive]:%s\n",read_buff );

}

usleep(50000);#endif}

close(fd);

}

在网上查了一下资料,有rfcomm_client.c是创建socket,并bind、connect,但是我调试的时候执行该程序,会报错。原因没有找到。下面将代码贴出来,以后可以找一下原因。

#include #include#include#include#include

int str2ba(const char *str, bdaddr_t *ba)

{

uint8_t b[6];const char *ptr =str;inti;for (i = 0; i < 6; i++)

{

b[i]= (uint8_t) strtol(ptr, NULL, 16);if (i != 5 && !(ptr = strchr(ptr, ':')))

ptr= ":00:00:00:00:00";

ptr++;

}

}int main(int argc, char **argv)

{struct sockaddr_rc addr = { 0};ints, status;char dest[18] = "00:19:86:00:2B:BD";//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 );

printf("connect device\n");//connect to server

status = connect(s, (struct sockaddr *)&addr, sizeof(addr));//send a message

if( status == 0) {

status= write(s, "hello!", 6);

}if( status < 0 ) perror("uh oh");

close(s);return 0;

}

网上资料,有文章介绍需要设置rfcomm.conf, 个人以为如果需要client上电自动连接,可以用此方法进行设置(还需要进行其他配置),和用命令设置效果一样。

其中:不知名蓝牙dongle ,hciconfig -a信息如下:

root@localhost:bin# hciconfig -a

hci0:   Type: BR/EDR  Bus: USB

BD Address: 00:19:86:00:2B:BD  ACL MTU: 1021:8  SCO MTU: 64:1

UP RUNNING PSCAN

RX bytes:66976 acl:1214 sco:0 events:1729 errors:0

TX bytes:67686 acl:1976 sco:0 commands:203 errors:0

Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87

Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3

Link policy: RSWITCH SNIFF

Link mode: SLAVE ACCEPT

Name: 'localhost-0'

Class: 0x600100

Service Classes: Audio, Telephony

Device Class: Computer, Uncategorized

HCI Version: 4.0 (0x6)  Revision: 0x1000

LMP Version: 4.0 (0x6)  Subversion: 0x220e

linux蓝牙串口 rfcomm,蓝牙RFCOMM通信相关推荐

  1. php蓝牙串口,打印机蓝牙模块(串口)使用说明及参考电路

    打印机蓝牙模块(串口)使用说明及参考电路 打印机蓝牙模块(串口),是专门针对热敏打印机.POS打印机等产品开发的蓝牙模块,可方便地实现上位机PC.PDA.手机与打印机的无线连接,形成透明串口,支持硬件 ...

  2. wince下的蓝牙串口通信

    wince下的蓝牙串口通信(上) wince下的蓝牙串口通信(下)--客户端

  3. Android 蓝牙串口通信工具类 SeriaPortUtil 2.0.+

    原文地址:https://www.shanya.world/archives/2fd981ea.html SerialPortUtil 提示 最新版本 3.0.+ 已发布,其对比 2.0.+ 版本,A ...

  4. ESP32-pico-kit 串口通信 与 蓝牙串口

    文章目录 一.串口及ESP32介绍 1.串口通信 2.ESP32-pico-kit 二.串口UART 1.串口引脚 2.串口常用函数 (1)开启串口 (2)关闭串口 (3)输出数据 (4)读取数据 ( ...

  5. 基于蓝牙串口通信,实现实时脉象采集(项目总结与思路梳理)

    写在前面 本项目用到的 主要知识点: 手机蓝牙 (动态权限申请,蓝牙打开,连接,配对,基于2.0蓝牙串口 Socket 通信),自定义View SurfaceView(实时绘制采集到的脉象波形).本人 ...

  6. 关于Android蓝牙串口通信那点破事

    Android蓝牙串口通讯 闲着无聊玩起了Android蓝牙模块与单片机蓝牙模块的通信,简单思路就是要手机通过蓝牙发送控制指令给单片机,并作简单的控制应用.单片机的蓝牙模块连接与程序暂且略过,此文主要 ...

  7. java 蓝牙读取数据格式,单片机与安卓手机通过蓝牙串口模块利用JSON数据格式通信实例...

    原标题:单片机与安卓手机通过蓝牙串口模块利用JSON数据格式通信实例 JSON 指的是 Java 对象表示法(Java Object Notation),JSON 是轻量级的文本数据交换格式,JSON ...

  8. Android与蓝牙串口模块通信

    由于项目的需要的Android与蓝牙模块通信,发了时间学习了下,实现了Android的与蓝牙模块的通信 1.蓝牙串口模块使用SPP-CA模块 蓝牙串口模块就是使用单片机的TX,RX与蓝牙模块通信, ...

  9. 【嵌入式】蓝牙串口通信透传模块(HC-08)的使用

    一 使用蓝牙透传模块简介 HC-08 蓝牙串口通信模块是新一代的基于 Bluetooth Specification V4.0 BLE 蓝牙协议的数传模块.无线工作频段为 2.4GHz ISM,调制方 ...

最新文章

  1. mongodb导入bson文件_Python爬虫进阶教程(七):MongoDB数据库
  2. kindeditor用法
  3. 让你的英语口语妙语连珠的句子
  4. [react] 路由切换时同一组件无法重新渲染的有什么方法可以解决?
  5. html 指定对象为块元素,html内联(行内)元素、块级(块状)元素和行内块元素分类...
  6. java script中==和===_Java Script 中 ==(Equal) 和 === (Identity Equal) 的区别和比较算法逻辑...
  7. python服务端编程_Python实现的简单文件传输服务器和客户端
  8. SQL SERVER2000教程-第五章 处理数据 第二节 检索数据
  9. dos下载ftp文件linux,在DOS和LINUX下的FTP命令
  10. DB2 亲身实例(GUI界面) 加 笔记和注意事项
  11. 正确修改LINUX SHELL的.bashrc,显示短路径
  12. 计算语言学之拼写纠错
  13. 华为存储更换故障硬盘
  14. 学习C++:C++基础(一)类和对象及C++对C的扩展
  15. 屏蔽非微信客户端和支付宝登陆登录操作
  16. 工程师,请把你的英语磨锐
  17. Seaborn(三)调色板palette
  18. 基于Python实现五子棋
  19. 让机器人懂感情:表情符与深度学习
  20. Revit建模弹窗警告:图元稍微偏离了轴,可能会导致不精确

热门文章

  1. 进程和线程上下文切换_编码人员:上下文切换对于计算机和关系而言都很难
  2. Mac虚拟机安装Windows server 2003 及安装组件提示插入软盘、Outlook提示无法连接pop3服务器
  3. Python 获取EXSI宿主机上虚拟机数据
  4. 小程序直播,助力教育机构获客
  5. CentOS下载安装rar压缩软件
  6. 这套动捕方案居然只用一个摄像头?
  7. 封神台靶场writeup
  8. python字典多重
  9. python花萼长度表_读取iris数据集中的花萼长度数据(已保存为csv格式),并对其进行排序、去重,并求出和、累积和、均值、标准差、方差、最小值、最大值...
  10. Oracle学习之建表