#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "modelbahn.h" #include "network.h" #include "json.h" Network::Network() { thread = 0; sessions.clear(); thread_running = 0; mtx = { 0 }; mtx = PTHREAD_MUTEX_INITIALIZER; } Network::~Network() { list::iterator iter; while ((iter = sessions.begin()) != sessions.end()) { Session *s = *iter; sessions.remove(*iter); delete s; } Stop(); }; int Network::LockThread() { if (pthread_mutex_lock(&mtx) == 0) return 1; else return 0; } int Network::UnLockThread() { if (pthread_mutex_unlock(&mtx) == 0) return 1; else return 0; } void Network::ThreadProcess() { list::iterator iteru; Session *s; UNIX *u; while (running) { // // check network // // server socket ServerLoop(); // // client socket for (iteru = clients.begin(); iteru != clients.end(); iteru++) { if (ClientLoop((UNIX*) *iteru) < 0) { u = *iteru; clients.remove(u); delete u; iteru = clients.begin(); } } usleep (100000); } thread_running = 0; }; int Network::Start() { int err; pthread_attr_t attr; mtx = { 0 }; mtx = PTHREAD_MUTEX_INITIALIZER; // // start socket server // if (sockserver.Listen(UNIX_SOCKET_FILE) != 1) { return 0; } chmod(UNIX_SOCKET_FILE, 00666); thread_running = 1; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE); err = pthread_create (&thread, &attr, ThreadEntry, this); if (err != 0) { debug (DEBUG_ERROR, (char*)"%s(%s:%d) pthread_create errror: %s", __FUNCTION__, __FILE__, __LINE__, strerror (errno)); running = 0; return 0; } return 1; }; void Network::Stop() { sockserver.Close(); unlink(UNIX_SOCKET_FILE); } void Network::_ChangeListPushToAll(string changes) { list::iterator iter; for (iter = sessions.begin(); iter != sessions.end(); iter++) { if ((*iter)->GetSessionID() > 0) (*iter)->ChangeListPush(changes); } }; void Network::ChangeListPushToAll(string changes) { LockThread(); _ChangeListPushToAll(changes); UnLockThread(); }; int Network::ServerLoop() { UNIX *u = NULL; if (sockserver.IsData(10)) { u = sockserver.Accept(); clients.push_back(u); } return 1; }; Session *Network::GetSession(int sid) { Session *s = NULL; list::iterator iter; for (iter = sessions.begin(); iter != sessions.end(); iter++) { if ((*iter)->GetSessionID() == sid) { s = *iter; break; } } return s; }; int Network::ClientLoop(UNIX *client) { char bufferin[BUFFERSIZE]; char bufferout[BUFFERSIZE]; int len, i, rid, sid; int res; list::iterator siter; Session *session = NULL; string value; string ssid; string srid; string s; int result = -1; struct timeval timer; timer_start(&timer); len = client->ReadTimeout(bufferin, BUFFERSIZE, 20); if (len > 0 && len < BUFFERSIZE) { JSONParse json; JSONParse jsonout; JSONParse jelement; bufferin[len] = 0; // prevent reading behind the data json.Set(bufferin); if (!json.GetValue("sid", &ssid)) { debug (0, "json.GetValue error --> sid"); return 0; } if (!json.GetValue("rid", &srid)) { debug (0, "json.GetValue error --> rid"); return 0; } // try { rid = stoi (srid); } catch (...) { rid = 0; debug (0, "* rid error"); } try { sid = stoi (ssid); } catch (...) { sid = 0; debug (0, "* sid error"); } if (sid <= 0) { int x, y; debug (0, "* sid not set, gettin new SID"); session = new Session(rid); sid = session->GetSessionID(); LockThread(); sessions.push_back(session); UnLockThread(); } else { LockThread(); // // search for session session = NULL; for (siter = sessions.begin(); siter != sessions.end(); siter++) { if ((*siter)->GetRandomID() == rid && ((Session*)(*siter))->GetSessionID() == sid) { session = (*siter); break; } } UnLockThread(); } if (session) { JSONElement je; int retval; LockThread(); retval = session->ProcessData(&json, &jsonout); UnLockThread(); len = BUFFERSIZE; if (retval) { je.Clear(); je.Set("success", 1); jsonout.AddObject(je); } else { je.Clear(); je.Set("success", 0); jsonout.AddObject(je); } s = jsonout.ToString(); client->Write((char*)s.c_str(), strlen(s.c_str())); result = 1; } else { // no session found result = 0; } } else if (len == 0) { result = 0; } return result; };