func (z *zeroconf) updatePrinterTXT(name, ty, url, id string, online bool) error { z.spMutex.Lock() defer z.spMutex.Unlock() r, exists := z.printers[name] if !exists { return fmt.Errorf("printer %s cannot be updated for Avahi publishing; it was never added", name) } r.ty = ty r.url = url r.id = id r.online = online if z.state == C.AVAHI_CLIENT_S_RUNNING && r.group != nil { txt := prepareTXT(ty, url, id, online) defer C.avahi_string_list_free(txt) C.avahi_threaded_poll_lock(z.threadedPoll) defer C.avahi_threaded_poll_unlock(z.threadedPoll) if errstr := C.updateAvahiGroup(z.threadedPoll, r.group, r.name, txt); errstr != nil { err := fmt.Errorf("Failed to update Avahi group: %s", C.GoString(errstr)) return err } } z.printers[name] = r return nil }
func (z *zeroconf) addPrinter(name string, port uint16, ty, url, id string, online bool) error { r := record{ name: C.CString(name), port: port, ty: ty, url: url, id: id, online: online, } z.spMutex.Lock() defer z.spMutex.Unlock() if _, exists := z.printers[name]; exists { return fmt.Errorf("printer %s was already added to Avahi publishing", name) } if z.state == C.AVAHI_CLIENT_S_RUNNING { txt := prepareTXT(ty, url, id, online) defer C.avahi_string_list_free(txt) C.avahi_threaded_poll_lock(z.threadedPoll) defer C.avahi_threaded_poll_unlock(z.threadedPoll) if errstr := C.addAvahiGroup(z.threadedPoll, z.client, &r.group, r.name, C.ushort(r.port), txt); errstr != nil { err := fmt.Errorf("Failed to add Avahi group: %s", C.GoString(errstr)) return err } } z.printers[name] = r return nil }
// handleClientStateChange makes clean transitions as the connection with // avahi-daemon changes. //export handleClientStateChange func handleClientStateChange(client *C.AvahiClient, newState C.AvahiClientState, userdata unsafe.Pointer) { z := instance z.spMutex.Lock() defer z.spMutex.Unlock() // Name conflict. if newState == C.AVAHI_CLIENT_S_COLLISION { log.Warning("Avahi reports a host name collision.") } // Transition from not connecting to connecting. Warn in logs. if newState == C.AVAHI_CLIENT_CONNECTING { log.Warning("Cannot find Avahi daemon. Is it running?") } // Transition from running to not running. Free all groups. if newState != C.AVAHI_CLIENT_S_RUNNING { log.Info("Local printing disabled (Avahi client is not running).") for name, r := range z.printers { if r.group != nil { if errstr := C.removeAvahiGroup(z.threadedPoll, r.group); errstr != nil { err := errors.New(C.GoString(errstr)) log.Errorf("Failed to remove Avahi group: %s", err) } r.group = nil z.printers[name] = r } } } // Transition from not running to running. Recreate all groups. if newState == C.AVAHI_CLIENT_S_RUNNING { log.Info("Local printing enabled (Avahi client is running).") for name, r := range z.printers { txt := prepareTXT(r.ty, r.url, r.id, r.online) defer C.avahi_string_list_free(txt) if errstr := C.addAvahiGroup(z.threadedPoll, z.client, &r.group, r.name, C.ushort(r.port), txt); errstr != nil { err := errors.New(C.GoString(errstr)) log.Errorf("Failed to add Avahi group: %s", err) } z.printers[name] = r } } // Transition from not failure to failure. Recreate thread poll and client. if newState == C.AVAHI_CLIENT_FAILURE { z.restart <- struct{}{} } z.state = newState }