|
degate 0.1.1
|
00001 /* -*-c++-*- 00002 00003 This file is part of the IC reverse engineering tool degate. 00004 00005 Copyright 2008, 2009, 2010 by Martin Schobert 00006 00007 Degate is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 any later version. 00011 00012 Degate is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with degate. If not, see <http://www.gnu.org/licenses/>. 00019 00020 */ 00021 00022 #include <XmlRpc.h> 00023 #include <Wire.h> 00024 #include <Via.h> 00025 00026 #include <boost/foreach.hpp> 00027 00028 using namespace degate; 00029 using namespace std; 00030 00031 00032 xmlrpc_c::value degate::remote_method_call(std::string const& server_url, 00033 std::string const& method_name, 00034 xmlrpc_c::paramList const& params) { 00035 00036 xmlrpc_c::clientXmlTransport_curl myTransport; 00037 xmlrpc_c::client_xml myClient(&myTransport); 00038 00039 xmlrpc_c::rpcPtr myRpcP(method_name, params); 00040 xmlrpc_c::carriageParm_curl0 myCarriageParam(server_url); 00041 00042 myRpcP->call(&myClient, &myCarriageParam); 00043 00044 assert(myRpcP->isFinished()); 00045 00046 return myRpcP->getResult(); 00047 } 00048 00049 00050 void degate::push_changes_to_server(std::string const& server_url, LogicModel_shptr lmodel) { 00051 00052 // iterate over gates 00053 for(LogicModel::object_collection::iterator iter = lmodel->objects_begin(); 00054 iter != lmodel->objects_end(); ++iter) { 00055 00056 object_id_t local_oid = iter->second->get_object_id(); 00057 00058 if(RemoteObject_shptr ro = std::tr1::dynamic_pointer_cast<RemoteObject>((*iter).second)) { 00059 00060 if(!ro->has_remote_object_id()) { 00061 std::cout << "Push object to server." << std::endl; 00062 object_id_t remote_oid = ro->push(server_url); 00063 00064 lmodel->update_roid_mapping(remote_oid, local_oid); 00065 } 00066 } 00067 } 00068 00069 BOOST_FOREACH(object_id_t id, lmodel->get_removed_remote_objetcs_list()) { 00070 xmlrpc_c::paramList params; 00071 params.add(xmlrpc_c::value_string("remove")); 00072 params.add(xmlrpc_c::value_int(id)); 00073 00074 remote_method_call(server_url, "degate.push", params); 00075 00076 debug(TM, "Send remove message for object with remote ID %d", id); 00077 } 00078 00079 lmodel->reset_removed_remote_objetcs_list(); 00080 } 00081 00082 00083 void degate::process_changelog_command(LogicModel_shptr lmodel, 00084 transaction_id_t transaction_id, 00085 std::vector<xmlrpc_c::value> const& command) { 00086 00087 debug(TM, "XMLRPC: process received command for transaction %d", transaction_id); 00088 00089 if(lmodel->get_local_oid_for_roid(transaction_id) != 0) { 00090 debug(TM, "XMLRPC: transaction %d aready known.", transaction_id); 00091 return; 00092 } 00093 00094 00095 if(command.size() < 2) throw XMLRPCException("Command has not enough parameters."); 00096 00097 if(command[0].type() != xmlrpc_c::value::TYPE_STRING) 00098 throw XMLRPCException("Command parameter is not a string"); 00099 00100 const std::string command_str = xmlrpc_c::value_string(command[0]); 00101 std::cout << " cmd: " << command_str << std::endl; 00102 00103 if(!command_str.compare("remove")) { 00104 if(command.size() < 2) 00105 throw XMLRPCException("Command wire add has less then 8 parameters."); 00106 int ro_id = xmlrpc_c::value_int(command[1]); 00107 lmodel->remove_remote_object(ro_id); 00108 } 00109 00110 else if( !command_str.compare("add")) { 00111 00112 const std::string obj_type_str = xmlrpc_c::value_string(command[1]); 00113 00114 if(!obj_type_str.compare("wire")) { 00115 if(command.size() < 8) 00116 throw XMLRPCException("Command wire add has less then 8 parameters."); 00117 00118 int layer_id = xmlrpc_c::value_int(command[2]); 00119 int from_x = xmlrpc_c::value_int(command[3]); 00120 int from_y = xmlrpc_c::value_int(command[4]); 00121 int to_x = xmlrpc_c::value_int(command[5]); 00122 int to_y = xmlrpc_c::value_int(command[6]); 00123 unsigned int diameter = xmlrpc_c::value_int(command[7]); 00124 00125 Wire_shptr w(new Wire(from_x, from_y, to_x, to_y, diameter)); 00126 w->set_remote_object_id(transaction_id); 00127 Layer_shptr layer = lmodel->get_layer_by_id(layer_id); 00128 lmodel->add_object(layer, w); 00129 } 00130 else if(!obj_type_str.compare("via")) { 00131 if(command.size() < 7) 00132 throw XMLRPCException("Command via add has less then 8 parameters."); 00133 00134 int layer_id = xmlrpc_c::value_int(command[2]); 00135 int x = xmlrpc_c::value_int(command[3]); 00136 int y = xmlrpc_c::value_int(command[4]); 00137 unsigned int diameter = xmlrpc_c::value_int(command[5]); 00138 const std::string direction = xmlrpc_c::value_string(command[6]); 00139 00140 Via_shptr v(new Via(x, y, diameter, Via::get_via_direction_from_string(direction))); 00141 v->set_remote_object_id(transaction_id); 00142 Layer_shptr layer = lmodel->get_layer_by_id(layer_id); 00143 lmodel->add_object(layer, v); 00144 } 00145 } 00146 00147 /* 00148 for(std::vector<xmlrpc_c::value>::const_iterator iter = command.begin(); 00149 iter != command.end(); ++iter) 00150 std::cout << "\ttype " << (*iter).type() << std::endl; 00151 } 00152 */ 00153 00154 } 00155 00156 transaction_id_t degate::pull_changes_from_server(std::string const& server_url, 00157 LogicModel_shptr lmodel, 00158 transaction_id_t start_tid) { 00159 try { 00160 xmlrpc_c::paramList params; 00161 params.add(xmlrpc_c::value_int(start_tid)); 00162 xmlrpc_c::value_array ret(remote_method_call(server_url, "degate.pull", params)); 00163 00164 std::vector<xmlrpc_c::value> v(ret.vectorValueValue()); 00165 00166 if(start_tid == 0) ++start_tid; 00167 00168 debug(TM, "Received %d changes since transaction %ld", v.size(), start_tid); 00169 00170 unsigned int pos = 0; 00171 for(std::vector<xmlrpc_c::value>::const_iterator iter = v.begin(); 00172 iter != v.end(); ++iter, pos++) { 00173 xmlrpc_c::value_array const& command(*iter); 00174 process_changelog_command(lmodel, start_tid + pos, command.vectorValueValue()); 00175 00176 /* If the process_changelog_command() fails with an exception, changes 00177 were already made to the logic model. That is no problem, because 00178 process_changelog_command() checks this case. 00179 */ 00180 } 00181 00182 return start_tid + v.size(); 00183 } 00184 catch(XMLRPCException const& e) { 00185 throw; 00186 } 00187 catch(exception const& e) { 00188 cerr << "Client threw error: " << e.what() << endl; 00189 throw XMLRPCException(e.what()); 00190 } 00191 catch(...) { 00192 cerr << "Client threw unexpected error." << endl; 00193 throw XMLRPCException("Client threw unexpected error."); 00194 } 00195 00196 return start_tid; 00197 } 00198
1.7.4