Move stop() call from closeTty() to the only calling site needing it
[remote/remote-mci.git] / mcs / Mote.cc
blobebf805bcd20fdff3149967a9a06c3320859ccdb9
1 #include "Mote.h"
2 #include "macros.h"
4 namespace remote { namespace mcs {
6 Mote::Mote( dbkey_t p_mote_id,
7 dbkey_t p_site_id,
8 MoteControlInfrastructure& p_messenger,
9 MCIAddress& p_mciAddress)
10 : mciAddress(p_mciAddress),
11 mote_id(p_mote_id),
12 site_id(p_site_id),
13 mci(p_messenger),
14 session(NULL)
16 mysqlpp::Connection& sqlConn = dbConn.getConnection();
17 // look up the mote record in the database and make sure it corresponds
18 // to the supplied information
19 mysqlpp::Query moteupdate = sqlConn.query();
20 moteupdate << "update mote set site_id = " << site_id << ", curr_session_id=NULL, priv_session_id=NULL"
21 << " where id = " << mote_id;
23 mysqlpp::ResNSel sqlres = moteupdate.execute();
25 if ( sqlres.success && sqlres.rows == 1) {
26 // register the mote in the mote pool
27 registerMote(this);
28 } else {
29 log("Info: %s, site_id: %u, mote_id: %u\n",sqlres.info.c_str(),site_id,mote_id);
30 delete this;
31 __THROW__ ("Unable to register site on mote!\n");
35 Mote::Mote( dbkey_t p_site_id,
36 MoteControlInfrastructure& p_messenger,
37 MCIAddress& p_mciAddress )
38 : mciAddress(p_mciAddress),
39 mote_id(0),
40 site_id(p_site_id),
41 mci(p_messenger),
42 session(NULL)
44 mysqlpp::Connection& sqlConn = dbConn.getConnection();
45 // create a new mote with the supplied site_id
46 mysqlpp::Query moteinsert = sqlConn.query();
47 moteinsert << "insert into mote(site_id)"
48 << "values(" << site_id << ")";
49 mysqlpp::ResNSel sqlres = moteinsert.execute();
50 if (sqlres.success)
52 mote_id = sqlres.insert_id;
53 // register the mote in the mote pool
54 registerMote(this);
55 // stop();
57 else
59 delete this;
60 __THROW__ ("Failed to insert new mote in database!\n");
65 Mote::~Mote()
67 mote.erase(mote_id);
70 void Mote::destroy(bool silent)
72 try {
73 dropSession();
74 mysqlpp::Connection& sqlConn = dbConn.getConnection();
75 mysqlpp::Query moteupdate = sqlConn.query();
76 moteupdate << "update mote set site_id=NULL where id=" << mote_id;
77 moteupdate.execute(); // no problem even if mote record does not exist
79 catch (mysqlpp::Exception e)
81 if (silent)
83 log("Exception while updating mote record: %s - record not updated!\n",e.what());
85 else
87 __THROW__(e.what());
90 delete this;
93 void Mote::request( MsgPayload& request)
95 mci.request(mciAddress,request);
98 void Mote::confirm( MsgPayload& confirm )
100 // if (confirm.result == SUCCESS) status = confirm.status;
101 if (session)
103 session->confirm(mote_id,confirm);
107 bool Mote::setSession( Session* p_session )
109 mysqlpp::Connection& sqlConn = dbConn.getConnection();
110 mysqlpp::Query query = sqlConn.query();
112 // check if the usage privilege has been granted
113 query << "select priv_session_id from mote where id=" << mote_id;
114 mysqlpp::ResUse res = query.use();
115 res.disable_exceptions();
116 mysqlpp::Row row = res.fetch_row();
117 if (!row || row.empty()) { __THROW__ ("Mote record not found in database!\n"); }
119 if (row["priv_session_id"].is_null())
121 return false;
123 dbkey_t session_id = (dbkey_t) row["priv_session_id"];
124 // free up the table again
125 res.purge();
127 if (session_id != p_session->session_id)
129 // no usage privilege granted
130 return false;
133 if (session)
135 if ( session != p_session )
137 // tell the current client to drop its reference to this mote
138 dropSession();
140 else
142 // session is already using this mote
143 return false;
146 session = p_session;
148 // set usage info on the database mote record
149 query.reset();
150 query << "update mote set curr_session_id=" << p_session->session_id
151 << " where id=" << mote_id;
152 query.execute();
153 return true;
157 void Mote::dropSession(bool notify)
159 if ( session )
161 // notify the client that it is being dropped
162 if (notify) session->freeMote(mote_id);
165 mysqlpp::Connection& sqlConn = dbConn.getConnection();
166 mysqlpp::Query moteupdate = sqlConn.query();
167 // remove session usage privilege on the mote, if still present
168 moteupdate << "update mote set priv_session_id=NULL"
169 << " where id=" << mote_id
170 << " and priv_session_id=" << session->session_id;
171 moteupdate.execute();
172 // reset usage info on the database mote record
173 moteupdate.reset();
174 moteupdate << "update mote set curr_session_id=NULL where id=" << mote_id;
175 moteupdate.execute();
176 session = NULL;
180 std::string Mote::getAttribute(std::string type)
182 mysqlpp::Connection& sqlConn = dbConn.getConnection();
183 mysqlpp::Query query = sqlConn.query();
184 const char *attr = "";
186 // get attribute type id
187 query << "select id from moteattrtype where name=" << mysqlpp::quote << type;
188 mysqlpp::ResUse res = query.use();
189 res.disable_exceptions();
190 mysqlpp::Row row = res.fetch_row();
191 if (!row || row.empty()) { __THROW__ ("Mote attribute type not found!"); }
192 dbkey_t type_id = (dbkey_t) row["id"];
194 res.purge();
195 query.reset();
196 query << "select val from mote_moteattr mma, moteattr ma"
197 " where mma.moteattr_id=ma.id"
198 " and ma.moteattrtype_id=" << type_id
199 << " and mma.mote_id=" << mote_id;
201 res = query.use();
202 res.disable_exceptions();
203 row = res.fetch_row();
204 if (row && !row.empty())
205 attr = row["val"];
207 return attr;
210 void Mote::setAttribute(std::string type, std::string value)
212 mysqlpp::Connection& sqlConn = dbConn.getConnection();
213 mysqlpp::Query query = sqlConn.query();
215 // get attribute type id
216 query << "select id from moteattrtype"
217 << " where name = " << mysqlpp::quote << type;
218 mysqlpp::ResUse res = query.use();
219 res.disable_exceptions();
220 mysqlpp::Row row = res.fetch_row();
221 if (!row || row.empty()) { __THROW__ ("Mote attribute type not found!"); }
222 dbkey_t type_id = (dbkey_t) row["id"];
223 res.purge();
224 query.reset();
226 // remove old attribute if it exists
227 query << "delete from mote_moteattr"
228 << " where mote_id=" << mote_id
229 << " and moteattr_id in"
230 << "(select id from moteattr where moteattrtype_id=" << type_id << ")";
231 query.execute();
232 query.reset();
234 // check if attribute value exists
235 query << "select id from moteattr"
236 << " where moteattrtype_id=" << type_id
237 << " and val=" << mysqlpp::quote << value;
238 res = query.use();
239 res.disable_exceptions();
240 row = res.fetch_row();
241 dbkey_t attr_id;
242 if (!row || row.empty()) {
243 // create attribute value
244 res.purge();
245 query.reset();
246 query << "insert into moteattr(moteattrtype_id,val) "
247 << "values(" << type_id << "," << mysqlpp::quote << value << ")";
248 mysqlpp::ResNSel sqlres = query.execute();
249 if (sqlres.success) {
250 attr_id = sqlres.insert_id;
251 } else {
252 __THROW__("Unable to create new mote attribute!");
254 } else {
255 attr_id = (dbkey_t) row["id"];
256 res.purge();
258 // assign attribute value
259 query.reset();
260 query << "insert into mote_moteattr(mote_id,moteattr_id) "
261 << "values(" << mote_id << "," << attr_id << ")";
262 query.execute();
266 // STATIC METHODS BELOW
268 result_t Mote::getById( dbkey_t p_mote_id,
269 Session* p_client,
270 Mote** p_mote )
272 motemapbykey_t::iterator mi;
273 Mote* themote;
274 *p_mote = NULL;
276 mi = mote.find(p_mote_id);
279 if (mi != mote.end())
281 themote = mi->second;
283 if ( themote->setSession(p_client) )
285 *p_mote = themote;
286 return SUCCESS;
288 else
290 return MOTE_OCCUPIED;
293 else
295 return MOTE_NOT_FOUND;
299 void Mote::registerMote(Mote* newmote)
301 motemapbykey_t::iterator mi;
302 Mote* oldmote;
303 mi = mote.find(newmote->mote_id);
304 if (mi != mote.end())
306 oldmote = mi->second;
307 delete oldmote;
310 mote[newmote->mote_id] = newmote;
313 void Mote::resetDb()
315 mysqlpp::Connection& sqlConn = dbConn.getConnection();
316 mysqlpp::Query reset = sqlConn.query();
317 reset << "update mote set site_id = null";
318 reset.parse();
319 reset.execute();
322 motemapbykey_t Mote::mote;