00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00061
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
00089
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
00120 DBG_COMM_PRINTF(("\nLINK %i WORKING", linkID));
00121
00122
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
00132 channel->ReceiveTimerOn();
00133 DBG_COMM_PRINTF(("\nLINK %i no local msg", linkID));
00134 }
00135
00136
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