func detectChanges(filters map[string]interface{}, state State, aliases map[string]string, changes chan AddressChange) State { arpTable := arp.Table() interfaces, _ := net.Interfaces() for _, iface := range interfaces { addrs, err := iface.Addrs() if err != nil { continue } for _, addr := range addrs { if ip := getIPv4(addr); ip != "" { arpTable[ip] = iface.HardwareAddr.String() } } } for ip, newAddress := range arpTable { if _, found := filters[ip]; !found && len(filters) > 0 { continue } if oldAddress := state[ip]; oldAddress != newAddress { changes <- AddressChange{ Name: aliasIP(ip, aliases), New: newAddress, Old: oldAddress, } } delete(state, ip) } for ip, oldAddress := range state { if _, found := filters[ip]; !found && len(filters) > 0 { continue } changes <- AddressChange{ Name: aliasIP(ip, aliases), New: "", Old: oldAddress, } } return State(arpTable) }
func Discover(discoverInterval time.Duration) (chan AC, error) { seen := map[string]*wirelessAC{} found := make(chan AC) /*clientAddr, err := net.ResolveUDPAddr("udp", udpClient) if err != nil { log.Fatal(err) } l, err := net.ListenUDP("udp", clientAddr) if err != nil { return nil, err } hostAddr, err := net.ResolveUDPAddr("udp", udpHost) if err != nil { log.Fatal(err) } ping := func() error { _, err = l.WriteToUDP([]byte("DAIKIN_UDP/common/basic_info\n"), hostAddr) return err }*/ arp := func() error { // We send out a broadcast pings first... ips, err := broadcastAddresses() if err != nil { return err } for _, ip := range ips { //log.Printf("Broadcast pinging %s", ip) cmd := exec.Command("ping", "-w", "5s", "-b", ip) err := cmd.Run() if err != nil { log.Printf("Failed to broadcast ping %s: %s", ip, err) } } for ip := range arp.Table() { mac := arp.Search(ip) if hemsPrefix != "" && !strings.HasPrefix(ip, hemsPrefix) { log.Printf("skipped non-hems address: %s", ip) continue } //if strings.HasPrefix(strings.ToUpper(mac), "90:B6:86") { // Murata Manufacturing Co., Ltd. log.Printf("Found a potential daikin AC: %s (mac: %s)", ip, mac) ac := NewWirelessAC(ip) info, err := ac.RefreshBasicInfo() if err == nil && info != nil && info.Ret == "OK" && info.Type == "aircon" { if existing, ok := seen[info.Id]; ok { existing.host = ip } else { seen[info.Id] = ac found <- ac } } //} else { //log.Printf("Fail: %s %s", mac, ip) //} } return nil } go func() { var t *time.Timer t = time.AfterFunc(0, func() { //log.Printf("Searching using ARP table...") if err := arp(); err != nil { log.Printf("Failed to discover daikin ACs using arp table: %s", err) } //time.Sleep(time.Second * 5) //log.Printf("Searching using UDP...") //if err := ping(); err != nil { //log.Printf("Failed to discover daikin ACs using udp: %s", err) //} t.Reset(discoverInterval) }) }() /*l.SetReadBuffer(maxDatagramSize) go func() { for { b := make([]byte, maxDatagramSize) n, src, err := l.ReadFromUDP(b) if err != nil { log.Printf("Daikin Discovery Error: ReadFromUDP failed: %s", err) continue } //log.Printf("Received response: %s", string(b[0:n])) info := &BasicInfo{} mapBytes(info, b[0:n]) if existing, ok := seen[info.Id]; ok { existing.host = src.IP.String() + ":80" } else { ac := NewWirelessAC(src.IP.String() + ":80") ac.info = info seen[info.Id] = ac found <- ac } } }() if err := ping(); err != nil { return nil, err }*/ return found, nil }
func main() { for ip, _ := range arp.Table() { fmt.Printf("%s : %s\n", ip, arp.Search(ip)) } }