104 lines
2.5 KiB
Go
104 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/paypal/gatt"
|
|
"github.com/paypal/gatt/examples/option"
|
|
"myschools.me/suguo/ble-ibeacon/model"
|
|
"myschools.me/suguo/ble-ibeacon/sqlite"
|
|
)
|
|
|
|
type IBeancon struct {
|
|
Uuid string
|
|
Major uint16
|
|
Minor uint16
|
|
}
|
|
|
|
func NewiBeacon(data []byte) (*IBeancon, error) {
|
|
if len(data) < 25 || binary.BigEndian.Uint32(data) != 0x4c000215 {
|
|
return nil, errors.New("not an iBeacon")
|
|
}
|
|
beacon := new(IBeancon)
|
|
beacon.Uuid = strings.ToUpper(hex.EncodeToString(data[4:8]) + hex.EncodeToString(data[8:10]) + hex.EncodeToString(data[10:12]) + hex.EncodeToString(data[12:14]) + hex.EncodeToString(data[14:20]))
|
|
beacon.Major = binary.BigEndian.Uint16(data[20:22])
|
|
beacon.Minor = binary.BigEndian.Uint16(data[22:24])
|
|
return beacon, nil
|
|
}
|
|
|
|
func onPerhipheralDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
|
|
// if p.ID() != "78:2C:29:16:F2:78" {
|
|
// return
|
|
// }
|
|
// if p.ID() != "90:98:38:F5:DA:60" {
|
|
// return
|
|
// }
|
|
// if !(p.ID() == "C6:1A:05:02:06:C0" || p.ID() == "90:98:38:F5:DA:60") {
|
|
// return
|
|
// }
|
|
fmt.Println("NAME:", a.LocalName, "T:", time.Now(), "MAC:", p.ID(), "RSSI:", rssi, "LEN:", len(a.ManufacturerData))
|
|
|
|
sqlite.Init(&sqlite.Config{
|
|
DBFile: fmt.Sprintf("./ble%s.db", p.ID()),
|
|
})
|
|
|
|
if err := sqlite.Migrate(&model.Rssi{}); err != nil {
|
|
log.Fatalln(err.Error())
|
|
}
|
|
db, err := sqlite.New()
|
|
if err != nil {
|
|
log.Fatalln(err.Error())
|
|
}
|
|
if err := db.Save(&model.Rssi{
|
|
MAC: p.ID(),
|
|
Name: a.LocalName,
|
|
Rssi: int32(rssi),
|
|
PackageLen: len(a.ManufacturerData),
|
|
}).Error; err != nil {
|
|
log.Fatalln(err.Error())
|
|
}
|
|
// for _, d := range a.ServiceData {
|
|
// fmt.Println("uuid:", d.UUID, " data:", d.Data)
|
|
// }
|
|
// b, err := NewiBeacon(a.ManufacturerData)
|
|
// if err != nil {
|
|
// fmt.Println(err.Error())
|
|
// return
|
|
// }
|
|
// fmt.Printf("UUID: %s Major: %d Minor: %d RSSI: %d\n", b.Uuid, b.Major, b.Minor, rssi)
|
|
}
|
|
|
|
func onStateChanged(device gatt.Device, s gatt.State) {
|
|
switch s {
|
|
case gatt.StatePoweredOn:
|
|
device.Scan([]gatt.UUID{}, true)
|
|
return
|
|
default:
|
|
device.StopScanning()
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
sqlite.Init(&sqlite.Config{
|
|
DBFile: "./ble.db",
|
|
})
|
|
|
|
if err := sqlite.Migrate(&model.Rssi{}); err != nil {
|
|
log.Fatalln(err.Error())
|
|
}
|
|
|
|
dev, err := gatt.NewDevice(option.DefaultClientOptions...)
|
|
if err != nil {
|
|
log.Fatalf("Failed to open device, err:%s\n", err)
|
|
}
|
|
dev.Handle(gatt.PeripheralDiscovered(onPerhipheralDiscovered))
|
|
dev.Init(onStateChanged)
|
|
select {}
|
|
}
|