4 namespace remote
{ namespace mcs
{
6 Session::Session(int p_fd
, sessionmapbyfd_t
& p_clientMap
)
7 : FileDescriptor(p_fd
),
10 sessionMap(p_clientMap
)
12 sessionMap
[fd
] = this;
13 setSendTimeout( fd
,0,500000); // 0.5 second host send timeout should be adequate
14 // set keepalive options
15 setKeepAlive( fd
, 3, 120, 30);
16 createSessionRecord();
21 log("Closing client connection!\n");
23 deleteSessionRecord();
26 void Session::destroy(bool silent
)
29 motemapbykey_t::iterator mi
;
30 // release any controlled motes
31 for ( mi
= motes
.begin() ; mi
!= motes
.end(); mi
++ )
35 if (mi
->second
) mi
->second
->dropSession(false);
37 catch (mysqlpp::Exception e
) // don't throw exceptions while destructing
41 log("Exception while dropping mote client: %s - record not updated!\n",e
.what());
53 void Session::resetDb()
55 mysqlpp::Connection
& sqlConn
= dbConn
.getConnection();
56 mysqlpp::Query reset
= sqlConn
.query();
57 reset
<< "delete from session";
62 void Session::createSessionRecord()
64 // create a session record for this connection
65 mysqlpp::Connection
& sqlConn
= dbConn
.getConnection();
67 mysqlpp::Query query
= sqlConn
.query();
68 query
<< "insert into session(auth) values (0)";
70 mysqlpp::ResNSel sqlres
= query
.execute();
73 session_id
= sqlres
.insert_id
;
75 MsgSession
msgSession(session_id
);
76 ClientMsg
msg(msgSession
);
77 message
.sendMsg(fd
,msg
);
82 __THROW__ ("Failed to insert new mote in database!\n");
87 void Session::deleteSessionRecord()
89 mysqlpp::Connection
& sqlConn
= dbConn
.getConnection();
91 mysqlpp::Query query
= sqlConn
.query();
92 query
<< "delete from session where id = '%0:session_id'";
94 query
.def
["session_id"] = session_id
;
97 authenticated
= false;
100 bool Session::isAuthenticated()
102 if (authenticated
) return true;
103 // look up and verify the authentication in the database
104 mysqlpp::Connection
& sqlConn
= dbConn
.getConnection();
106 mysqlpp::Query query
= sqlConn
.query();
108 query
<< "select auth from session where id = '%0:session_id'";
110 query
.def
["session_id"] = session_id
;
113 if ( res
.num_rows() == 1 )
115 authenticated
= res
.at(0)["auth"];
119 if (authenticated
){ log("Client authenticated!\n");}
120 else { log("Client not authenticated!\n"); }
121 return authenticated
;
124 void Session::freeMote(dbkey_t mote_id
)
127 motemapbykey_t::iterator mi
;
128 mi
= motes
.find(mote_id
);
129 if ( mi
!= motes
.end() )
132 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_DROPMOTECONTROL
, SUCCESS
, mote_id
);
133 ClientMsg
clientMsg(confirm
);
134 message
.sendMsg(fd
,clientMsg
);
138 void Session::confirm(dbkey_t mote_id
, MsgPayload
& moteMsg
)
141 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_MOTEMESSAGE
, SUCCESS
, mote_id
, moteMsg
);
142 ClientMsg
clientMsg(confirm
);
145 message
.sendMsg(fd
,clientMsg
);
147 catch (remote::protocols::MMSException e
)
149 log("Exception: %s\n",e
.what());
154 void Session::handleEvent(short events
)
156 if ( (events
& POLLHUP
) || (events
& POLLNVAL
) ) __THROW__ ("Client connection closed by peer!");
157 if ( (events
& POLLIN
) || (events
& POLLPRI
) )
159 // no input is accepted before external authorization
160 if ( !isAuthenticated() )
162 __THROW__ ("Client not authenticated!\n");
165 // wait for an entire message before continuing
166 if (!message_in
.nonBlockingRecv(fd
))
171 uint32_t msglen
= message_in
.getLength();
172 uint8_t* buffer
= message_in
.getData();
173 ClientMsg
msg(buffer
,msglen
);
175 switch (msg
.getType())
177 case CLIENTMSG_CLIENTREQUEST
:
179 MsgClientRequest
& msgClientRequest
= msg
.getClientRequest();
180 handleClientRequest(msgClientRequest
);
184 __THROW__ ("Invalid message type from client!");
189 else if ( (events
& POLLERR
) || (events
& POLLHUP
) || (events
& POLLNVAL
) )
191 __THROW__ ("Client connection closed.\n");
195 void Session::handleClientRequest(MsgClientRequest
& request
)
198 motemapbykey_t::const_iterator mi
;
199 MsgMoteIdList
& idlist
= request
.getMoteIdList();
201 while( idlist
.getNextMoteId(mote_id
) )
203 // check the session id
204 switch ( request
.getCommand() )
206 case MSGCLIENTCOMMAND_GETMOTECONTROL
:
207 getMoteControl(mote_id
);
209 case MSGCLIENTCOMMAND_DROPMOTECONTROL
:
210 dropMoteControl(mote_id
);
212 case MSGCLIENTCOMMAND_MOTEMESSAGE
:
213 handleMoteRequest(mote_id
,request
.getMoteMsg());
216 __THROW__ ("Got unknown request from client.\n");
223 void Session::handleMoteRequest(dbkey_t mote_id
,MsgPayload
& request
)
226 motemapbykey_t::const_iterator mi
;
228 mi
= motes
.find(mote_id
);
230 if ( mi
!= motes
.end() )
232 mi
->second
->request(request
);
236 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_MOTEMESSAGE
, MOTE_NOT_CONTROLLED
, mote_id
);
237 ClientMsg
msg(confirm
);
239 message
.sendMsg(fd
,msg
);
243 void Session::getMoteControl( dbkey_t mote_id
)
247 // figure out which mote is referred to
248 Mote::getById(mote_id
,this,&mote
);
252 motes
[mote_id
] = mote
;
253 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_GETMOTECONTROL
, SUCCESS
, mote_id
);
254 ClientMsg
msg(confirm
);
255 message
.sendMsg(fd
,msg
);
258 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_GETMOTECONTROL
, FAILURE
, mote_id
);
259 ClientMsg
msg(confirm
);
260 message
.sendMsg(fd
,msg
);
264 void Session::dropMoteControl(dbkey_t mote_id
)
267 motemapbykey_t::const_iterator mi
;
269 mi
= motes
.find(mote_id
);
271 if ( mi
!= motes
.end() )
273 mi
->second
->dropSession();
274 // dropSession should invoke freeMote that confirms the drop request
278 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_DROPMOTECONTROL
, MOTE_NOT_CONTROLLED
, mote_id
);
279 ClientMsg
msg(confirm
);
280 message
.sendMsg(fd
,msg
);
285 /*void Session::handleAuthRequest(MsgAuthRequest& authReq)
288 msg_out.type = SERVERMSG_AUTHORIZECONFIRM;
289 mysqlpp::Connection& sqlConn = dbConn.getConnection();
290 // look up and verify the credentials in the database
292 mysqlpp::Query query = sqlConn.query();
294 query << "select up.id user_project_id, up.user_id,up.project_id \
295 from user_project up, user u, project p \
296 where p.name ='%0:project' \
297 and u.login ='%1:username' \
298 and u.password=md5('%2:password') \
299 and up.user_id = u.id \
300 and up.project_id = p.id";
304 query.def["project"] = *(new std::string(authReq.getProject().getString()));
305 query.def["username"] = *(new std::string(authReq.getUsername().getString()));
306 query.def["password"] = *(new std::string(authReq.getPassword().getString()));
310 if ( res.num_rows() != 1 )
312 msg_out.getAuthConfirm().result = FAILURE;
313 log("Client not authorized!\n");
317 user_id = res.at(0)["user_id"];
318 project_id = res.at(0)["project_id"];
319 user_project_id = res.at(0)["user_project_id"];
321 msg_out.getAuthConfirm().result = SUCCESS;
322 log("Client authorized!\n");
325 message.sendMsg(fd,msg_out);