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 }
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 { tyC := C.CString(ty) defer C.free(unsafe.Pointer(tyC)) urlC := C.CString(url) defer C.free(unsafe.Pointer(urlC)) idC := C.CString(id) defer C.free(unsafe.Pointer(idC)) var onlineC *C.char if online { onlineC = C.CString("online") } else { onlineC = C.CString("offline") } defer C.free(unsafe.Pointer(onlineC)) C.avahi_threaded_poll_lock(z.threadedPoll) defer C.avahi_threaded_poll_unlock(z.threadedPoll) var errstr *C.char C.addAvahiGroup(z.threadedPoll, z.client, &r.group, r.name, C.ushort(port), tyC, urlC, idC, onlineC, &errstr) if errstr != nil { err := errors.New(C.GoString(errstr)) C.free(unsafe.Pointer(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() // Transition from not connecting to connecting. Warn in logs. if z.state != C.AVAHI_CLIENT_CONNECTING && newState == C.AVAHI_CLIENT_CONNECTING { glog.Warning("Avahi client is looking for avahi-daemon. Is it running?") } // Transition from running to not running. Free all groups. if z.state == C.AVAHI_CLIENT_S_RUNNING && newState != C.AVAHI_CLIENT_S_RUNNING { glog.Info("Avahi client stopped running.") for name, r := range z.printers { if r.group != nil { var errstr *C.char C.removeAvahiGroup(z.threadedPoll, r.group, &errstr) if errstr != nil { fmt.Println(C.GoString(errstr)) C.free(unsafe.Pointer(errstr)) } r.group = nil z.printers[name] = r } } } // Transition from not running to running. Recreate all groups. if z.state != C.AVAHI_CLIENT_S_RUNNING && newState == C.AVAHI_CLIENT_S_RUNNING { glog.Info("Avahi client running.") for name, r := range z.printers { tyC := C.CString(r.ty) defer C.free(unsafe.Pointer(tyC)) urlC := C.CString(r.url) defer C.free(unsafe.Pointer(urlC)) idC := C.CString(r.id) defer C.free(unsafe.Pointer(idC)) var onlineC *C.char if r.online { onlineC = C.CString("online") } else { onlineC = C.CString("offline") } defer C.free(unsafe.Pointer(onlineC)) var errstr *C.char C.addAvahiGroup(z.threadedPoll, z.client, &r.group, r.name, C.ushort(r.port), tyC, urlC, idC, onlineC, &errstr) if errstr != nil { err := errors.New(C.GoString(errstr)) C.free(unsafe.Pointer(errstr)) glog.Error(err) } z.printers[name] = r } } // Transition from not failure to failure. Recreate thread poll and client. if z.state != C.AVAHI_CLIENT_FAILURE && newState == C.AVAHI_CLIENT_FAILURE { z.restart <- struct{}{} } z.state = newState }