00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifdef HAVE_CONFIG_H
00015 # include <config.h>
00016 #endif
00017
00018
00019 #include "io_packets_p.h"
00020 #include <gwenhywfar/iolayer_be.h>
00021 #include <gwenhywfar/iorequest_be.h>
00022 #include <gwenhywfar/iomanager.h>
00023 #include <gwenhywfar/io_buffered.h>
00024
00025 #include "i18n_l.h"
00026 #include <gwenhywfar/misc.h>
00027 #include <gwenhywfar/debug.h>
00028 #include <gwenhywfar/gui.h>
00029 #include <gwenhywfar/text.h>
00030
00031 #include <assert.h>
00032 #include <ctype.h>
00033
00034
00035
00036
00037 GWEN_INHERIT(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS)
00038
00039
00040
00041
00042 GWEN_IO_LAYER *GWEN_Io_LayerPackets_new(GWEN_IO_LAYER *baseLayer) {
00043 GWEN_IO_LAYER *io;
00044 GWEN_IO_LAYER_PACKETS *xio;
00045
00046 io=GWEN_Io_Layer_new(GWEN_IO_LAYER_PACKETS_TYPE, baseLayer);
00047 assert(io);
00048 GWEN_NEW_OBJECT(GWEN_IO_LAYER_PACKETS, xio);
00049 assert(xio);
00050 GWEN_INHERIT_SETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io, xio, GWEN_Io_LayerPackets_freeData);
00051
00052 xio->requestsIn=GWEN_Io_Request_List_new();
00053 xio->requestsOut=GWEN_Io_Request_List_new();
00054 xio->readSize=GWEN_IO_LAYER_PACKETS_DEFAULT_READSIZE;
00055 xio->maxReadQueue=GWEN_IO_LAYER_PACKETS_DEFAULT_READQUEUE;
00056 xio->maxWriteQueue=GWEN_IO_LAYER_PACKETS_DEFAULT_WRITEQUEUE;
00057
00058 GWEN_Io_Layer_SetWorkOnRequestsFn(io, GWEN_Io_LayerPackets_WorkOnRequests);
00059 GWEN_Io_Layer_SetAddRequestFn(io, GWEN_Io_LayerPackets_AddRequest);
00060 GWEN_Io_Layer_SetDelRequestFn(io, GWEN_Io_LayerPackets_DelRequest);
00061 GWEN_Io_Layer_SetHasWaitingRequestsFn(io, GWEN_Io_LayerPackets_HasWaitingRequests);
00062
00063 return io;
00064 }
00065
00066
00067
00068 GWENHYWFAR_CB
00069 void GWEN_Io_LayerPackets_freeData(void *bp, void *p) {
00070 GWEN_IO_LAYER *io;
00071 GWEN_IO_LAYER_PACKETS *xio;
00072
00073 io=(GWEN_IO_LAYER*)bp;
00074 xio=(GWEN_IO_LAYER_PACKETS*)p;
00075
00076 GWEN_Io_LayerPackets_Abort(io);
00077 GWEN_Io_Request_List_free(xio->requestsIn);
00078 GWEN_Io_Request_List_free(xio->requestsOut);
00079
00080 GWEN_FREE_OBJECT(xio);
00081 }
00082
00083
00084
00085 int GWEN_Io_LayerPackets_GetReadRequest(GWEN_IO_LAYER *io,
00086 GWEN_IO_REQUEST **pRequest,
00087 uint32_t guiid, int msecs) {
00088 GWEN_IO_LAYER_PACKETS *xio;
00089 GWEN_IO_REQUEST *r;
00090
00091 assert(io);
00092 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00093 assert(xio);
00094
00095 r=GWEN_Io_Request_List_First(xio->requestsIn);
00096 if (r) {
00097 GWEN_Io_Request_List_Del(r);
00098 *pRequest=r;
00099 return 0;
00100 }
00101 else {
00102 if (msecs==GWEN_TIMEOUT_NONE)
00103 return GWEN_ERROR_TIMEOUT;
00104 else {
00105 uint32_t oldGuiid;
00106 int rv;
00107
00108 if (xio->currentReadRequest==NULL)
00109 GWEN_Io_LayerPackets_WorkOnReadRequests(io);
00110 if (xio->currentReadRequest==NULL) {
00111 DBG_INFO(GWEN_LOGDOMAIN, "Could not generate read request");
00112 return GWEN_ERROR_IO;
00113 }
00114 r=xio->currentReadRequest;
00115 oldGuiid=GWEN_Io_Request_GetGuiId(r);
00116 GWEN_Io_Request_SetGuiId(r, guiid);
00117
00118 rv=GWEN_Io_Manager_WaitForRequest(r, msecs);
00119 GWEN_Io_Request_SetGuiId(r, oldGuiid);
00120 if (rv) {
00121 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00122 return rv;
00123 }
00124
00125
00126 r=GWEN_Io_Request_List_First(xio->requestsIn);
00127 if (r) {
00128 GWEN_Io_Request_List_Del(r);
00129 *pRequest=r;
00130 return 0;
00131 }
00132 else {
00133 DBG_INFO(GWEN_LOGDOMAIN, "Still no read request");
00134 return GWEN_ERROR_IO;
00135 }
00136 }
00137 }
00138 }
00139
00140
00141
00142 int GWEN_Io_LayerPackets_AddRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00143 GWEN_IO_LAYER_PACKETS *xio;
00144 GWEN_IO_LAYER_STATUS st;
00145 uint32_t lflags;
00146 uint32_t rflags;
00147
00148 assert(io);
00149 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00150 assert(xio);
00151
00152 st=GWEN_Io_Layer_GetStatus(io);
00153 lflags=GWEN_Io_Layer_GetFlags(io);
00154 rflags=GWEN_Io_Request_GetFlags(r);
00155
00156 DBG_INFO(GWEN_LOGDOMAIN, "Add %s request...",
00157 GWEN_Io_RequestType_toString(GWEN_Io_Request_GetType(r)));
00158
00159 switch(GWEN_Io_Request_GetType(r)) {
00160 case GWEN_Io_Request_TypeWrite:
00161
00162 if (st!=GWEN_Io_Layer_StatusConnected) {
00163 DBG_INFO(GWEN_LOGDOMAIN, "IO layer is not open");
00164 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00165 return GWEN_ERROR_NOT_OPEN;
00166 }
00167
00168 if (GWEN_Io_Request_List_GetCount(xio->requestsOut)>=xio->maxWriteQueue)
00169 return GWEN_ERROR_TRY_AGAIN;
00170 GWEN_Io_Request_Attach(r);
00171 GWEN_Io_Request_List_Add(r, xio->requestsOut);
00172 break;
00173
00174 case GWEN_Io_Request_TypeConnect:
00175
00176 if (st!=GWEN_Io_Layer_StatusUnconnected &&
00177 st!=GWEN_Io_Layer_StatusDisconnected) {
00178 DBG_INFO(GWEN_LOGDOMAIN, "Layer not un-/disconnected");
00179 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00180 return GWEN_ERROR_NOT_OPEN;
00181 }
00182 GWEN_Io_Request_List_Clear(xio->requestsIn);
00183 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusConnected);
00184 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00185 DBG_INFO(GWEN_LOGDOMAIN, "Layer now connected");
00186 break;
00187
00188 case GWEN_Io_Request_TypeDisconnect:
00189
00190 if (st!=GWEN_Io_Layer_StatusConnected) {
00191 DBG_INFO(GWEN_LOGDOMAIN, "IO layer is not open");
00192 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_OPEN);
00193 return GWEN_ERROR_NOT_OPEN;
00194 }
00195 else
00196 GWEN_Io_LayerPackets_Abort(io);
00197 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, 0);
00198 DBG_INFO(GWEN_LOGDOMAIN, "Layer now disconnected");
00199 break;
00200
00201 case GWEN_Io_Request_TypeRead:
00202 default:
00203 DBG_INFO(GWEN_LOGDOMAIN, "This request type is not supported (%d)", GWEN_Io_Request_GetType(r));
00204 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_NOT_SUPPORTED);
00205 return GWEN_ERROR_NOT_SUPPORTED;
00206 }
00207
00208
00209 return 0;
00210 }
00211
00212
00213
00214 int GWEN_Io_LayerPackets_DelRequest(GWEN_IO_LAYER *io, GWEN_IO_REQUEST *r) {
00215 GWEN_IO_LAYER_PACKETS *xio;
00216
00217 assert(io);
00218 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00219 assert(xio);
00220
00221 switch(GWEN_Io_Request_GetType(r)) {
00222 case GWEN_Io_Request_TypeWrite:
00223 if (xio->currentWriteRequest==r) {
00224 int rv;
00225
00226 rv=GWEN_Io_Layer_DelRequest(GWEN_Io_Layer_GetBaseLayer(io), r);
00227 xio->currentWriteRequest=NULL;
00228 return rv;
00229 }
00230 else {
00231 if (GWEN_Io_Request_List_HasElement(xio->requestsOut, r)) {
00232 GWEN_Io_Request_List_Del(r);
00233 }
00234 else {
00235 DBG_INFO(GWEN_LOGDOMAIN, "Request is not enqeued here");
00236 return GWEN_ERROR_NOT_FOUND;
00237 }
00238 }
00239 break;
00240
00241 default:
00242 break;
00243 }
00244
00245 return 0;
00246 }
00247
00248
00249
00250 int GWEN_Io_LayerPackets_GetReadSize(const GWEN_IO_LAYER *io) {
00251 GWEN_IO_LAYER_PACKETS *xio;
00252
00253 assert(io);
00254 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00255 assert(xio);
00256
00257 return xio->readSize;
00258 }
00259
00260
00261
00262 void GWEN_Io_LayerPackets_SetReadSize(GWEN_IO_LAYER *io, int i) {
00263 GWEN_IO_LAYER_PACKETS *xio;
00264
00265 assert(io);
00266 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00267 assert(xio);
00268
00269 xio->readSize=i;
00270 }
00271
00272
00273
00274 int GWEN_Io_LayerPackets_GetMaxReadQueue(const GWEN_IO_LAYER *io) {
00275 GWEN_IO_LAYER_PACKETS *xio;
00276
00277 assert(io);
00278 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00279 assert(xio);
00280
00281 return xio->maxReadQueue;
00282 }
00283
00284
00285
00286 void GWEN_Io_LayerPackets_SetMaxReadQueue(GWEN_IO_LAYER *io, int i) {
00287 GWEN_IO_LAYER_PACKETS *xio;
00288
00289 assert(io);
00290 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00291 assert(xio);
00292
00293 xio->maxReadQueue=i;
00294 }
00295
00296
00297
00298 int GWEN_Io_LayerPackets_GetMaxWriteQueue(const GWEN_IO_LAYER *io) {
00299 GWEN_IO_LAYER_PACKETS *xio;
00300
00301 assert(io);
00302 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00303 assert(xio);
00304
00305 return xio->maxWriteQueue;
00306 }
00307
00308
00309
00310 void GWEN_Io_LayerPackets_SetMaxWriteQueue(GWEN_IO_LAYER *io, int i) {
00311 GWEN_IO_LAYER_PACKETS *xio;
00312
00313 assert(io);
00314 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00315 assert(xio);
00316
00317 xio->maxWriteQueue=i;
00318 }
00319
00320
00321
00322 void GWEN_Io_LayerPackets_Abort(GWEN_IO_LAYER *io) {
00323 GWEN_IO_LAYER_PACKETS *xio;
00324 GWEN_IO_REQUEST *r;
00325
00326 assert(io);
00327 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00328 assert(xio);
00329
00330 if (xio->currentReadRequest) {
00331 GWEN_Io_Layer_DelRequest(GWEN_Io_Layer_GetBaseLayer(io), xio->currentReadRequest);
00332 GWEN_Io_Request_free(xio->currentReadRequest);
00333 xio->currentReadRequest=NULL;
00334 }
00335 if (xio->currentWriteRequest) {
00336 GWEN_Io_Layer_DelRequest(GWEN_Io_Layer_GetBaseLayer(io), xio->currentWriteRequest);
00337 GWEN_Io_Request_free(xio->currentWriteRequest);
00338 xio->currentWriteRequest=NULL;
00339 }
00340
00341
00342
00343
00344
00345 r=GWEN_Io_Request_List_First(xio->requestsOut);
00346 while( (r=GWEN_Io_Request_List_First(xio->requestsOut)) ) {
00347 GWEN_Io_Request_Finished(r, GWEN_Io_Request_StatusFinished, GWEN_ERROR_ABORTED);
00348 GWEN_Io_Request_List_Del(r);
00349 GWEN_Io_Request_free(r);
00350 }
00351
00352 GWEN_Io_Layer_SetStatus(io, GWEN_Io_Layer_StatusDisconnected);
00353 }
00354
00355
00356
00357 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerPackets_WorkOnReadRequests(GWEN_IO_LAYER *io) {
00358 GWEN_IO_LAYER_PACKETS *xio;
00359 int doneSomething=0;
00360
00361 assert(io);
00362 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00363 assert(xio);
00364
00365 if (xio->currentReadRequest) {
00366 if (GWEN_Io_Request_GetStatus(xio->currentReadRequest)==GWEN_Io_Request_StatusFinished) {
00367 doneSomething=1;
00368
00369 if (GWEN_Io_Request_GetFlags(xio->currentReadRequest) & GWEN_IO_REQUEST_FLAGS_PACKETEND) {
00370 DBG_INFO(GWEN_LOGDOMAIN, "Got a complete incoming packet");
00371 GWEN_Io_Request_List_Add(xio->currentReadRequest, xio->requestsIn);
00372 xio->currentReadRequest=NULL;
00373 }
00374 else {
00375 int res;
00376
00377 res=GWEN_Io_Request_GetResultCode(xio->currentReadRequest);
00378 if (res) {
00379 if (res==GWEN_ERROR_EOF) {
00380 DBG_INFO(GWEN_LOGDOMAIN, "EOF met, disconnecting");
00381 }
00382 else {
00383 DBG_WARN(GWEN_LOGDOMAIN, "Incomplete request received, aborting connection");
00384 }
00385 GWEN_Io_Request_free(xio->currentReadRequest);
00386 xio->currentReadRequest=NULL;
00387 GWEN_Io_LayerPackets_Abort(io);
00388 }
00389 }
00390 }
00391 }
00392
00393 if (xio->currentReadRequest==NULL && GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusConnected) {
00394 if (GWEN_Io_Request_List_GetCount(xio->requestsIn)<xio->maxReadQueue) {
00395 uint8_t *buf;
00396 GWEN_IO_REQUEST *r;
00397 int rv;
00398
00399 buf=(uint8_t*) malloc(xio->readSize);
00400 assert(buf);
00401
00402 r=GWEN_Io_Request_new(GWEN_Io_Request_TypeRead,
00403 buf, xio->readSize,
00404 NULL, NULL, 0);
00405 assert(r);
00406
00407 GWEN_Io_Request_AddFlags(r,
00408 GWEN_IO_REQUEST_FLAGS_TAKEOVER |
00409 GWEN_IO_REQUEST_FLAGS_PACKETBEGIN);
00410 DBG_INFO(GWEN_LOGDOMAIN, "Trying to send read request");
00411 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), r);
00412 if (rv) {
00413 if (rv!=GWEN_ERROR_TRY_AGAIN) {
00414 DBG_WARN(GWEN_LOGDOMAIN, "Error adding request to baselayer (%d), aborting", rv);
00415 GWEN_Io_LayerPackets_Abort(io);
00416 doneSomething=1;
00417 }
00418 GWEN_Io_Request_free(r);
00419 }
00420 else {
00421 xio->currentReadRequest=r;
00422 doneSomething=1;
00423 }
00424 }
00425 }
00426
00427 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00428 }
00429
00430
00431
00432 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerPackets_WorkOnWriteRequests(GWEN_IO_LAYER *io) {
00433 GWEN_IO_LAYER_PACKETS *xio;
00434 int doneSomething=0;
00435
00436 assert(io);
00437 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00438 assert(xio);
00439
00440 if (xio->currentWriteRequest) {
00441 if (GWEN_Io_Request_GetStatus(xio->currentWriteRequest)==GWEN_Io_Request_StatusFinished) {
00442 doneSomething=1;
00443 GWEN_Io_Request_free(xio->currentWriteRequest);
00444 xio->currentWriteRequest=NULL;
00445 }
00446 }
00447
00448 if (xio->currentWriteRequest==NULL && GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusConnected) {
00449 GWEN_IO_REQUEST *r;
00450
00451 r=GWEN_Io_Request_List_First(xio->requestsOut);
00452 if (r) {
00453 int rv;
00454
00455 GWEN_Io_Request_AddFlags(r,
00456 GWEN_IO_REQUEST_FLAGS_PACKETBEGIN |
00457 GWEN_IO_REQUEST_FLAGS_PACKETEND |
00458 GWEN_IO_REQUEST_FLAGS_WRITEALL |
00459 GWEN_IO_REQUEST_FLAGS_FLUSH);
00460 DBG_INFO(GWEN_LOGDOMAIN, "Trying to send write request");
00461 rv=GWEN_Io_Layer_AddRequest(GWEN_Io_Layer_GetBaseLayer(io), r);
00462 if (rv) {
00463 if (rv!=GWEN_ERROR_TRY_AGAIN) {
00464 DBG_WARN(GWEN_LOGDOMAIN, "Error adding request to baselayer (%d), aborting", rv);
00465 GWEN_Io_LayerPackets_Abort(io);
00466 doneSomething=1;
00467 }
00468 }
00469 else {
00470 xio->currentWriteRequest=r;
00471
00472 GWEN_Io_Request_List_Del(r);
00473 doneSomething=1;
00474 }
00475 }
00476 }
00477
00478 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00479 }
00480
00481
00482
00483 GWEN_IO_LAYER_WORKRESULT GWEN_Io_LayerPackets_WorkOnRequests(GWEN_IO_LAYER *io) {
00484 GWEN_IO_LAYER_PACKETS *xio;
00485 int doneSomething=0;
00486
00487 assert(io);
00488 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00489 assert(xio);
00490
00491
00492 if (GWEN_Io_LayerPackets_WorkOnReadRequests(io)!=GWEN_Io_Layer_WorkResultBlocking)
00493 doneSomething=1;
00494
00495
00496 if (GWEN_Io_LayerPackets_WorkOnWriteRequests(io)!=GWEN_Io_Layer_WorkResultBlocking)
00497 doneSomething=1;
00498
00499
00500 if (GWEN_Io_Layer_WorkOnRequests(GWEN_Io_Layer_GetBaseLayer(io))!=GWEN_Io_Layer_WorkResultBlocking)
00501 doneSomething=1;
00502
00503 if (GWEN_Io_Layer_GetStatus(io)==GWEN_Io_Layer_StatusListening) {
00504 GWEN_IO_LAYER *newIo;
00505
00506 newIo=GWEN_Io_Layer_GetNextIncomingLayer(GWEN_Io_Layer_GetBaseLayer(io));
00507 if (newIo) {
00508 GWEN_IO_LAYER *newNewIo;
00509
00510 newNewIo=GWEN_Io_LayerPackets_new(newIo);
00511 GWEN_Io_Layer_AddIncomingLayer(io, newNewIo);
00512 doneSomething=1;
00513 }
00514 }
00515
00516 return (doneSomething==0)?GWEN_Io_Layer_WorkResultBlocking:GWEN_Io_Layer_WorkResultOk;
00517 }
00518
00519
00520
00521 int GWEN_Io_LayerPackets_HasWaitingRequests(GWEN_IO_LAYER *io) {
00522 GWEN_IO_LAYER_PACKETS *xio;
00523
00524 assert(io);
00525 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00526 assert(xio);
00527
00528 if (xio->currentReadRequest ||
00529 xio->currentWriteRequest ||
00530 GWEN_Io_Request_List_GetCount(xio->requestsOut))
00531
00532 return 1;
00533 else
00534 return 0;
00535 }
00536
00537
00538
00539 int GWEN_Io_LayerPackets_HasReadRequests(const GWEN_IO_LAYER *io) {
00540 GWEN_IO_LAYER_PACKETS *xio;
00541
00542 assert(io);
00543 xio=GWEN_INHERIT_GETDATA(GWEN_IO_LAYER, GWEN_IO_LAYER_PACKETS, io);
00544 assert(xio);
00545
00546 if (GWEN_Io_Request_List_GetCount(xio->requestsIn))
00547 return 1;
00548 return 0;
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558