24 #include <fvutils/net/fuse_server_client_thread.h>
26 #include <fvutils/net/fuse_server.h>
27 #include <fvutils/net/fuse_server.h>
28 #include <fvutils/net/fuse_transceiver.h>
29 #include <fvutils/net/fuse_message_queue.h>
30 #include <fvutils/net/fuse_image_content.h>
31 #include <fvutils/net/fuse_lut_content.h>
32 #include <fvutils/net/fuse_imagelist_content.h>
33 #include <fvutils/net/fuse_lutlist_content.h>
34 #include <fvutils/ipc/shm_image.h>
35 #include <fvutils/ipc/shm_lut.h>
36 #include <fvutils/compression/jpeg_compressor.h>
38 #include <core/exceptions/system.h>
39 #include <netcomm/socket/stream.h>
40 #include <netcomm/utils/exceptions.h>
41 #include <logging/liblogger.h>
43 #include <netinet/in.h>
69 :
Thread(
"FuseServerClientThread")
71 __fuse_server = fuse_server;
73 __jpeg_compressor = NULL;
79 greetmsg->
version = htonl(FUSE_CURRENT_VERSION);
91 delete __jpeg_compressor;
93 for (__bit = __buffers.begin(); __bit != __buffers.end(); ++__bit) {
98 for (__lit = __luts.begin(); __lit != __luts.end(); ++__lit ) {
103 while ( ! __inbound_queue->empty() ) {
106 __inbound_queue->pop();
109 while ( ! __outbound_queue->empty() ) {
112 __outbound_queue->pop();
115 delete __inbound_queue;
116 delete __outbound_queue;
124 if ( ! __outbound_queue->empty() ) {
159 if ( ntohl(gm->
version) != FUSE_CURRENT_VERSION ) {
160 throw Exception(
"Invalid version on other side");
166 FuseServerClientThread::get_shmimgbuf(
const char *
id)
168 char tmp_image_id[IMAGE_ID_MAX_LENGTH + 1];
169 tmp_image_id[IMAGE_ID_MAX_LENGTH] = 0;
170 strncpy(tmp_image_id,
id, IMAGE_ID_MAX_LENGTH);
172 if ( (__bit = __buffers.find( tmp_image_id )) == __buffers.end() ) {
176 __buffers[tmp_image_id] = b;
182 return __bit->second;
202 __outbound_queue->push(nm);
206 if ( irm->
format == FUSE_IF_RAW ) {
209 }
else if ( irm->
format == FUSE_IF_JPEG ) {
210 if ( ! __jpeg_compressor) {
222 long int sec = 0, usec = 0;
223 b->capture_time(&sec, &usec);
225 compressed_buffer, compressed_buffer_size,
226 CS_UNKNOWN, b->width(), b->height(),
229 free(compressed_buffer);
234 __outbound_queue->push(nm);
252 strncpy(ii->
image_id, b->image_id(), IMAGE_ID_MAX_LENGTH);
254 ii->
width = htonl(b->width());
255 ii->
height = htonl(b->height());
256 ii->
buffer_size = colorspace_buffer_size(b->colorspace(), b->width(), b->height());
260 __outbound_queue->push(nm);
265 __outbound_queue->push(nm);
278 char tmp_lut_id[LUT_ID_MAX_LENGTH + 1];
279 tmp_lut_id[LUT_ID_MAX_LENGTH] = 0;
280 strncpy(tmp_lut_id, idm->
lut_id, LUT_ID_MAX_LENGTH);
282 if ( (__lit = __luts.find( tmp_lut_id )) != __luts.end() ) {
289 __luts[tmp_lut_id] = b;
297 __outbound_queue->push(nm);
311 strncpy(reply->lut_id, lc->
lut_id(), LUT_ID_MAX_LENGTH);
315 if ( (__lit = __luts.find( lc->
lut_id() )) != __luts.end() ) {
325 e.
append(
"Cannot open shared memory lookup table %s", lc->
lut_id());
326 LibLogger::log_warn(
"FuseServerClientThread", e);
332 if ( (b->width() != lc->
width()) ||
333 (b->height() != lc->
height()) ||
334 (b->depth() != lc->
depth()) ||
338 LibLogger::log_warn(
"FuseServerClientThread",
"LUT upload: dimensions do not match. "
339 "Existing (%u,%u,%u,%u) != uploaded (%u,%u,%u,%u)",
340 b->width(), b->height(), b->depth(), b->bytes_per_cell(),
364 while ( i != endi ) {
391 while ( i != endi ) {
408 FuseServerClientThread::process_inbound()
410 __inbound_queue->
lock();
411 while ( ! __inbound_queue->empty() ) {
416 case FUSE_MT_GREETING:
419 case FUSE_MT_GET_IMAGE:
422 case FUSE_MT_GET_IMAGE_INFO:
425 case FUSE_MT_GET_IMAGE_LIST:
428 case FUSE_MT_GET_LUT_LIST:
431 case FUSE_MT_GET_LUT:
434 case FUSE_MT_SET_LUT:
438 throw Exception(
"Unknown message type received\n");
441 e.
append(
"FUSE protocol error");
442 LibLogger::log_warn(
"FuseServerClientThread", e);
448 __inbound_queue->pop();
450 __inbound_queue->
unlock();
464 p = __socket->
poll(10);
470 if ( (p & Socket::POLL_ERR) ||
471 (p & Socket::POLL_HUP) ||
472 (p & Socket::POLL_RDHUP)) {
475 }
else if ( p & Socket::POLL_IN ) {
void unlock() const
Unlock list.
void process_setlut_message(FuseNetworkMessage *m)
Process LUT setting.
FireVision FUSE protocol server.
static void recv(fawkes::StreamSocket *s, FuseNetworkMessageQueue *msgq, unsigned int max_num_msgs=8)
Receive data.
char image_id[IMAGE_ID_MAX_LENGTH]
image ID
void * payload() const
Get pointer to payload.
virtual void close()
Close socket.
void process_getlut_message(FuseNetworkMessage *m)
Process LUT request message.
void connection_died(FuseServerClientThread *client)
Connection died.
FUSE lookup table content.
void process_greeting_message(FuseNetworkMessage *m)
Process greeting message.
void unref()
Decrement reference count and conditionally delete this instance.
Fawkes library namespace.
MT * msgc() const
Get correctly parsed output.
uint32_t type() const
Get message type.
void process_getimagelist_message(FuseNetworkMessage *m)
Process image list request message.
virtual void set_compression_destination(ImageCompressor::CompressionDestination cd)
Set compression destination.
virtual size_t recommended_compressed_buffer_size()
Get the recommended size for the compressed buffer.
Image description message.
Thread class encapsulation of pthreads.
static void send(fawkes::StreamSocket *s, FuseNetworkMessageQueue *msgq)
Send messages.
TCP stream socket over IP.
virtual void set_destination_buffer(unsigned char *buf, unsigned int buf_size)
Set destination buffer (if compressing to memory).
uint32_t width
width in pixels
void add_lutinfo(const char *lut_id, unsigned int width, unsigned int height, unsigned int depth, unsigned int bytes_per_cell)
Add LUT info.
uint32_t colorspace
color space
uint32_t version
version from FUSE_version_t
char image_id[IMAGE_ID_MAX_LENGTH]
image ID
virtual void set_image_buffer(colorspace_t cspace, unsigned char *buffer)
Set image buffer to compress.
void process_getimageinfo_message(FuseNetworkMessage *m)
Process image info request message.
Base class for exceptions in Fawkes.
FUSE lookup table list content.
version packet, bi-directional
A LockQueue of FuseNetworkMessage to hold messages in inbound and outbound queues.
Shared memory image buffer.
unsigned int height() const
Height of LUT.
void send()
Send all messages in outbound queue.
void process_getimage_message(FuseNetworkMessage *m)
Process image request message.
char image_id[IMAGE_ID_MAX_LENGTH]
image ID
virtual ~FuseServerClientThread()
Destructor.
The current system call has been interrupted (for instance by a signal).
write compressed image to buffer in memory
void add_imageinfo(const char *image_id, colorspace_t colorspace, unsigned int pixel_width, unsigned int pixel_height)
Add image info.
void process_getlutlist_message(FuseNetworkMessage *m)
Process LUT list request message.
Thrown if the connection died during an operation.
unsigned int width() const
Width of LUT.
char lut_id[LUT_ID_MAX_LENGTH]
LUT ID.
uint32_t format
requested image format, see FUSE_image_format_t
uint32_t height
height in pixels
virtual void set_image_dimensions(unsigned int width, unsigned int height)
Set dimensions of image to compress.
void lock() const
Lock queue.
virtual short poll(int timeout=-1, short what=POLL_IN|POLL_HUP|POLL_PRI|POLL_RDHUP)
Wait for some event on socket.
virtual size_t compressed_size()
Get compressed size.
virtual void compress()
Compress image.
unsigned int depth() const
Depth of LUT.
unsigned int bytes_per_cell() const
Bytes per cell in LUT.
unsigned char * buffer() const
Get buffer.
size_t payload_size() const
Get payload size.
uint32_t buffer_size
size of following image buffer in bytes
virtual void loop()
Code to execute in the thread.
const char * lut_id() const
Get LUT ID.
Shared memory lookup table.
void append(const char *format,...)
Append messages to the message list.
MT * msg() const
Get correctly casted payload.