You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
4.7 KiB
280 lines
4.7 KiB
|
|
|
|
#include <string>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <netdb.h>
|
|
#include <errno.h>
|
|
#include <syslog.h>
|
|
#include <pthread.h>
|
|
#include <math.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/syscall.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <list>
|
|
|
|
#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<Session*>::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<UNIX*>::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<Session*>::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<Session*>::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<Session*>::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;
|
|
};
|
|
|