Fawkes API  Fawkes Development Version
fuse_transceiver.cpp
1 
2 /***************************************************************************
3  * fuse_transceiver.cpp - Fuse transceiver
4  *
5  * Created: Wed Nov 14 13:30:34 2007
6  * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <fvutils/net/fuse_message.h>
25 #include <fvutils/net/fuse_message_queue.h>
26 #include <fvutils/net/fuse_transceiver.h>
27 #include <netcomm/socket/stream.h>
28 #include <netcomm/utils/exceptions.h>
29 #include <netinet/in.h>
30 
31 #include <cstdlib>
32 
33 using namespace fawkes;
34 
35 namespace firevision {
36 
37 /** @class FuseNetworkTransceiver <fvutils/net/fuse_transceiver.h>
38  * FUSE Network Transceiver.
39  * Utility class that provides methods to send and receive messages via
40  * the network. Operates on message queues and a given socket.
41  *
42  * @ingroup FUSE
43  * @ingroup FireVision
44  * @author Tim Niemueller
45  */
46 
47 /** Send messages.
48  * @param s socket over which the data shall be transmitted.
49  * @param msgq message queue that contains the messages that have to be sent
50  * @exception ConnectionDiedException Thrown if any error occurs during the
51  * operation since for any error the conncetion is considered dead.
52  */
53 void
54 FuseNetworkTransceiver::send(StreamSocket *s, FuseNetworkMessageQueue *msgq)
55 {
56  msgq->lock();
57  try {
58  while (!msgq->empty()) {
59  FuseNetworkMessage *m = msgq->front();
60  m->pack();
61  const FUSE_message_t &f = m->fmsg();
62  unsigned int payload_size = m->payload_size();
63  s->write(&(f.header), sizeof(f.header));
64  s->write(f.payload, payload_size);
65  m->unref();
66  msgq->pop();
67  }
68  } catch (SocketException &e) {
69  msgq->unlock();
70  throw ConnectionDiedException("Write failed");
71  }
72  msgq->unlock();
73 }
74 
75 /** Receive data.
76  * This method receives all messages currently available from the network, or
77  * a limited number depending on max_num_msgs. If max_num_msgs is 0 then all
78  * messages are read. Note that on a busy connection this may cause recv() to
79  * never return! The default is to return after 8 messages.
80  * The messages are stored in the supplied message queue.
81  * @param s socket to gather messages from
82  * @param msgq message queue to store received messages in
83  * @param max_num_msgs maximum number of messages to read from stream in one go.
84  * @exception ConnectionDiedException Thrown if any error occurs during the
85  * operation since for any error the conncetion is considered dead.
86  */
87 void
88 FuseNetworkTransceiver::recv(StreamSocket * s,
90  unsigned int max_num_msgs)
91 {
92  msgq->lock();
93 
94  try {
95  unsigned int num_msgs = 0;
96  do {
97  FUSE_message_t msg;
98  s->read(&(msg.header), sizeof(msg.header));
99 
100  unsigned int payload_size = ntohl(msg.header.payload_size);
101 
102  if (payload_size > 0) {
103  msg.payload = malloc(payload_size);
104  s->read(msg.payload, payload_size);
105  } else {
106  msg.payload = NULL;
107  }
108 
109  FuseNetworkMessage *m = new FuseNetworkMessage(&msg);
110  msgq->push(m);
111 
112  ++num_msgs;
113  } while (s->available() && (num_msgs < max_num_msgs));
114  } catch (SocketException &e) {
115  msgq->unlock();
116  throw ConnectionDiedException("Read failed");
117  }
118  msgq->unlock();
119 }
120 
121 } // end namespace firevision
Thrown if the connection died during an operation.
Definition: exceptions.h:32
void lock() const
Lock queue.
Definition: lock_queue.h:114
void unlock() const
Unlock list.
Definition: lock_queue.h:128
void unref()
Decrement reference count and conditionally delete this instance.
Definition: refcount.cpp:95
Socket exception.
Definition: socket.h:57
virtual bool available()
Check if data is available.
Definition: socket.cpp:644
virtual size_t read(void *buf, size_t count, bool read_all=true)
Read from socket.
Definition: socket.cpp:760
virtual void write(const void *buf, size_t count)
Write to the socket.
Definition: socket.cpp:713
TCP stream socket over IP.
Definition: stream.h:32
A LockQueue of FuseNetworkMessage to hold messages in inbound and outbound queues.
FUSE Network Message.
Definition: fuse_message.h:40
size_t payload_size() const
Get payload size.
const FUSE_message_t & fmsg() const
Get plain message.
void pack()
Pack data for sending.
Fawkes library namespace.
uint32_t payload_size
payload size
Definition: fuse.h:86
FUSE message.
Definition: fuse.h:91
void * payload
payload
Definition: fuse.h:93
FUSE_header_t header
header
Definition: fuse.h:92