func (e *Engine) handleDevice(device *network.Device) { e.devices[device.Id] = device if i := e.getKnownDevice(device); i != -1 { device.Paired = true //device.PublicKey = e.config.KnownDevices[i].PublicKey } select { case e.Joins <- device: default: } go device.Listen() go e.sendIdentity(device) for pkg := range device.Incoming { if pkg == nil { continue } // Decrypt package if encrypted if pkg.Type == protocol.EncryptedType { var err error pkg, err = pkg.Body.(*protocol.Encrypted).Decrypt(e.config.PrivateKey) if err != nil { log.Println("Cannot decrypt package:", err) continue } } if pkg.Type == protocol.PairType { pair := pkg.Body.(*protocol.Pair) if pair.Pair { // Remote asks pairing device.PairRequestReceived = true if len(pair.PublicKey) > 0 { // Remote sent its public key pub := &crypto.PublicKey{} if err := pub.Unmarshal([]byte(pair.PublicKey)); err != nil { log.Println("Cannot parse public key:", err) break } log.Println("Received public key") device.PublicKey = pub } if device.PairRequestSent { // We asked for pairing first, remote accepted log.Println("Device accepted pairing") e.PairDevice(device) } else { log.Println("Device requested pairing") select { case e.RequestsPairing <- device: default: } } } else { log.Println("Device requested unpairing") device.Paired = false e.UnpairDevice(device) } } else if pkg.Type == protocol.IdentityType { setDeviceIdentity(device, pkg.Body.(*protocol.Identity)) } else { err := e.handler.Handle(device, pkg) if err != nil { log.Println("Error handling package:", err, pkg.Type, string(pkg.RawBody)) } } } log.Println("Closed TCP connection") delete(e.devices, device.Id) select { case e.Leaves <- device: default: } }