Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members

DCDT_Link.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 dEVICE cOMMUNITIES dEVELOPMENT tOOLKIT 
00003 
00004 DCDT_Link.cpp
00005 
00006 COPYRIGHT (C) 2002   Alessandro Mazzini (mazzini@airlab.elet.polimi.it)
00007 
00008 
00009 This library is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU Lesser General Public
00011 License as published by the Free Software Foundation; either
00012 version 2 of the License, or (at your option) any later version.
00013 
00014 This library is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public
00020 License along with this library; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
00022 
00023 ****************************************************************************/
00024 
00025 
00026 #ifndef LINK_CPP
00027 #define LINK_CPP
00028 #include <DCDT_Link.h>
00029 #include <DCDT_Finder.h>
00030 
00031 DCDT_Link::DCDT_Link(DCDT_Agora *agora, int id, int r_id) : DCDT_Member(agora)
00032 {
00033   linkID = id;
00034   remoteID = r_id;
00035   status = restart_counter = 0;
00036   for (int i=0; i<NUMINT_MSGTYPE; i++)
00037     mymask[i] = 0;
00038   msgsub = CreateMsg(MT_SUBSUPD);
00039   msgsub->SetDeliveryWarranty(TCP_WARRANTY);
00040   msgsub->SetPayload(subs_mask, NUMINT_MSGTYPE*sizeof(unsigned int));
00041   msgrcv = NULL;
00042   localCD = NULL;
00043   remoteCD = NULL;
00044 
00045 }
00046 
00047 void
00048 DCDT_Link::Init()
00049 {
00050 }
00051 
00052 void
00053 DCDT_Link::Close()
00054 {
00055   channel->Close();
00056 }
00057 
00058 /***********************************************
00059 
00060   Prepare(): l_cd deve essere presente: ogni campo con valore nullo al ritorno contiene i campi
00061              scelti dal kernel
00062 
00063 ***********************************************/
00064 CommData* DCDT_Link::Prepare(int stat, CommData *l_cd, CommData *r_cd)
00065 {
00066   channel = l_cd->CreateChannel(myAgoraID);
00067   channel->Prepare(l_cd, r_cd);
00068   channel->Open(creation_status = status = stat);
00069   channel->SetTimers();
00070   return channel->GetCommData();
00071 }
00072 
00073 
00074 void DCDT_Link::DoYourJob(int par = 0)
00075 {
00076  try {
00077   switch (status) {
00078 
00079     case L_WAITING:
00080       DBG_COMM_PRINTF(("\nLINK %i channel waiting\n", linkID));
00081       try {
00082         channel->WaitConn();
00083       } catch (TimeOut t) {
00084         if (status != L_RESETTOCONN)
00085           throw;
00086         else break;
00087       }
00088       // qui anche se lo stato č di riconnessione, non lo considero
00089       // e vado avanti per la mia strada, cioč per lo stabilimento del Link
00090       myPostOffice->ReadSubscribedMsgMask(subs_mask,ReadID());
00091       channel->Send(msgsub);
00092       status = L_WORKING;
00093       channel->SetTimers();
00094       break;
00095 
00096     case L_CONNECTING:
00097       DBG_COMM_PRINTF(("LINK %i Wow, we're connecting!!!\n", linkID));
00098       channel->StartConn();
00099       myPostOffice->ReadSubscribedMsgMask(subs_mask,ReadID());
00100       channel->Send(msgsub);
00101       status = L_WORKING;
00102       channel->SetTimers();
00103       break;
00104 
00105     case L_RESETTOCONN:
00106       DBG_COMM_PRINTF(("\nReset LINK %i to L_CONNECTING", linkID));
00107       channel->Stop();
00108       channel->Dispose();
00109       Restart(L_CONNECTING, localCD, remoteCD);
00110       break;
00111 
00112     case L_WORKING:
00113       if (myPostOffice->UpdateSubs(ReadID())) {
00114       cout << "\nMemID=" << ReadID() << " LinkID=" << linkID << "\n";
00115         if (myPostOffice->ReadSubscribedMsgMask(subs_mask,ReadID()))
00116           channel->Send(msgsub);
00117       }
00118       channel->KeepAlive();
00119     // spedisco (se c'č) e ricevo (con timer) un msg
00120       DBG_COMM_PRINTF(("\nLINK %i WORKING", linkID));
00121 
00122       // LOCAL RECEIVE
00123       if ((msgrcv = ReceiveMsg())) {
00124         DBG_COMM_PRINTF(("\nLINK %i read local msg type %i\nNow sending...", linkID, msgrcv->ReadType()));
00125 
00126         channel->Send(msgrcv);
00127         RemoveCurrMsg();
00128         channel->UnblockReceive();
00129       }
00130       else {
00131         // se non ho spedito, al prossimo ciclo mi fermo in ascolto sul canale
00132         channel->ReceiveTimerOn();
00133         DBG_COMM_PRINTF(("\nLINK %i no local msg", linkID));
00134       }
00135 
00136       // REMOTE RECEIVE
00137       if ((msgrcv = channel->Receive())) {
00138         DBG_COMM_PRINTF(("\nLINK %i received remote msg type %i", linkID, msgrcv->ReadType()));
00139         if ((msgrcv->ReadType()) == MT_SUBSUPD) {
00140           UnSubscribeAll();
00141           subs_mask_rcv = (unsigned int*)msgrcv->GetPayload();
00142           Subscribe(subs_mask_rcv);
00143           delete msgrcv;
00144         }
00145         else if ((msgrcv->ReadType()) == MT_KEEPALIVE) {
00146           delete msgrcv;
00147         }
00148         else {
00149           ShareMsg(msgrcv);
00150         }
00151       }
00152       break;
00153 
00154     case L_LOST:
00155       if ((lost_counter++) == LINK_LOST_NUM) {
00156         UnSubscribeAll();
00157         Close();
00158         myFinder->CloseLink(linkID);
00159         break;
00160       }
00161       Delay(LINK_LOST_TIMER);
00162   }
00163  } catch(TimeOut e) {
00164    cout << "\nTimeout on link " << linkID << "\nConnection lost";
00165    channel->Stop();
00166    channel->Dispose();
00167    status = L_LOST;
00168    lost_counter = 0;
00169  } catch(ConnError e) {
00170    cout << "\nError on link " << linkID << "\nerrno=" << e.errval << "\nConnection lost";
00171    channel->Stop();
00172    channel->Dispose();
00173    status = L_LOST;
00174    lost_counter = 0;
00175  } catch(ChannelError e) {
00176    cout << "\nError on link " << linkID << "\nerrno=" << e.errval << "\nConnection lost";
00177    channel->Stop();
00178    channel->Dispose();
00179    status = L_LOST;
00180    lost_counter = 0;
00181  } catch(Exception e) {
00182    cout << "\nException! Closing link " << linkID << "\n";
00183    UnSubscribeAll();
00184    Close();
00185    myFinder->CloseLink(linkID);
00186  }
00187 }
00188 
00189 void DCDT_Link::Subscribe(unsigned int *mask)
00190 {
00191   int i,j,dim = 8*sizeof(unsigned int), filter;
00192   for (i=0; i<NUMINT_MSGTYPE; i++) {
00193     filter = 1;
00194     for (j=1; j<=dim; j++) {
00195       if ((mask[i] & filter) > 0) {
00196         DBG_COMM_PRINTF(("\nSubscribed to type %i", j+i*dim));
00197         SubscribeMsgType(j+i*dim);
00198       }
00199       filter <<= 1;
00200     }
00201   }
00202 }
00203 
00204 
00205 CommData* DCDT_Link::GetCommData()
00206 {
00207   return channel->GetCommData();
00208 }
00209 
00210 
00211 CommData* DCDT_Link::Restart(int re_status, CommData *l_cd, CommData *r_cd)
00212 {
00213   cout << "\nRestarting LINK " << linkID;
00214   channel->Prepare(l_cd, r_cd);
00215   channel->Reopen(creation_status = status = re_status);
00216   l_cd = channel->GetCommData();
00217   channel->SetTimers();
00218   return l_cd;
00219 }
00220 
00221 void DCDT_Link::ResetToConnecting(CommData *l_cd, CommData *r_cd)
00222 {
00223   SetCDs(l_cd, r_cd);
00224   status = L_RESETTOCONN;
00225 }
00226 
00227 
00228 void DCDT_Link::ChangeStatus(int newstat)
00229 {
00230   status = newstat;
00231 }
00232 
00233 void DCDT_Link::SetCDs(CommData *l_cd, CommData *r_cd)
00234 {
00235   if (localCD)
00236     delete localCD;
00237   localCD = l_cd;
00238   if (remoteCD)
00239     delete remoteCD;
00240   remoteCD = r_cd;
00241 }
00242 
00243 
00244 #endif
00245 

Generated on Tue Aug 12 17:55:41 2003 for dcdt by doxygen 1.3.2