ipc.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     cvs         : $Id$
00005     begin       : Fri May 07 2004
00006     copyright   : (C) 2004 by Martin Preuss
00007     email       : martin@libchipcard.de
00008 
00009  ***************************************************************************
00010  *          Please see toplevel file COPYING for license details           *
00011  ***************************************************************************/
00012 
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016 
00017 #include <strings.h>
00018 
00019 #include "ipc_p.h"
00020 #include <gwenhywfar/debug.h>
00021 #include <gwenhywfar/io_packets.h>
00022 #include <gwenhywfar/iomanager.h>
00023 #include <gwenhywfar/text.h>
00024 
00025 
00026 
00027 GWEN_LIST_FUNCTIONS(GWEN_IPCNODE, GWEN_IpcNode)
00028 GWEN_LIST_FUNCTIONS(GWEN_IPCMSG, GWEN_IpcMsg)
00029 GWEN_LIST_FUNCTIONS(GWEN_IPC__REQUEST, GWEN_Ipc__Request)
00030 
00031 
00032 static uint32_t gwen_ipc__lastid=0;
00033 
00034 
00035 /* _________________________________________________________________________
00036  * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
00037  *                                IPC Node
00038  * YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
00039  */
00040 
00041 
00042 /* -------------------------------------------------------------- FUNCTION */
00043 GWEN_IPCNODE *GWEN_IpcNode_new(){
00044   GWEN_IPCNODE *n;
00045 
00046   GWEN_NEW_OBJECT(GWEN_IPCNODE, n);
00047   DBG_MEM_INC("GWEN_IPCNODE", 0);
00048   GWEN_LIST_INIT(GWEN_IPCNODE, n);
00049 
00050   if (gwen_ipc__lastid==0)
00051     gwen_ipc__lastid=time(0);
00052   n->id=++gwen_ipc__lastid;
00053   n->usage=1;
00054   return n;
00055 }
00056 
00057 
00058 
00059 /* -------------------------------------------------------------- FUNCTION */
00060 void GWEN_IpcNode_free(GWEN_IPCNODE *n){
00061   if (n) {
00062     DBG_MEM_DEC("GWEN_IPCNODE");
00063     assert(n->usage);
00064     if (--(n->usage)==0) {
00065       GWEN_Io_Layer_free(n->ioLayer);
00066       GWEN_LIST_FINI(GWEN_IPCNODE, n);
00067       GWEN_FREE_OBJECT(n);
00068     }
00069   }
00070 }
00071 
00072 
00073 
00074 /* -------------------------------------------------------------- FUNCTION */
00075 void GWEN_IpcNode_Attach(GWEN_IPCNODE *n){
00076   assert(n);
00077   DBG_MEM_INC("GWEN_IPCNODE", 1);
00078   n->usage++;
00079 }
00080 
00081 
00082 
00083 /* -------------------------------------------------------------- FUNCTION */
00084 void GWEN_IpcNode_Dump(GWEN_IPCNODE *n, FILE *f, int indent){
00085   int i;
00086 
00087   assert(n);
00088   for (i=0; i<indent; i++)
00089     fprintf(f, " ");
00090   fprintf(f, "---------------------------------------\n");
00091   for (i=0; i<indent; i++)
00092     fprintf(f, " ");
00093   fprintf(f, "IPC Node:\n");
00094   for (i=0; i<indent; i++)
00095     fprintf(f, " ");
00096   fprintf(f, "Id               : %08x\n", n->id);
00097   for (i=0; i<indent; i++)
00098     fprintf(f, " ");
00099   fprintf(f, "Mark             : %d\n", n->mark);
00100   for (i=0; i<indent; i++)
00101     fprintf(f, " ");
00102   fprintf(f, "Usage            : %d\n", n->usage);
00103   for (i=0; i<indent; i++)
00104     fprintf(f, " ");
00105   fprintf(f, "Is Server        : ");
00106   if (n->isServer)
00107     fprintf(f, "yes\n");
00108   else
00109     fprintf(f, "no\n");
00110   for (i=0; i<indent; i++)
00111     fprintf(f, " ");
00112   fprintf(f, "Is Passive Client: ");
00113   if (n->isPassiveClient)
00114     fprintf(f, "yes\n");
00115   else
00116     fprintf(f, "no\n");
00117 }
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 /* _________________________________________________________________________
00126  * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
00127  *                                IPC Message
00128  * YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
00129  */
00130 
00131 /* -------------------------------------------------------------- FUNCTION */
00132 GWEN_IPCMSG *GWEN_IpcMsg_new(GWEN_IPCNODE *n){
00133   GWEN_IPCMSG *m;
00134 
00135   assert(n);
00136   GWEN_NEW_OBJECT(GWEN_IPCMSG, m);
00137   DBG_MEM_INC("GWEN_IPCMSG", 0);
00138   GWEN_LIST_INIT(GWEN_IPCMSG, m);
00139   m->node=n;
00140   GWEN_IpcNode_Attach(m->node);
00141   return m;
00142 }
00143 
00144 
00145 
00146 /* -------------------------------------------------------------- FUNCTION */
00147 void GWEN_IpcMsg_free(GWEN_IPCMSG *m){
00148   if (m) {
00149     DBG_MEM_DEC("GWEN_IPCMSG");
00150     GWEN_Io_Request_free(m->packet);
00151     GWEN_IpcNode_free(m->node);
00152     GWEN_DB_Group_free(m->db);
00153     GWEN_LIST_FINI(GWEN_IPCMSG, m);
00154     GWEN_FREE_OBJECT(m);
00155   }
00156 }
00157 
00158 
00159 
00160 /* -------------------------------------------------------------- FUNCTION */
00161 void GWEN_IpcMsg_Dump(GWEN_IPCMSG *m, FILE *f, int indent){
00162   int i;
00163 
00164   assert(m);
00165   for (i=0; i<indent; i++)
00166     fprintf(f, " ");
00167   fprintf(f, "---------------------------------------\n");
00168   for (i=0; i<indent; i++)
00169     fprintf(f, " ");
00170   fprintf(f, "IPC Message:\n");
00171   for (i=0; i<indent; i++)
00172     fprintf(f, " ");
00173   fprintf(f, "Id               : %08x\n", m->id);
00174   for (i=0; i<indent; i++)
00175     fprintf(f, " ");
00176   fprintf(f, "RefId            : %08x\n", m->refId);
00177   for (i=0; i<indent; i++)
00178     fprintf(f, " ");
00179   fprintf(f, "Node Id          : %08x\n", m->node->id);
00180   for (i=0; i<indent; i++)
00181     fprintf(f, " ");
00182   fprintf(f, "DB:\n");
00183   GWEN_DB_Dump(m->db, f, indent+4);
00184   for (i=0; i<indent; i++)
00185     fprintf(f, " ");
00186   fprintf(f, "Send Time        : %s",
00187           (m->sendTime)?ctime(&(m->sendTime)):"never\n");
00188   for (i=0; i<indent; i++)
00189     fprintf(f, " ");
00190   fprintf(f, "Receiption Time  : %s",
00191           (m->receivedTime)?ctime(&(m->receivedTime)):"never\n");
00192 }
00193 
00194 
00195 
00196 
00197 
00198 
00199 /* _________________________________________________________________________
00200  * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
00201  *                                IPC Request
00202  * YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
00203  */
00204 
00205 
00206 /* -------------------------------------------------------------- FUNCTION */
00207 GWEN_IPC__REQUEST *GWEN_Ipc__Request_new(){
00208   GWEN_IPC__REQUEST *r;
00209 
00210   GWEN_NEW_OBJECT(GWEN_IPC__REQUEST, r);
00211   DBG_MEM_INC("GWEN_IPC__REQUEST", 0);
00212   GWEN_LIST_INIT(GWEN_IPC__REQUEST, r);
00213 
00214   r->requestMsgs=GWEN_IpcMsg_List_new();
00215   r->responseMsgs=GWEN_IpcMsg_List_new();
00216   r->usage=1;
00217   return r;
00218 }
00219 
00220 
00221 
00222 /* -------------------------------------------------------------- FUNCTION */
00223 void GWEN_Ipc__Request_free(GWEN_IPC__REQUEST *r){
00224   if (r) {
00225     assert(r->usage);
00226     if (--(r->usage)==0) {
00227       DBG_MEM_DEC("GWEN_IPC__REQUEST");
00228       GWEN_IpcMsg_List_free(r->responseMsgs);
00229       GWEN_IpcMsg_List_free(r->requestMsgs);
00230       GWEN_LIST_FINI(GWEN_IPC__REQUEST, r);
00231       GWEN_FREE_OBJECT(r);
00232     }
00233   }
00234 }
00235 
00236 
00237 
00238 /* -------------------------------------------------------------- FUNCTION */
00239 void GWEN_Ipc__Request_Attach(GWEN_IPC__REQUEST *r){
00240   assert(r);
00241   assert(r->usage);
00242   r->usage++;
00243 }
00244 
00245 
00246 
00247 /* -------------------------------------------------------------- FUNCTION */
00248 void GWEN_Ipc__Request_AddRequestMsg(GWEN_IPC__REQUEST *r, GWEN_IPCMSG *m){
00249   assert(r);
00250   assert(m);
00251   GWEN_IpcMsg_List_Add(m, r->requestMsgs);
00252 }
00253 
00254 
00255 
00256 /* -------------------------------------------------------------- FUNCTION */
00257 GWEN_IPCMSG_LIST *GWEN_Ipc__Request_GetRequestMsgList(const GWEN_IPC__REQUEST *r){
00258   assert(r);
00259   return r->requestMsgs;
00260 }
00261 
00262 
00263 
00264 /* -------------------------------------------------------------- FUNCTION */
00265 void GWEN_Ipc__Request_AddResponseMsg(GWEN_IPC__REQUEST *r, GWEN_IPCMSG *m){
00266   assert(r);
00267   assert(m);
00268   GWEN_IpcMsg_List_Add(m, r->responseMsgs);
00269 }
00270 
00271 
00272 
00273 /* -------------------------------------------------------------- FUNCTION */
00274 int GWEN_Ipc__Request_HasRequestMsg(GWEN_IPC__REQUEST *r,
00275                                     uint32_t nid,
00276                                     uint32_t id){
00277   GWEN_IPCMSG *m;
00278 
00279   assert(r);
00280   assert(id);
00281 
00282   m=GWEN_IpcMsg_List_First(r->requestMsgs);
00283   while(m) {
00284     if (m->node->id==nid &&
00285         m->id==id)
00286       return 1;
00287     m=GWEN_IpcMsg_List_Next(m);
00288   } /* while */
00289 
00290   return 0;
00291 }
00292 
00293 
00294 
00295 /* -------------------------------------------------------------- FUNCTION */
00296 void GWEN_Ipc__Request_Dump(GWEN_IPC__REQUEST *r, FILE *f, int indent){
00297   int i;
00298   GWEN_IPCMSG *m;
00299 
00300   assert(r);
00301   for (i=0; i<indent; i++)
00302     fprintf(f, " ");
00303   fprintf(f, "---------------------------------------\n");
00304   for (i=0; i<indent; i++)
00305     fprintf(f, " ");
00306   fprintf(f, "IPC Request:\n");
00307   for (i=0; i<indent; i++)
00308     fprintf(f, " ");
00309   fprintf(f, "Id               : %08x\n", r->id);
00310   for (i=0; i<indent; i++)
00311     fprintf(f, " ");
00312   fprintf(f, "Request Message(s)\n");
00313   m=GWEN_IpcMsg_List_First(r->requestMsgs);
00314   if (!m) {
00315     for (i=0; i<indent+4; i++)
00316       fprintf(f, " ");
00317     fprintf(f, "none\n");
00318   }
00319   while(m) {
00320     GWEN_IpcMsg_Dump(m, f, indent+4);
00321     m=GWEN_IpcMsg_List_Next(m);
00322   }
00323   for (i=0; i<indent; i++)
00324     fprintf(f, " ");
00325   fprintf(f, "Response Message(s)\n");
00326   m=GWEN_IpcMsg_List_First(r->responseMsgs);
00327   if (!m) {
00328     for (i=0; i<indent+4; i++)
00329       fprintf(f, " ");
00330     fprintf(f, "none\n");
00331   }
00332   while(m) {
00333     GWEN_IpcMsg_Dump(m, f, indent+4);
00334     m=GWEN_IpcMsg_List_Next(m);
00335   }
00336 }
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 /* _________________________________________________________________________
00345  * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
00346  *                                IPC Manager
00347  * YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
00348  */
00349 
00350 
00351 
00352 
00353 /* -------------------------------------------------------------- FUNCTION */
00354 GWEN_IPCMANAGER *GWEN_IpcManager_new(){
00355   GWEN_IPCMANAGER *mgr;
00356 
00357   GWEN_NEW_OBJECT(GWEN_IPCMANAGER, mgr);
00358   DBG_MEM_INC("GWEN_IPCMANAGER", 0);
00359   mgr->nodes=GWEN_IpcNode_List_new();
00360   mgr->outRequests=GWEN_Ipc__Request_List_new();
00361   mgr->newInRequests=GWEN_Ipc__Request_List_new();
00362   mgr->oldInRequests=GWEN_Ipc__Request_List_new();
00363 
00364   mgr->usage=1;
00365   return mgr;
00366 }
00367 
00368 
00369 
00370 /* -------------------------------------------------------------- FUNCTION */
00371 void GWEN_IpcManager_Attach(GWEN_IPCMANAGER *mgr){
00372   assert(mgr);
00373   DBG_MEM_INC("GWEN_IPCMANAGER", 1);
00374   mgr->usage++;
00375 }
00376 
00377 
00378 
00379 
00380 /* -------------------------------------------------------------- FUNCTION */
00381 void GWEN_IpcManager_free(GWEN_IPCMANAGER *mgr){
00382   if (mgr) {
00383     DBG_MEM_DEC("GWEN_IPCMANAGER");
00384     assert(mgr->usage);
00385     if (--(mgr->usage)==0) {
00386       free(mgr->application);
00387       GWEN_Ipc__Request_List_free(mgr->oldInRequests);
00388       GWEN_Ipc__Request_List_free(mgr->newInRequests);
00389       GWEN_Ipc__Request_List_free(mgr->outRequests);
00390       GWEN_IpcNode_List_free(mgr->nodes);
00391 
00392       GWEN_FREE_OBJECT(mgr);
00393     }
00394   }
00395 }
00396 
00397 
00398 
00399 /* -------------------------------------------------------------- FUNCTION */
00400 const char *GWEN_IpcManager_GetApplicationName(const GWEN_IPCMANAGER *mgr) {
00401   assert(mgr);
00402   return mgr->application;
00403 }
00404 
00405 
00406 /* -------------------------------------------------------------- FUNCTION */
00407 void GWEN_IpcManager_SetApplicationName(GWEN_IPCMANAGER *mgr,
00408                                         const char *s){
00409   assert(mgr);
00410   if (s) mgr->application=strdup(s);
00411   else mgr->application=0;
00412 }
00413 
00414 
00415 
00416 /* -------------------------------------------------------------- FUNCTION */
00417 uint32_t GWEN_IpcManager_AddServer(GWEN_IPCMANAGER *mgr,
00418                                    GWEN_IO_LAYER *ioBase,
00419                                    uint32_t mark){
00420   GWEN_IPCNODE *n;
00421   GWEN_IO_LAYER *io;
00422   int rv;
00423 
00424   /* create connection layer */
00425   io=GWEN_Io_LayerPackets_new(ioBase);
00426   assert(io);
00427   rv=GWEN_Io_Manager_RegisterLayer(io);
00428   if (rv<0) {
00429     DBG_INFO(GWEN_LOGDOMAIN, "Could not register io layer (%d)", rv);
00430     GWEN_Io_Layer_free(io);
00431     return 0;
00432   }
00433 
00434   /* go into listening state */
00435   rv=GWEN_Io_Layer_ListenRecursively(io, NULL);
00436   if (rv<0) {
00437     DBG_INFO(GWEN_LOGDOMAIN, "Could not start listening (%d)", rv);
00438     GWEN_Io_Layer_free(io);
00439     return 0;
00440   }
00441 
00442   n=GWEN_IpcNode_new();
00443   n->ioLayer=io;
00444   n->mark=mark;
00445   n->isServer=1;
00446   GWEN_IpcNode_List_Add(n, mgr->nodes);
00447   return n->id;
00448 }
00449 
00450 
00451 
00452 /* -------------------------------------------------------------- FUNCTION */
00453 uint32_t GWEN_IpcManager_AddClient(GWEN_IPCMANAGER *mgr,
00454                                    GWEN_IO_LAYER *ioBase,
00455                                    uint32_t mark){
00456   GWEN_IPCNODE *n;
00457   GWEN_IO_LAYER *io;
00458   int rv;
00459 
00460   n=GWEN_IpcNode_new();
00461 
00462   io=GWEN_Io_LayerPackets_new(ioBase);
00463   assert(io);
00464   rv=GWEN_Io_Manager_RegisterLayer(io);
00465   if (rv<0) {
00466     DBG_INFO(GWEN_LOGDOMAIN, "Could not register io layer (%d)", rv);
00467     GWEN_Io_Layer_free(io);
00468     return 0;
00469   }
00470 
00471   n->ioLayer=io;
00472   n->mark=mark;
00473   n->isServer=0;
00474   GWEN_IpcNode_List_Add(n, mgr->nodes);
00475   return n->id;
00476 }
00477 
00478 
00479 
00480 /* -------------------------------------------------------------- FUNCTION */
00481 void GWEN_IpcManager__RemoveNodeRequestMessages(GWEN_UNUSED GWEN_IPCMANAGER *mgr,
00482                                                 GWEN_IPCNODE *n,
00483                                                 GWEN_IPC__REQUEST_LIST *rl,
00484                                                 const char *msgType) {
00485   GWEN_IPC__REQUEST *r;
00486 
00487   /* remove all messages for/of this client from request */
00488   r=GWEN_Ipc__Request_List_First(rl);
00489   while(r) {
00490     GWEN_IPC__REQUEST *rnext;
00491     GWEN_IPCMSG *msg;
00492 
00493     rnext=GWEN_Ipc__Request_List_Next(r);
00494     msg=GWEN_IpcMsg_List_First(r->requestMsgs);
00495     while(msg) {
00496       GWEN_IPCMSG *nextmsg;
00497 
00498       nextmsg=GWEN_IpcMsg_List_Next(msg);
00499       assert(msg->node);
00500       if (msg->node==n) {
00501         /* same node, remove msg */
00502         DBG_INFO(GWEN_LOGDOMAIN, "Removing %s message for/from node %08x",
00503                  msgType, n->id);
00504         if (GWEN_Logger_GetLevel(GWEN_LOGDOMAIN)>=GWEN_LoggerLevel_Info) {
00505           if (msg->db) {
00506             GWEN_DB_Dump(msg->db, stderr, 2);
00507           }
00508         }
00509         GWEN_IpcMsg_List_Del(msg);
00510         GWEN_IpcMsg_free(msg);
00511       }
00512       msg=nextmsg;
00513     } /* while msg */
00514 
00515     /* check whether the request is empty */
00516     if (GWEN_IpcMsg_List_First(r->requestMsgs)==0) {
00517       /* it is, remove the request */
00518       DBG_INFO(GWEN_LOGDOMAIN, "Removing %s request %08x for/from node %08x",
00519                msgType, r->id, n->id);
00520       GWEN_Ipc__Request_List_Del(r);
00521       GWEN_Ipc__Request_free(r);
00522     }
00523     r=rnext;
00524   } /* while r */
00525 }
00526 
00527 
00528 
00529 /* -------------------------------------------------------------- FUNCTION */
00530 int GWEN_IpcManager_RemoveClient(GWEN_IPCMANAGER *mgr, uint32_t nid) {
00531   GWEN_IPCNODE *n;
00532 
00533   DBG_DEBUG(GWEN_LOGDOMAIN, "Removing client %08x", nid);
00534   assert(mgr);
00535 
00536   /* get client node */
00537   n=GWEN_IpcNode_List_First(mgr->nodes);
00538   while(n) {
00539     if (n->id==nid)
00540       break;
00541     n=GWEN_IpcNode_List_Next(n);
00542   } /* while */
00543   if (!n) {
00544     DBG_ERROR(GWEN_LOGDOMAIN, "Node %08x not found", nid);
00545     return -1;
00546   }
00547 
00548   /* remove all messages of this client in any request */
00549   GWEN_IpcManager__RemoveNodeRequestMessages(mgr, n, mgr->outRequests,
00550                                              "outRequest");
00551   GWEN_IpcManager__RemoveNodeRequestMessages(mgr, n, mgr->newInRequests,
00552                                              "newInRequest");
00553   GWEN_IpcManager__RemoveNodeRequestMessages(mgr, n, mgr->oldInRequests,
00554                                              "newOutRequest");
00555   /* remove node */
00556   DBG_NOTICE(GWEN_LOGDOMAIN, "Disconnecting netLayer");
00557   GWEN_Io_Layer_DisconnectRecursively(n->ioLayer, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 2000);
00558   GWEN_Io_Manager_UnregisterLayer(n->ioLayer);
00559   DBG_NOTICE(GWEN_LOGDOMAIN, "Removing client %08x", n->id);
00560   GWEN_IpcNode_List_Del(n);
00561   GWEN_IpcNode_free(n);
00562 
00563   return 0;
00564 }
00565 
00566 
00567 
00568 /* -------------------------------------------------------------- FUNCTION */
00569 GWEN_IPC__REQUEST *GWEN_IpcManager__FindRequest(GWEN_IPCMANAGER *mgr,
00570                                                 uint32_t rid,
00571                                                 GWEN_IPC__REQUEST *r) {
00572   assert(mgr);
00573   assert(r);
00574 
00575   while(r) {
00576     if (r->id==rid)
00577       return r;
00578     r=GWEN_Ipc__Request_List_Next(r);
00579   }
00580   return 0;
00581 }
00582 
00583 
00584 
00585 /* -------------------------------------------------------------- FUNCTION */
00586 int GWEN_IpcManager_SendRequest(GWEN_IPCMANAGER *mgr,
00587                                 uint32_t nid,
00588                                 GWEN_DB_NODE *req,
00589                                 uint32_t *pReqId){
00590   GWEN_IPCNODE *n;
00591   GWEN_IPC__REQUEST *r;
00592   GWEN_IPCMSG *m;
00593   int rv;
00594 
00595   n=GWEN_IpcNode_List_First(mgr->nodes);
00596   while(n) {
00597     if (n->id==nid)
00598       break;
00599     n=GWEN_IpcNode_List_Next(n);
00600   } /* while */
00601   if (!n) {
00602     DBG_ERROR(GWEN_LOGDOMAIN, "Node %08x not found", nid);
00603     return GWEN_ERROR_NOT_FOUND;
00604   }
00605 
00606   m=GWEN_IpcMsg_new(n);
00607   m->db=req;
00608   m->id=++(n->nextMsgId);
00609 
00610   rv=GWEN_IpcManager__SendMsg(mgr, m);
00611   if (rv) {
00612     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00613     GWEN_IpcMsg_free(m);
00614     return rv;
00615   }
00616 
00617   r=GWEN_Ipc__Request_new();
00618   r->id=++gwen_ipc__lastid;
00619   GWEN_Ipc__Request_AddRequestMsg(r, m);
00620   GWEN_Ipc__Request_List_Add(r, mgr->outRequests);
00621   *pReqId=r->id;
00622 
00623   return 0;
00624 }
00625 
00626 
00627 
00628 /* -------------------------------------------------------------- FUNCTION */
00629 int GWEN_IpcManager_SendResponse(GWEN_IPCMANAGER *mgr,
00630                                  uint32_t rid,
00631                                  GWEN_DB_NODE *rsp){
00632   GWEN_IPC__REQUEST *r;
00633   GWEN_IPCMSG *m;
00634   GWEN_IPCMSG *om;
00635   int rv;
00636 
00637   r=GWEN_Ipc__Request_List_First(mgr->oldInRequests);
00638   while(r) {
00639     if (r->id==rid)
00640       break;
00641     r=GWEN_Ipc__Request_List_Next(r);
00642   } /* while */
00643   if (!r) {
00644     DBG_ERROR(GWEN_LOGDOMAIN, "Request %08x not found", rid);
00645     return GWEN_ERROR_NOT_FOUND;
00646   }
00647 
00648   om=GWEN_IpcMsg_List_First(r->requestMsgs);
00649   assert(om);
00650 
00651   m=GWEN_IpcMsg_new(om->node);
00652   m->refId=om->id;
00653   m->db=rsp;
00654   m->id=++(om->node->nextMsgId);
00655 
00656   DBG_DEBUG(GWEN_LOGDOMAIN, "Sending response %08x for request %08x",
00657             m->id, m->refId);
00658 
00659   rv=GWEN_IpcManager__SendMsg(mgr, m);
00660   if (rv) {
00661     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00662     GWEN_IpcMsg_free(m);
00663     return rv;
00664   }
00665 
00666   GWEN_Ipc__Request_AddResponseMsg(r, m);
00667   return 0;
00668 }
00669 
00670 
00671 
00672 /* -------------------------------------------------------------- FUNCTION */
00673 int GWEN_IpcManager_RemoveRequest(GWEN_IPCMANAGER *mgr,
00674                                   uint32_t rid,
00675                                   int inOrOut){
00676   GWEN_IPC__REQUEST *r;
00677 
00678   if (inOrOut==0)
00679     r=GWEN_Ipc__Request_List_First(mgr->oldInRequests);
00680   else
00681     r=GWEN_Ipc__Request_List_First(mgr->outRequests);
00682   while(r) {
00683     if (r->id==rid)
00684       break;
00685     r=GWEN_Ipc__Request_List_Next(r);
00686   } /* while */
00687   if (!r) {
00688     DBG_ERROR(GWEN_LOGDOMAIN, "%s request %08x not found",
00689               inOrOut?"Outgoing":"Incoming", rid);
00690     return -1;
00691   }
00692   GWEN_Ipc__Request_List_Del(r);
00693   GWEN_Ipc__Request_free(r);
00694   return 0;
00695 }
00696 
00697 
00698 
00699 /* -------------------------------------------------------------- FUNCTION */
00700 uint32_t GWEN_IpcManager_GetNextInRequest(GWEN_IPCMANAGER *mgr,
00701                                                   uint32_t mark){
00702   GWEN_IPC__REQUEST *r;
00703 
00704   r=GWEN_Ipc__Request_List_First(mgr->newInRequests);
00705   while(r) {
00706     GWEN_IPCMSG *om;
00707 
00708     if (mark==0)
00709       break;
00710 
00711     om=GWEN_IpcMsg_List_First(r->requestMsgs);
00712     assert(om);
00713     assert(om->node);
00714     if (om->node->mark==mark)
00715       break;
00716     r=GWEN_Ipc__Request_List_Next(r);
00717   }
00718 
00719   if (r) {
00720     GWEN_Ipc__Request_List_Del(r);
00721     GWEN_Ipc__Request_List_Add(r, mgr->oldInRequests);
00722     return r->id;
00723   }
00724   return 0;
00725 }
00726 
00727 
00728 
00729 /* -------------------------------------------------------------- FUNCTION */
00730 GWEN_DB_NODE *GWEN_IpcManager_GetInRequestData(GWEN_IPCMANAGER *mgr,
00731                                                uint32_t rid){
00732   GWEN_IPC__REQUEST *r;
00733   GWEN_IPCMSG *om;
00734 
00735   r=GWEN_Ipc__Request_List_First(mgr->oldInRequests);
00736   while(r) {
00737     if (r->id==rid)
00738       break;
00739     r=GWEN_Ipc__Request_List_Next(r);
00740   } /* while */
00741   if (!r) {
00742     DBG_ERROR(GWEN_LOGDOMAIN, "Request %08x not found", rid);
00743     return 0;
00744   }
00745 
00746   om=GWEN_IpcMsg_List_First(r->requestMsgs);
00747   assert(om);
00748 
00749   return om->db;
00750 }
00751 
00752 
00753 
00754 /* -------------------------------------------------------------- FUNCTION */
00755 GWEN_IO_LAYER *GWEN_IpcManager_GetIoLayer(GWEN_IPCMANAGER *mgr, uint32_t nid){
00756   GWEN_IPCNODE *n;
00757 
00758   n=GWEN_IpcNode_List_First(mgr->nodes);
00759   while(n) {
00760     if (n->id==nid)
00761       break;
00762     n=GWEN_IpcNode_List_Next(n);
00763   } /* while */
00764   if (!n) {
00765     DBG_ERROR(GWEN_LOGDOMAIN, "Node %08x not found", nid);
00766     return 0;
00767   }
00768 
00769   return n->ioLayer;
00770 }
00771 
00772 
00773 
00774 /* -------------------------------------------------------------- FUNCTION */
00775 uint32_t GWEN_IpcManager_GetClientForNetLayer(const GWEN_IPCMANAGER *mgr,
00776                                               const GWEN_IO_LAYER *io) {
00777   GWEN_IPCNODE *n;
00778 
00779   n=GWEN_IpcNode_List_First(mgr->nodes);
00780   while(n) {
00781     if (n->ioLayer==io)
00782       break;
00783     n=GWEN_IpcNode_List_Next(n);
00784   } /* while */
00785   if (!n) {
00786     DBG_ERROR(GWEN_LOGDOMAIN, "No node found for connection");
00787     return 0;
00788   }
00789   return n->id;
00790 }
00791 
00792 
00793 
00794 /* -------------------------------------------------------------- FUNCTION */
00795 GWEN_DB_NODE *GWEN_IpcManager_PeekResponseData(GWEN_IPCMANAGER *mgr,
00796                                                uint32_t rid){
00797   GWEN_IPC__REQUEST *r;
00798   GWEN_IPCMSG *m;
00799   GWEN_DB_NODE *db;
00800 
00801   r=GWEN_Ipc__Request_List_First(mgr->outRequests);
00802   while(r) {
00803     if (r->id==rid)
00804       break;
00805     r=GWEN_Ipc__Request_List_Next(r);
00806   } /* while */
00807   if (!r) {
00808     DBG_ERROR(GWEN_LOGDOMAIN, "Request %08x not found", rid);
00809     return 0;
00810   }
00811 
00812   m=GWEN_IpcMsg_List_First(r->responseMsgs);
00813   if (!m) {
00814     DBG_DEBUG(GWEN_LOGDOMAIN, "No response yet");
00815     return 0;
00816   }
00817   db=m->db;
00818   assert(m->node);
00819   assert(m->node->id);
00820   return db;
00821 }
00822 
00823 
00824 
00825 /* -------------------------------------------------------------- FUNCTION */
00826 GWEN_DB_NODE *GWEN_IpcManager_GetResponseData(GWEN_IPCMANAGER *mgr,
00827                                               uint32_t rid){
00828   GWEN_IPC__REQUEST *r;
00829   GWEN_IPCMSG *m;
00830   GWEN_DB_NODE *db;
00831 
00832   r=GWEN_Ipc__Request_List_First(mgr->outRequests);
00833   while(r) {
00834     if (r->id==rid)
00835       break;
00836     r=GWEN_Ipc__Request_List_Next(r);
00837   } /* while */
00838   if (!r) {
00839     DBG_ERROR(GWEN_LOGDOMAIN, "Request %08x not found", rid);
00840     return 0;
00841   }
00842 
00843   m=GWEN_IpcMsg_List_First(r->responseMsgs);
00844   if (!m) {
00845     DBG_VERBOUS(GWEN_LOGDOMAIN, "No response yet");
00846     return 0;
00847   }
00848 
00849   db=m->db;
00850   assert(m->node);
00851   assert(m->node->id);
00852   m->db=0;
00853   GWEN_IpcMsg_List_Del(m);
00854   GWEN_IpcMsg_free(m);
00855   return db;
00856 }
00857 
00858 
00859 
00860 /* -------------------------------------------------------------- FUNCTION */
00861 GWEN_IPCMSG *GWEN_IpcManager__MakeErrorResponse(GWEN_UNUSED GWEN_IPCMANAGER *mgr,
00862                                                 GWEN_IPCMSG *m,
00863                                                 int code,
00864                                                 const char *txt) {
00865   GWEN_DB_NODE *db;
00866   GWEN_IPCMSG *newm;
00867 
00868   db=GWEN_DB_Group_new("Error");
00869   GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_DEFAULT,
00870                       "code", code);
00871   if (txt)
00872     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_DEFAULT,
00873                          "text", txt);
00874 
00875   newm=GWEN_IpcMsg_new(m->node);
00876   newm->db=db;
00877   return newm;
00878 }
00879 
00880 
00881 
00882 /* -------------------------------------------------------------- FUNCTION */
00883 int GWEN_IpcManager__CheckRequests(GWEN_IPCMANAGER *mgr) {
00884   GWEN_IPC__REQUEST *r;
00885 
00886   r=GWEN_Ipc__Request_List_First(mgr->outRequests);
00887   while(r) {
00888     GWEN_IPCMSG *m;
00889     GWEN_IPC__REQUEST *nextr;
00890 
00891     nextr=GWEN_Ipc__Request_List_Next(r);
00892     m=GWEN_IpcMsg_List_First(r->requestMsgs);
00893     while(m) {
00894       GWEN_IPCMSG *nextm;
00895       int removeIt;
00896 
00897       nextm=GWEN_IpcMsg_List_Next(m);
00898       removeIt=0;
00899       assert(m->node);
00900 
00901       /* check connection status */
00902       assert(m->node->ioLayer);
00903       if (GWEN_Io_Layer_GetStatus(m->node->ioLayer)==
00904           GWEN_Io_Layer_StatusDisabled) {
00905         GWEN_IPCMSG *errm;
00906 
00907         /* connection broken, remove msg */
00908         DBG_INFO(GWEN_LOGDOMAIN, "Connection broken");
00909         errm=GWEN_IpcManager__MakeErrorResponse(mgr,
00910                                                 m,
00911                                                 GWEN_IPC_ERROR_CONNERR,
00912                                                 "Connection down");
00913         GWEN_IpcMsg_List_Add(errm, r->responseMsgs);
00914         removeIt=1;
00915       }
00916 
00917       /* check timeout */
00918       if (m->sendTime && mgr->sendTimeOut) {
00919         if (difftime(time(0), m->sendTime)>mgr->sendTimeOut) {
00920           GWEN_IPCMSG *errm;
00921 
00922           DBG_INFO(GWEN_LOGDOMAIN, "Message timed out");
00923           errm=GWEN_IpcManager__MakeErrorResponse(mgr,
00924                                                   m,
00925                                                   GWEN_IPC_ERROR_TIMEOUT,
00926                                                   "Message timed out");
00927           GWEN_IpcMsg_List_Add(errm, r->responseMsgs);
00928           removeIt=1;
00929         }
00930       }
00931 
00932       if (removeIt) {
00933         GWEN_IpcMsg_List_Del(m);
00934         GWEN_IpcMsg_free(m);
00935       }
00936       m=nextm;
00937     } /* while */
00938 
00939     r=nextr;
00940   } /* while */
00941 
00942   return 0;
00943 }
00944 
00945 
00946 
00947 /* -------------------------------------------------------------- FUNCTION */
00948 int GWEN_IpcManager_Work(GWEN_IPCMANAGER *mgr) {
00949   int done=0;
00950 
00951   assert(mgr);
00952 
00953   if (GWEN_IpcManager__Work(mgr)==0)
00954     done++;
00955 
00956   if (GWEN_IpcManager__CheckRequests(mgr)) {
00957     DBG_ERROR(GWEN_LOGDOMAIN, "Error checking requests");
00958   }
00959 
00960   return done?0:1;
00961 }
00962 
00963 
00964 
00965 /* -------------------------------------------------------------- FUNCTION */
00966 int GWEN_IpcManager_Disconnect(GWEN_IPCMANAGER *mgr, uint32_t nid){
00967   GWEN_IPCNODE *n;
00968   int rv;
00969 
00970   n=GWEN_IpcNode_List_First(mgr->nodes);
00971   while(n) {
00972     if (n->id==nid)
00973       break;
00974     n=GWEN_IpcNode_List_Next(n);
00975   } /* while */
00976   if (!n) {
00977     DBG_ERROR(GWEN_LOGDOMAIN, "Node %08x not found", nid);
00978     return -1;
00979   }
00980 
00981   n->nextMsgId=0;
00982   n->lastMsgId=0;
00983 
00984   /* remove all messages of this client in any request */
00985   GWEN_IpcManager__RemoveNodeRequestMessages(mgr, n, mgr->outRequests,
00986                                              "outRequest");
00987   GWEN_IpcManager__RemoveNodeRequestMessages(mgr, n, mgr->newInRequests,
00988                                              "newInRequest");
00989   GWEN_IpcManager__RemoveNodeRequestMessages(mgr, n, mgr->oldInRequests,
00990                                              "newOutRequest");
00991 
00992   rv=GWEN_Io_Layer_DisconnectRecursively(n->ioLayer, NULL, 0, 0, 2000);
00993   return rv;
00994 }
00995 
00996 
00997 
00998 /* -------------------------------------------------------------- FUNCTION */
00999 void GWEN_IpcManager_Dump(GWEN_IPCMANAGER *mgr, FILE *f, int indent){
01000   int i;
01001   GWEN_IPCNODE *n;
01002   GWEN_IPC__REQUEST *r;
01003 
01004   assert(mgr);
01005   for (i=0; i<indent; i++)
01006     fprintf(f, " ");
01007   fprintf(f, "=======================================\n");
01008   for (i=0; i<indent; i++)
01009     fprintf(f, " ");
01010   fprintf(f, "IPC Manager:\n");
01011   for (i=0; i<indent; i++)
01012     fprintf(f, " ");
01013   fprintf(f, "Active Nodes     : %ld\n",
01014           GWEN_MemoryDebug_GetObjectCount("GWEN_IPCNODE"));
01015   for (i=0; i<indent; i++)
01016     fprintf(f, " ");
01017   fprintf(f, "Active Messages  : %ld\n",
01018           GWEN_MemoryDebug_GetObjectCount("GWEN_IPCMSG"));
01019   for (i=0; i<indent; i++)
01020     fprintf(f, " ");
01021   fprintf(f, "Active Requests  : %ld\n",
01022           GWEN_MemoryDebug_GetObjectCount("GWEN_IPC__REQUEST"));
01023   for (i=0; i<indent; i++)
01024     fprintf(f, " ");
01025   fprintf(f, "Application      : %s\n", mgr->application);
01026   for (i=0; i<indent; i++)
01027     fprintf(f, " ");
01028   fprintf(f, "Nodes(s)\n");
01029   n=GWEN_IpcNode_List_First(mgr->nodes);
01030   if (!n) {
01031     for (i=0; i<indent+4; i++)
01032       fprintf(f, " ");
01033     fprintf(f, "none\n");
01034   }
01035   while(n) {
01036     GWEN_IpcNode_Dump(n, f, indent+4);
01037     n=GWEN_IpcNode_List_Next(n);
01038   }
01039   for (i=0; i<indent; i++)
01040     fprintf(f, " ");
01041   fprintf(f, "Outgoing Request(s)\n");
01042   r=GWEN_Ipc__Request_List_First(mgr->outRequests);
01043   if (!r) {
01044     for (i=0; i<indent+4; i++)
01045       fprintf(f, " ");
01046     fprintf(f, "none\n");
01047   }
01048   while(r) {
01049     GWEN_Ipc__Request_Dump(r, f, indent+4);
01050     r=GWEN_Ipc__Request_List_Next(r);
01051   }
01052   for (i=0; i<indent; i++)
01053     fprintf(f, " ");
01054   fprintf(f, "Unhandled Incoming Request(s)\n");
01055   r=GWEN_Ipc__Request_List_First(mgr->newInRequests);
01056   if (!r) {
01057     for (i=0; i<indent+4; i++)
01058       fprintf(f, " ");
01059     fprintf(f, "none\n");
01060   }
01061   while(r) {
01062     GWEN_Ipc__Request_Dump(r, f, indent+4);
01063     r=GWEN_Ipc__Request_List_Next(r);
01064   }
01065   for (i=0; i<indent; i++)
01066     fprintf(f, " ");
01067   fprintf(f, "Incoming Request(s) in Work\n");
01068   r=GWEN_Ipc__Request_List_First(mgr->oldInRequests);
01069   if (!r) {
01070     for (i=0; i<indent+4; i++)
01071       fprintf(f, " ");
01072     fprintf(f, "none\n");
01073   }
01074   while(r) {
01075     GWEN_Ipc__Request_Dump(r, f, indent+4);
01076     r=GWEN_Ipc__Request_List_Next(r);
01077   }
01078 }
01079 
01080 
01081 
01082 /* -------------------------------------------------------------- FUNCTION */
01083 int GWEN_IpcManager__SendMsg(GWEN_UNUSED GWEN_IPCMANAGER *mgr,
01084                              GWEN_IPCMSG *m) {
01085   GWEN_BUFFER *buf;
01086   int err;
01087   GWEN_DB_NODE *dbReq;
01088   GWEN_DB_NODE *dbIpc;
01089   GWEN_DB_NODE *dbData;
01090   char numbuf[16];
01091   GWEN_IO_LAYER_STATUS nst;
01092   int rv;
01093 
01094   nst=GWEN_Io_Layer_GetStatus(m->node->ioLayer);
01095   if (nst==GWEN_Io_Layer_StatusDisabled) {
01096     DBG_INFO(GWEN_LOGDOMAIN, "NetLayer is disabled");
01097     return GWEN_ERROR_NOT_OPEN;
01098   }
01099 
01100   /* check for connection state, connect if necessary */
01101   if (nst==GWEN_Io_Layer_StatusUnconnected) {
01102     if (m->node->isPassiveClient) {
01103       DBG_INFO(GWEN_LOGDOMAIN,
01104                "Passive IPC client \"%08x\" is down, "
01105                "not sending message", m->node->id);
01106       return -1;
01107     }
01108     rv=GWEN_Io_Layer_ConnectRecursively(m->node->ioLayer, NULL, 0, 0, 10000);
01109     if (rv<0) {
01110       DBG_INFO(GWEN_LOGDOMAIN, "Could not connect (%d)", rv);
01111       return rv;
01112     }
01113   }
01114 
01115   dbReq=GWEN_DB_Group_new("request");
01116   /* prepare IPC group */
01117   dbIpc=GWEN_DB_GetGroup(dbReq, GWEN_DB_FLAGS_DEFAULT, "ipc");
01118   snprintf(numbuf, sizeof(numbuf), "%d", m->id);
01119   GWEN_DB_SetCharValue(dbIpc, GWEN_DB_FLAGS_DEFAULT,
01120                        "id", numbuf);
01121   if (m->refId) {
01122     snprintf(numbuf, sizeof(numbuf), "%d", m->refId);
01123     GWEN_DB_SetCharValue(dbIpc, GWEN_DB_FLAGS_DEFAULT,
01124                          "refid", numbuf);
01125   }
01126   GWEN_DB_SetCharValue(dbIpc, GWEN_DB_FLAGS_DEFAULT,
01127                        "cmd", GWEN_DB_GroupName(m->db));
01128 
01129   dbData=GWEN_DB_GetGroup(dbReq, GWEN_DB_FLAGS_DEFAULT, "data");
01130   GWEN_DB_AddGroupChildren(dbData, m->db);
01131 
01132   buf=GWEN_Buffer_new(0, 512, 0, 1);
01133   /* encode db */
01134   err=GWEN_DB_WriteToBuffer(dbReq, buf, GWEN_DB_FLAGS_COMPACT, 0, 2000);
01135   if (err) {
01136     DBG_INFO(GWEN_LOGDOMAIN, "Could not encode db (%d)", err);
01137     GWEN_Buffer_free(buf);
01138     GWEN_DB_Group_free(dbReq);
01139     return err;
01140   }
01141   GWEN_DB_Group_free(dbReq);
01142 
01143   rv=GWEN_Buffer_Relinquish(buf);
01144   if (rv<0) {
01145     DBG_ERROR(GWEN_LOGDOMAIN, "Internal error, buffer does not relinquish data (%d)", rv);
01146     GWEN_Buffer_free(buf);
01147     return GWEN_ERROR_INTERNAL;
01148   }
01149 
01150   /* send packet */
01151   rv=GWEN_Io_Layer_WriteBytes(m->node->ioLayer,
01152                               (const uint8_t*)GWEN_Buffer_GetStart(buf),
01153                               GWEN_Buffer_GetUsedBytes(buf),
01154                               GWEN_IO_REQUEST_FLAGS_PACKETBEGIN |
01155                               GWEN_IO_REQUEST_FLAGS_PACKETEND |
01156                               GWEN_IO_REQUEST_FLAGS_TAKEOVER |
01157                               GWEN_IO_REQUEST_FLAGS_FLUSH,
01158                               0, 10000);
01159   if (rv<0) {
01160     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01161     GWEN_Buffer_free(buf);
01162     return rv;
01163   }
01164 
01165   GWEN_Buffer_free(buf);
01166 
01167   DBG_DEBUG(GWEN_LOGDOMAIN, "Message is on its way");
01168   m->sendTime=time(0);
01169   return 0;
01170 }
01171 
01172 
01173 
01174 
01175 /* -------------------------------------------------------------- FUNCTION */
01176 int GWEN_IpcManager__HandlePacket(GWEN_IPCMANAGER *mgr,
01177                                   GWEN_IPCNODE *n,
01178                                   GWEN_IO_REQUEST *pk) {
01179   GWEN_DB_NODE *dbReq;
01180   GWEN_DB_NODE *dbIpc;
01181   uint32_t msgId;
01182   uint32_t refId;
01183   const char *pBuffer;
01184   uint32_t lBuffer;
01185   int rv;
01186 
01187   /* read and decode message */
01188   pBuffer=(const char*)GWEN_Io_Request_GetBufferPtr(pk);
01189   lBuffer=GWEN_Io_Request_GetBufferPos(pk);
01190 
01191   DBG_DEBUG(GWEN_LOGDOMAIN, "Got an incoming message");
01192   if (GWEN_Logger_GetLevel(0)>=GWEN_LoggerLevel_Debug)
01193     GWEN_Text_DumpString(pBuffer, lBuffer, stderr, 2);
01194   dbReq=GWEN_DB_Group_new("request");
01195 
01196   rv=GWEN_DB_ReadFromString(dbReq, pBuffer, lBuffer,
01197                             GWEN_DB_FLAGS_DEFAULT |
01198                             GWEN_DB_FLAGS_UNTIL_EMPTY_LINE,
01199                             0, 2000);
01200   if (rv) {
01201     DBG_ERROR(GWEN_LOGDOMAIN, "Bad incoming request (%d)", rv);
01202     GWEN_Text_DumpString(pBuffer, lBuffer, stderr, 2);
01203     GWEN_DB_Dump(dbReq, stderr, 2);
01204     GWEN_DB_Group_free(dbReq);
01205     return rv;
01206   }
01207 
01208   /* parse decoded message */
01209   dbIpc=GWEN_DB_GetGroup(dbReq,
01210                          GWEN_PATH_FLAGS_NAMEMUSTEXIST,
01211                          "ipc");
01212   if (dbIpc==0) {
01213     DBG_ERROR(GWEN_LOGDOMAIN, "Invalid incoming request (no IPC group)");
01214     GWEN_DB_Dump(dbReq, stderr, 2);
01215     GWEN_DB_Group_free(dbReq);
01216     return -1;
01217   }
01218   msgId=GWEN_DB_GetIntValue(dbIpc, "id", 0, 0);
01219   refId=GWEN_DB_GetIntValue(dbIpc, "refId", 0, 0);
01220 
01221   if (msgId<=n->lastMsgId) {
01222     DBG_ERROR(GWEN_LOGDOMAIN, "Bad message id (%d<=%d)",
01223               msgId, n->lastMsgId);
01224     GWEN_DB_Group_free(dbReq);
01225     return -1;
01226   }
01227 
01228   n->lastMsgId=msgId;
01229   GWEN_DB_SetIntValue(dbIpc, GWEN_DB_FLAGS_OVERWRITE_VARS,
01230                       "nodeId", n->id);
01231   /* got a valid message */
01232   if (refId) {
01233     GWEN_IPC__REQUEST *r;
01234     GWEN_IPCMSG *m;
01235 
01236     /* it pretends to be a response, check it */
01237     r=GWEN_Ipc__Request_List_First(mgr->outRequests);
01238     while(r) {
01239       if (GWEN_Ipc__Request_HasRequestMsg(r, n->id, refId))
01240         break;
01241       r=GWEN_Ipc__Request_List_Next(r);
01242     } /* while r */
01243     if (!r) {
01244       DBG_WARN(GWEN_LOGDOMAIN,
01245                "Got a response for invalid request (%08x)",
01246                refId);
01247       GWEN_DB_Group_free(dbReq);
01248       return -1;
01249     }
01250 
01251     DBG_DEBUG(GWEN_LOGDOMAIN,
01252               "Got a response for request %08x",
01253               r->id);
01254     m=GWEN_IpcMsg_new(n);
01255     m->db=dbReq;
01256     m->id=msgId;
01257     m->refId=refId;
01258     m->receivedTime=time(0);
01259     GWEN_Ipc__Request_AddResponseMsg(r, m);
01260   }
01261   else {
01262     GWEN_IPC__REQUEST *r;
01263     GWEN_IPCMSG *m;
01264 
01265     /* this is a new incoming request */
01266     DBG_DEBUG(GWEN_LOGDOMAIN, "Got an incoming request (%08x)",
01267               msgId);
01268     if (GWEN_Logger_GetLevel(GWEN_LOGDOMAIN)>=GWEN_LoggerLevel_Debug) {
01269       GWEN_DB_Dump(dbReq, stderr, 2);
01270     }
01271     m=GWEN_IpcMsg_new(n);
01272     m->db=dbReq;
01273     m->id=msgId;
01274     m->refId=refId;
01275     m->receivedTime=time(0);
01276     r=GWEN_Ipc__Request_new();
01277     r->id=++gwen_ipc__lastid;
01278     GWEN_Ipc__Request_AddRequestMsg(r, m);
01279     GWEN_Ipc__Request_List_Add(r, mgr->newInRequests);
01280   } /* if refId found */
01281 
01282   return 0;
01283 }
01284 
01285 
01286 
01287 /* -------------------------------------------------------------- FUNCTION */
01288 int GWEN_IpcManager__Work(GWEN_IPCMANAGER *mgr) {
01289   GWEN_IPCNODE *n;
01290   int done=0;
01291 
01292   n=GWEN_IpcNode_List_First(mgr->nodes);
01293   while(n) {
01294     GWEN_IPCNODE *next;
01295     GWEN_IO_LAYER_STATUS st;
01296 
01297     next=GWEN_IpcNode_List_Next(n);
01298     DBG_DEBUG(GWEN_LOGDOMAIN, "Checking node");
01299 
01300     st=GWEN_Io_Layer_GetStatus(n->ioLayer);
01301     if (st==GWEN_Io_Layer_StatusDisabled ||
01302         st==GWEN_Io_Layer_StatusDisconnected) {
01303       if (!GWEN_Io_LayerPackets_HasReadRequests(n->ioLayer)) {
01304         if (!(n->flags & GWEN_IPCNODE_FLAGS_MGR_INFORMED)) {
01305           n->flags|=GWEN_IPCNODE_FLAGS_MGR_INFORMED;
01306           GWEN_Io_Layer_DisconnectRecursively(n->ioLayer, NULL, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 5000);
01307           if (mgr->clientDownFn) {
01308             GWEN_IpcNode_Attach(n);
01309             DBG_DEBUG(GWEN_LOGDOMAIN, "Notifying server...");
01310             mgr->clientDownFn(mgr, n->id, n->ioLayer, mgr->user_data);
01311             if (n->usage==1) {
01312               DBG_DEBUG(GWEN_LOGDOMAIN, "Will definately free node");
01313               GWEN_IpcNode_free(n);
01314               n=next;
01315               if (n)
01316                 next=GWEN_IpcNode_List_Next(n);
01317               else
01318                 next=NULL;
01319             }
01320             else
01321               GWEN_IpcNode_free(n);
01322           }
01323         }
01324       }
01325     }
01326 
01327     if (n) {
01328       if (n->isServer) {
01329         GWEN_IO_LAYER *newLayer;
01330   
01331         DBG_DEBUG(GWEN_LOGDOMAIN, "Node is a server");
01332         /* collect connections */
01333         newLayer=GWEN_Io_Layer_GetNextIncomingLayer(n->ioLayer);
01334         if (newLayer) {
01335           int rv;
01336   
01337           done++;
01338           DBG_INFO(GWEN_LOGDOMAIN, "Got an incoming connection");
01339           rv=GWEN_Io_Manager_RegisterLayer(newLayer);
01340           if (rv<0) {
01341             DBG_INFO(GWEN_LOGDOMAIN, "Could not register io layer (%d)", rv);
01342             GWEN_Io_Layer_free(newLayer);
01343           }
01344           else {
01345             /* make sure all layers are connected */
01346             rv=GWEN_Io_Layer_ConnectRecursively(newLayer, NULL, 0, 0, 10000);
01347             if (rv) {
01348               rv=GWEN_Io_Layer_DisconnectRecursively(newLayer, NULL,
01349                                                      GWEN_IO_REQUEST_FLAGS_FORCE,
01350                                                      0, 2000);
01351               DBG_INFO(GWEN_LOGDOMAIN, "Could not connect io layer (%d)", rv);
01352               GWEN_Io_Layer_free(newLayer);
01353             }
01354             else {
01355               GWEN_IPCNODE *newnode;
01356   
01357               newnode=GWEN_IpcNode_new();
01358               newnode->ioLayer=newLayer;
01359               newnode->mark=n->mark;
01360               newnode->isPassiveClient=1;
01361               GWEN_IpcNode_List_Add(newnode, mgr->nodes);
01362             }
01363           }
01364         }
01365         else {
01366           DBG_DEBUG(GWEN_LOGDOMAIN, "No incoming connection");
01367         }
01368       } /* if isServer */
01369       else {
01370         GWEN_IO_REQUEST *pk;
01371         int rv;
01372   
01373         DBG_DEBUG(GWEN_LOGDOMAIN, "Node is NOT a server");
01374         rv=GWEN_Io_LayerPackets_GetReadRequest(n->ioLayer, &pk, 0, GWEN_TIMEOUT_NONE);
01375         if (rv) {
01376           if (rv!=GWEN_ERROR_TIMEOUT && rv!=GWEN_ERROR_TRY_AGAIN) {
01377             DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01378             done++;
01379           }
01380         }
01381         else {
01382           rv=GWEN_IpcManager__HandlePacket(mgr, n, pk);
01383           GWEN_Io_Request_free(pk);
01384           if (rv) {
01385             DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
01386           }
01387           done++;
01388         }
01389       } /* if client */
01390     } /* if n */
01391 
01392     n=next;
01393   } /* while */
01394 
01395   if (done)
01396     return 0;
01397   return 1;
01398 }
01399 
01400 
01401 
01402 void GWEN_IpcManager_SetClientDownFn(GWEN_IPCMANAGER *mgr,
01403                                      GWEN_IPCMANAGER_CLIENTDOWN_FN f,
01404                                      void *user_data) {
01405   assert(mgr);
01406   mgr->clientDownFn=f;
01407   mgr->user_data=user_data;
01408 }
01409 
01410 
01411 
01412 
01413 
01414 
01415 
01416 
01417 
01418 
01419 
01420 
01421 
Generated on Mon Jul 5 22:52:48 2010 for gwenhywfar by  doxygen 1.6.3