Fix typo in the dig528-2 platform string causing wrong baud rate
[remote/remote-mci.git] / mcs / Host.cc
blobfbcc2207b757bd4957b585ccc563d2876f4bf67d
1 #include "Host.h"
2 #include "macros.h"
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)
9 hostMap[id] = this;
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);
15 Host::~Host()
17 log("Closing host %s!\n",ipaddress.c_str());
18 hostMap.erase(id);
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);
29 delete this;
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;
49 Mote* mote = NULL;
50 mI = motesByMac.find(mac);
52 if ( mI != motesByMac.end() )
54 mote = mI->second;
55 motesByMac.erase(mI);
58 if (mote)
60 mote->destroy();
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;
85 Mote* mote;
86 mysqlpp::ResUse selectRes;
87 mysqlpp::ResNSel execRes;
88 mysqlpp::Row row;
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
104 query.reset();
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
111 site_id = 1;
113 } else {
114 site_id = (dbkey_t) row["site_id"];
117 // look for the mac addresses in the database, get mote_id
118 query.reset();
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'";
125 selectRes.purge();
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;
136 selectRes.purge();
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());
152 else
154 mote_id = (dbkey_t) row["mote_id"]; // save the mote_id
155 selectRes.purge();
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
165 if (mote)
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);
198 try {
199 Message msg;
200 msg.sendMsg(fd,message);
202 catch (remote::protocols::MMSException e)
204 log("Exception: %s\n",e.what());
205 this->destroy(true);
210 void Host::handleEvent(short events)
213 if ( (events & POLLIN) || (events & POLLPRI) )
215 if (!message_in.nonBlockingRecv(fd))
217 return;
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());
228 break;
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());
238 else
240 __THROW__ ("Invalid plugevent received from host!");
242 break;
243 default:
244 __THROW__ ("Invalid message type received from host!");
245 break;
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());
264 } else {
265 mI->second->confirm(msgHostConfirm.getMessage());