// Copyright © 2013 sss //. // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. //. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. //. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "headers.h" using namespace proto; using namespace service; void session::handle_handshake(const boost::system::error_code& error) { if (!error) { recv_data = new char [32]; socket_.async_read_some(boost::asio::buffer(recv_data, 32), boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { delete this; } } void session::handle_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { // std::cout<<"recieved: "< v; v.assign(recv_data, recv_data + bytes_transferred); delete [] recv_data; packet p(v); v.clear(); if(!p.is_good()) { delete this; } switch(p.get_type()) { case TYPE_AUTH_REQUEST: { if(!packet::serv_validate_client_proto(p)) { packet *r = packet::make_status_packet(TYPE_AUTH_REPLY, STATUS_FAILURE); write_w_close(r->raw()); delete r; return; } else { packet *r = packet::make_status_packet(TYPE_AUTH_REPLY, STATUS_SUCCESS); write_w_response(r->raw()); delete r; return; } } break; case TYPE_COMMAND_REQUEST: { svc_cmd c = packet::serv_extract_command(p); if(c.service.empty()) break; std::list::iterator i = std::find(installed_services.begin(), installed_services.end(), c.service); if(!c.command.empty()) { if(i != installed_services.end()) { std::list::iterator ii = std::find(i->predefined.begin(), i->predefined.end(), c.command); if(ii != i->predefined.end()) { switch(i->acc) { case ACC_CHAR_PTR: { switch(i->ret) { case RET_CHAR_PTR: { char *arg = strdup(c.command.c_str()); char *data = (char*)i->exec((void*)arg); std::string s(data); delete [] data; packet *p = packet::serv_make_command_reply_packet(s, STATUS_SUCCESS); delete [] data; write_w_response(p->raw()); delete p; } break; case RET_FLOAT_PTR: { char *arg = strdup(c.command.c_str()); float *ret = (float*)i->exec((void*)arg); //todo pack float to unsigned char vector std::vector v; packet *p = packet::serv_make_command_reply_packet(v, STATUS_SUCCESS); write_w_response(p->raw()); delete p; delete ret; } break; case RET_INT_PTR: { char *arg = strdup(c.command.c_str()); int *ret = (int*)i->exec((void*)arg); //todo pack float to unsigned char vector std::vector v; packet *p = packet::serv_make_command_reply_packet(v, STATUS_SUCCESS); write_w_response(p->raw()); delete p; delete ret; } break; case RET_NONE: { char *arg = strdup(c.command.c_str()); i->exec((void*)arg); packet *p = packet::make_status_packet(TYPE_AUTH_REPLY, STATUS_SUCCESS); write_w_response(p->raw()); delete p; } break; case RET_STD_STRING_PTR: { char *arg = strdup(c.command.c_str()); std::string *str = (std::string*)i->exec((void*)arg); packet *p = packet::serv_make_command_reply_packet(*str, STATUS_SUCCESS); write_w_response(p->raw()); delete p; delete str; } break; case RET_VOID_PTR: { //TODO } break; }; } break; case ACC_FLOAT_PTR: { } break; case ACC_INT_PTR: { } break; case ACC_STD_STRING_PTR: { } break; case ACC_VOID_PTR: { } break; default: break; } } } } else { if(i->acc == ACC_NONE) { switch(i->ret) { case RET_CHAR_PTR: { char *data = (char*)i->exec((void*)NULL); std::string s(data); delete [] data; packet *p = packet::serv_make_command_reply_packet(s, STATUS_SUCCESS); delete [] data; write_w_response(p->raw()); delete p; } break; case RET_FLOAT_PTR: { float *ret = (float*)i->exec((void*)NULL); //todo pack float to unsigned char vector std::vector v; packet *p = packet::serv_make_command_reply_packet(v, STATUS_SUCCESS); write_w_response(p->raw()); delete p; delete ret; } break; case RET_INT_PTR: { int *ret = (int*)i->exec((void*)NULL); //todo pack float to unsigned char vector std::vector v; packet *p = packet::serv_make_command_reply_packet(v, STATUS_SUCCESS); write_w_response(p->raw()); delete p; delete ret; } break; case RET_NONE: { i->exec((void*)NULL); packet *p = packet::make_status_packet(TYPE_AUTH_REPLY, STATUS_SUCCESS); write_w_response(p->raw()); delete p; } break; case RET_STD_STRING_PTR: { std::string *str = (std::string*)i->exec((void*)NULL); packet *p = packet::serv_make_command_reply_packet(*str, STATUS_SUCCESS); write_w_response(p->raw()); delete p; delete str; } break; case RET_VOID_PTR: { //TODO } break; }; } } } break; } } } void session::handle_write(const boost::system::error_code& error, size_t bytes_transferred) { delete [] snd_data; if(error) { delete this; return; //? } recv_data = (char*)new unsigned char[128]; socket_.async_read_some(boost::asio::buffer(recv_data, 128), boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void session::write_w_close(const std::vector& data) { snd_data = (char*)new unsigned char[data.size() + 1]; memset(snd_data, 0, data.size() + 1); for(int i = 0; i < data.size(); i++) snd_data[i] = data[i]; socket_.async_write_some(boost::asio::buffer(snd_data, data.size() + 1), boost::bind(&session::handle_write_close, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void session::write_w_response(const std::vector& data) { pack_buffer(data); socket_.async_write_some(boost::asio::buffer(snd_data, data.size()+1), boost::bind(&session::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void session::write_wo_response(const std::vector& data) { pack_buffer(data); socket_.async_write_some(boost::asio::buffer(snd_data, data.size() +1), boost::bind(&session::handle_operation, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void session::handle_write_close(const boost::system::error_code& error, size_t bytes_transferred) { delete [] snd_data; delete this; } void session::handle_operation(const boost::system::error_code& error, size_t bytes_transferred) { delete [] snd_data; } void session::pack_buffer(const std::vector& data) { snd_data = (char*)new unsigned char[data.size()+1]; memset(snd_data, 0, data.size()+1); for(int i = 0; i < data.size(); i++) snd_data[i] = data[i]; }