蓝牙rfcomm

rfcomm的使用,类似tcp, 也有port的概念,在rfcomm中,称为channel, channel可以从1到30
————-
L2CAP, 默认最大包是 672, 但可以协商到65535
在L2CAP中, port 被称作psm(Protocol Service Multiplexers), 从1到32767的奇数。
——————
通过 Service Discovery Protocol 来寻找端口号

Linux下蓝牙工具

$   hciconfig 
hci0:	Type: Primary  Bus: USB
	BD Address: E1:E2:E3:E7:E8:91  ACL MTU: 1021:4  SCO MTU: 96:6
	UP RUNNING PSCAN ISCAN 
	RX bytes:16759 acl:20 sco:0 events:2538 errors:0
	TX bytes:605245 acl:20 sco:0 commands:2498 errors:0

关闭 
hciconfig hci0 down
开启
hciconfig hci0 up
查看设备名称
 hciconfig hci0 name
hci0:	Type: Primary  Bus: USB
	BD Address: E1:E2:E3:E7:E8:91  ACL MTU: 1021:4  SCO MTU: 96:6
	Name: 'radio'

这笔记本上确实是usb的蓝牙适配器

$  lsusb
Bus 001 Device 004: ID 8087:0a2b Intel Corp. Bluetooth wireless interface

hcitool用来搜索设备,或者显示底层的连接

hcitool scan
...
hcitool con

sdptool用来搜索并浏览 SDP服务, 或者配置本机的SDP

 $ sdptool browse  88:BB:99:11:22:33

Browsing 88:BB:99:11:22:33 ...

Service RecHandle: 0x10001
Service Class ID List:
  "PnP Information" (0x1200)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 1
  "SDP" (0x0001)
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "PnP Information" (0x1200)
    Version: 0x0100

Failed to connect to SDP server on 88:BB:99:11:22:33 Connection refused
Service Name: SerialPort
Service RecHandle: 0x10007
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 6
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100

而 hcidump 则类似于 tcpdump
l2ping类似于ping

l2ping  88:BB:99:11:22:33
Ping: 88:BB:99:11:22:33 from E1:E2:E3:E7:E8:91 (data size 44) ...
0 bytes from 88:1B:99:16:F6:AD id 0 time 7.11ms
0 bytes from 88:1B:99:16:F6:AD id 1 time 5.95ms
0 bytes from 88:1B:99:16:F6:AD id 2 time 4.80ms
0 bytes from 88:1B:99:16:F6:AD id 3 time 4.66ms

发送 echo 包到另一台设备
echo包是一个特殊类型的 LCAP包

rfcomm命令

rfcomm bind /dev/rfcomm0 88:BB:99:11:22:33 6

将channel 6 绑定到 /dev/rfcomm0 上,形成一个虚拟 serial port

rfcomm bind 6 98:D3:31:FC:73:2D

将channel 6 绑定到 /dev/rfcomm6上

或者不绑定,直接连接

rfcomm connect /dev/rfcomm0 88:BB:99:11:22:33 6

在 Python 3.3 之后 socket,直接支持蓝牙

import socket
import binascii

macAddr = '88:BB:99:11:22:33'
port = 6

s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.connect((macAddr, port))

s.send(binascii.unhexlify('1200AAAAAA9669000B0600FFF20000000000')) 
data = s.recv(4)
print(data)

如果不支持AF_BLUETOOTH, 也可以用串口, 但是必须 先绑定正确的channel

import serial

DEVICE = '/dev/rfcomm6'
BAUD_RATE = 115200

s = serial.Serial(DEVICE, BAUD_RATE)
print('Connect to', DEVICE)

# Send data
s.write(b'hello\n')

# Receive data
data = s.read(3)
print(data)

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注