带Golang的蓝牙RFCOMM插槽

时间:2017-10-10 13:41:22

标签: sockets go bluetooth

我试图从Go打开一个RFCOMM套接字。我有一个测试设置,客户端连接到echo服务器。我坚持的部分是设置蓝牙地址。在C中你有str2ba,它将MAC字符串转换为六个元素的字节数组。在Go中,它似乎期望该设备是一个uint16。我不确定这是如何运作的。

package main

import (
    "fmt"
    "log"
    "syscall"

    "golang.org/x/sys/unix"
)


func main() {
    fd, err := unix.Socket(syscall.AF_BLUETOOTH, syscall.SOCK_STREAM, unix.BTPROTO_RFCOMM)
    if err != nil {
        log.Fatalf("%v\n", err)
    }
    addr := unix.SockaddrHCI{Dev: 1, Channel: 1}
    unix.Connect(fd, addr)
    unix.Write(fd, []byte("Hello"))
    var data []byte
    unix.Read(fd, data)
    fmt.Printf("Received: %v\n", string(data))
}

Dev中的unix.SockaddrHCI成员是uint16,我认为这是代表蓝牙MAC。这是对的吗?

感谢。

1 个答案:

答案 0 :(得分:3)

我认为topicstarter已经不需要这个答案,但是昨天我需要它))Kinda找到了正确的答案,所以让我分享适用于我的情况的代码(这是Arduino的HC06蓝牙模块)。我认为该模块已经被bt发现并配对(例如通过bluetoothctl)。

package main

import (
    "strconv"
    "strings"
    "syscall"

    "github.com/sirupsen/logrus"
    "golang.org/x/sys/unix"
)

func main() {
    mac := str2ba("00:19:10:08:FE:08") // YOUR BLUETOOTH MAC ADDRESS HERE

    fd, err := unix.Socket(syscall.AF_BLUETOOTH, syscall.SOCK_STREAM, unix.BTPROTO_RFCOMM)
    check(err)
    addr := &unix.SockaddrRFCOMM{Addr: mac, Channel: 1}

    var data = make([]byte, 50)
    logrus.Print("connecting...")
    err = unix.Connect(fd, addr)
    check(err)
    defer unix.Close(fd)
    logrus.Println("done")

    for {
        n, err := unix.Read(fd, data)
        check(err)
        if n > 0 {
            logrus.Infof("Received: %v\n", string(data[:n]))
        }
    }
}

func check(err error) {
    if err != nil {
        logrus.Fatal(err)
    }
}

// str2ba converts MAC address string representation to little-endian byte array
func str2ba(addr string) [6]byte {
    a := strings.Split(addr, ":")
    var b [6]byte
    for i, tmp := range a {
        u, _ := strconv.ParseUint(tmp, 16, 8)
        b[len(b)-1-i] = byte(u)
    }
    return b
}