Example #1
0
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
}
Example #2
0
// 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
}
Example #3
0
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
}
Example #4
0
// 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
}