...
 
Commits (3)
......@@ -100,83 +100,15 @@ CMDstatus CMD::command(string line, TermOutput& termout, string& cmdname, Server
*/
} else if(cmd == HELP) {
req_ret.status=CMD_STATUS_OK;
termout.strout << "Available commands:" << endl;
termout.strout << endl << "Available commands:" << endl;
for(uint i=0; i < supported_cmds.size(); i++) {
termout.strout << i << ". " << supported_cmds[i] << endl;
}
termout.strout << endl << "Server also supports '>' and '>>' and '|' operators like the Bash shell" << endl;
termout.strout << endl << "Syntax help: use option -h for each command" << endl;
} else if(cmd == QUIT) {
req_ret.status = CMD_REQUEST_QUIT;
}
/*
* Check if commandline contains '>' '>>' or '|'
*/
string fname="";
ofstream fd;
string pipecmd = "";
char **pipeargv = NULL;
for(uint i=0; i < argc; i++) {
if(argv[i][0] == '>') {
if(argv[i][1] == '>') { // >> =append to file
if(strlen(argv[i]) > 2) fname = &argv[i][2]; // >>filename
else {
i++;
if(i<argc && strlen(argv[i]) > 1) fname = argv[i]; // >> filename
}
if(fname != "") {
cout << "append to file: " << fname << endl;
fd.open (fname, std::ofstream::out | std::ofstream::app);
}
} else { // > =open new file
if(strlen(argv[i]) > 1) fname = &argv[i][1]; // >filename
else {
i++;
if(i<argc && strlen(argv[i]) > 1) fname = argv[i]; // > filename
}
if(fname != "") {
cout << "new file: " << fname << endl;
fd.open (fname, std::ofstream::out);
}
}
if(!fd) throw runtime_error("Cannot open file: \""+fname+"\"");
break;
} else if(argv[i][0] == '|') {
if(strlen(argv[i]) > 1) pipecmd = &argv[i][1]; // |command
else {
i++;
if(i<argc && strlen(argv[i]) > 1) pipecmd = argv[i]; // | command
}
// pass all args on this line to the pipecmd
pipeargv = new char* [argc-i+1];
pipeargv[0] = new char[pipecmd.size()+1];
strcpy(pipeargv[0], pipecmd.c_str());
int pai=1;
for(uint j=i+1; j< argc; j++) {
pipeargv[pai] = new char[strlen(argv[j])+1];
strcpy(pipeargv[pai], argv[j]);
pai++;
}
pipeargv[pai] = (char *)0;
break;
}
}
if(fname != "" && !fd.fail()) { // in case of a given: >file or >>file
// write streams strout to this file fd
fd << termout.strout.str();
fd.close();
} else if(pipecmd != "") { // in case of a given: |shell command
ostringstream strs_filter;
// pass stream strout to system command and replace strout with output of system command:
strs_filter << exec_system_cmd_rw(termout.strout.str(), pipecmd.c_str(), pipeargv);
termout.strout.str(""); termout.strout.clear();
termout.strout << strs_filter.str();
for(int i=0; (pipeargv[i] != (char *)0); i++) delete[] pipeargv[i];
delete[] pipeargv;
}
} catch(exception& e) {
termout.strerr << "Error: " << e.what() << endl;
}
......@@ -239,7 +171,7 @@ CMDstatus CMD::Info(int argc, char* argv[], TermOutput& termout, Serverdat *sd)
if(nodes.size()==0) throw runtime_error("missing file(s), add /unb.../pn...");
for(auto node : nodes) {
RegisterMap *regmap = sd->unb->get_RegisterMap(termout, node);
RegisterMap *regmap = sd->unb->get_RegisterMap(node);
std::string prefix = sd->unb->string_node_id(node);
std::vector<std::string> regnames = regmap->getRegnames_full(prefix);
......@@ -315,7 +247,7 @@ CMDstatus CMD::Mwrite(int argc, char* argv[], TermOutput& termout, Serverdat *sd
{
CMDstatus ret = {CMD_STATUS_ERROR,0,0};
po::options_description generic("Memory mapped write");
po::options_description generic("Generic write");
generic.add_options()
("help,h", "shows this help text")
("offs", po::value<uint>(),"offset from base address (per dword)")
......@@ -420,7 +352,6 @@ CMDstatus CMD::Reload(int argc, char* argv[], TermOutput& termout, Serverdat *sd
***********************/
bool CMD::supported_cmd(std::string cmd)
{
for(auto supported : supported_cmds) {
......@@ -429,57 +360,3 @@ bool CMD::supported_cmd(std::string cmd)
return false;
}
string CMD::exec_system_cmd_rw(const string input, const char* cmd, char *const argv[])
{
#define PIPE_READ 0
#define PIPE_WRITE 1
std::string result = "";
int pipe_stdin_fd[2];
int pipe_stdout_fd[2];
if(pipe(pipe_stdin_fd) == -1) throw runtime_error("pipe error");
if(pipe(pipe_stdout_fd) == -1) throw runtime_error("pipe error");
pid_t pid = fork();
if (pid == -1) {
throw runtime_error("fork error");
} else if (pid == 0) { // child
// redirect stdin
dup2(pipe_stdin_fd[PIPE_READ], STDIN_FILENO);
// redirect stdout
dup2(pipe_stdout_fd[PIPE_WRITE], STDOUT_FILENO);
// redirect stderr
dup2(pipe_stdout_fd[PIPE_WRITE], STDERR_FILENO);
// all these are for use by parent only
close(pipe_stdin_fd[PIPE_READ]);
close(pipe_stdin_fd[PIPE_WRITE]);
close(pipe_stdout_fd[PIPE_READ]);
close(pipe_stdout_fd[PIPE_WRITE]);
// run cmd now
execvp(cmd, argv);
// should not come here
exit(1);
} else { // parent
// close unused file descriptors, these are for child only
close(pipe_stdin_fd[PIPE_READ]);
close(pipe_stdout_fd[PIPE_WRITE]);
if(write(pipe_stdin_fd[PIPE_WRITE], input.c_str(), input.size()) < 0) {
cerr << "Error write pipe: " << strerror(errno) << endl;
}
close(pipe_stdin_fd[PIPE_WRITE]); // must close otherwise 'execlp' blocks and waits for EOF
char c;
while(read(pipe_stdout_fd[PIPE_READ], &c, 1)==1)
result = result + c;
close(pipe_stdout_fd[PIPE_READ]);
}
return result;
}
......@@ -58,7 +58,6 @@ private:
std::vector<std::string> supported_cmds;
std::list<std::string> cmd_history;
string exec_system_cmd_rw(const string input, const char* cmd, char *const argv[]);
// (3)
CMDstatus Info(int argc, char* argv[], TermOutput& termout, Serverdat *sd);
......
......@@ -92,10 +92,10 @@ std::vector<int> Common::get_nodes(void)
return nodes;
}
RegisterMap * Common::get_RegisterMap(TermOutput& termout, int node)
RegisterMap * Common::get_RegisterMap(int node)
{
auto n = select_node(node);
return n->get_RegisterMap(termout.strout);
return n->get_RegisterMap();
}
bool Common::monitor(TermOutput& termout)
......@@ -103,12 +103,12 @@ bool Common::monitor(TermOutput& termout)
bool retval=false;
uint retcnt=0;
std::vector<int> nodes = get_nodes();
termout.strout << "[";
for(uint idx=0;idx<nodes.size();idx++) {
auto node = select_node(nodes[idx]);
print_node_id(termout.strout,node);
uint node_nr = node_number(node);
if(idx > 0) termout.strout << ",";
termout.strout << "[";
termout.strout << "(" << node_nr << ",0,[";
try {
if(node->cread(termout.strout, "system")) {
retcnt++;
......@@ -116,8 +116,9 @@ bool Common::monitor(TermOutput& termout)
} catch(std::exception& e) {
termout.strerr << e.what() << endl;
}
termout.strout << "]";
termout.strout << "])";
}
termout.strout << "]";
retval = (retcnt==nodes.size());
return retval;
}
......@@ -125,39 +126,44 @@ bool Common::monitor(TermOutput& termout)
bool Common::read(TermOutput& termout, const string addr, const uint offs, const int len)
{
bool retval=false;
bool ret, retval = false;
uint retcnt=0;
std::vector<int> nodes = path_to_node(addr);
std::string relative_addr = addr_to_relative_addr(addr);
std::string type = addr_to_type(addr);
std::string peripheral = addr_to_peripheral(addr);
ostringstream strs;
termout.strout << "[";
for(uint idx=0;idx<nodes.size();idx++) {
auto node = select_node(nodes[idx]);
//print_node_id(termout.strout,node);
uint node_nr = node_number(node);
if(idx > 0) termout.strout << ",";
termout.strout << "(" << node_nr << ",0,";
if(type == "mm") {
RegisterMap *regmap = node->get_RegisterMap(termout.strout);
uint32_t nvalues = (len<0 ? regmap->getSpan(relative_addr) : len);
std::vector<int> datavec;
if(node->mread(termout.strout, relative_addr, offs, datavec, nvalues)) {
retcnt++;
}
} else if(type == "dev") {
if(node->cread(termout.strout, peripheral)) {
retcnt++;
strs.str(""); strs.clear();
ret = false;
try {
if(type == "mm") {
RegisterMap *regmap = node->get_RegisterMap();
uint32_t nvalues = (len<0 ? regmap->getSpan(relative_addr) : len);
std::vector<int> datavec;
if((ret=node->mread(strs, relative_addr, offs, datavec, nvalues))) {
retcnt++;
}
} else if(type == "dev") {
if((ret=node->cread(strs, peripheral))) {
retcnt++;
} else {
termout.strerr << "no such peripheral: " << peripheral;
}
} else {
termout.strerr << "no such peripheral: " << peripheral;
termout.strerr << "no such type: " << type;
}
} else {
termout.strerr << "no such type: " << type;
} catch(std::exception& e) {
termout.strerr << e.what() << endl;
}
termout.strout << ")";
termout.strout << "(" << node_nr << (ret ? ",0,[" : ",1,[") << strs.str() << "])";
}
termout.strout << "]";
retval = (retcnt==nodes.size());
......@@ -171,7 +177,7 @@ bool Common::read(TermOutput& termout, const string addr, const uint offs, const
bool Common::write(TermOutput& termout, const string addr,
const uint offs, const std::vector<int>& data)
{
bool retval = false;
bool ret, retval = false;
uint retcnt = 0;
std::vector<int> nodes = path_to_node(addr);
......@@ -182,25 +188,29 @@ bool Common::write(TermOutput& termout, const string addr,
termout.strout << "[";
for(uint idx = 0; idx<nodes.size(); idx++) {
auto node = select_node(nodes[idx]);
//print_node_id(termout.strout, node);
uint node_nr = node_number(node);
if(idx > 0) termout.strout << ",";
termout.strout << "(" << node_nr << ",0,";
if(type == "mm") {
if(node->mwrite(termout.strout, addr, offs, data)) retcnt++;
} else if(type == "dev") {
if(node->cwrite(termout.strout, peripheral)) {
retcnt++;
ret = false;
try {
if(type == "mm") {
if((ret=node->mwrite(relative_addr, offs, data))) retcnt++;
} else if(type == "dev") {
if((ret=node->cwrite(peripheral))) {
retcnt++;
} else {
termout.strerr << "no such peripheral: " << peripheral;
}
} else {
termout.strerr << "no such peripheral: " << peripheral;
termout.strerr << "no such type: " << type;
}
} else {
termout.strerr << "no such type: " << type;
} catch(std::exception& e) {
termout.strerr << e.what() << endl;
}
termout.strout << ")";
termout.strout << "(" << node_nr << "," << (ret ? "0)" : "1)");
}
termout.strout << "]";
retval = (retcnt==nodes.size());
if(nodes.size() == 0) {
termout.strerr << "no nodes";
......
......@@ -59,7 +59,7 @@ public:
std::vector<int> unb_pn__to__nodes(std::vector<int> unbs, std::vector<int> pns);
uint ipaddr_to_id(const string ipaddr);
RegisterMap * get_RegisterMap(TermOutput& termout, int node);
RegisterMap * get_RegisterMap(int node);
std::string string_node_id(int node);
......
......@@ -82,12 +82,12 @@ bool Node::cread(ostringstream& strs,const string peripheral) {
else return false;
}
bool Node::cwrite(ostringstream& strs,const string peripheral) {
strs << "cwrite() not yet implemented TODO";
bool Node::cwrite(const string peripheral) {
cerr << "cwrite() not yet implemented TODO";
return false;
}
RegisterMap * Node::get_RegisterMap(std::ostringstream& strs)
RegisterMap * Node::get_RegisterMap(void)
{
return periph_system->getRegisterMap();
}
......@@ -97,8 +97,8 @@ bool Node::mread(std::ostringstream& strs,const std::string addr, const uint off
std::vector<int>& data, const uint len) {
return periph_system->mread(strs, addr, offs, data, len);
}
bool Node::mwrite(std::ostringstream& strs,const std::string addr, const uint offs,
bool Node::mwrite(const std::string addr, const uint offs,
const std::vector<int>& data) {
return periph_system->mwrite(strs, addr, offs, data);
return periph_system->mwrite(addr, offs, data);
}
......@@ -83,13 +83,13 @@ class Node {
const std::string GetType() { return Type; }
bool cread(std::ostringstream& strs, const std::string peripheral);
bool cwrite(std::ostringstream& strs, const std::string peripheral);
bool cwrite(const std::string peripheral);
bool mread(std::ostringstream& strs,const std::string addr, const uint offs,
std::vector<int>& data, const uint len);
bool mwrite(std::ostringstream& strs,const std::string addr, const uint offs,
bool mwrite(const std::string addr, const uint offs,
const std::vector<int>& data);
RegisterMap * get_RegisterMap(std::ostringstream& strs);
RegisterMap * get_RegisterMap(void);
};
#endif /* NODE_H */
......@@ -155,7 +155,7 @@ int ua_server_init(bool warm_start)
addVariable(mUaServer);
for(auto node : nodes) {
RegisterMap *regmap = SD.unb->get_RegisterMap(termout, node);
RegisterMap *regmap = SD.unb->get_RegisterMap(node);
std::string prefix = SD.unb->string_node_id(node);
std::vector<std::string> regnames = regmap->getRegnames(prefix);
......
......@@ -126,15 +126,13 @@ bool Periph_system::read_system_info(ostringstream& strs)
uint32_t data;
bool retval = Read("mm/system/info/info",0,1,&data);
std::string design_name = read_design_name();
strs << "Design name = " << design_name << endl;
strs << "design_name=" << design_name << ", ";
char str[1000];
// FIXME: get rid of magic constants in masks, should be in CCFG:
uint firmware_version = (data & 0x00F00000) >> 20;
uint firmware_subversion = (data & 0x000F0000) >> 16;
uint hardware_version = (data & 0x00000300) >> 8;
sprintf(str,"Firmware version = %d.%d\n",firmware_version,firmware_subversion); strs << str;
sprintf(str,"Hardware version = %d\n",hardware_version); strs << str;
sprintf(str,"fw_version=%d.%d",firmware_version,firmware_subversion); strs << str;
if(design_name == my_expected_design_name && firmware_version >= my_expected_firmware_version) {
my_current_status = "online";
......@@ -163,32 +161,24 @@ bool Periph_system::mread(std::ostringstream& strs, const std::string addr,
bool retval = Read(addr,offs,nvalues,data);
if(retval) {
datavec.resize(nvalues);
strs << "[";
for(uint i=0; i < nvalues; i++) {
if(i>0) strs << ",";
//strs << hex << "0x" << data[i] << dec;
strs << data[i];
datavec[i] = data[i];
}
strs << "]";// << endl;
}
delete[] data;
return retval;
}
bool Periph_system::mwrite(std::ostringstream& strs, const std::string addr,
bool Periph_system::mwrite(const std::string addr,
const uint offs, const std::vector<int>& datavec)
{
uint32_t *data = new uint32_t[datavec.size()*sizeof(uint32_t)];
strs << "[";
for(uint i = 0;i < datavec.size(); i++) {
if(i>0) strs << ",";
//strs << hex << "0x" << datavec[i] << dec;
strs << datavec[i];
data[i] = (uint32_t)datavec[i];
}
strs << "]";// << endl;
bool retval = Write(addr, offs, 1, data);
bool retval = Write(addr, offs, datavec.size(), data);
delete[] data;
return retval;
}
......
......@@ -44,7 +44,7 @@ public:
bool read_system_info(std::ostringstream& strs);
bool mread(std::ostringstream& strs, const std::string addr, const uint offs,
std::vector<int>& data, const uint len);
bool mwrite(std::ostringstream& strs, const std::string addr, const uint offs,
bool mwrite(const std::string addr, const uint offs,
const std::vector<int>& data);
std::string read_design_name(void);
std::string read_design_note(void);
......