Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * fuse_message.cpp - FireVision Remote Control Protocol Message Type 00004 * 00005 * Created: Wed Nov 07 13:01:20 2007 00006 * Copyright 2005-2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <core/exceptions/software.h> 00025 #include <fvutils/net/fuse_message.h> 00026 #include <fvutils/net/fuse_message_content.h> 00027 00028 #include <cstdio> 00029 #include <cstring> 00030 #include <cstdlib> 00031 #include <netinet/in.h> 00032 00033 namespace firevision { 00034 #if 0 /* just to make Emacs auto-indent happy */ 00035 } 00036 #endif 00037 00038 /** @class FuseNetworkMessage <fvutils/net/fuse_message.h> 00039 * FUSE Network Message. 00040 * This is the basic entity for messages that are sent over the network. Either 00041 * just use this message to send arbitrary payload or derive this class for more 00042 * complex behavior or nice encapsulations of messages. 00043 * 00044 * @ingroup FUSE 00045 * @ingroup FireVision 00046 * @author Tim Niemueller 00047 */ 00048 00049 /** Constructor. */ 00050 FuseNetworkMessage::FuseNetworkMessage() 00051 { 00052 memset(&_msg, 0, sizeof(_msg)); 00053 __content = NULL; 00054 } 00055 00056 00057 /** Constructor. 00058 * @param msg message information to copy 00059 */ 00060 FuseNetworkMessage::FuseNetworkMessage(FUSE_message_t *msg) 00061 { 00062 memcpy(&_msg, msg, sizeof(FUSE_message_t)); 00063 __content = NULL; 00064 } 00065 00066 00067 /** Constructor. 00068 * @param type message type 00069 * @param payload payload 00070 * @param payload_size size of payload 00071 * @param copy_payload if true payload is copied, otherwise payload is referenced 00072 * and ownership of payload is claimed. 00073 */ 00074 FuseNetworkMessage::FuseNetworkMessage(FUSE_message_type_t type, 00075 void *payload, size_t payload_size, 00076 bool copy_payload) 00077 { 00078 __content = NULL; 00079 _msg.header.message_type = htonl(type); 00080 _msg.header.payload_size = htonl(payload_size); 00081 00082 if ( copy_payload ) { 00083 _msg.payload = malloc(payload_size); 00084 memcpy(_msg.payload, payload, payload_size); 00085 } else { 00086 _msg.payload = payload; 00087 } 00088 } 00089 00090 00091 /** Constructor without payload. 00092 * Constructs message without payload. 00093 * @param type FUSE message type 00094 */ 00095 FuseNetworkMessage::FuseNetworkMessage(FUSE_message_type_t type) 00096 { 00097 __content = NULL; 00098 _msg.header.message_type = htonl(type); 00099 _msg.header.payload_size = htonl(0); 00100 _msg.payload = NULL; 00101 } 00102 00103 00104 /** Content constructor. 00105 * Construct a message with complex message content. 00106 * @param type FUSE message type 00107 * @param content complex message content. 00108 */ 00109 FuseNetworkMessage::FuseNetworkMessage(FUSE_message_type_t type, FuseMessageContent *content) 00110 { 00111 __content = content; 00112 _msg.header.message_type = htonl(type); 00113 _msg.header.payload_size = htonl(0); 00114 _msg.payload = NULL; 00115 } 00116 00117 /** Destructor. */ 00118 FuseNetworkMessage::~FuseNetworkMessage() 00119 { 00120 if ( __content == NULL ) { 00121 if ( _msg.payload != NULL ) { 00122 free(_msg.payload); 00123 _msg.payload = NULL; 00124 } 00125 } else { 00126 __content->free_payload(); 00127 delete __content; 00128 } 00129 } 00130 00131 /** Get message type. 00132 * @return message type 00133 */ 00134 uint32_t 00135 FuseNetworkMessage::type() const 00136 { 00137 return ntohl(_msg.header.message_type); 00138 } 00139 00140 00141 /** Get payload size. 00142 * @return payload size 00143 */ 00144 size_t 00145 FuseNetworkMessage::payload_size() const 00146 { 00147 return ntohl(_msg.header.payload_size); 00148 } 00149 00150 00151 /** Get pointer to payload. 00152 * @return pointer to payload. 00153 */ 00154 void * 00155 FuseNetworkMessage::payload() const 00156 { 00157 return _msg.payload; 00158 } 00159 00160 00161 /** Get plain message. 00162 * @return plain message 00163 */ 00164 const FUSE_message_t & 00165 FuseNetworkMessage::fmsg() const 00166 { 00167 return _msg; 00168 } 00169 00170 00171 /** Set payload. 00172 * Payload is referenced and ownership claimed. 00173 * @param payload payload 00174 * @param payload_size size of payload 00175 */ 00176 void 00177 FuseNetworkMessage::set_payload(void *payload, size_t payload_size) 00178 { 00179 if ( payload_size > 0xFFFFFFFF ) { 00180 // cannot carry that many bytes 00181 throw fawkes::OutOfBoundsException("Payload too big", payload_size, 0, 0xFFFFFFFF); 00182 } 00183 _msg.payload = payload; 00184 _msg.header.payload_size = htonl(payload_size); 00185 } 00186 00187 00188 /** Set from message. 00189 * @param msg reference to message. Content is deep-copied. 00190 */ 00191 void 00192 FuseNetworkMessage::set(FUSE_message_t &msg) 00193 { 00194 memcpy(&_msg, &msg, sizeof(FUSE_message_t)); 00195 } 00196 00197 /** Pack data for sending. 00198 * Use this if any additional packing is needed before sending the data (for 00199 * example if using a DynamicBuffer). 00200 */ 00201 void 00202 FuseNetworkMessage::pack() 00203 { 00204 if ( __content != NULL ) { 00205 __content->serialize(); 00206 _msg.payload = __content->payload(); 00207 _msg.header.payload_size = htonl(__content->payload_size()); 00208 } 00209 } 00210 00211 } // end namespace firevision