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/message.h>
25#include <netcomm/fawkes/message_queue.h>
26#include <netcomm/fawkes/transceiver.h>
27#include <netcomm/socket/stream.h>
28#include <netcomm/utils/exceptions.h>
29#include <netinet/in.h>
30
31#include <cstdlib>
32
33namespace 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 */
50void
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/** Receive data.
73 * This method receives all messages currently available from the network, or
74 * a limited number depending on max_num_msgs. If max_num_msgs is 0 then all
75 * messages are read. Note that on a busy connection this may cause recv() to
76 * never return! The default is to return after 8 messages.
77 * The messages are stored in the supplied message queue.
78 * @param s socket to gather messages from
79 * @param msgq message queue to store received messages in
80 * @param max_num_msgs maximum number of messages to read from stream in one go.
81 * @exception ConnectionDiedException Thrown if any error occurs during the
82 * operation since for any error the conncetion is considered dead.
83 */
84void
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)) {
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
Thrown if the connection died during an operation.
Definition: exceptions.h:32
A LockQueue of FawkesNetworkMessage to hold messages in inbound and outbound queues.
Definition: message_queue.h:33
Representation of a message that is sent over the network.
Definition: message.h:77
const fawkes_message_t & fmsg() const
Get message reference.
Definition: message.cpp:321
size_t payload_size() const
Get payload size.
Definition: message.cpp:303
void pack()
Pack data for sending.
Definition: message.cpp:392
static void send(StreamSocket *s, FawkesNetworkMessageQueue *msgq)
Send messages.
Definition: transceiver.cpp:51
static void recv(StreamSocket *s, FawkesNetworkMessageQueue *msgq, unsigned int max_num_msgs=8)
Receive data.
Definition: transceiver.cpp:85
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
Fawkes library namespace.
unsigned int payload_size
payload size in bytes
Definition: message.h:43
Message as stored in local queues.
Definition: message.h:54
fawkes_message_header_t header
message header
Definition: message.h:55
void * payload
message payload
Definition: message.h:56