| package hci |
| |
| import ( |
| "net" |
| |
| "github.com/go-ble/ble" |
| "github.com/go-ble/ble/linux/adv" |
| "github.com/go-ble/ble/linux/hci/evt" |
| ) |
| |
| // RandomAddress is a Random Device Address. |
| type RandomAddress struct { |
| ble.Addr |
| } |
| |
| // [Vol 6, Part B, 4.4.2] [Vol 3, Part C, 11] |
| const ( |
| evtTypAdvInd = 0x00 // Connectable undirected advertising (ADV_IND). |
| evtTypAdvDirectInd = 0x01 // Connectable directed advertising (ADV_DIRECT_IND). |
| evtTypAdvScanInd = 0x02 // Scannable undirected advertising (ADV_SCAN_IND). |
| evtTypAdvNonconnInd = 0x03 // Non connectable undirected advertising (ADV_NONCONN_IND). |
| evtTypScanRsp = 0x04 // Scan Response (SCAN_RSP). |
| ) |
| |
| func newAdvertisement(e evt.LEAdvertisingReport, i int) *Advertisement { |
| return &Advertisement{e: e, i: i} |
| } |
| |
| // Advertisement implements ble.Advertisement and other functions that are only |
| // available on Linux. |
| type Advertisement struct { |
| e evt.LEAdvertisingReport |
| i int |
| sr *Advertisement |
| |
| // cached packets. |
| p *adv.Packet |
| } |
| |
| // setScanResponse ssociate sca response to the existing advertisement. |
| func (a *Advertisement) setScanResponse(sr *Advertisement) { |
| a.sr = sr |
| a.p = nil // clear the cached. |
| } |
| |
| // packets returns the combined advertising packet and scan response (if presents) |
| func (a *Advertisement) packets() *adv.Packet { |
| if a.p != nil { |
| return a.p |
| } |
| return adv.NewRawPacket(a.Data(), a.ScanResponse()) |
| } |
| |
| // LocalName returns the LocalName of the remote peripheral. |
| func (a *Advertisement) LocalName() string { |
| return a.packets().LocalName() |
| } |
| |
| // ManufacturerData returns the ManufacturerData of the advertisement. |
| func (a *Advertisement) ManufacturerData() []byte { |
| return a.packets().ManufacturerData() |
| } |
| |
| // ServiceData returns the service data of the advertisement. |
| func (a *Advertisement) ServiceData() []ble.ServiceData { |
| return a.packets().ServiceData() |
| } |
| |
| // Services returns the service UUIDs of the advertisement. |
| func (a *Advertisement) Services() []ble.UUID { |
| return a.packets().UUIDs() |
| } |
| |
| // OverflowService returns the UUIDs of overflowed service. |
| func (a *Advertisement) OverflowService() []ble.UUID { |
| return a.packets().UUIDs() |
| } |
| |
| // TxPowerLevel returns the tx power level of the remote peripheral. |
| func (a *Advertisement) TxPowerLevel() int { |
| pwr, _ := a.packets().TxPower() |
| return pwr |
| } |
| |
| // SolicitedService returns UUIDs of solicited services. |
| func (a *Advertisement) SolicitedService() []ble.UUID { |
| return a.packets().ServiceSol() |
| } |
| |
| // Connectable indicates weather the remote peripheral is connectable. |
| func (a *Advertisement) Connectable() bool { |
| return a.EventType() == evtTypAdvDirectInd || a.EventType() == evtTypAdvInd |
| } |
| |
| // RSSI returns RSSI signal strength. |
| func (a *Advertisement) RSSI() int { |
| return int(a.e.RSSI(a.i)) |
| } |
| |
| // Addr returns the address of the remote peripheral. |
| func (a *Advertisement) Addr() ble.Addr { |
| b := a.e.Address(a.i) |
| addr := net.HardwareAddr([]byte{b[5], b[4], b[3], b[2], b[1], b[0]}) |
| if a.e.AddressType(a.i) == 1 { |
| return RandomAddress{addr} |
| } |
| return addr |
| } |
| |
| // EventType returns the event type of Advertisement. |
| // This is linux sepcific. |
| func (a *Advertisement) EventType() uint8 { |
| return a.e.EventType(a.i) |
| } |
| |
| // AddressType returns the address type of the Advertisement. |
| // This is linux sepcific. |
| func (a *Advertisement) AddressType() uint8 { |
| return a.e.AddressType(a.i) |
| } |
| |
| // Data returns the advertising data of the packet. |
| // This is linux sepcific. |
| func (a *Advertisement) Data() []byte { |
| return a.e.Data(a.i) |
| } |
| |
| // ScanResponse returns the scan response of the packet, if it presents. |
| // This is linux sepcific. |
| func (a *Advertisement) ScanResponse() []byte { |
| if a.sr == nil { |
| return nil |
| } |
| return a.sr.Data() |
| } |