Issue 22: Convert remaining code to use the log module
[remote/remote-mci.git] / mcs / Host.cc
blob175d9c91e70d4f4df78656e29379edbf071b6c0f
1 #include "Host.h"
3 namespace remote { namespace mcs {
5 Host::Host( int fd, dbkey_t p_id, std::string ip, hostmapbykey_t& p_hostMap )
6 : FileDescriptor(fd), id(p_id), message_in(), ipaddress(ip), hostMap(p_hostMap)
8 hostMap[id] = this;
9 protocols::setSendTimeout( fd,5,0); // 5 second host send timeout should be adequate
10 // set keepalive options: 3 attempts after 120 seconds, 30 second interval
11 setKeepAlive( fd, 3, 120, 30);
14 Host::~Host()
16 Log::info("Closing host %s!", ipaddress.c_str());
17 hostMap.erase(id);
20 void Host::destroy(bool silent)
22 motemapbymac_t::iterator mI;
24 Log::info("Deleting motes");
25 for(mI = motesByMac.begin(); mI != motesByMac.end(); mI++)
26 if (mI->second)
27 mI->second->destroy(silent);
28 delete this;
31 void Host::registerMoteByMac(std::string mac, Mote *mote)
33 motemapbymac_t::iterator mI;
35 mI = motesByMac.find(mac);
37 if ( mI != motesByMac.end() )
39 mI->second->destroy();
42 motesByMac[mac] = mote;
45 void Host::deleteMoteByMac(std::string mac)
47 motemapbymac_t::iterator mI;
48 Mote* mote = NULL;
49 mI = motesByMac.find(mac);
51 if ( mI != motesByMac.end() )
53 mote = mI->second;
54 motesByMac.erase(mI);
57 if (mote)
59 mote->destroy();
63 void Host::findOrCreateMote(MsgMoteConnectionInfo& info)
65 std::string path = info.getPath().getString();
66 std::string mac = info.getMac();
67 mysqlpp::Connection& sqlConn = dbConn.getConnection();
68 dbkey_t site_id, mote_id;
69 Mote* mote;
70 mysqlpp::ResUse selectRes;
71 mysqlpp::ResNSel execRes;
72 mysqlpp::Row row;
74 Log::info("Mote %s plugged at %s", mac.c_str(), path.c_str());
76 mysqlpp::Query query = sqlConn.query();
78 query << "select site_id from path"
79 " where host_id = " << id
80 << " and path = " << mysqlpp::quote << path;
82 // look for the connection path + host id to get the site_id
83 selectRes = query.use();
84 selectRes.disable_exceptions();
85 row = selectRes.fetch_row();
86 if (!row || row.empty()) {
87 // if not found, create the path in the database with no site_id
88 query.reset();
89 query << "insert into path(host_id,path) "
90 << "values(" << id << "," << mysqlpp::quote << path << ")";
92 query.execute(); // TODO: error checking
94 // XXX: Set to the default site_id for new paths
95 site_id = 1;
97 } else {
98 site_id = (dbkey_t) row["site_id"];
101 // look for the mac addresses in the database, get mote_id
102 query.reset();
103 query << "select mote_id from moteattr ma, mote_moteattr mma, moteattrtype mat"
104 " where ma.val=" << mysqlpp::quote << mac
105 << " and mma.moteattr_id=ma.id"
106 " and ma.moteattrtype_id=mat.id"
107 " and mat.name='macaddress'";
109 selectRes.purge();
110 selectRes = query.use();
111 selectRes.disable_exceptions();
112 row = selectRes.fetch_row();
114 MoteAddresses *newtarget = new MoteAddresses(mac);
116 if ( !row || row.empty() )
118 std::ostringstream oss;
120 selectRes.purge();
121 // create the mote using site_id only - the mote class will create the
122 // mote database record itself
123 mote = new Mote(site_id,(MoteControlInfrastructure&)*this,*newtarget);
124 // TODO: error checking
125 // create the mac and net address database records using the mote id
126 oss << (uint16_t) mote->mote_id;
127 newtarget->netAddress = oss.str();
129 Log::info("Attributes: macaddress=%s netaddress=%s platform=%s\n",
130 mac.c_str(), newtarget->netAddress.c_str(),
131 info.getPlatform().c_str());
132 mote->setAttribute("macaddress", mac);
133 mote->setAttribute("netaddress", newtarget->netAddress);
134 mote->setAttribute("platform", info.getPlatform());
136 else
138 mote_id = (dbkey_t) row["mote_id"]; // save the mote_id
139 selectRes.purge();
140 // create the mote object using mote_id and site_id - the mote class will
141 // update the mote database record to reflect the new site
142 mote = new Mote(mote_id,site_id,(MoteControlInfrastructure&)*this,*newtarget);
144 // get the net address mote attribute
145 newtarget->netAddress = mote->getAttribute("netaddress");
146 // TODO: error checking
149 if (mote)
151 // finally, register the new mote in the local map
152 registerMoteByMac(mac, mote);
156 void Host::handleMotesLostList(MsgMoteConnectionInfoList& infolist)
158 MsgMoteConnectionInfo info;
160 while (infolist.getNextMoteInfo(info))
161 deleteMoteByMac(info.getMac());
164 void Host::handleMotesFoundList(MsgMoteConnectionInfoList& infolist)
166 MsgMoteConnectionInfo info;
168 while (infolist.getNextMoteInfo(info)) {
169 findOrCreateMote(info);
173 void Host::request(MCIAddress& address, MsgPayload& request )
175 MsgMoteAddresses addresses(((MoteAddresses&)address).mac,
176 ((MoteAddresses&)address).netAddress);
177 MsgHostRequest msgHostRequest(addresses,request);
178 HostMsg message(msgHostRequest);
180 try {
181 Message msg;
182 msg.sendMsg(fd,message);
184 catch (remote::protocols::MMSException e)
186 Log::error("Exception: %s", e.what());
187 this->destroy(true);
192 void Host::handleEvent(short events)
195 if ( (events & POLLIN) || (events & POLLPRI) )
197 if (!message_in.nonBlockingRecv(fd))
199 return;
202 uint32_t msglen = message_in.getLength();
203 uint8_t* buffer = message_in.getData();
204 HostMsg message(buffer,msglen);
206 switch (message.getType())
208 case HOSTMSGTYPE_HOSTCONFIRM:
209 handleMsgIn(message.getHostConfirm());
210 break;
211 case HOSTMSGTYPE_PLUGEVENT:
212 if ( message.getPlugEvent().getType() == PLUG_MOTES )
214 handleMotesFoundList(message.getPlugEvent().getInfoList());
216 else if ( message.getPlugEvent().getType() == UNPLUG_MOTES )
218 handleMotesLostList(message.getPlugEvent().getInfoList());
220 else
222 __THROW__ ("Invalid plugevent received from host!");
224 break;
225 default:
226 __THROW__ ("Invalid message type received from host!");
227 break;
230 else if ( (events & POLLERR) || (events & POLLHUP) || (events & POLLNVAL) )
232 __THROW__ ("Host connection error!\n");
236 void Host::handleMsgIn(MsgHostConfirm& msgHostConfirm)
238 motemapbymac_t::iterator mI;
240 mI = motesByMac.find(msgHostConfirm.getMoteAddresses().getMac());
241 if (mI != motesByMac.end()) {
242 if (msgHostConfirm.getStatus() == MSGHOSTCONFIRM_UNKNOWN_MOTE) {
243 deleteMoteByMac(msgHostConfirm.getMoteAddresses().getMac());
244 } else {
245 mI->second->confirm(msgHostConfirm.getMessage());