23 #include <core/exceptions/software.h>
24 #include <core/threading/mutex.h>
25 #include <core/threading/wait_condition.h>
26 #include <fvutils/color/colorspaces.h>
27 #include <fvutils/colormap/cmfile.h>
28 #include <fvutils/colormap/yuvcm.h>
29 #include <fvutils/net/fuse.h>
30 #include <fvutils/net/fuse_client.h>
31 #include <fvutils/net/fuse_client_handler.h>
32 #include <fvutils/net/fuse_image_content.h>
33 #include <fvutils/net/fuse_imagelist_content.h>
34 #include <fvutils/net/fuse_lut_content.h>
35 #include <fvutils/net/fuse_lutlist_content.h>
36 #include <fvutils/net/fuse_message.h>
37 #include <fvutils/writers/fvraw.h>
38 #include <netcomm/service_discovery/browse_handler.h>
39 #include <utils/system/argparser.h>
40 #include <utils/system/console_colors.h>
42 # include <netcomm/dns-sd/avahi_thread.h>
46 #include <arpa/inet.h>
47 #include <netinet/in.h>
54 using namespace firevision;
67 explore_waitcond_ = NULL;
71 fuse_invalid_server_version(uint32_t local_version, uint32_t remote_version)
throw()
73 printf(
"Invalid version received (local: %u, remote: %u)\n", local_version, remote_version);
77 fuse_connection_established() throw()
82 fuse_connection_died() throw()
96 if (ic->
format() == FUSE_IF_RAW) {
104 }
else if (ic->
format() == FUSE_IF_JPEG) {
105 FILE *f = fopen(file_,
"w");
107 printf(
"Failed to write data to file");
111 printf(
"Image of unknown format (%u) received.\n", ic->
format());
115 printf(
"Received message cannot be casted to FuseImageMessage\n");
120 case FUSE_MT_IMAGE_LIST:
124 printf(
"Available images:\n");
127 char tmp[IMAGE_ID_MAX_LENGTH + 1];
128 tmp[IMAGE_ID_MAX_LENGTH] = 0;
129 strncpy(tmp, ii->
image_id, IMAGE_ID_MAX_LENGTH);
130 printf(
" %s (%u x %u, %s)\n",
134 colorspace_to_string((colorspace_t)ntohs(ii->
colorspace)));
137 printf(
"No images available\n");
141 printf(
"Received message cannot be casted to FuseImageListMessage\n");
145 case FUSE_MT_LUT_LIST:
149 printf(
"Available lookup tables:\n");
152 char tmp[LUT_ID_MAX_LENGTH + 1];
153 tmp[LUT_ID_MAX_LENGTH] = 0;
154 strncpy(tmp, li->
lut_id, LUT_ID_MAX_LENGTH);
155 printf(
" %s (%u x %u x %u, %u bpc)\n",
163 printf(
"No lookup tables available\n");
167 printf(
"Received message cannot be casted to FuseImageListMessage\n");
178 if (lc->
width() != 256) {
179 printf(
"Invalid dimensions for LUT received, colormap width %u != 256", lc->
width());
180 }
else if (lc->
height() != 256) {
181 printf(
"Invalid dimensions for LUT received, colormap height %u != 256", lc->
height());
182 }
else if (lc->
depth() > 256) {
183 printf(
"Invalid dimensions for LUT received, colormap depth %u > 256", lc->
depth());
192 e.
append(
"Failed to save colormap");
198 printf(
"Received message cannot be casted to FuseLutMessage\n");
204 case FUSE_MT_SET_LUT_SUCCEEDED: {
206 char lut_id[LUT_ID_MAX_LENGTH + 1];
207 lut_id[LUT_ID_MAX_LENGTH] = 0;
208 strncpy(lut_id, lutdesc->
lut_id, LUT_ID_MAX_LENGTH);
209 printf(
"LUT %s has been uploaded successfully.\n", lut_id);
213 case FUSE_MT_SET_LUT_FAILED: {
215 char lut_id[LUT_ID_MAX_LENGTH + 1];
216 lut_id[LUT_ID_MAX_LENGTH] = 0;
217 strncpy(lut_id, lutdesc->
lut_id, LUT_ID_MAX_LENGTH);
218 printf(
"LUT upload of %s has failed.\n", lut_id);
223 printf(
"Unhandled message of type %u received\n", m->type());
232 printf(
"All for now\n");
233 explore_mutex_->lock();
234 explore_waitcond_->wake_all();
235 explore_mutex_->unlock();
244 browse_failed(
const char *name,
const char *type,
const char *domain)
246 printf(
"Browsing for %s failed\n", type);
250 service_added(
const char * name,
253 const char * host_name,
254 const char * interface,
255 const struct sockaddr * addr,
256 const socklen_t addr_size,
258 std::list<std::string> &txt,
261 struct sockaddr_in *s;
262 if (addr_size ==
sizeof(
struct sockaddr_in)) {
263 s = (
struct sockaddr_in *)addr;
265 printf(
"%s socket data not IPv4, ignoring\n", name);
269 char addrp[INET_ADDRSTRLEN];
270 inet_ntop(AF_INET, &(s->sin_addr), addrp,
sizeof(addrp));
272 "Found %s%s%s (%s/%s on %hu), querying\n",
c_blue, name,
c_normal, host_name, addrp, port);
274 client_ =
new FuseClient(host_name, port,
this);
277 client_->wait_greeting();
286 service_removed(
const char *name,
const char *type,
const char *domain)
294 printf(
"Usage: %s -i/-c/-C/-s/-e [-n host[:port]/id file]\n"
296 " -j Get JPEG-compressed image\n"
298 " -C Set colormap from file\n"
299 " -s Show available images and LUTs\n"
300 " -e Explore network. Will query all instances of Fountain\n"
301 " found on the network for all available images and LUTs.\n"
302 " -n net_string Open network camera, the camera string is of the form\n"
303 " host[:port]/id. You have to specify at least the host\n"
304 " and the id, the port is optional and defaults to 5000\n"
305 " Depending on the operation id is the image or the LUT ID\n"
306 " file File to write incoming data to or to read data to send from\n",
307 argp_->program_name());
315 get_image(
const char *image_id,
bool jpeg)
320 strncpy(idm->
image_id, image_id, IMAGE_ID_MAX_LENGTH - 1);
321 idm->
format = (jpeg ? FUSE_IF_JPEG : FUSE_IF_RAW);
329 get_colormap(
const char *lut_id)
333 strncpy(ldm->
lut_id, lut_id, LUT_ID_MAX_LENGTH - 1);
341 set_colormap(
const char *lut_id)
361 client_->enqueue(FUSE_MT_GET_IMAGE_LIST);
362 client_->enqueue(FUSE_MT_GET_LUT_LIST);
375 explore_mutex_ =
new Mutex();
378 explore_mutex_->lock();
381 avahi_thread_->start();
383 avahi_thread_->watch_service(
"_fountain._tcp",
this);
385 explore_waitcond_->wait();
386 delete explore_waitcond_;
387 explore_mutex_->unlock();
388 delete explore_mutex_;
389 avahi_thread_->cancel();
390 avahi_thread_->join();
391 delete avahi_thread_;
393 printf(
"\nExploration is not available because Avahi support is missing. "
394 "Install avahi-devel and recompile.\n\n");
402 if (argp_->has_arg(
"h")) {
407 if (argp_->has_arg(
"n")) {
408 net_string = strdup(argp_->arg(
"n"));
410 net_string = strdup(
"localhost");
415 char *save_ptr = NULL;
419 hostport = strtok_r(net_string,
"/", &save_ptr);
420 id = strtok_r(NULL,
"", &save_ptr);
422 if (strchr(hostport,
':') != NULL) {
423 host = strtok_r(hostport,
":", &save_ptr);
424 port = strtok_r(NULL,
"", &save_ptr);
430 port_num = atoi(port);
431 if ((port_num < 0) || (port_num > 0xFFFF)) {
436 if (argp_->has_arg(
"i") || argp_->has_arg(
"j") || argp_->has_arg(
"c")
437 || argp_->has_arg(
"C")) {
438 if (argp_->num_items() == 0) {
440 printf(
"\nFile name missing\n\n");
443 file_ = argp_->items()[0];
448 printf(
"\nNo Image/LUT ID given, needed for -i/-c/-C\n\n");
453 if (!argp_->has_arg(
"e")) {
454 client_ =
new FuseClient(host, port_num,
this);
457 client_->wait_greeting();
460 if (argp_->has_arg(
"i")) {
461 get_image(
id,
false);
462 }
else if (argp_->has_arg(
"j")) {
464 }
else if (argp_->has_arg(
"c")) {
466 }
else if (argp_->has_arg(
"C")) {
468 }
else if (argp_->has_arg(
"s")) {
470 }
else if (argp_->has_arg(
"e")) {
477 if (!argp_->has_arg(
"e")) {
493 Mutex * explore_mutex_;
502 main(
int argc,
char **argv)