github.com/martinohmann/rfoutlet@v1.2.1-0.20220707195255-8a66aa411105/cmd/sniff.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/martinohmann/rfoutlet/internal/config" 8 "github.com/martinohmann/rfoutlet/pkg/gpio" 9 log "github.com/sirupsen/logrus" 10 "github.com/spf13/cobra" 11 ) 12 13 func NewSniffCommand() *cobra.Command { 14 options := &SniffOptions{ 15 Pin: config.DefaultReceivePin, 16 } 17 18 cmd := &cobra.Command{ 19 Use: "sniff", 20 Short: "Sniff codes sent out to remote controlled outlets", 21 Long: "The sniff command can be used to sniff codes sent out to remote controlled outlets.", 22 RunE: func(cmd *cobra.Command, _ []string) error { 23 return options.Run(cmd) 24 }, 25 } 26 27 options.AddFlags(cmd) 28 29 return cmd 30 } 31 32 type SniffOptions struct { 33 Pin uint 34 } 35 36 func (o *SniffOptions) AddFlags(cmd *cobra.Command) { 37 cmd.Flags().UintVar(&o.Pin, "pin", o.Pin, "gpio pin to sniff on") 38 } 39 40 func (o *SniffOptions) Run(cmd *cobra.Command) error { 41 device, err := openGPIODevice(cmd) 42 if err != nil { 43 return err 44 } 45 defer device.Close() 46 47 receiver, err := gpio.NewReceiver(device.Chip, int(o.Pin)) 48 if err != nil { 49 return fmt.Errorf("failed to create gpio receiver: %v", err) 50 } 51 defer receiver.Close() 52 53 ctx, cancel := context.WithCancel(context.Background()) 54 defer cancel() 55 56 go handleSignals(cancel) 57 58 for { 59 select { 60 case res := <-receiver.Receive(): 61 log.WithFields(log.Fields{ 62 "pulseLength": res.PulseLength, 63 "protocol": res.Protocol, 64 "bitlength": res.BitLength, 65 }).Infof("received code %d", res.Code) 66 case <-ctx.Done(): 67 return nil 68 } 69 } 70 }