Skip to content
Snippets Groups Projects
Commit 49002611 authored by Kenneth Hiemstra's avatar Kenneth Hiemstra
Browse files

added SIGHUP signal to reload configfile, REGMAP

parent c4acd04a
No related branches found
No related tags found
No related merge requests found
...@@ -52,6 +52,9 @@ Common::Common(list<class Node*>& nodelist) ...@@ -52,6 +52,9 @@ Common::Common(list<class Node*>& nodelist)
Common::~Common() Common::~Common()
{ {
for(auto node : NODE) {
delete node;
}
} }
Node * Common::select_node(const int nr) Node * Common::select_node(const int nr)
......
...@@ -49,6 +49,7 @@ class TCPCSSocket { ...@@ -49,6 +49,7 @@ class TCPCSSocket {
TCPCSSocket(int descr = -1); TCPCSSocket(int descr = -1);
~TCPCSSocket(); ~TCPCSSocket();
void Shutdown() { shutdown(sock,SHUT_RDWR); } void Shutdown() { shutdown(sock,SHUT_RDWR); }
void Close() { close(sock); }
size_t rx(unsigned char* buf, size_t size) throw(const char*); size_t rx(unsigned char* buf, size_t size) throw(const char*);
size_t _rx(unsigned char* buf, size_t size) throw(const char*); size_t _rx(unsigned char* buf, size_t size) throw(const char*);
size_t tx(const unsigned char* data, size_t size) throw(const char*); size_t tx(const unsigned char* data, size_t size) throw(const char*);
......
...@@ -24,8 +24,10 @@ ...@@ -24,8 +24,10 @@
#include "ua_server.h" #include "ua_server.h"
extern volatile bool ServerRunning; extern volatile bool ServerRunning;
extern Serverdat SD;
UA_Server *mUaServer;
Serverdat *SD;
string p_termout(TermOutput& termout) string p_termout(TermOutput& termout)
{ {
...@@ -84,7 +86,7 @@ static UA_StatusCode UNB_MethodCallback(UA_Server *server, ...@@ -84,7 +86,7 @@ static UA_StatusCode UNB_MethodCallback(UA_Server *server,
cout <<"inputStr->data=" << inputStr->data <<endl; cout <<"inputStr->data=" << inputStr->data <<endl;
try { try {
SD->unb->read(termout,std::string((char *)inputStr->data),0,-1); // TODO: make read/write SD.unb->read(termout,std::string((char *)inputStr->data),0,-1); // TODO: make read/write
} catch(runtime_error& e) { } catch(runtime_error& e) {
cerr << "UNB_MethodCallback: " << e.what() << endl; cerr << "UNB_MethodCallback: " << e.what() << endl;
termout.strout << e.what(); termout.strout << e.what();
...@@ -137,28 +139,39 @@ static void add_UNB_Method(UA_Server *server, std::string regname) ...@@ -137,28 +139,39 @@ static void add_UNB_Method(UA_Server *server, std::string regname)
1, &inputArgument, 1, &outputArgument, NULL, NULL); 1, &inputArgument, 1, &outputArgument, NULL, NULL);
} }
int ua_server(Serverdat *sd) { // FIXME: test the SD.ready* lines first
int ua_server_init(void)
SD = sd; {
TermOutput termout; TermOutput termout;
std::vector<int> nodes = SD->unb->get_nodes(); // all nodes std::vector<int> nodes = SD.unb->get_nodes(); // all nodes
UA_Server *mUaServer = UA_Server_new();
UA_ServerConfig_setDefault(UA_Server_getConfig(mUaServer));
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "UA Server add nodes");
addVariable(mUaServer); addVariable(mUaServer);
for(auto node : nodes) { for(auto node : nodes) {
RegisterMap *regmap = SD->unb->get_RegisterMap(termout, node); RegisterMap *regmap = SD.unb->get_RegisterMap(termout, node);
std::string prefix = SD->unb->string_node_id(node); std::string prefix = SD.unb->string_node_id(node);
std::vector<std::string> regnames = regmap->getRegnames(prefix); std::vector<std::string> regnames = regmap->getRegnames(prefix);
for(auto m : regnames) { for(auto m : regnames) {
add_UNB_Method(mUaServer, m); add_UNB_Method(mUaServer, m);
} }
} }
return 0;
}
int ua_server_delete(void)
{
//UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "UA Server delete nodes");
return 0;
}
int ua_server(void)
{
mUaServer = UA_Server_new();
UA_ServerConfig_setDefault(UA_Server_getConfig(mUaServer));
ua_server_init();
UA_StatusCode retval = UA_Server_run(mUaServer, &ServerRunning); UA_StatusCode retval = UA_Server_run(mUaServer, &ServerRunning);
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
using namespace std; using namespace std;
int ua_server(Serverdat *sd); int ua_server_init(void);
int ua_server_delete(void);
int ua_server(void);
#endif // UA_SERVER_H #endif // UA_SERVER_H
...@@ -124,6 +124,7 @@ bool Periph_system::read_system_info(ostringstream& strs) ...@@ -124,6 +124,7 @@ bool Periph_system::read_system_info(ostringstream& strs)
(data & 0x000F0000) >> 16); strs << str; (data & 0x000F0000) >> 16); strs << str;
sprintf(str," Hardware version = %d\n", ((data & 0x00000300) >> 8)); strs << str; sprintf(str," Hardware version = %d\n", ((data & 0x00000300) >> 8)); strs << str;
return retval; return retval;
// FIXME: test if design_name is expected, otherwise reload REGMAP by calling function: raise(SIGHUP);
} }
bool Periph_system::mread(std::ostringstream& strs, const std::string addr, bool Periph_system::mread(std::ostringstream& strs, const std::string addr,
......
...@@ -49,6 +49,7 @@ namespace po = boost::program_options; ...@@ -49,6 +49,7 @@ namespace po = boost::program_options;
volatile bool ServerRunning = true; volatile bool ServerRunning = true;
int debug = 0; int debug = 0;
const char* SDPUNB_VERSION= " (testing) " __DATE__ " " __TIME__; const char* SDPUNB_VERSION= " (testing) " __DATE__ " " __TIME__;
Serverdat SD;
...@@ -64,15 +65,16 @@ string print_termout(TermOutput& termout) ...@@ -64,15 +65,16 @@ string print_termout(TermOutput& termout)
return s; return s;
} }
void control_server(TCPSSocket *sock, Serverdat *sd, const int clientId, std::atomic<size_t> *nthreads) void control_server(TCPSSocket *sock, const int clientId, std::atomic<size_t> *nthreads)
{ {
bool quit=false; bool quit=false;
while(ServerRunning) { while(ServerRunning) {
try { try {
sd->controlSocket[clientId] = new TCPCSSocket(sock->listen()); SD.ready_client[clientId] = true;
SD.controlSocket[clientId] = new TCPCSSocket(sock->listen());
string banner = "output={ SDP to Uniboard Translator " + string(SDPUNB_VERSION) string banner = "output={ SDP to Uniboard Translator " + string(SDPUNB_VERSION)
+ ". (use 'help' for available commands) }\n"; + ". (use 'help' for available commands) }\n";
sd->controlSocket[clientId]->tx((unsigned char *)banner.c_str(), strlen(banner.c_str())); SD.controlSocket[clientId]->tx((unsigned char *)banner.c_str(), strlen(banner.c_str()));
CMD Cmd; CMD Cmd;
string line; string line;
...@@ -85,9 +87,9 @@ void control_server(TCPSSocket *sock, Serverdat *sd, const int clientId, std::at ...@@ -85,9 +87,9 @@ void control_server(TCPSSocket *sock, Serverdat *sd, const int clientId, std::at
unsigned char tcpbuf[c_TCP_CONTROL_BUFFERSIZE]; unsigned char tcpbuf[c_TCP_CONTROL_BUFFERSIZE];
while(!quit) { while(!quit) {
string prompt = "sdpunb:" + cmdname + ":" + to_string(cmdstatus.status) + ":CMD>"; string prompt = "sdpunb:" + cmdname + ":" + to_string(cmdstatus.status) + ":CMD>";
sd->controlSocket[clientId]->tx((unsigned char *)prompt.c_str(), strlen(prompt.c_str())); SD.controlSocket[clientId]->tx((unsigned char *)prompt.c_str(), strlen(prompt.c_str()));
int len = sd->controlSocket[clientId]->rx(tcpbuf, c_TCP_CONTROL_BUFFERSIZE); int len = SD.controlSocket[clientId]->rx(tcpbuf, c_TCP_CONTROL_BUFFERSIZE);
if(len < 1) { if(len < 1) {
quit = true; quit = true;
} else { } else {
...@@ -97,33 +99,98 @@ void control_server(TCPSSocket *sock, Serverdat *sd, const int clientId, std::at ...@@ -97,33 +99,98 @@ void control_server(TCPSSocket *sock, Serverdat *sd, const int clientId, std::at
if (pos != string::npos) tcpbuf[pos] = 0; if (pos != string::npos) tcpbuf[pos] = 0;
pos = sbuf.find("\r"); pos = sbuf.find("\r");
if (pos != string::npos) tcpbuf[pos] = 0; if (pos != string::npos) tcpbuf[pos] = 0;
cmdstatusnew = Cmd.command(string((char *)tcpbuf), termout, cmdname, sd);
while(!SD.ready_init) { cout << "init not ready\n"; usleep(100000); }
SD.ready_client[clientId] = false;
cmdstatusnew = Cmd.command(string((char *)tcpbuf), termout, cmdname, &SD);
SD.ready_client[clientId] = true;
if(cmdstatusnew.status != CMD_EMPTY) cmdstatus = cmdstatusnew; if(cmdstatusnew.status != CMD_EMPTY) cmdstatus = cmdstatusnew;
string s = print_termout(termout); string s = print_termout(termout);
sd->controlSocket[clientId]->tx((unsigned char *)s.c_str(), strlen(s.c_str())); SD.controlSocket[clientId]->tx((unsigned char *)s.c_str(), strlen(s.c_str()));
termout.clear(); termout.clear();
if(cmdstatus.status == CMD_REQUEST_QUIT) { if(cmdstatus.status == CMD_REQUEST_QUIT) {
quit = true; quit = true;
} }
} }
} }
sd->controlSocket[clientId]->Shutdown(); SD.controlSocket[clientId]->Shutdown();
delete sd->controlSocket[clientId]; delete SD.controlSocket[clientId];
} catch(const char *str) { } catch(const char *str) {
delete sd->controlSocket[clientId]; delete SD.controlSocket[clientId];
} }
} }
(*nthreads)--; (*nthreads)--;
} }
// FIXME: find a way to 'disable interrupts'
void wait_for_clients_to_start_init(void)
{
for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) {
while(!SD.ready_client[c]) { cout << "client not ready\n"; usleep(100000); }
}
SD.ready_init = false;
}
void server_init(void)
{
ostringstream sstr;
list<class NODE_config> NC;
ifstream ifs;
cout << "Reading configfile: " << SD.configfile << endl;
ifs.open(SD.configfile.c_str());
if (!ifs.is_open()) {
syslog(LOG_ERR,"Error opening config file: %s (use --configfile=filename)\n",
SD.configfile.c_str());
throw runtime_error("Cannot open configfile: \""+SD.configfile+"\" (use --configfile=filename)");
} else {
if(!importdatfile(ifs, NC)) {
syslog(LOG_ERR,"Error reading config file: %s\n", SD.configfile.c_str());
throw runtime_error("Cannot read configfile: \""+SD.configfile+"\"");
}
}
cout << "Hint: follow the syslog: tail -f /var/log/localmessages" << endl;
wait_for_clients_to_start_init();
list<class Node*> nodelist;
for(auto nc : NC) {
uint gn = (uint)nc.gn;
uint uniboardnr = GLOBALNODE_to_UNB(gn);
uint n = GLOBALNODE_to_NODE(gn);
string type = GLOBALNODE_to_TYPE(gn);
Node *node = new Node(nc.ipaddr, uniboardnr, n, type, nc.firmware);
nodelist.push_back(node);
}
SD.unb = new UniboardMap(nodelist);
SD.ready_init = true;
}
void server_delete(void)
{
wait_for_clients_to_start_init();
delete SD.unb;
}
static void stopHandler(int signal) static void stopHandler(int signal)
{ {
cerr << "received ctrl-c" << endl; cerr << "received ctrl-c: exit" << endl;
ServerRunning = false; ServerRunning = false;
usleep(1000000); usleep(2000000);
exit(0); exit(0);
} }
static void hupHandler(int signal)
{
cerr << "received HUP signal: reload" << endl;
server_delete();
ua_server_delete();
server_init();
ua_server_init();
}
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
// defaults: // defaults:
...@@ -131,7 +198,7 @@ int main (int argc, char* argv[]) ...@@ -131,7 +198,7 @@ int main (int argc, char* argv[])
bool nodaemon = false; bool nodaemon = false;
int verbose = 1; int verbose = 1;
debug=0; debug=0;
string configfile = "/etc/uniboard.conf"; SD.configfile = "/etc/uniboard.conf";
std::atomic<size_t> ncthreads(0); std::atomic<size_t> ncthreads(0);
std::thread *control_server_thread[c_MAX_CONTROL_SERVERS]; std::thread *control_server_thread[c_MAX_CONTROL_SERVERS];
...@@ -146,7 +213,7 @@ int main (int argc, char* argv[]) ...@@ -146,7 +213,7 @@ int main (int argc, char* argv[])
"With this flag, the server runs NOT as daemon") "With this flag, the server runs NOT as daemon")
("debug", po::value(&debug), "Prints out debug info (default=0)") ("debug", po::value(&debug), "Prints out debug info (default=0)")
("verbose", po::value(&verbose), "More messages and infos") ("verbose", po::value(&verbose), "More messages and infos")
("configfile", po::value<string>(&configfile)->default_value(configfile), ("configfile", po::value<string>(&SD.configfile)->default_value(SD.configfile),
"Specify uniboard configuration file location") "Specify uniboard configuration file location")
; ;
...@@ -176,69 +243,40 @@ int main (int argc, char* argv[]) ...@@ -176,69 +243,40 @@ int main (int argc, char* argv[])
signal(SIGINT, stopHandler); signal(SIGINT, stopHandler);
//signal(SIGTERM, stopHandler); //signal(SIGTERM, stopHandler);
signal(SIGHUP, hupHandler);
try { try {
/* Open syslog connection */ /* Open syslog connection */
openlog(basename(argv[0]), 0, LOG_LOCAL0); openlog(basename(argv[0]), 0, LOG_LOCAL0);
syslog(LOG_INFO,"Starting server %s\n", SDPUNB_VERSION); syslog(LOG_INFO,"Starting server %s\n", SDPUNB_VERSION);
ostringstream sstr;
list<class NODE_config> NC;
ifstream ifs;
cout << "Reading configfile: " << configfile << endl;
ifs.open(configfile.c_str());
if (!ifs.is_open()) {
cerr << "Error opening config file: " << configfile << " (use --configfile=filename)" << endl;
syslog(LOG_ERR,"Error opening config file: %s (use --configfile=filename)\n",
configfile.c_str());
exit(EXIT_FAILURE);
} else {
if(!importdatfile(ifs, NC)) {
cerr << "Error reading config file: " << configfile << endl;
syslog(LOG_ERR,"Error reading config file: %s\n", configfile.c_str());
exit(EXIT_FAILURE);
}
}
cout << "Hint: follow the syslog: tail -f /var/log/localmessages" << endl;
list<class Node*> nodelist;
for(auto nc : NC) {
uint gn = (uint)nc.gn;
uint uniboardnr = GLOBALNODE_to_UNB(gn);
uint n = GLOBALNODE_to_NODE(gn);
string type = GLOBALNODE_to_TYPE(gn);
Node *node = new Node(nc.ipaddr, uniboardnr, n, type, nc.firmware);
nodelist.push_back(node);
}
if(!nodaemon) { if(!nodaemon) {
if(daemon(1, 0) < 0) cerr << "Error fork as daemon: " << strerror(errno) << endl; if(daemon(1, 0) < 0) cerr << "Error fork as daemon: " << strerror(errno) << endl;
} }
Serverdat control_server_dat;
control_server_dat.unb = new UniboardMap(nodelist);
for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) { for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) {
control_server_dat.tcpport = control_tcpport; SD.tcpport = control_tcpport;
control_server_dat.verbose[c] = verbose; SD.verbose[c] = verbose;
SD.ready_client[c] = true;
} }
server_init();
TCPSSocket sock(control_tcpport, "", c_MAX_CONTROL_SERVERS); TCPSSocket sock(control_tcpport, "", c_MAX_CONTROL_SERVERS);
for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) { for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) {
control_server_thread[c] = new std::thread(control_server, &sock, &control_server_dat, c, &ncthreads); control_server_thread[c] = new std::thread(control_server, &sock, c, &ncthreads);
++ncthreads; ++ncthreads;
} }
ua_server(&control_server_dat); ua_server();
for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) { control_server_thread[c]->join(); } for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) { control_server_thread[c]->join(); }
for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) { delete control_server_thread[c]; } for(uint c=0; c<c_MAX_CONTROL_SERVERS; c++) { delete control_server_thread[c]; }
for(auto node : nodelist) { delete node; }
closelog(); // close syslog connection closelog(); // close syslog connection
delete control_server_dat.unb; server_delete();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} catch(exception& e) { } catch(exception& e) {
......
...@@ -25,6 +25,7 @@ using namespace std; ...@@ -25,6 +25,7 @@ using namespace std;
#include <list> #include <list>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <atomic>
#include "map.h" #include "map.h"
#include "io/tcpsocket.h" #include "io/tcpsocket.h"
...@@ -40,6 +41,9 @@ public: ...@@ -40,6 +41,9 @@ public:
UniboardMap *unb; UniboardMap *unb;
struct timespec t0; struct timespec t0;
TCPCSSocket *controlSocket[c_MAX_CONTROL_SERVERS]; TCPCSSocket *controlSocket[c_MAX_CONTROL_SERVERS];
std::string configfile;
std::atomic<bool> ready_client[c_MAX_CONTROL_SERVERS];
std::atomic<bool> ready_init;
}; };
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment