Fawkes API  Fawkes Development Version
transceiver.cpp
1 
2 /***************************************************************************
3  * transceiver.cpp - Fawkes transceiver
4  *
5  * Created: Tue Nov 21 23:46:13 2006
6  * Copyright 2006 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 <netcomm/fawkes/transceiver.h>
25 #include <netcomm/fawkes/message.h>
26 #include <netcomm/fawkes/message_queue.h>
27 #include <netcomm/socket/stream.h>
28 #include <netcomm/utils/exceptions.h>
29 
30 #include <netinet/in.h>
31 #include <cstdlib>
32 
33 namespace fawkes {
34 
35 /** @class FawkesNetworkTransceiver transceiver.h <netcomm/fawkes/transceiver.h>
36  * Fawkes Network Transceiver.
37  * Utility class that provides methods to send and receive messages via
38  * the network. Operates on message queues and a given socket.
39  *
40  * @ingroup NetComm
41  * @author Tim Niemueller
42  */
43 
44 /** Send messages.
45  * @param s socket over which the data shall be transmitted.
46  * @param msgq message queue that contains the messages that have to be sent
47  * @exception ConnectionDiedException Thrown if any error occurs during the
48  * operation since for any error the conncetion is considered dead.
49  */
50 void
52 {
53  msgq->lock();
54  try {
55  while ( ! msgq->empty() ) {
56  FawkesNetworkMessage *m = msgq->front();
57  m->pack();
58  const fawkes_message_t &f = m->fmsg();
59  unsigned int payload_size = m->payload_size();
60  s->write(&(f.header), sizeof(f.header));
61  s->write(f.payload, payload_size);
62  m->unref();
63  msgq->pop();
64  }
65  } catch (SocketException &e) {
66  msgq->unlock();
67  throw ConnectionDiedException("Write failed");
68  }
69  msgq->unlock();
70 }
71 
72 
73 /** Receive data.
74  * This method receives all messages currently available from the network, or
75  * a limited number depending on max_num_msgs. If max_num_msgs is 0 then all
76  * messages are read. Note that on a busy connection this may cause recv() to
77  * never return! The default is to return after 8 messages.
78  * The messages are stored in the supplied message queue.
79  * @param s socket to gather messages from
80  * @param msgq message queue to store received messages in
81  * @param max_num_msgs maximum number of messages to read from stream in one go.
82  * @exception ConnectionDiedException Thrown if any error occurs during the
83  * operation since for any error the conncetion is considered dead.
84  */
85 void
87  unsigned int max_num_msgs)
88 {
89  msgq->lock();
90 
91  try {
92  unsigned int num_msgs = 0;
93  while ( s->available() && (num_msgs++ < max_num_msgs) ) {
94  fawkes_message_t msg;
95  s->read(&(msg.header), sizeof(msg.header));
96 
97  unsigned int payload_size = ntohl(msg.header.payload_size);
98 
99  if ( payload_size > 0 ) {
100  msg.payload = malloc(payload_size);
101  s->read(msg.payload, payload_size);
102  } else {
103  msg.payload = NULL;
104  }
105 
107  msgq->push(m);
108  }
109  } catch (SocketException &e) {
110  msgq->unlock();
111  throw ConnectionDiedException("Read failed");
112  }
113  msgq->unlock();
114 }
115 
116 } // end namespace fawkes
A LockQueue of FawkesNetworkMessage to hold messages in inbound and outbound queues.
Definition: message_queue.h:33
void unref()
Decrement reference count and conditionally delete this instance.
Definition: refcount.cpp:99
virtual void write(const void *buf, size_t count)
Write to the socket.
Definition: socket.cpp:681
void unlock() const
Unlock list.
Definition: lock_queue.h:131
fawkes_message_header_t header
message header
Definition: message.h:53
Fawkes library namespace.
static void recv(StreamSocket *s, FawkesNetworkMessageQueue *msgq, unsigned int max_num_msgs=8)
Receive data.
Definition: transceiver.cpp:86
Representation of a message that is sent over the network.
Definition: message.h:75
TCP stream socket over IP.
Definition: stream.h:31
virtual bool available()
Check if data is available.
Definition: socket.cpp:611
void pack()
Pack data for sending.
Definition: message.cpp:409
unsigned int payload_size
payload size in bytes
Definition: message.h:42
virtual size_t read(void *buf, size_t count, bool read_all=true)
Read from socket.
Definition: socket.cpp:729
Message as stored in local queues.
Definition: message.h:52
void * payload
message payload
Definition: message.h:54
const fawkes_message_t & fmsg() const
Get message reference.
Definition: message.cpp:331
Thrown if the connection died during an operation.
Definition: exceptions.h:31
void lock() const
Lock queue.
Definition: lock_queue.h:115
static void send(StreamSocket *s, FawkesNetworkMessageQueue *msgq)
Send messages.
Definition: transceiver.cpp:51
Socket exception.
Definition: socket.h:58
size_t payload_size() const
Get payload size.
Definition: message.cpp:311