4 namespace remote
{ namespace 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(std::string 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(std::string mac
)
48 motemapbymac_t::iterator mI
;
50 mI
= motesByMac
.find(mac
);
52 if ( mI
!= motesByMac
.end() )
64 void Host::registerMoteInfoByMac(std::string mac
, moteinfo_t moteinfo
)
66 moteInfoByMac
[mac
] = moteinfo
;
69 void Host::deleteMoteInfoByMac(std::string 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 std::string path
= info
.getPath().getString();
82 std::string mac
= info
.getMac();
83 mysqlpp::Connection
& sqlConn
= dbConn
.getConnection();
84 dbkey_t site_id
, mote_id
;
86 mysqlpp::ResUse selectRes
;
87 mysqlpp::ResNSel execRes
;
90 log("Mote %s plugged at %s\n", mac
.c_str(), path
.c_str());
92 mysqlpp::Query query
= sqlConn
.query();
94 query
<< "select site_id from path"
95 " where host_id = " << id
96 << " and path = " << mysqlpp::quote
<< path
;
98 // look for the connection path + host id to get the site_id
99 selectRes
= query
.use();
100 selectRes
.disable_exceptions();
101 row
= selectRes
.fetch_row();
102 if (!row
|| row
.empty()) {
103 // if not found, create the path in the database with no site_id
105 query
<< "insert into path(host_id,path) "
106 << "values(" << id
<< "," << mysqlpp::quote
<< path
<< ")";
108 query
.execute(); // TODO: error checking
110 // XXX: Set to the default site_id for new paths
114 site_id
= (dbkey_t
) row
["site_id"];
117 // look for the mac addresses in the database, get mote_id
119 query
<< "select mote_id from moteattr ma, mote_moteattr mma, moteattrtype mat"
120 " where ma.val=" << mysqlpp::quote
<< mac
121 << " and mma.moteattr_id=ma.id"
122 " and ma.moteattrtype_id=mat.id"
123 " and mat.name='macaddress'";
126 selectRes
= query
.use();
127 selectRes
.disable_exceptions();
128 row
= selectRes
.fetch_row();
130 MoteAddresses
*newtarget
= new MoteAddresses(mac
);
132 if ( !row
|| row
.empty() )
134 std::ostringstream oss
;
137 // create the mote using site_id only - the mote class will create the
138 // mote database record itself
139 mote
= new Mote(site_id
,(MoteControlInfrastructure
&)*this,*newtarget
);
140 // TODO: error checking
141 // create the mac and net address database records using the mote id
142 oss
<< (uint16_t) mote
->mote_id
;
143 newtarget
->netAddress
= oss
.str();
145 log("Attributes: macaddress=%s netaddress=%s platform=%s\n",
146 mac
.c_str(), newtarget
->netAddress
.c_str(),
147 info
.getPlatform().c_str());
148 mote
->setAttribute("macaddress", mac
);
149 mote
->setAttribute("netaddress", newtarget
->netAddress
);
150 mote
->setAttribute("platform", info
.getPlatform());
154 mote_id
= (dbkey_t
) row
["mote_id"]; // save the mote_id
156 // create the mote object using mote_id and site_id - the mote class will
157 // update the mote database record to reflect the new site
158 mote
= new Mote(mote_id
,site_id
,(MoteControlInfrastructure
&)*this,*newtarget
);
160 // get the net address mote attribute
161 newtarget
->netAddress
= mote
->getAttribute("netaddress");
162 // TODO: error checking
167 // finally, register the new mote in the local map
168 registerMoteByMac(mac
, mote
);
172 void Host::handleMotesLostList(MsgMoteConnectionInfoList
& infolist
)
174 MsgMoteConnectionInfo info
;
175 while ( infolist
.getNextMoteInfo(info
) )
177 deleteMoteByMac(info
.getMac());
178 deleteMoteInfoByMac(info
.getMac());
182 void Host::handleMotesFoundList(MsgMoteConnectionInfoList
& infolist
)
184 MsgMoteConnectionInfo info
;
186 while (infolist
.getNextMoteInfo(info
)) {
187 findOrCreateMote(info
);
191 void Host::request(MCIAddress
& address
, MsgPayload
& request
)
193 MsgMoteAddresses
addresses(((MoteAddresses
&)address
).mac
,
194 ((MoteAddresses
&)address
).netAddress
);
195 MsgHostRequest
msgHostRequest(addresses
,request
);
196 HostMsg
message(msgHostRequest
);
200 msg
.sendMsg(fd
,message
);
202 catch (remote::protocols::MMSException e
)
204 log("Exception: %s\n",e
.what());
210 void Host::handleEvent(short events
)
213 if ( (events
& POLLIN
) || (events
& POLLPRI
) )
215 if (!message_in
.nonBlockingRecv(fd
))
220 uint32_t msglen
= message_in
.getLength();
221 uint8_t* buffer
= message_in
.getData();
222 HostMsg
message(buffer
,msglen
);
224 switch (message
.getType())
226 case HOSTMSGTYPE_HOSTCONFIRM
:
227 handleMsgIn(message
.getHostConfirm());
229 case HOSTMSGTYPE_PLUGEVENT
:
230 if ( message
.getPlugEvent().getType() == PLUG_MOTES
)
232 handleMotesFoundList(message
.getPlugEvent().getInfoList());
234 else if ( message
.getPlugEvent().getType() == UNPLUG_MOTES
)
236 handleMotesLostList(message
.getPlugEvent().getInfoList());
240 __THROW__ ("Invalid plugevent received from host!");
244 __THROW__ ("Invalid message type received from host!");
248 else if ( (events
& POLLERR
) || (events
& POLLHUP
) || (events
& POLLNVAL
) )
250 __THROW__ ("Host connection error!\n");
254 void Host::handleMsgIn(MsgHostConfirm
& msgHostConfirm
)
256 motemapbymac_t::iterator mI
;
257 mI
= motesByMac
.find(msgHostConfirm
.getMoteAddresses().getMac());
258 if ( mI
!= motesByMac
.end() )
260 if (msgHostConfirm
.getStatus() == MSGHOSTCONFIRM_UNKNOWN_MOTE
)
262 deleteMoteByMac(msgHostConfirm
.getMoteAddresses().getMac());
263 deleteMoteInfoByMac(msgHostConfirm
.getMoteAddresses().getMac());
265 mI
->second
->confirm(msgHostConfirm
.getMessage());