The Assimilation Project  based on Assimilation version 1.1.7.1474836767
reliableudp.c
Go to the documentation of this file.
1 
27 #include <memory.h>
28 #include <proj_classes.h>
29 #include <reliableudp.h>
30 #include <frameset.h>
31 #include <framesettypes.h>
32 #include <frametypes.h>
33 
34 
43 
44 // Saved base class functions - so we call them w/o storing a copy in every object
45 static void (*_baseclass_finalize)(AssimObj*);
46 static GSList* (*_baseclass_rcvmany)(NetIO*, NetAddr**);
47 // These two could probably be eliminated...
48 static void (*_baseclass_sendone)(NetIO*, const NetAddr*, FrameSet*);
49 static void (*_baseclass_sendmany)(NetIO*, const NetAddr*, GSList*);
50 
51 FSTATIC gboolean _reliableudp_sendareliablefs(NetIO*self, NetAddr*, guint16, FrameSet*);
52 FSTATIC gboolean _reliableudp_sendreliablefs(NetIO*self, NetAddr*, guint16, GSList*);
53 FSTATIC gboolean _reliableudp_ackmessage (NetIO* self, NetAddr* dest, FrameSet* frameset);
54 FSTATIC void _reliableudp_closeconn(NetIO*self, guint16 qid, const NetAddr* dest);
55 FSTATIC void _reliableudp_log_conn(ReliableUDP* self, guint16 qid, NetAddr* destaddr);
56 
57 // Our functions that override base class functions...
59 FSTATIC gboolean _reliableudp_input_queued(const NetIO*);
61 FSTATIC void _reliableudp_sendframesets(NetIO*, const NetAddr*, GSList*);
65 
66 
69 reliableudp_new(gsize objsize
71  , PacketDecoder* decoder
72  , guint rexmit_timer_uS)
73 {
74  NetIOudp* uret;
75  ReliableUDP* self = NULL;
76 
78  if (objsize < sizeof(ReliableUDP)) {
79  objsize = sizeof(ReliableUDP);
80  }
81  uret = netioudp_new(objsize, config, decoder);
82  if (uret) {
83  if (!_baseclass_finalize) {
84  _baseclass_finalize = uret->baseclass.baseclass._finalize;
85  _baseclass_sendone = uret->baseclass.sendaframeset;
86  _baseclass_sendmany = uret->baseclass.sendframesets;
87  _baseclass_rcvmany = uret->baseclass.recvframesets;
88  }
89  self = NEWSUBCLASS(ReliableUDP, uret);
90  // Now for the base class functions which we override
91  self->baseclass.baseclass.baseclass._finalize = _reliableudp_finalize;
92  self->baseclass.baseclass.recvframesets = _reliableudp_recvframesets;
93  self->baseclass.baseclass.input_queued = _reliableudp_input_queued;
94  self->baseclass.baseclass.sendareliablefs = _reliableudp_sendareliablefs;
95  self->baseclass.baseclass.sendreliablefs = _reliableudp_sendreliablefs;
96  self->baseclass.baseclass.ackmessage = _reliableudp_ackmessage;
97  self->baseclass.baseclass.closeconn = _reliableudp_closeconn;
98  self->baseclass.baseclass.supportsreliable = _reliableudp_supportsreliable;
99  self->baseclass.baseclass.outputpending = _reliableudp_outputpending;
100  // These next two don't really do anything different - and could be eliminated
101  // as of now.
102  self->baseclass.baseclass.sendframesets = _reliableudp_sendframesets;
103  self->baseclass.baseclass.sendaframeset = _reliableudp_sendaframeset;
104 
105  self->_protocol = fsprotocol_new(0, &uret->baseclass, rexmit_timer_uS);
106  self->log_conn = _reliableudp_log_conn;
107  }
108  return self;
109 }
110 
112 FSTATIC void
114 {
115  ReliableUDP* self = CASTTOCLASS(ReliableUDP, obj);
116  if (self) {
117  DUMP2("ReliableUDP finalize", &self->baseclass.baseclass.baseclass, __FUNCTION__);
118  if (self->_protocol) {
119  // Un-ref that puppy!
120  UNREF(self->_protocol);
121  }
122  }
123  _baseclass_finalize(&self->baseclass.baseclass.baseclass);
124 }
125 
127 FSTATIC gboolean
129 {
130  const ReliableUDP* self = CASTTOCONSTCLASS(ReliableUDP, nself);
131  gboolean retval;
132  g_return_val_if_fail(nself != NULL, FALSE);
133  retval = self->_protocol->iready(self->_protocol);
134  DEBUGMSG5("%s: Checking input ready: returning %s", __FUNCTION__, (retval?"True":"False"));
135  return retval;
136 }
137 
140 FSTATIC void
142 {
143  DEBUGMSG3("%s.%d: Calling _baseclass_sendone()", __FUNCTION__, __LINE__);
144  _baseclass_sendone(nself, dest, fs);
145 }
146 
149 FSTATIC void
150 _reliableudp_sendframesets(NetIO* nself, const NetAddr* dest, GSList* fslist)
151 {
152  _baseclass_sendmany(nself, dest, fslist);
153 }
154 
159 FSTATIC GSList*
161 {
162  NetAddr* oursrcaddr;
163  ReliableUDP* self;
164  GSList* fsread;
165  GSList* lelem;
166  FsProtocol* proto;
167  GSList* retval = NULL;
168 
169  g_return_val_if_fail(nself != NULL, NULL);
170  fsread = _baseclass_rcvmany(nself, &oursrcaddr);
171  self = CASTTOCLASS(ReliableUDP, nself);
172  g_return_val_if_fail(self != NULL, NULL);
173  proto = self->_protocol;
174 
175  // Loop over all the packets we read in, and put them in our protocol queues
176  for (lelem=fsread; lelem; lelem=lelem->next) {
177  FrameSet* fs = CASTTOCLASS(FrameSet, lelem->data);
178  // Put that puppy in the queue...
179  //proto->log_conn(proto, DEFAULT_FSP_QID, oursrcaddr);
180  proto->receive(proto, oursrcaddr, fs);
181  UNREF(fs);
182  }
183  g_slist_free(fsread); fsread = NULL;
184  // Do we have any packets ready to read out of the reliable protocol?
185  if (proto->iready(proto)) {
186  FrameSet* fs = proto->read(proto, srcaddr);
187 
188  // In theory, we might have several from the same endpoint...
189  // The problem is, they might be from different endpoints too...
190  // So, let's just deliver them to our clients one at a time for now...
191  if (fs) {
192  retval = g_slist_prepend(NULL, fs);
193  }
194  }else{
195  *srcaddr = NULL;
196  }
197  return retval;
198 }
199 
201 FSTATIC gboolean
203 {
204  ReliableUDP * self = CASTTOCLASS(ReliableUDP, nself);
205  // Send it out!
206  DEBUGMSG3("%s.%d: Sending packet with _protocol->send1()", __FUNCTION__, __LINE__);
207  DUMP3("_reliableudp_sendareliablefs: Sending packet with self->_protocol->send1(fs, qid, dest) ", &dest->baseclass, "");
208  return self->_protocol->send1(self->_protocol, fs, qid, dest);
209 }
210 
212 FSTATIC gboolean
213 _reliableudp_sendreliablefs(NetIO* nself, NetAddr* dest, guint16 qid, GSList* fslist)
214 {
215  ReliableUDP * self = CASTTOCLASS(ReliableUDP, nself);
216  DEBUGMSG3("%s.%d: Sending packet with _protocol->send(%d)", __FUNCTION__, __LINE__
217  , g_slist_length(fslist));
218  DUMP3("_reliableudp_sendreliablefs: Sending packet with self->_protocol->send(fs, qid, dest) ", &dest->baseclass, "");
219  return self->_protocol->send(self->_protocol, fslist, qid, dest);
220 }
221 
223 FSTATIC gboolean
225 {
226  ReliableUDP * self = CASTTOCLASS(ReliableUDP, nself);
227  DUMP3("ACKing FrameSet with _protocol->ackmessage"
228  , &frameset->baseclass, NULL);
229  self->_protocol->ackmessage(self->_protocol, dest, frameset);
230  return TRUE;
231 }
232 
234 FSTATIC void
235 _reliableudp_closeconn(NetIO* nself, guint16 qid, const NetAddr* dest)
236 {
237  ReliableUDP * self = CASTTOCLASS(ReliableUDP, nself);
238  DUMP2("Closing connection to", &dest->baseclass, " calling protocol->closeconn()")
239  self->_protocol->closeconn(self->_protocol, qid, dest);
240 }
242 FSTATIC gboolean
244 {
245  (void) self;
246  return TRUE;
247 }
249 FSTATIC gboolean
251 {
252  ReliableUDP * self = CASTTOCLASS(ReliableUDP, nself);
253  return self->_protocol->outputpending(self->_protocol);
254 }
255 
257 FSTATIC void
259 {
260  self->_protocol->log_conn(self->_protocol, qid, destaddr);
261 }
262 
263 
FSTATIC gboolean _reliableudp_ackmessage(NetIO *self, NetAddr *dest, FrameSet *frameset)
Send an ACK (as requested) for for the packet we&#39;ve been handed.
Definition: reliableudp.c:224
FSTATIC void _reliableudp_sendframesets(NetIO *, const NetAddr *, GSList *)
Reliable UDP verison of &#39;sendframesets&#39; from base class.
Definition: reliableudp.c:150
gboolean(* iready)(FsProtocol *)
TRUE if input is ready to be read.
Definition: fsprotocol.h:122
AssimObj baseclass
Definition: frameset.h:47
void(* receive)(FsProtocol *, NetAddr *, FrameSet *)
Enqueue a received input FrameSet class.
Definition: fsprotocol.h:125
NetAddr * destaddr
Definition: nanomain.c:75
NetIOudp * netioudp_new(gsize objsize, ConfigContext *config, PacketDecoder *decoder)
Construct new UDP NetIO object (and its socket, etc)
Definition: netioudp.c:52
NetIOudp is a NetIOudp class subclass specialized to provide reliable UDP connections.
Definition: reliableudp.h:43
Implements minimal client-oriented Frame and Frameset capabilities.
#define DEBUGMSG5(...)
Definition: proj_classes.h:93
AssimObj baseclass
Definition: netaddr.h:44
#define FSTATIC
Definition: projectcommon.h:31
#define DEBUGMSG3(...)
Definition: proj_classes.h:91
WINEXPORT FsProtocol * fsprotocol_new(guint objsize, NetIO *io, guint rexmit_timer_uS)
Construct an FsProtocol object.
Definition: fsprotocol.c:784
#define BINDDEBUG(Cclass)
BINDDEBUG is for telling the class system where the debug variable for this class is - put it in the ...
Definition: proj_classes.h:82
#define __FUNCTION__
AssimObj baseclass
Definition: netio.h:59
Implements the Reliable UDP network I/O transport (ReliableUDP) class.
#define DUMP3(prefix, obj, suffix)
Definition: proj_classes.h:97
FSTATIC gboolean _reliableudp_supportsreliable(NetIO *)
Just return TRUE - we support reliable transport.
Definition: reliableudp.c:243
NetIOudp is a NetIO class subclass specialized to UDP connections.
Definition: netioudp.h:40
Header file defining all known FrameSet types THIS FILE MECHANICALLY GENERATED by "/home/alanr/assim/...
void sendaframeset(NetIO *self, const NetAddr *dest, FrameSet *frameset)
< Send a FrameSet list to a NetIO class
#define CASTTOCONSTCLASS(Cclass, obj)
Safely cast &#39;obj&#39; to const C-class &#39;class&#39; - verifying that it was registered as being of type class ...
Definition: proj_classes.h:71
Header file defining the data layouts for our Frames.
FSTATIC gboolean _reliableudp_outputpending(NetIO *)
Return TRUE if any (reliable) output is pending.
Definition: reliableudp.c:250
FSTATIC gboolean _reliableudp_sendareliablefs(NetIO *self, NetAddr *, guint16, FrameSet *)
Send a single packet reliably.
Definition: reliableudp.c:202
ReliableUDP * reliableudp_new(gsize objsize, ConfigContext *config, PacketDecoder *decoder, guint rexmit_timer_uS)
Construct new UDP NetIO object (and its socket, etc)
Definition: reliableudp.c:69
FSTATIC void _reliableudp_finalize(AssimObj *)
Finalize (free up) our ReliableUDP class object.
Definition: reliableudp.c:113
FSTATIC void _reliableudp_log_conn(ReliableUDP *self, guint16 qid, NetAddr *destaddr)
Dump connection information.
Definition: reliableudp.c:258
FrameSet *(* read)(FsProtocol *, NetAddr **)
Read the next FrameSet class.
Definition: fsprotocol.h:124
The NetAddr class class represents a general network address - whether IP, MAC, or any other type of ...
Definition: netaddr.h:43
Defines interfaces a project Class system for class hierarchies in &#39;C&#39;.
NetIO baseclass
Base class (NetIO) object.
Definition: netioudp.h:41
FrameSet class - used for collecting Frames when not on the wire, and for marshalling/demarshalling t...
Definition: frameset.h:46
GSList * recvframesets(NetIO *, NetAddr **src)
< Receive a single datagram&#39;s framesets
struct _ReliableUDP ReliableUDP
Definition: reliableudp.h:39
#define DEBUGDECLARATIONS
Definition: proj_classes.h:79
#define DUMP2(prefix, obj, suffix)
Definition: proj_classes.h:96
void(* _finalize)(AssimObj *)
Free object (private)
Definition: assimobj.h:55
FSTATIC void _reliableudp_closeconn(NetIO *self, guint16 qid, const NetAddr *dest)
Close a reliable UDP connection (reset it, really)
Definition: reliableudp.c:235
#define CASTTOCLASS(Cclass, obj)
Safely cast &#39;obj&#39; to C-class &#39;class&#39; - verifying that it was registerd as being of type class ...
Definition: proj_classes.h:66
#define UNREF(obj)
Definition: assimobj.h:35
This is a basic NetIO class abstract class for doing network I/O.
Definition: netio.h:58
FSTATIC void _reliableudp_sendaframeset(NetIO *, const NetAddr *, FrameSet *)
Reliable UDP verison of &#39;sendaframeset&#39; from base class.
Definition: reliableudp.c:141
FSTATIC gboolean _reliableudp_input_queued(const NetIO *)
Return TRUE if we have input to read from someone...
Definition: reliableudp.c:128
#define NEWSUBCLASS(Cclass, obj)
Definition: proj_classes.h:67
FSTATIC gboolean _reliableudp_sendreliablefs(NetIO *self, NetAddr *, guint16, GSList *)
Send several packets reliably.
Definition: reliableudp.c:213
void sendframesets(NetIO *self, const NetAddr *dest, GSList *framesets)
< Send a FrameSet list to a NetIO class
This is an FsProtocol class object - implementing a reliable user-level FrameSet class delivery syste...
Definition: fsprotocol.h:107
FSTATIC GSList * _reliableudp_recvframesets(NetIO *, NetAddr **)
Reliable UDP verison of &#39;recvframesets&#39; from base class We get called when the user thinks he might h...
Definition: reliableudp.c:160