func explore(cln ble.Client, p *ble.Profile) error { for _, s := range p.Services { fmt.Printf(" Service: %s %s, Handle (0x%02X)\n", s.UUID, ble.Name(s.UUID), s.Handle) for _, c := range s.Characteristics { fmt.Printf(" Characteristic: %s %s, Property: 0x%02X (%s), Handle(0x%02X), VHandle(0x%02X)\n", c.UUID, ble.Name(c.UUID), c.Property, propString(c.Property), c.Handle, c.ValueHandle) if (c.Property & ble.CharRead) != 0 { b, err := cln.ReadCharacteristic(c) if err != nil { fmt.Printf("Failed to read characteristic: %s\n", err) continue } fmt.Printf(" Value %x | %q\n", b, b) } for _, d := range c.Descriptors { fmt.Printf(" Descriptor: %s %s, Handle(0x%02x)\n", d.UUID, ble.Name(d.UUID), d.Handle) b, err := cln.ReadDescriptor(d) if err != nil { fmt.Printf("Failed to read descriptor: %s\n", err) continue } fmt.Printf(" Value %x | %q\n", b, b) } } fmt.Printf("\n") } return nil }
func cmdConnect(c *cli.Context) error { curr.client = nil var cln ble.Client var err error ctx := ble.WithSigHandler(context.WithTimeout(context.Background(), c.Duration("tmo"))) if c.String("addr") != "" { curr.addr = ble.NewAddr(c.String("addr")) fmt.Printf("Dialing to specified address: %s\n", curr.addr) cln, err = ble.Dial(ctx, curr.addr) } else if filter(c) != nil { fmt.Printf("Scanning with filter...\n") if cln, err = ble.Connect(ctx, filter(c)); err == nil { curr.addr = cln.Address() fmt.Printf("Connected to %s\n", curr.addr) } } else if curr.addr != nil { fmt.Printf("Dialing to implicit address: %s\n", curr.addr) cln, err = ble.Dial(ctx, curr.addr) } else { return fmt.Errorf("no filter specified, and cached peripheral address") } if err == nil { curr.client = cln curr.clients[cln.Address().String()] = cln } go func() { <-cln.Disconnected() delete(curr.clients, cln.Address().String()) curr.client = nil fmt.Printf("\n%s disconnected\n", cln.Address().String()) }() return err }
func explore(cln ble.Client, p *ble.Profile) error { for _, s := range p.Services { fmt.Printf(" Service: %s %s, Handle (0x%02X)\n", s.UUID, ble.Name(s.UUID), s.Handle) for _, c := range s.Characteristics { fmt.Printf(" Characteristic: %s %s, Property: 0x%02X (%s), Handle(0x%02X), VHandle(0x%02X)\n", c.UUID, ble.Name(c.UUID), c.Property, propString(c.Property), c.Handle, c.ValueHandle) if (c.Property & ble.CharRead) != 0 { b, err := cln.ReadCharacteristic(c) if err != nil { fmt.Printf("Failed to read characteristic: %s\n", err) continue } fmt.Printf(" Value %x | %q\n", b, b) } for _, d := range c.Descriptors { fmt.Printf(" Descriptor: %s %s, Handle(0x%02x)\n", d.UUID, ble.Name(d.UUID), d.Handle) b, err := cln.ReadDescriptor(d) if err != nil { fmt.Printf("Failed to read descriptor: %s\n", err) continue } fmt.Printf(" Value %x | %q\n", b, b) } if *sub != 0 { // Don't bother to subscribe the Service Changed characteristics. if c.UUID.Equal(ble.ServiceChangedUUID) { continue } // Don't touch the Apple-specific Service/Characteristic. // Service: D0611E78BBB44591A5F8487910AE4366 // Characteristic: 8667556C9A374C9184ED54EE27D90049, Property: 0x18 (WN), // Descriptor: 2902, Client Characteristic Configuration // Value 0000 | "\x00\x00" if c.UUID.Equal(ble.MustParse("8667556C9A374C9184ED54EE27D90049")) { continue } if (c.Property & ble.CharNotify) != 0 { fmt.Printf("\n-- Subscribe to notification for %s --\n", *sub) h := func(req []byte) { fmt.Printf("Notified: %q [ % X ]\n", string(req), req) } if err := cln.Subscribe(c, false, h); err != nil { log.Fatalf("subscribe failed: %s", err) } time.Sleep(*sub) if err := cln.Unsubscribe(c, false); err != nil { log.Fatalf("unsubscribe failed: %s", err) } fmt.Printf("-- Unsubscribe to notification --\n") } if (c.Property & ble.CharIndicate) != 0 { fmt.Printf("\n-- Subscribe to indication of %s --\n", *sub) h := func(req []byte) { fmt.Printf("Indicated: %q [ % X ]\n", string(req), req) } if err := cln.Subscribe(c, true, h); err != nil { log.Fatalf("subscribe failed: %s", err) } time.Sleep(*sub) if err := cln.Unsubscribe(c, true); err != nil { log.Fatalf("unsubscribe failed: %s", err) } fmt.Printf("-- Unsubscribe to indication --\n") } } } fmt.Printf("\n") } return nil }