func (p *V2) process(pkt *packet.Packet, addr *net.UDPAddr) { common.Log.Debugf("Processing packet from %v: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", addr.IP, pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) // Update device seen time for any targeted packets if pkt.Target != 0 { dev, err := p.getDevice(pkt.Target) if err == nil { dev.SetSeen(time.Now()) } } // Broadcast packets, or packets generated by other clients if pkt.GetSource() != packet.ClientID { switch pkt.GetType() { case device.StatePower: dev, err := p.getDevice(pkt.GetTarget()) if err != nil { common.Log.Debugf("Skipping StatePower packet for unknown device: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) return } err = dev.SetStatePower(pkt) if err != nil { common.Log.Debugf("Failed setting StatePower on device: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) return } case device.StateLabel: dev, err := p.getDevice(pkt.GetTarget()) if err != nil { common.Log.Debugf("Skipping StateLabel packet for unknown device: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) return } err = dev.SetStateLabel(pkt) if err != nil { common.Log.Debugf("Failed setting StatePower on device: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) return } case device.State: dev, err := p.getDevice(pkt.GetTarget()) if err != nil { common.Log.Debugf("Skipping State packet for unknown device: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) return } light, ok := dev.(*device.Light) if !ok { common.Log.Debugf("Skipping State packet for non-light device: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) return } err = light.SetState(pkt) if err != nil { common.Log.Debugf("Error setting State on device: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) return } default: common.Log.Debugf("Skipping packet with non-local source: source %v, type %v, sequence %v, target %v, tagged %v, resRequired %v, ackRequired %v: %+v\n", pkt.GetSource(), pkt.GetType(), pkt.GetSequence(), pkt.GetTarget(), pkt.GetTagged(), pkt.GetResRequired(), pkt.GetAckRequired(), *pkt) } return } // Packets processed at the protocol level regardless of target switch pkt.GetType() { case device.StateLocation: p.addLocation(pkt) case device.StateGroup: p.addGroup(pkt) } // Packets processed at the protocol level or returned to target switch pkt.GetType() { case device.StateService: dev, err := p.getDevice(pkt.Target) if err != nil { dev, err := device.New(addr, p.socket, p.timeout, p.retryInterval, p.Reliable, pkt) if err != nil { common.Log.Errorf("Failed creating device: %v\n", err) return } p.addDevice(dev) return } // Perform state discovery on lights if l, ok := dev.(*device.Light); ok { if err := l.Get(); err != nil { common.Log.Debugf("Failed getting light state: %v\n", err) } } default: if pkt.GetTarget() == 0 { common.Log.Debugf("Skipping packet without target: %+v\n", *pkt) return } dev, err := p.getDevice(pkt.GetTarget()) if err != nil { common.Log.Errorf("No known device with ID %v\n", pkt.GetTarget()) return } common.Log.Debugf("Returning packet to device %v: %+v\n", dev.ID(), *pkt) dev.Handle(pkt) } }