4 namespace remote
{ namespace diku_mcs
{
6 Host::Host( int fd
, dbkey_t p_id
, std::string ip
, hostmapbykey_t
& p_hostMap
)
7 : FileDescriptor(fd
), id(p_id
), message_in(), ipaddress(ip
), hostMap(p_hostMap
)
10 protocols::setSendTimeout( fd
,5,0); // 5 second host send timeout should be adequate
11 // set keepalive options: 3 attempts after 120 seconds, 30 second interval
12 setKeepAlive( fd
, 3, 120, 30);
17 log("Closing host %s!\n",ipaddress
.c_str());
21 void Host::destroy(bool silent
)
23 log("Deleting motes\n");
24 motemapbymac_t::iterator mI
;
25 for( mI
= motesByMac
.begin(); mI
!= motesByMac
.end(); mI
++)
27 if (mI
->second
) mI
->second
->destroy(silent
);
32 void Host::registerMoteByMac(uint64_t mac
,Mote
* mote
)
34 motemapbymac_t::iterator mI
;
36 mI
= motesByMac
.find(mac
);
38 if ( mI
!= motesByMac
.end() )
40 mI
->second
->destroy();
43 motesByMac
[mac
] = mote
;
46 void Host::deleteMoteByMac(uint64_t mac
)
48 motemapbymac_t::iterator mI
;
50 mI
= motesByMac
.find(mac
);
52 if ( mI
!= motesByMac
.end() )
64 void Host::registerMoteInfoByMac(uint64_t mac
, moteinfo_t moteinfo
)
66 moteInfoByMac
[mac
] = moteinfo
;
69 void Host::deleteMoteInfoByMac(uint64_t mac
)
71 moteinfobymac_t::iterator mI
;
72 mI
= moteInfoByMac
.find(mac
);
73 if ( mI
!= moteInfoByMac
.end() )
75 moteInfoByMac
.erase(mI
);
79 void Host::findOrCreateMote(MsgMoteConnectionInfo
& info
)
81 mysqlpp::Connection
& sqlConn
= dbConn
.getConnection();
82 dbkey_t site_id
, mote_id
;
84 mysqlpp::ResUse selectRes
;
85 mysqlpp::ResNSel execRes
;
88 mysqlpp::Query siteselect
= sqlConn
.query();
89 mysqlpp::Query moteselect
= sqlConn
.query();
90 mysqlpp::Query tosselect
= sqlConn
.query();
92 mysqlpp::Query pathinsert
= sqlConn
.query();
93 mysqlpp::Query macinsert
= sqlConn
.query();
94 mysqlpp::Query tosinsert
= sqlConn
.query();
96 siteselect
<< "select site_id from path \
97 where host_id = %0:hostid \
100 moteselect
<< "select mote_id from macaddress \
101 where macaddress = %0:macaddress";
103 tosselect
<< "select tosaddress from tosaddress \
104 where mote_id = %0:mote_id";
106 pathinsert
<< "insert into path(host_id,path) \
107 values( %0:hostid,'%1:path' )";
109 macinsert
<< "insert into macaddress(macaddress,mote_id) \
110 values ( %0:macaddress,%1:mote_id)";
112 tosinsert
<< "insert into tosaddress(mote_id) values( %0:mote_id )";
123 // look for the connection path + host id to get the site_id
124 siteselect
.def
["hostid"] = id
;
125 siteselect
.def
["path"] = info
.getPath().getString();
127 selectRes
= siteselect
.use();
128 selectRes
.disable_exceptions();
129 row
= selectRes
.fetch_row();
130 if ( !row
|| row
.empty() )
132 // if not found, create the path in the database with no site_id
133 pathinsert
.def
["hostid"] = id
;
134 pathinsert
.def
["path"] = info
.getPath().getString();
135 pathinsert
.execute(); // TODO: error checking
137 // get the newly inserted paths site_id
139 selectRes
= siteselect
.use();
140 selectRes
.disable_exceptions();
141 row
= selectRes
.fetch_row();
145 site_id
= (dbkey_t
) row
["site_id"];
147 // look for the mac addresses in the database, get mote_id
148 moteselect
.def
["macaddress"] = info
.macAddress
;
151 selectRes
= moteselect
.use();
152 selectRes
.disable_exceptions();
153 row
= selectRes
.fetch_row();
155 MoteAddresses
* newtarget
= new MoteAddresses(0,info
.macAddress
);
157 if ( !row
|| row
.empty() )
160 // create the mote using site_id only - the mote class will create the
161 // mote database record itself
162 mote
= new Mote(site_id
,(MoteControlInfrastructure
&)*this,*newtarget
);
163 // TODO: error checking
164 // create the mac and tos address database records using the mote id
165 macinsert
.def
["macaddress"] = info
.macAddress
;
166 macinsert
.def
["mote_id"] = mote
->mote_id
;
168 tosinsert
.def
["mote_id"] = mote
->mote_id
;
169 execRes
= tosinsert
.execute();
170 newtarget
->tosAddress
= execRes
.insert_id
;
171 // FIXME: convert MAC address to hex string!!
172 //mote->setAttribute("macaddress",std::string::info.macAddress);
173 // TODO: tos address as well
177 mote_id
= (dbkey_t
) row
["mote_id"]; // save the mote_id
179 // create the mote object using mote_id and site_id - the mote class will
180 // update the mote database record to reflect the new site
181 mote
= new Mote(mote_id
,site_id
,(MoteControlInfrastructure
&)*this,*newtarget
);
183 // add tosAddress as external mote info
184 tosselect
.def
["mote_id"] = mote_id
; // get the tos address
185 selectRes
= tosselect
.use();
186 selectRes
.disable_exceptions();
187 row
= selectRes
.fetch_row();
188 newtarget
->tosAddress
= (uint16_t)row
["tosaddress"];
193 // finally, register the new mote in the local map
194 registerMoteByMac(info
.macAddress
,mote
);
198 void Host::handleMotesLostList(MsgMoteConnectionInfoList
& infolist
)
200 MsgMoteConnectionInfo info
;
201 while ( infolist
.getNextMoteInfo(info
) )
203 deleteMoteByMac(info
.macAddress
);
204 deleteMoteInfoByMac(info
.macAddress
);
208 void Host::handleMotesFoundList(MsgMoteConnectionInfoList
& infolist
)
210 MsgMoteConnectionInfo info
;
212 while ( infolist
.getNextMoteInfo(info
) )
214 uint8_t* m
= (uint8_t*)&info
.macAddress
;
215 log("Mote %02x%02x%02x%02x %02x%02x%02x%02x plugged at %s\n",m
[7],m
[6],m
[5],m
[4],m
[3],m
[2],m
[1],m
[0],info
.getPath().getString().c_str());
217 findOrCreateMote(info
);
221 void Host::request(MCIAddress
& address
, MsgPayload
& request
)
223 MsgMoteAddresses
addresses(((MoteAddresses
&)address
).tosAddress
,
224 ((MoteAddresses
&)address
).macAddress
);
225 MsgHostRequest
msgHostRequest(addresses
,request
);
226 HostMsg
message(msgHostRequest
);
230 msg
.sendMsg(fd
,message
);
232 catch (remote::protocols::MMSException e
)
234 log("Exception: %s\n",e
.what());
240 void Host::handleEvent(short events
)
243 if ( (events
& POLLIN
) || (events
& POLLPRI
) )
245 if (!message_in
.nonBlockingRecv(fd
))
250 uint32_t msglen
= message_in
.getLength();
251 uint8_t* buffer
= message_in
.getData();
252 HostMsg
message(buffer
,msglen
);
254 switch (message
.getType())
256 case HOSTMSGTYPE_HOSTCONFIRM
:
257 handleMsgIn(message
.getHostConfirm());
259 case HOSTMSGTYPE_PLUGEVENT
:
260 if ( message
.getPlugEvent().getType() == PLUG_MOTES
)
262 handleMotesFoundList(message
.getPlugEvent().getInfoList());
264 else if ( message
.getPlugEvent().getType() == UNPLUG_MOTES
)
266 handleMotesLostList(message
.getPlugEvent().getInfoList());
270 __THROW__ ("Invalid plugevent received from host!");
274 __THROW__ ("Invalid message type received from host!");
278 else if ( (events
& POLLERR
) || (events
& POLLHUP
) || (events
& POLLNVAL
) )
280 __THROW__ ("Host connection error!\n");
284 void Host::handleMsgIn(MsgHostConfirm
& msgHostConfirm
)
286 motemapbymac_t::iterator mI
;
287 mI
= motesByMac
.find(msgHostConfirm
.getMoteAddresses().getMacAddress());
288 if ( mI
!= motesByMac
.end() )
290 if (msgHostConfirm
.getStatus() == MSGHOSTCONFIRM_UNKNOWN_MOTE
)
292 deleteMoteByMac(msgHostConfirm
.getMoteAddresses().getMacAddress());
293 deleteMoteInfoByMac(msgHostConfirm
.getMoteAddresses().getMacAddress());
295 mI
->second
->confirm(msgHostConfirm
.getMessage());