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 session 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 = " << session_id
;
95 authenticated
= false;
98 bool Session::isAuthenticated()
100 if (authenticated
) return true;
101 // look up and verify the authentication in the database
102 mysqlpp::Connection
& sqlConn
= dbConn
.getConnection();
104 mysqlpp::Query query
= sqlConn
.query();
106 query
<< "select auth from session where id = " << session_id
;
109 if ( res
.num_rows() == 1 )
111 authenticated
= res
.at(0)["auth"];
115 if (authenticated
){ log("Client authenticated!\n");}
116 else { log("Client not authenticated!\n"); }
117 return authenticated
;
120 void Session::freeMote(dbkey_t mote_id
)
123 motemapbykey_t::iterator mi
;
124 mi
= motes
.find(mote_id
);
125 if ( mi
!= motes
.end() )
128 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_DROPMOTECONTROL
, SUCCESS
, mote_id
);
129 ClientMsg
clientMsg(confirm
);
130 message
.sendMsg(fd
,clientMsg
);
134 void Session::confirm(dbkey_t mote_id
, MsgPayload
& moteMsg
)
137 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_MOTEMESSAGE
, SUCCESS
, mote_id
, moteMsg
);
138 ClientMsg
clientMsg(confirm
);
141 message
.sendMsg(fd
,clientMsg
);
143 catch (remote::protocols::MMSException e
)
145 log("Exception: %s\n",e
.what());
150 void Session::handleEvent(short events
)
152 if ( (events
& POLLHUP
) || (events
& POLLNVAL
) ) __THROW__ ("Client connection closed by peer!");
153 if ( (events
& POLLIN
) || (events
& POLLPRI
) )
155 // no input is accepted before external authorization
156 if ( !isAuthenticated() )
158 __THROW__ ("Client not authenticated!\n");
161 // wait for an entire message before continuing
162 if (!message_in
.nonBlockingRecv(fd
))
167 uint32_t msglen
= message_in
.getLength();
168 uint8_t* buffer
= message_in
.getData();
169 ClientMsg
msg(buffer
,msglen
);
171 switch (msg
.getType())
173 case CLIENTMSG_CLIENTREQUEST
:
175 MsgClientRequest
& msgClientRequest
= msg
.getClientRequest();
176 handleClientRequest(msgClientRequest
);
180 __THROW__ ("Invalid message type from client!");
185 else if ( (events
& POLLERR
) || (events
& POLLHUP
) || (events
& POLLNVAL
) )
187 __THROW__ ("Client connection closed.\n");
191 void Session::handleClientRequest(MsgClientRequest
& request
)
194 motemapbykey_t::const_iterator mi
;
195 MsgMoteIdList
& idlist
= request
.getMoteIdList();
197 while( idlist
.getNextMoteId(mote_id
) )
199 // check the session id
200 switch ( request
.getCommand() )
202 case MSGCLIENTCOMMAND_GETMOTECONTROL
:
203 getMoteControl(mote_id
);
205 case MSGCLIENTCOMMAND_DROPMOTECONTROL
:
206 dropMoteControl(mote_id
);
208 case MSGCLIENTCOMMAND_MOTEMESSAGE
:
209 handleMoteRequest(mote_id
,request
.getMoteMsg());
212 __THROW__ ("Got unknown request from client.\n");
219 void Session::handleMoteRequest(dbkey_t mote_id
,MsgPayload
& request
)
222 motemapbykey_t::const_iterator mi
;
224 mi
= motes
.find(mote_id
);
226 if ( mi
!= motes
.end() )
228 mi
->second
->request(request
);
232 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_MOTEMESSAGE
, MOTE_NOT_CONTROLLED
, mote_id
);
233 ClientMsg
msg(confirm
);
235 message
.sendMsg(fd
,msg
);
239 void Session::getMoteControl( dbkey_t mote_id
)
243 // figure out which mote is referred to
244 Mote::getById(mote_id
,this,&mote
);
248 motes
[mote_id
] = mote
;
249 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_GETMOTECONTROL
, SUCCESS
, mote_id
);
250 ClientMsg
msg(confirm
);
251 message
.sendMsg(fd
,msg
);
254 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_GETMOTECONTROL
, FAILURE
, mote_id
);
255 ClientMsg
msg(confirm
);
256 message
.sendMsg(fd
,msg
);
260 void Session::dropMoteControl(dbkey_t mote_id
)
263 motemapbykey_t::const_iterator mi
;
265 mi
= motes
.find(mote_id
);
267 if ( mi
!= motes
.end() )
269 mi
->second
->dropSession();
270 // dropSession should invoke freeMote that confirms the drop request
274 MsgClientConfirm
confirm( MSGCLIENTCOMMAND_DROPMOTECONTROL
, MOTE_NOT_CONTROLLED
, mote_id
);
275 ClientMsg
msg(confirm
);
276 message
.sendMsg(fd
,msg
);