@@ -2,93 +2,92 @@ package rtlsdr
22
33import (
44 "context"
5- "fmt "
5+ "io/fs "
66 "log/slog"
77
8- "github.com/google/gousb"
98 pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1"
109)
1110
1211const (
1312 ResourceName = "rtl-sdr"
1413)
1514
16- type Plugin struct {
17- RtlSdrs map [string ]* RtlSdrDev
18- Heartbeat chan bool
15+ type plugin struct {
16+ devices map [string ]* UsbDevice
17+ heartbeat chan bool
18+ fsys fs.FS
1919}
2020
21- func (p * Plugin ) GetDevicePluginOptions (ctx context.Context , e * pluginapi.Empty ) (* pluginapi.DevicePluginOptions , error ) {
21+ func NewPlugin (heartbeat chan bool , fsys fs.FS ) * plugin {
22+ return & plugin {
23+ heartbeat : heartbeat ,
24+ fsys : fsys ,
25+ devices : make (map [string ]* UsbDevice ),
26+ }
27+ }
28+
29+ func (p * plugin ) GetDevicePluginOptions (ctx context.Context , e * pluginapi.Empty ) (* pluginapi.DevicePluginOptions , error ) {
2230 return & pluginapi.DevicePluginOptions {}, nil
2331}
2432
25- func (p * Plugin ) PreStartContainer (ctx context.Context , r * pluginapi.PreStartContainerRequest ) (* pluginapi.PreStartContainerResponse , error ) {
33+ func (p * plugin ) PreStartContainer (ctx context.Context , r * pluginapi.PreStartContainerRequest ) (* pluginapi.PreStartContainerResponse , error ) {
2634 return & pluginapi.PreStartContainerResponse {}, nil
2735}
2836
29- func (p * Plugin ) UpdateDevices () error {
30- rtls , err := ListDevices ( )
37+ func (p * plugin ) UpdateDevices () ([] * pluginapi. Device , error ) {
38+ connectedDevs , err := ListUsbDevices ( p . fsys )
3139 if err != nil {
3240 slog .Info ("Error listing devices" , slog .Any ("error" , err ))
33- return err
41+ return nil , err
3442 }
3543
36- slog .Info ("Found devices" , "len" , len (rtls ))
44+ slog .Info ("Found devices" , "len" , len (connectedDevs ))
3745
38- for _ , rtl := range p .RtlSdrs {
39- rtl .Connected = false
46+ connectedDevsBySerial := map [string ]* UsbDevice {}
47+ for i := range connectedDevs {
48+ connectedDevsBySerial [connectedDevs [i ].Serial ] = connectedDevs [i ]
49+ p .devices [connectedDevs [i ].Serial ] = connectedDevs [i ]
4050 }
4151
42- for i := range rtls {
43- p .RtlSdrs [rtls [i ].SerialNumber ] = rtls [i ]
44- }
45-
46- return nil
47- }
48-
49- func (p * Plugin ) GetDevices () []* pluginapi.Device {
50- devs := make ([]* pluginapi.Device , len (p .RtlSdrs ))
52+ pdevs := make ([]* pluginapi.Device , len (p .devices ))
5153 i := 0
52- for _ , rtl := range p .RtlSdrs {
53- devs [i ] = & pluginapi.Device {
54- ID : rtl .SerialNumber ,
54+ for _ , rtl := range p .devices {
55+ pdevs [i ] = & pluginapi.Device {
56+ ID : rtl .Serial ,
5557 Health : pluginapi .Unhealthy ,
5658 }
5759
58- if rtl .Connected {
59- devs [i ].Health = pluginapi .Healthy
60+ if _ , ok := connectedDevsBySerial [ rtl .Serial ]; ok {
61+ pdevs [i ].Health = pluginapi .Healthy
6062 }
6163
6264 i ++
6365 }
6466
65- return devs
67+ return pdevs , nil
6668}
6769
68- func (p * Plugin ) ListAndWatch (e * pluginapi.Empty , s pluginapi.DevicePlugin_ListAndWatchServer ) error {
69- err := p .UpdateDevices ()
70+ func (p * plugin ) ListAndWatch (e * pluginapi.Empty , s pluginapi.DevicePlugin_ListAndWatchServer ) error {
71+ devs , err := p .UpdateDevices ()
7072 if err != nil {
7173 slog .Error ("Error listing devices" , slog .Any ("error" , err ))
7274 }
7375
74- devs := p .GetDevices ()
75-
7676 err = s .Send (& pluginapi.ListAndWatchResponse {Devices : devs })
7777 if err != nil {
7878 slog .Error ("Error sending initial response" , slog .Any ("error" , err ))
7979 }
8080
8181 slog .Info ("Waiting for updates..." )
8282
83- for range p .Heartbeat {
84- err = p .UpdateDevices ()
83+ for range p .heartbeat {
84+ devs , err = p .UpdateDevices ()
8585 if err != nil {
8686 slog .Error ("Error reading devices" , slog .Any ("error" , err ))
8787 continue
8888 }
8989
90- devs := p .GetDevices ()
91- slog .Info ("Devices updated" , "len" , len (devs ))
90+ slog .Info ("Devices updated" , slog .Int ("len" , len (devs )))
9291
9392 err = s .Send (& pluginapi.ListAndWatchResponse {Devices : devs })
9493 if err != nil {
@@ -100,11 +99,11 @@ func (p *Plugin) ListAndWatch(e *pluginapi.Empty, s pluginapi.DevicePlugin_ListA
10099 return nil
101100}
102101
103- func (p * Plugin ) GetPreferredAllocation (context.Context , * pluginapi.PreferredAllocationRequest ) (* pluginapi.PreferredAllocationResponse , error ) {
102+ func (p * plugin ) GetPreferredAllocation (context.Context , * pluginapi.PreferredAllocationRequest ) (* pluginapi.PreferredAllocationResponse , error ) {
104103 return & pluginapi.PreferredAllocationResponse {}, nil
105104}
106105
107- func (p * Plugin ) Allocate (ctx context.Context , r * pluginapi.AllocateRequest ) (* pluginapi.AllocateResponse , error ) {
106+ func (p * plugin ) Allocate (ctx context.Context , r * pluginapi.AllocateRequest ) (* pluginapi.AllocateResponse , error ) {
108107 var response pluginapi.AllocateResponse
109108 var car pluginapi.ContainerAllocateResponse
110109 var dev * pluginapi.DeviceSpec
@@ -119,61 +118,12 @@ func (p *Plugin) Allocate(ctx context.Context, r *pluginapi.AllocateRequest) (*p
119118 for _ , id := range req .DevicesIDs {
120119 slog .Info ("Allocating device" , slog .String ("ID" , id ))
121120
122- dev .HostPath = p .RtlSdrs [id ].DevicePath ()
123- dev .ContainerPath = p .RtlSdrs [id ].DevicePath ()
121+ dev .HostPath = p .devices [id ].DevicePath ()
122+ dev .ContainerPath = p .devices [id ].DevicePath ()
124123 }
125124
126125 response .ContainerResponses = append (response .ContainerResponses , & car )
127126 }
128127
129128 return & response , nil
130129}
131-
132- type RtlSdrDev struct {
133- * gousb.Device
134-
135- SerialNumber string
136- Connected bool
137- }
138-
139- func (r RtlSdrDev ) DevicePath () string {
140- return fmt .Sprintf ("/dev/bus/usb/%03d/%03d" , r .Device .Desc .Bus , r .Device .Desc .Address )
141- }
142-
143- func NewRtlSdrDev (dev * gousb.Device ) * RtlSdrDev {
144- serial , _ := dev .SerialNumber ()
145-
146- return & RtlSdrDev {
147- Device : dev ,
148- SerialNumber : serial ,
149- Connected : true ,
150- }
151- }
152-
153- func ListDevices () ([]* RtlSdrDev , error ) {
154- ctx := gousb .NewContext ()
155- defer func () {
156- _ = ctx .Close ()
157- }()
158-
159- devs , err := ctx .OpenDevices (func (desc * gousb.DeviceDesc ) bool {
160- return desc .Vendor == 0x0bda
161- })
162- for i := range devs {
163- defer func (i int ) {
164- _ = devs [i ].Close ()
165- }(i )
166- }
167-
168- if err != nil {
169- slog .Info ("Error open device" , slog .Int ("len" , len (devs )), slog .Any ("error" , err ))
170- return nil , err
171- }
172-
173- devices := make ([]* RtlSdrDev , len (devs ))
174- for i := range devs {
175- devices [i ] = NewRtlSdrDev (devs [i ])
176- }
177-
178- return devices , nil
179- }
0 commit comments