00001 #include "Connector.h"
00005 #define DEFAULT_PORT 6780
00006
00007 Connector::Connector() {
00008 init(DEFAULT_PORT,DEFAULT_PORT+1,DEFAULT_PORT+2,DEFAULT_PORT+3);
00009 }
00010 Connector::~Connector() {
00011 list<ConnectionWrap *>::iterator iter;
00012 for (iter = allConnections->begin(); iter != allConnections->end(); iter++) {
00013 (*iter)->disconnect();
00014 delete *iter;
00015 }
00016 allConnections->clear();
00017
00018 list<ConfigConnection *>::iterator citer;
00019 for (citer = configConnections->begin(); citer != configConnections->end(); citer++) {
00020 (*citer)->disconnect();
00021 delete *citer;
00022 }
00023 configConnections->clear();
00024 currentConfig = NULL;
00025 {
00026 list<ConnectionWrap *>::iterator iter;
00027 for (iter = allConnections->begin(); iter != allConnections->end(); iter++) {
00028 allConnections->erase(iter);
00029 delete (*iter);
00030 }
00031 }
00032 {
00033 list<ConfigConnection *>::iterator iter;
00034 for (iter = configConnections->begin(); iter != configConnections->end(); iter++) {
00035 configConnections->erase(iter);
00036 delete (*iter);
00037 }
00038 }
00039 delete allConnections;
00040 delete configConnections;
00041 delete (MessageExecutor*)messageExecutor;
00042 delete connectionFactory;
00043 delete bf;
00044 }
00045 Connector::Connector(int start) {
00046 init(start,start+1,start+2,start+3);
00047 }
00048 Connector::Connector(int inputport,int outputport,int filterport, int configport) {
00049 init(inputport,outputport,filterport,configport);
00050 }
00051 void Connector::init(int inputport,int outputport,int filterport, int configport) {
00052 bf = new BufferedFileFactory();
00053 connectionFactory = new ConnectionFactory(bf,inputport,outputport,filterport,configport);
00054 updated();
00055 allConnections = new list<ConnectionWrap *>();
00056 messageExecutor = new MessageExecutor();
00057 configConnections = new list<ConfigConnection *>();
00058 ConnectorSingleton().setConnector(this);
00059 quit = false;
00060 processUpdate = lastUpdated;
00061 }
00062 int Connector::lastUpdate() {
00063 return lastUpdated;
00064 }
00065 void Connector::lastChange() {
00066 char number[12];
00067 snprintf(number,12,"%d",lastUpdate());
00068 string final = "<lastChange>";
00069 final += "<time>";
00070 final += string(number);
00071 final += "</time></lastChange>";
00072 currentConfig->write(final.c_str(),final.size());
00073 }
00074 void Connector::updated() {
00075 lastUpdated = time(NULL);
00076 }
00077 list<ConnectionWrap *> * Connector::getConnectionList() {
00078 return allConnections;
00079 }
00080 void Connector::disconnect(int fd) {
00081 list<ConnectionWrap *>::iterator eter;
00082 list<ConnectionWrap *>::iterator iter;
00083 ConnectionWrap * it = NULL;
00084 int fh;
00085 for (eter = allConnections->begin(); eter != allConnections->end(); eter++) {
00086
00087 fh = (*eter)->getFileHandle();
00088 if (fd == fh) {
00089 it = *eter;
00090 break;
00091 }
00092 }
00093 if (it!=NULL) {
00094 allConnections->remove(it);
00095 for (iter = allConnections->begin(); iter != allConnections->end(); iter++) {
00096 (*iter)->disconnectFrom(it);
00097 }
00098 it->disconnect();
00099 updated();
00100 delete it;
00101 return;
00102 }
00103
00104 throw new string("No connection found. Could not disconnect connection");
00105 }
00106 void Connector::unPatch(int from, int to) {
00107 cout << "UNPATCH " << from << " TO " << to << "\n";
00108 list<ConnectionWrap *>::iterator iter;
00109 ConnectionWrap * fromConn = NULL;
00110 ConnectionWrap * toConn = NULL;
00111 for (iter = allConnections->begin(); iter != allConnections->end(); iter++) {
00112 int fd = (*iter)->getFileHandle();
00113 if (fd == from) {
00114 fromConn = (*iter);
00115 } else if (fd == to) {
00116 toConn = (*iter);
00117 }
00118 }
00119 if (fromConn == NULL || toConn == NULL) {
00120 throw new string("There is no patch between these connections!");
00121 }
00122 toConn->disconnectFrom(fromConn);
00123 updated();
00124 }
00125 void Connector::patch(int from, int to) {
00126 list<ConnectionWrap *>::iterator iter;
00127 ConnectionWrap * fromConn = NULL;
00128 ConnectionWrap * toConn = NULL;
00129 for (iter = allConnections->begin(); iter != allConnections->end(); iter++) {
00130 int fd = (*iter)->getFileHandle();
00131 if (fd == from) {
00132 fromConn = (*iter);
00133 if (toConn!=NULL) { break;}
00134
00135 } else if (fd == to) {
00136 toConn = (*iter);
00137 if (fromConn!=NULL) { break;}
00138 }
00139 }
00140 if (fromConn == NULL || toConn == NULL) {
00141 throw new string("There is no patch between these connections!");
00142 }
00143 if (!fromConn->readable()) {
00144 throw new string("This is not a valid patch!");
00145 }
00146 toConn->connectFrom(fromConn);
00147 updated();
00148 }
00149 void Connector::sendUpdate() {
00150 char number[12];
00151 if (currentConfig==NULL) {
00152 list<ConfigConnection *>::iterator iter;
00153 for (iter = configConnections->begin(); iter != configConnections->end(); iter++) {
00154 currentConfig = (*iter);
00155 break;
00156 }
00157 if (currentConfig==NULL) {
00158 return;
00159 }
00160 }
00161 string final = "<update>";
00162 list<ConnectionWrap *>::iterator iter;
00163 for (iter = allConnections->begin(); iter != allConnections->end(); iter++) {
00164 string * str = (*iter)->getXML();
00165 if (str!=NULL) {
00166 final += *str;
00167 delete str;
00168 }
00169 }
00170 snprintf(number,12,"%d",lastUpdate());
00171 final += "<time>";
00172 final += string(number);
00173 final += "</time></update>";
00174 currentConfig->write(final.c_str(),final.size());
00175 }
00176
00177 void Connector::process() {
00178
00179
00180
00181 int rw = bf->process(100);
00182 Clock::clock++;
00183 if (rw) {
00184 list<ConnectionWrap *>::iterator iter;
00185 for (iter = allConnections->begin(); iter != allConnections->end(); iter++) {
00186 (*iter)->process();
00187 }
00188 list<ConfigConnection *>::iterator citer;
00189 if (processUpdate!=lastUpdated) {
00190 ConfigConnection * tmp = currentConfig;
00191 for (citer = configConnections->begin(); citer != configConnections->end(); citer++) {
00192 currentConfig = *citer;
00193 try {
00194 sendUpdate();
00195 } catch (string * err) {
00196 cout << "Disconnecting a ConfigConnection\n";
00197 configConnections->remove(currentConfig);
00198
00199 delete currentConfig;
00200 currentConfig = NULL;
00201 delete err;
00202 }
00203 }
00204 processUpdate = lastUpdated;
00205 currentConfig = tmp;
00206 }
00207 for (citer = configConnections->begin(); citer != configConnections->end(); citer++) {
00208 try {
00209 if ((*citer)->isMessage()) {
00210 currentConfig = (*citer);
00211 Message *m = (*citer)->getMessage();
00212 string * mstr = m->getXML();
00213 cout << "THERE IS A MESSAGE "<< *mstr << "\n" ;
00214 try {
00215 ((MessageExecutor*)messageExecutor)->executeMessage(m);
00216 } catch (string * err) {
00217 string error = "<error>";
00218 error += *err;
00219 error += "</error>";
00220 currentConfig->write(error.c_str(),error.size());
00221 }
00222 delete m;
00223 }
00224 if (processUpdate!=lastUpdated) {
00225
00226 }
00227 } catch (string * err) {
00228 cout << "Disconnecting a ConfigConnection\n";
00229 configConnections->remove(currentConfig);
00230
00231 delete currentConfig;
00232 currentConfig = NULL;
00233 delete err;
00234 break;
00235 }
00236 }
00237 }
00238 if (connectionFactory->isThereANewConnection()) {
00239 cout << "There is a connection!\n";
00240
00241 ConnectionWrap * wrap = connectionFactory->processConnection();
00242 if (wrap!=NULL) {
00243 cout << (int)(wrap->conn.floatConn->getFileHandle()) << "\n";
00244 assert(wrap->conn.floatConn!=0);
00245 if (wrap->type == CONFIGCONN) {
00246 cout << "It's a config connection!\n";
00247 configConnections->push_back(wrap->conn.configConn);
00248 wrap->conn.configConn = NULL;
00249 delete wrap;
00250 } else if (wrap == NULL) {
00251 cout << "NULL Wrapper Returned?\n";
00252 } else {
00253 cout << "It's not config connection!\n";
00254 allConnections->push_back(wrap);
00255 }
00256 updated();
00257 } else {
00258 cout << "Connection Failed!\n";
00259 }
00260 }
00261 }
00262 void Connector::shutDown() {
00263 quit = true;
00264
00265 }
00266 bool Connector::done() {
00267 return quit;
00268 }