gorileylink

package module
v0.0.0-...-34b6559 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 13, 2019 License: Apache-2.0 Imports: 10 Imported by: 0

README

RileyLink BLE driver and utilities in Go.

Currently only works on Linux, but should work with Mac OS X after minor platform abstraction

Caveats

NO WARRANTY EXPRESSED OR IMPLIED

There are many, this list is not exhaustive.

root access required

One of the most annoying is that it requires extended capabilities to function and thus everything must be called as root, or with explicit granted capability privileges:

$ sudo setcap cap_net_admin,cap_net_raw+ep ./grl-demo
$ ./grl-demo SWEETBREAD-TWO

This appears to be an inherited caveat of the BT library (github.com/currantlabs/ble); likely related to the requirement that all things start as a "scan", vs. a direct (address) connect which by design does not need privs

Existing BT connections drop during use

Existing connections will be terminated temporarily (e.g. your wireless mouse will stop working and your heavy metal music will blare out of your speakers instead of your BT headset)

Temporary name confusion

For some reason, a rename(A, B) followed immediately by a rename(B, A) will not work, and it will not appear as B until you interact with it as A for something. This may be due to value caching on some layer.

Connecting

A RileyLink can be identified either by its current custom name (e.g. SWEETBREAD-TWO), or its BT address (e.g. 88:6B:0F:FF:FF:FF)

Utilities

gorileylink ships with some useful utilities. To build these, it's recommended that you be in a ~/go/bin directory (or wherever you like to store custom-built utilities, you do you), and then e.g. for grl-demo:

$ go get -v -u github.com/thecubic/gorileylink/cmd/grl-demo

This results in a grl-demo binary. go get can just be go build after the module is fetched (and it has to be when developing on a local head)

This will either need to be called as root (via sudo), or can be called as a regular user provided granted capabilities:

$ sudo setcap cap_net_admin,cap_net_raw+ep ~/go/bin/grl-demo

The utilities accept identifying RileyLinks by name or by address. Should there be two with the same name, the "first" matching one wins.

grl-rename: Naming Utility

WARNING: there is a weird here; the RileyLink may have both names temporarily

You can rename a RileyLink to any accepted name from address or name input, or just report the current name by not providing a new name

$ go build github.com/thecubic/gorileylink/cmd/grl-rename
$ sudo ~/go/bin/grl-rename SWEETBREAD-TWO DaveyLink
INFO[0001] Renamed                                       customName=DaveyLink customNameBefore=SWEETBREAD-TWO rileylink=SWEETBREAD-TWO
$ # see WARNING above
$ sudo ~/go/bin/grl-rename DaveyLink
INFO[0003] Report Name                                   customName=DaveyLink rileylink=DaveyLink
grl-info: Quick supervisor-chip (BLE) information

This reads the immediate information from the device; the BT address, the custom name, the BLE firmware version, and the battery level which is really not reliable at this time (here it says 80% but it's 100% and plugged-in)

$ go build github.com/thecubic/gorileylink/cmd/grl-info
$ sudo ~/go/bin/grl-info  SWEETBREAD-TWO
SWEETBREAD-TWO @ 88:6b:0f:ff:ff:ff: SWEETBREAD-TWO ble_rfspy 2.0 80%
grl-leds: Set diagnostic LED mode

This sets the diagnostic LED mode, so that both blues will light up when it is talking to the the pump (or not). Like grl-rename, providing no new value results in just fetching the existing value.

$ go build github.com/thecubic/gorileylink/cmd/grl-leds 
$ sudo ~/go/bin/grl-leds SWEETBREAD-TWO
INFO[0001] LED Mode                                      leds=off rileylink=SWEETBREAD-TWO
$ sudo ~/go/bin/grl-leds SWEETBREAD-TWO on
INFO[0002] LED Mode                                      leds=on rileylink=SWEETBREAD-TWO
grl-demo: Demo application

Effectively a tour of supported features.

$ go build github.com/thecubic/gorileylink/cmd/grl-demo
$ sudo ~/go/bin/grl-demo -debug SWEETBREAD-TWO
DEBU[0005] connection succeeded                          nameoraddress=SWEETBREAD-TWO
DEBU[0005] bind as RileyLink succeeded                   nameoraddress=SWEETBREAD-TWO
DEBU[0005] BLE Subscription Successful                  
INFO[0005] Battery Level                                 batteryLevel=81
INFO[0005] Custom Name                                   customName=SWEETBREAD-TWO
INFO[0005] BLE Version                                   bleversion="ble_rfspy 2.0"
INFO[0005] State: OK                                    
INFO[0005] Radio Version                                 radioversion="subg_rfspy 2.2"
INFO[0005] Statistics                                    collected="2018-12-30 11:23:02.215360983 -0800 PST m=+5.675019184" crcfails=0 packetsrecv=0 packetsxmit=0 recvfifooverflows=0 recvoverflows=0 spisyncfails=0 uptime=43m3.886s
INFO[0005] starting LED dance                           
DEBU[0005] step                                          green=on
DEBU[0005] step + wait                                   blue=on
...
DEBU[0010] step                                          blue=off
DEBU[0010] step + wait                                   green=off

Documentation

Index

Constants

View Source
const (
	RxFilterWide       RxFilter   = 0x50 // 300KHz
	RxFilterNarrow     RxFilter   = 0x90 // 150KHz
	EncodingNone       SwEncoding = 0x00
	EncodingManchester SwEncoding = 0x01
	Encoding4b6b       SwEncoding = 0x02
	RegisterSync1      CxRegister = 0x00
	RegisterSync0      CxRegister = 0x01
	RegisterPktlen     CxRegister = 0x02
	RegisterPktctrl1   CxRegister = 0x03
	RegisterPktctrl0   CxRegister = 0x04
	RegisterFsctrl1    CxRegister = 0x07
	RegisterFreq2      CxRegister = 0x09
	RegisterFreq1      CxRegister = 0x0a
	RegisterFreq0      CxRegister = 0x0b
	RegisterMdmcfg4    CxRegister = 0x0c
	RegisterMdmcfg3    CxRegister = 0x0d
	RegisterMdmcfg2    CxRegister = 0x0e
	RegisterMdmcfg1    CxRegister = 0x0f
	RegisterMdmcfg0    CxRegister = 0x10
	RegisterDeviatn    CxRegister = 0x11
	RegisterMcsm0      CxRegister = 0x14
	RegisterFoccfg     CxRegister = 0x15
	RegisterAgcctrl2   CxRegister = 0x17
	RegisterAgcctrl1   CxRegister = 0x18
	RegisterAgcctrl0   CxRegister = 0x19
	RegisterFrend1     CxRegister = 0x1a
	RegisterFrend0     CxRegister = 0x1b
	RegisterFscal3     CxRegister = 0x1c
	RegisterFscal2     CxRegister = 0x1d
	RegisterFscal1     CxRegister = 0x1e
	RegisterFscal0     CxRegister = 0x1f
	RegisterTest1      CxRegister = 0x24
	RegisterTest0      CxRegister = 0x25
	RegisterPaTable0   CxRegister = 0x2e
	// 24MHz crystal
	OscillatorHz = 24000000
)

Variables

This section is empty.

Functions

func ConnectAddress

func ConnectAddress(ctx context.Context, address string) (ble.Client, error)

ConnectAddress binds a RileyLink via BT address

func ConnectName

func ConnectName(ctx context.Context, name string) (ble.Client, error)

ConnectName binds a RileyLink via local (custom) name

func ConnectNameOrAddress

func ConnectNameOrAddress(ctx context.Context, nameoraddress string) (ble.Client, error)

ConnectNameOrAddress binds a RileyLink based on address or name input

func OpenBLE

func OpenBLE(timeout time.Duration) (*linux.Device, context.Context)

OpenBLE creates a bluetooth context

Types

type CarelinkMessage

type CarelinkMessage struct {
	MessageType CarelinkMessageType
	Data        []byte
}

CarelinkMessage encapsulates a command with associated data

type CarelinkMessageType

type CarelinkMessageType byte

CarelinkMessageType is the literal type of commands

const (
	CMTAlert                        CarelinkMessageType = 0x01
	CMTAlertCleared                 CarelinkMessageType = 0x02
	CMTDeviceTest                   CarelinkMessageType = 0x03
	CMTPumpStatus                   CarelinkMessageType = 0x04
	CMTPumpAck                      CarelinkMessageType = 0x06
	CMTPumpBackfill                 CarelinkMessageType = 0x08
	CMTFindDevice                   CarelinkMessageType = 0x09
	CMTDeviceLink                   CarelinkMessageType = 0x0A
	CMTErrorResponse                CarelinkMessageType = 0x15
	CMTWriteGlucoseHistoryTimestamp CarelinkMessageType = 0x28

	CMTSetBasalProfileA CarelinkMessageType = 0x30 // CMD_SET_A_PROFILE
	CMTSetBasalProfileB CarelinkMessageType = 0x31 // CMD_SET_B_PROFILE

	CMTChangeTime  CarelinkMessageType = 0x40
	CMTSetMaxBolus CarelinkMessageType = 0x41 // CMD_SET_MAX_BOLUS
	CMTBolus       CarelinkMessageType = 0x42

	CMTPumpExperimentOP67 CarelinkMessageType = 0x43
	CMTPumpExperimentOP68 CarelinkMessageType = 0x44
	CMTPumpExperimentOP69 CarelinkMessageType = 0x45 // CMD_SET_VAR_BOLUS_ENABLE

	CMTSelectBasalProfile CarelinkMessageType = 0x4a

	CMTChangeTempBasal CarelinkMessageType = 0x4c

	CMTPumpExperimentOP80      CarelinkMessageType = 0x50
	CMTSetRemoteControlID      CarelinkMessageType = 0x51 // CMD_SET_RF_REMOTE_ID
	CMTPumpExperimentOP82      CarelinkMessageType = 0x52 // CMD_SET_BLOCK_ENABLE
	CMTSetLanguage             CarelinkMessageType = 0x53
	CMTPumpExperimentOP84      CarelinkMessageType = 0x54 // CMD_SET_ALERT_TYPE
	CMTPumpExperimentOP85      CarelinkMessageType = 0x55 // CMD_SET_PATTERNS_ENABLE
	CMTPumpExperimentOP86      CarelinkMessageType = 0x56
	CMTSetRemoteControlEnabled CarelinkMessageType = 0x57 // CMD_SET_RF_ENABLE
	CMTPumpExperimentOP88      CarelinkMessageType = 0x58 // CMD_SET_INSULIN_ACTION_TYPE
	CMTPumpExperimentOP89      CarelinkMessageType = 0x59
	CMTPumpExperimentOP90      CarelinkMessageType = 0x5a

	CMTButtonPress CarelinkMessageType = 0x5b

	CMTPumpExperimentOP92 CarelinkMessageType = 0x5c

	CMTPowerOn CarelinkMessageType = 0x5d

	CMTSetBolusWizardEnabled1 CarelinkMessageType = 0x61
	CMTSetBolusWizardEnabled2 CarelinkMessageType = 0x62
	CMTSetBolusWizardEnabled3 CarelinkMessageType = 0x63
	CMTSetBolusWizardEnabled4 CarelinkMessageType = 0x64
	CMTSetBolusWizardEnabled5 CarelinkMessageType = 0x65
	CMTSetAlarmClockEnable    CarelinkMessageType = 0x67

	CMTSetMaxBasalRate         CarelinkMessageType = 0x6e // CMD_SET_MAX_BASAL
	CMTSetBasalProfileStandard CarelinkMessageType = 0x6f // CMD_SET_STD_PROFILE

	CMTReadTime             CarelinkMessageType = 0x70
	CMTGetBattery           CarelinkMessageType = 0x72
	CMTReadRemainingInsulin CarelinkMessageType = 0x73
	CMTReadFirmwareVersion  CarelinkMessageType = 0x74
	CMTReadErrorStatus      CarelinkMessageType = 0x75
	CMTReadRemoteControlIDs CarelinkMessageType = 0x76 // CMD_READ_REMOTE_CTRL_IDS

	CMTGetHistoryPage         CarelinkMessageType = 0x80
	CMTGetPumpModel           CarelinkMessageType = 0x8d
	CMTReadProfileSTD512      CarelinkMessageType = 0x92
	CMTReadProfileA512        CarelinkMessageType = 0x93
	CMTReadProfileB512        CarelinkMessageType = 0x94
	CMTReadTempBasal          CarelinkMessageType = 0x98
	CMTGetGlucosePage         CarelinkMessageType = 0x9A
	CMTReadCurrentPageNumber  CarelinkMessageType = 0x9d
	CMTReadSettings           CarelinkMessageType = 0xc0
	CMTReadCurrentGlucosePage CarelinkMessageType = 0xcd
	CMTReadPumpStatus         CarelinkMessageType = 0xce

	CMTUnknownE2             CarelinkMessageType = 0xe2 // a7594040e214190226330000000000021f99011801e00103012c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
	CMTUnknownE6             CarelinkMessageType = 0xe6 // a7594040e60200190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
	CMTSettingsChangeCounter CarelinkMessageType = 0xec // Body[3] increments by 1 after changing certain settings 0200af0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

	CMTReadOtherDevicesIDs      CarelinkMessageType = 0xf0
	CMTReadCaptureEventEnabled  CarelinkMessageType = 0xf1 // Body[1] encodes the bool state 0101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
	CMTChangeCaptureEventEnable CarelinkMessageType = 0xf2
	CMTReadOtherDevicesStatus   CarelinkMessageType = 0xf3
)
type ConnectedRileyLink struct {
	// contains filtered or unexported fields
}

ConnectedRileyLink represents a BLE connection to a rileylink

func AttachBTLE

func AttachBTLE(blec ble.Client) (*ConnectedRileyLink, error)

AttachBTLE creates a connection descriptor for a rileylink based on input of a legitimate BLE-layer connected device. It will fail if you give it a BT speaker or whatever Effectively the constructor

func (*ConnectedRileyLink) GetBLEVersion

func (crl *ConnectedRileyLink) GetBLEVersion() (string, error)

Version [BLE] returns the BLE firmware revision on the device

func (*ConnectedRileyLink) GetBatteryLevel

func (crl *ConnectedRileyLink) GetBatteryLevel() (int, error)

BatteryLevel [BLE] retrieves an approximated battery percentage from the device

func (*ConnectedRileyLink) GetCustomName

func (crl *ConnectedRileyLink) GetCustomName() (string, error)

GetCustomName [BLE] returns the device's name set by the user

func (*ConnectedRileyLink) GetFrequency

func (crl *ConnectedRileyLink) GetFrequency() (uint32, error)

GetFrequency returns the radio's current tuning in Hz (from Kenneth)

func (*ConnectedRileyLink) GetLEDMode

func (crl *ConnectedRileyLink) GetLEDMode() (LEDMode, error)

GetLEDMode [BLE] retrieves the mode of the diagnostic LEDs (blue)

func (*ConnectedRileyLink) GetPacket

func (crl *ConnectedRileyLink) GetPacket(rlpc RileyLinkPacketChannel, timeout time.Duration) (*RLCCResponse, error)

GetPacket [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) GetRadioVersion

func (crl *ConnectedRileyLink) GetRadioVersion() (string, error)

GetRadioVersion [CC] returns the version of the CC firmware

func (*ConnectedRileyLink) GetState

func (crl *ConnectedRileyLink) GetState() (bool, error)

GetState [CC] is an internal diagnostic call

func (*ConnectedRileyLink) GetStatistics

func (crl *ConnectedRileyLink) GetStatistics() (*RileyLinkStatistics, error)

GetStatistics [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) Interrupt

func (crl *ConnectedRileyLink) Interrupt() error

Interrupt [CC] is, like, stop what you're doing

func (*ConnectedRileyLink) LED

func (crl *ConnectedRileyLink) LED(ledc LEDColor, ledm LEDMode) error

LED [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) NotifySubscribe

func (crl *ConnectedRileyLink) NotifySubscribe() error

NotifySubscribe [local] wires a function as a callback to the data notifier

func (*ConnectedRileyLink) RawReset

func (crl *ConnectedRileyLink) RawReset() error

RawReset [CC] resets the CC chip and that's that

func (*ConnectedRileyLink) ReadRSSI

func (crl *ConnectedRileyLink) ReadRSSI() int

ReadRSSI [local] just exposes the underlying call

func (*ConnectedRileyLink) ReadRegister

func (crl *ConnectedRileyLink) ReadRegister(reg CxRegister) (byte, error)

ReadRegister [CC] reads a cute 'lil 8-bit register

func (*ConnectedRileyLink) Reset

func (crl *ConnectedRileyLink) Reset() (bool, error)

Reset [CC] resets the CC chip, and returns a state call after 100ms

func (*ConnectedRileyLink) ResetRadioConfig

func (crl *ConnectedRileyLink) ResetRadioConfig() error

ResetRadioConfig [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) SendAndListen

func (crl *ConnectedRileyLink) SendAndListen() error

SendAndListen [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) SendPacket

func (crl *ConnectedRileyLink) SendPacket() error

SendPacket [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) SetCustomName

func (crl *ConnectedRileyLink) SetCustomName(newname string) error

SetCustomName [BLE] pushes a new name to the device

func (*ConnectedRileyLink) SetFrequency

func (crl *ConnectedRileyLink) SetFrequency(freq uint32) error

SetFrequency tells the CC to tune to a specific frequency

func (*ConnectedRileyLink) SetLEDMode

func (crl *ConnectedRileyLink) SetLEDMode(mode LEDMode) error

SetLEDMode [BLE] switches the mode of the diagnostic LEDs (blue)

func (*ConnectedRileyLink) SetModeRegisters

func (crl *ConnectedRileyLink) SetModeRegisters() error

SetModeRegisters [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) SetPreamble

func (crl *ConnectedRileyLink) SetPreamble() error

SetPreamble [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) SetSWEncoding

func (crl *ConnectedRileyLink) SetSWEncoding() error

SetSWEncoding [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) UpdateRegister

func (crl *ConnectedRileyLink) UpdateRegister() error

UpdateRegister [CC] does a thing that will be documented at some point

func (*ConnectedRileyLink) WriteRegister

func (crl *ConnectedRileyLink) WriteRegister(reg CxRegister, value byte) error

WriteRegister [CC] writes a cute 'lil 8-bit register

type CxRegister

type CxRegister byte

type LEDColor

type LEDColor byte

LEDColor is the literal type of the choice of LED Valid for CC LEDs for sure, BLE LEDs idk

const (
	// LEDGreen is Green, really zeroth
	LEDGreen LEDColor = 0x00
	// LEDBlue is Blue, really first
	LEDBlue LEDColor = 0x01
)

func (LEDColor) String

func (ledc LEDColor) String() string

type LEDMode

type LEDMode byte

LEDMode is the literal type of the LED mode flag

const (
	// LEDOff turns diag LEDs off
	LEDOff LEDMode = 0x00
	// LEDOn turns diag LEDs on
	LEDOn LEDMode = 0x01
	// LEDAuto ???
	LEDAuto LEDMode = 0x02
)

func (LEDMode) String

func (ledm LEDMode) String() string

type MMTPumpSize

type MMTPumpSize int
const (
	MMTPumpSizeUnknown MMTPumpSize = 0
	MMTPumpSizeSmall   MMTPumpSize = 500
	MMTPumpSizeLarge   MMTPumpSize = 700
)

type MedtronicPump

type MedtronicPump struct {
	ModelNumber int
}

func (*MedtronicPump) ASWTHOSOD

func (mmtpump *MedtronicPump) ASWTHOSOD() bool

func (*MedtronicPump) GetGeneration

func (mmtpump *MedtronicPump) GetGeneration() int

func (*MedtronicPump) GetMaxReserviorSize

func (mmtpump *MedtronicPump) GetMaxReserviorSize() MMTPumpSize

func (*MedtronicPump) HasBolusErrorQuirk

func (mmtpump *MedtronicPump) HasBolusErrorQuirk() bool

func (*MedtronicPump) HasLowSuspend

func (mmtpump *MedtronicPump) HasLowSuspend() bool

func (*MedtronicPump) HasMySentry

func (mmtpump *MedtronicPump) HasMySentry() bool

func (*MedtronicPump) Modern

func (mmtpump *MedtronicPump) Modern() bool

Modern returns whether the pump is considered "modern"

func (*MedtronicPump) NewRecordStyle

func (mmtpump *MedtronicPump) NewRecordStyle() bool

func (*MedtronicPump) RBPSE

func (mmtpump *MedtronicPump) RBPSE() bool

func (*MedtronicPump) StrokesPerUnit

func (mmtpump *MedtronicPump) StrokesPerUnit() int

type RLCCResponse

type RLCCResponse struct {
	Result  RileyLinkCCResponseType
	Payload []byte
	RSSI    int
}

RLCCResponse represents a return from the CC chip

type RileyLinkCCResponseType

type RileyLinkCCResponseType byte

RileyLinkCCResponseType represents the outcome of the sent command

const (
	RLRRecvTimeout    RileyLinkCCResponseType = 0xaa
	RLRInterrupted    RileyLinkCCResponseType = 0xbb
	RLRZeroData       RileyLinkCCResponseType = 0xcc
	RLRSuccess        RileyLinkCCResponseType = 0xdd
	RLRInvalidParam   RileyLinkCCResponseType = 0x11
	RLRUnknownCommand RileyLinkCCResponseType = 0x22
)

func (RileyLinkCCResponseType) String

func (rlr RileyLinkCCResponseType) String() string

type RileyLinkCommand

type RileyLinkCommand byte

RileyLinkCommand is the literal type of a device command

const (
	// RLCInterrupt just pushes a null command out, effectively
	// interrupting another command in progress
	RLCInterrupt RileyLinkCommand = 0x00
	// RLCGetState returns "OK" when the CC chip is ... OK
	RLCGetState RileyLinkCommand = 0x01
	// RLCGetVersion returns the version of the CC firmware (subg_rfspy)
	RLCGetVersion RileyLinkCommand = 0x02

	RLCGetPacket        RileyLinkCommand = 0x03
	RLCSendPacket       RileyLinkCommand = 0x04
	RLCSendAndListen    RileyLinkCommand = 0x05
	RLCUpdateRegister   RileyLinkCommand = 0x06
	RLCReset            RileyLinkCommand = 0x07
	RLCLED              RileyLinkCommand = 0x08
	RLCReadRegister     RileyLinkCommand = 0x09
	RLCSetModeRegisters RileyLinkCommand = 0x0A
	RLCSetSWEncoding    RileyLinkCommand = 0x0B
	RLCSetPreamble      RileyLinkCommand = 0x0C
	RLCResetRadioConfig RileyLinkCommand = 0x0D
	RLCGetStatistics    RileyLinkCommand = 0x0E
)

func (RileyLinkCommand) String

func (rlc RileyLinkCommand) String() string

type RileyLinkPacketChannel

type RileyLinkPacketChannel byte

RileyLinkPacketChannel represents the internal channel type

const (
	RLPCMeter RileyLinkPacketChannel = 0x01
	RLPCPump  RileyLinkPacketChannel = 0x02
)

func (RileyLinkPacketChannel) String

func (rlpc RileyLinkPacketChannel) String() string

type RileyLinkStatistics

type RileyLinkStatistics struct {
	Collected         time.Time
	Uptime            time.Duration
	RecvOverflows     uint16
	RecvFifoOverflows uint16
	PacketsRecv       uint16
	PacketsXmit       uint16
	CRCFailures       uint16
	SPISyncFailures   uint16
}

RileyLinkStatistics represents a concrete statistics pull event

type RxFilter

type RxFilter byte

type SwEncoding

type SwEncoding byte

Directories

Path Synopsis
cmd
grl-demo command
grl-getpacket command
grl-info command
grl-leds command
grl-rename command
grl-sendpacket command
grl-tune command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL