2020-04-03 09:58:19 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 2020 Fredrik Öhrström
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include<curses.h>
|
|
|
|
#include<menu.h>
|
|
|
|
#include<string.h>
|
|
|
|
#include<stdio.h>
|
|
|
|
#include<stdlib.h>
|
2020-06-29 14:35:58 +00:00
|
|
|
#include <syslog.h>
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
#include"serial.h"
|
2020-05-30 16:45:29 +00:00
|
|
|
#include"shell.h"
|
2020-05-09 19:56:37 +00:00
|
|
|
#include"wmbus.h"
|
|
|
|
|
2020-04-03 09:58:19 +00:00
|
|
|
#define BG_PAIR 1
|
|
|
|
#define WIN_PAIR 2
|
|
|
|
#define TITLE_PAIR 3
|
|
|
|
#define HILIGHT_PAIR 4
|
|
|
|
|
|
|
|
#include <menu.h>
|
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
bool running_as_root_ = false;
|
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
#define LIST_OF_MAIN_MENU \
|
2020-06-29 14:35:58 +00:00
|
|
|
X(DETECT_WMBUS_RECEIVERS, "Detect wmbus receiver") \
|
|
|
|
X(RESET_WMBUS_RECEIVERS, "Reset wmbus receiver") \
|
2020-05-09 19:56:37 +00:00
|
|
|
X(LISTEN_FOR_METERS, "Listen for meters") \
|
|
|
|
X(EDIT_CONFIG, "Edit config") \
|
|
|
|
X(EDIT_METERS, "Edit meters") \
|
|
|
|
X(STOP_DAEMON, "Stop daemon") \
|
|
|
|
X(START_DAEMON, "Start daemon") \
|
|
|
|
X(EXIT_ADMIN, "Exit")
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
enum class MainMenuType {
|
|
|
|
#define X(name,description) name,
|
|
|
|
LIST_OF_MAIN_MENU
|
|
|
|
#undef X
|
|
|
|
};
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
const char *main_menu[] = {
|
|
|
|
#define X(name,description) description,
|
|
|
|
LIST_OF_MAIN_MENU
|
|
|
|
#undef X
|
|
|
|
(char *)NULL,
|
|
|
|
};
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
#define LIST_OF_WMBUS_RECEIVERS \
|
|
|
|
X(AMB8465, "amb8465") \
|
|
|
|
X(CUL, "cul") \
|
|
|
|
X(IM871A, "im871a")
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
enum class ReceiversType {
|
|
|
|
#define X(name,description) name,
|
|
|
|
LIST_OF_WMBUS_RECEIVERS
|
|
|
|
#undef X
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *receivers_menu[] = {
|
|
|
|
#define X(name,description) description,
|
|
|
|
LIST_OF_WMBUS_RECEIVERS
|
|
|
|
#undef X
|
|
|
|
(char *)NULL,
|
|
|
|
};
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
bool detectIfRoot();
|
|
|
|
void detectProcesses(string cmd, vector<int> *pids);
|
2020-06-29 14:35:58 +00:00
|
|
|
void detectWMBUSReceiver();
|
|
|
|
void resetWMBUSReceiver();
|
2020-05-09 19:56:37 +00:00
|
|
|
void probeFor(string type, AccessCheck(*func)(string,SerialCommunicationManager*));
|
|
|
|
|
|
|
|
void printAt(WINDOW *win, int y, int x, const char *str, chtype color);
|
|
|
|
void printMiddle(WINDOW *win, int y, int width, const char *str, chtype color);
|
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
void alwaysOnScreen();
|
2020-05-09 19:56:37 +00:00
|
|
|
int selectFromMenu(const char *title, const char *menu[]);
|
2020-06-29 14:35:58 +00:00
|
|
|
int selectFromMenu(const char *title, vector<string> menu);
|
2020-05-30 16:45:29 +00:00
|
|
|
void displayInformationAndWait(string title, vector<string> entries, int px=-1, int py=-1);
|
|
|
|
void displayInformationNoWait(WINDOW **win, string title, vector<string> entries, int px=-1, int py=-1);
|
2020-05-25 17:05:45 +00:00
|
|
|
|
2020-06-29 14:35:58 +00:00
|
|
|
void notImplementedYet(string msg);
|
|
|
|
|
2020-05-25 17:05:45 +00:00
|
|
|
int screen_width, screen_height;
|
|
|
|
unique_ptr<SerialCommunicationManager> handler;
|
2020-05-09 19:56:37 +00:00
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
WINDOW *status_window;
|
|
|
|
WINDOW *serial_ports_window;
|
|
|
|
WINDOW *processes_window;
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
2020-05-09 19:56:37 +00:00
|
|
|
{
|
2020-05-30 16:45:29 +00:00
|
|
|
if (argc == 2 && !strcmp(argv[1], "--debug"))
|
|
|
|
{
|
|
|
|
debugEnabled(true);
|
2020-06-29 14:35:58 +00:00
|
|
|
setlogmask(LOG_UPTO (LOG_INFO));
|
|
|
|
openlog("wmbusmeters-admin", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
|
|
|
|
enableSyslog();
|
2020-05-30 16:45:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
running_as_root_ = detectIfRoot();
|
|
|
|
|
2020-05-25 17:05:45 +00:00
|
|
|
handler = createSerialCommunicationManager(0, 0, false);
|
|
|
|
|
2020-04-03 09:58:19 +00:00
|
|
|
initscr();
|
2020-05-09 19:56:37 +00:00
|
|
|
getmaxyx(stdscr, screen_height, screen_width);
|
2020-04-03 09:58:19 +00:00
|
|
|
start_color();
|
|
|
|
cbreak();
|
|
|
|
curs_set(0);
|
|
|
|
noecho();
|
|
|
|
keypad(stdscr, TRUE);
|
|
|
|
|
|
|
|
init_pair(BG_PAIR, COLOR_WHITE, COLOR_BLUE);
|
|
|
|
init_pair(WIN_PAIR, COLOR_BLACK, COLOR_WHITE);
|
|
|
|
init_pair(TITLE_PAIR, COLOR_WHITE, COLOR_CYAN);
|
|
|
|
init_pair(HILIGHT_PAIR, COLOR_WHITE, COLOR_RED);
|
|
|
|
wbkgd(stdscr, COLOR_PAIR(BG_PAIR));
|
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
bool running = true;
|
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
alwaysOnScreen();
|
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
int c = selectFromMenu("wmbusmeters admin", main_menu);
|
|
|
|
|
|
|
|
switch (static_cast<MainMenuType>(c))
|
|
|
|
{
|
|
|
|
case MainMenuType::DETECT_WMBUS_RECEIVERS:
|
2020-06-29 14:35:58 +00:00
|
|
|
detectWMBUSReceiver();
|
|
|
|
break;
|
|
|
|
case MainMenuType::RESET_WMBUS_RECEIVERS:
|
|
|
|
resetWMBUSReceiver();
|
2020-05-09 19:56:37 +00:00
|
|
|
break;
|
|
|
|
case MainMenuType::LISTEN_FOR_METERS:
|
2020-06-29 14:35:58 +00:00
|
|
|
notImplementedYet("Listen for meters");
|
2020-05-09 19:56:37 +00:00
|
|
|
break;
|
|
|
|
case MainMenuType::EDIT_CONFIG:
|
2020-06-29 14:35:58 +00:00
|
|
|
notImplementedYet("Edit config");
|
2020-05-09 19:56:37 +00:00
|
|
|
break;
|
|
|
|
case MainMenuType::EDIT_METERS:
|
2020-06-29 14:35:58 +00:00
|
|
|
notImplementedYet("Edit meters");
|
2020-05-09 19:56:37 +00:00
|
|
|
break;
|
|
|
|
case MainMenuType::STOP_DAEMON:
|
2020-06-29 14:35:58 +00:00
|
|
|
notImplementedYet("Stop daemon");
|
2020-05-09 19:56:37 +00:00
|
|
|
break;
|
|
|
|
case MainMenuType::START_DAEMON:
|
2020-06-29 14:35:58 +00:00
|
|
|
notImplementedYet("Start daemon");
|
2020-05-09 19:56:37 +00:00
|
|
|
break;
|
|
|
|
case MainMenuType::EXIT_ADMIN:
|
|
|
|
running = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (running);
|
|
|
|
|
|
|
|
|
|
|
|
endwin();
|
|
|
|
}
|
|
|
|
|
|
|
|
void printAt(WINDOW *win, int y, int x, const char *str, chtype color)
|
|
|
|
{
|
|
|
|
wattron(win, color);
|
|
|
|
mvwprintw(win, y, x, "%s", str);
|
|
|
|
wattroff(win, color);
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
void printMiddle(WINDOW *win, int y, int width, const char *str, chtype color)
|
|
|
|
{
|
|
|
|
int len = strlen(str);
|
|
|
|
int wh, ww;
|
|
|
|
|
|
|
|
getyx(win, wh, ww);
|
|
|
|
((void)wh);
|
|
|
|
|
|
|
|
int x = (width-len)/2;
|
|
|
|
wattron(win, color);
|
|
|
|
mvwprintw(win, y, x, "%s", str);
|
|
|
|
wattroff(win, color);
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
int countEntries(const char *entries[])
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
for (; entries[i] != 0; ++i);
|
|
|
|
return i+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int maxWidth(const char *entries[])
|
|
|
|
{
|
|
|
|
int max = 0;
|
|
|
|
for (int i=0; entries[i] != 0; ++i)
|
|
|
|
{
|
|
|
|
int n = strlen(entries[i]);
|
|
|
|
if (max < n) max = n;
|
|
|
|
}
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
|
|
|
|
int maxWidth(vector<string> entries)
|
|
|
|
{
|
|
|
|
int max = 0;
|
|
|
|
for (string& s : entries)
|
|
|
|
{
|
|
|
|
int n = s.length();
|
|
|
|
if (max < n) max = n;
|
|
|
|
}
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
void alwaysOnScreen()
|
2020-05-25 17:05:45 +00:00
|
|
|
{
|
2020-05-30 17:12:05 +00:00
|
|
|
static uchar ticktock = 0;
|
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
vector<string> info;
|
2020-05-30 17:12:05 +00:00
|
|
|
ticktock++;
|
2020-05-30 16:45:29 +00:00
|
|
|
|
|
|
|
if (running_as_root_ == false)
|
|
|
|
{
|
|
|
|
info.push_back("Not running as root!");
|
|
|
|
info.push_back("Limited functionality.");
|
|
|
|
info.push_back("----------------------");
|
|
|
|
}
|
|
|
|
vector<int> daemons;
|
|
|
|
detectProcesses("wmbusmetersd", &daemons);
|
|
|
|
if (daemons.size() == 0)
|
|
|
|
{
|
|
|
|
info.push_back("No daemons running.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i : daemons)
|
|
|
|
{
|
|
|
|
info.push_back("Daemon "+to_string(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vector<int> processes;
|
|
|
|
detectProcesses("wmbusmeters", &processes);
|
|
|
|
|
|
|
|
if (processes.size() == 0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i : processes)
|
|
|
|
{
|
|
|
|
info.push_back("Process "+to_string(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-30 17:12:05 +00:00
|
|
|
displayInformationNoWait(&status_window, (ticktock%2==0)?"Status ":"Status.", info, 1, 1);
|
2020-05-30 16:45:29 +00:00
|
|
|
|
2020-05-25 17:05:45 +00:00
|
|
|
vector<string> devices = handler->listSerialDevices();
|
2020-05-30 16:45:29 +00:00
|
|
|
if (devices.size() == 0)
|
|
|
|
{
|
|
|
|
devices.push_back("No serial ports found!");
|
|
|
|
}
|
|
|
|
//info.insert(info.end(), devices.begin(), devices.end());
|
|
|
|
|
|
|
|
displayInformationNoWait(&serial_ports_window, "Serial ports", devices, 1, 15);
|
|
|
|
|
|
|
|
erase();
|
|
|
|
redrawwin(status_window);
|
|
|
|
redrawwin(serial_ports_window);
|
2020-05-25 17:05:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
int selectFromMenu(const char *title, const char *entries[])
|
2020-06-29 14:35:58 +00:00
|
|
|
{
|
|
|
|
vector<string> menu;
|
|
|
|
int n_choices = countEntries(entries);
|
|
|
|
|
|
|
|
for (int i=0; i<n_choices; ++i)
|
|
|
|
{
|
|
|
|
if (entries[i] == NULL) break;
|
|
|
|
menu.push_back(entries[i]);
|
|
|
|
}
|
|
|
|
return selectFromMenu(title, menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
int selectFromMenu(const char *title, vector<string> entries)
|
2020-05-09 19:56:37 +00:00
|
|
|
{
|
|
|
|
int selected = -1;
|
|
|
|
ITEM **menu_items;
|
|
|
|
int c;
|
|
|
|
MENU *menu;
|
|
|
|
WINDOW *frame_window, *menu_window;
|
|
|
|
int n_choices, i;
|
|
|
|
|
2020-06-29 14:35:58 +00:00
|
|
|
n_choices = entries.size()+1;
|
2020-05-09 19:56:37 +00:00
|
|
|
menu_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
|
2020-06-29 14:35:58 +00:00
|
|
|
for(i = 0; i < n_choices-1; ++i)
|
2020-04-03 09:58:19 +00:00
|
|
|
{
|
2020-06-29 14:35:58 +00:00
|
|
|
menu_items[i] = new_item(entries[i].c_str(), NULL);
|
2020-05-09 19:56:37 +00:00
|
|
|
}
|
2020-06-29 14:35:58 +00:00
|
|
|
menu_items[n_choices-1] = NULL;
|
2020-05-09 19:56:37 +00:00
|
|
|
|
|
|
|
menu = new_menu(menu_items);
|
|
|
|
int mw = 0;
|
|
|
|
int mh = 0;
|
|
|
|
scale_menu(menu, &mh, &mw);
|
|
|
|
int w = mw+2;
|
|
|
|
int h = mh+4;
|
|
|
|
if (w-2 < (int)strlen(title))
|
|
|
|
{
|
|
|
|
w = (int)strlen(title)+2;
|
2020-04-03 09:58:19 +00:00
|
|
|
}
|
2020-05-09 19:56:37 +00:00
|
|
|
int x = screen_width/2-w/2;
|
|
|
|
int y = screen_height/2-h/2;
|
|
|
|
frame_window = newwin(h, w, y, x);
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
int mx = (w-mw)/2;
|
|
|
|
int my = 3;
|
|
|
|
menu_window = derwin(frame_window, mh, mw, my, mx);
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
set_menu_fore(menu, COLOR_PAIR(HILIGHT_PAIR));
|
|
|
|
set_menu_back(menu, COLOR_PAIR(WIN_PAIR));
|
|
|
|
set_menu_grey(menu, COLOR_PAIR(3));
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
keypad(frame_window, TRUE);
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
set_menu_win(menu, frame_window);
|
|
|
|
set_menu_sub(menu, menu_window);
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
set_menu_mark(menu, ">");
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
box(frame_window, 0, 0);
|
|
|
|
wbkgd(frame_window, COLOR_PAIR(WIN_PAIR));
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
printMiddle(frame_window, 1, w, title, COLOR_PAIR(WIN_PAIR));
|
|
|
|
mvwaddch(frame_window, 2, 0, ACS_LTEE);
|
|
|
|
mvwhline(frame_window, 2, 1, ACS_HLINE, 38);
|
|
|
|
mvwaddch(frame_window, 2, w-1, ACS_RTEE);
|
2020-04-03 09:58:19 +00:00
|
|
|
refresh();
|
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
post_menu(menu);
|
|
|
|
wrefresh(frame_window);
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
alwaysOnScreen();
|
|
|
|
|
2020-05-25 17:05:45 +00:00
|
|
|
wtimeout(frame_window, 1000);
|
|
|
|
|
2020-04-03 09:58:19 +00:00
|
|
|
bool running = true;
|
|
|
|
do
|
|
|
|
{
|
2020-05-09 19:56:37 +00:00
|
|
|
c = wgetch(frame_window);
|
|
|
|
ITEM *cur = current_item(menu);
|
|
|
|
selected = item_index(cur);
|
2020-04-03 09:58:19 +00:00
|
|
|
switch(c)
|
|
|
|
{
|
2020-05-25 17:05:45 +00:00
|
|
|
case ERR:
|
2020-05-30 16:45:29 +00:00
|
|
|
alwaysOnScreen();
|
|
|
|
redrawwin(frame_window);
|
2020-05-25 17:05:45 +00:00
|
|
|
break;
|
2020-04-03 09:58:19 +00:00
|
|
|
case KEY_DOWN:
|
2020-05-09 19:56:37 +00:00
|
|
|
if (selected < n_choices-2)
|
|
|
|
{
|
|
|
|
menu_driver(menu, REQ_DOWN_ITEM);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
menu_driver(menu, REQ_FIRST_ITEM);
|
|
|
|
}
|
2020-04-03 09:58:19 +00:00
|
|
|
break;
|
|
|
|
case KEY_UP:
|
2020-05-09 19:56:37 +00:00
|
|
|
if (selected > 0)
|
|
|
|
{
|
|
|
|
menu_driver(menu, REQ_UP_ITEM);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
menu_driver(menu, REQ_LAST_ITEM);
|
|
|
|
}
|
2020-04-03 09:58:19 +00:00
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
running = false;
|
|
|
|
break;
|
|
|
|
}
|
2020-05-09 19:56:37 +00:00
|
|
|
wrefresh(frame_window);
|
2020-04-03 09:58:19 +00:00
|
|
|
} while (running);
|
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
unpost_menu(menu);
|
|
|
|
free_menu(menu);
|
|
|
|
delwin(frame_window);
|
|
|
|
erase();
|
|
|
|
refresh();
|
2020-04-03 09:58:19 +00:00
|
|
|
for(i = 0; i < n_choices; ++i)
|
|
|
|
{
|
2020-05-09 19:56:37 +00:00
|
|
|
free_item(menu_items[i]);
|
2020-04-03 09:58:19 +00:00
|
|
|
}
|
2020-05-09 19:56:37 +00:00
|
|
|
|
|
|
|
return selected;
|
2020-04-03 09:58:19 +00:00
|
|
|
}
|
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
void displayInformationAndWait(string title, vector<string> entries, int px, int py)
|
2020-04-03 09:58:19 +00:00
|
|
|
{
|
2020-05-09 19:56:37 +00:00
|
|
|
WINDOW *frame_window;
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
alwaysOnScreen();
|
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
int mw = maxWidth(entries)+1;
|
|
|
|
int mh = entries.size();
|
|
|
|
int w = mw+2;
|
|
|
|
int h = mh+4;
|
|
|
|
if (w-2 < (int)title.length())
|
2020-04-03 09:58:19 +00:00
|
|
|
{
|
2020-05-09 19:56:37 +00:00
|
|
|
w = (int)title.length()+2;
|
2020-04-03 09:58:19 +00:00
|
|
|
}
|
2020-05-09 19:56:37 +00:00
|
|
|
int x = screen_width/2-w/2;
|
|
|
|
int y = screen_height/2-h/2;
|
2020-05-25 17:05:45 +00:00
|
|
|
if (px != -1)
|
|
|
|
{
|
|
|
|
x = px;
|
|
|
|
}
|
|
|
|
if (py != -1)
|
|
|
|
{
|
|
|
|
y = py;
|
|
|
|
}
|
2020-05-09 19:56:37 +00:00
|
|
|
frame_window = newwin(h, w, y, x);
|
|
|
|
|
|
|
|
keypad(frame_window, TRUE);
|
|
|
|
|
|
|
|
box(frame_window, 0, 0);
|
|
|
|
wbkgd(frame_window, COLOR_PAIR(WIN_PAIR));
|
|
|
|
|
|
|
|
printMiddle(frame_window, 1, w, title.c_str(), COLOR_PAIR(WIN_PAIR));
|
|
|
|
mvwaddch(frame_window, 2, 0, ACS_LTEE);
|
|
|
|
mvwhline(frame_window, 2, 1, ACS_HLINE, 38);
|
|
|
|
mvwaddch(frame_window, 2, w-1, ACS_RTEE);
|
2020-05-30 16:45:29 +00:00
|
|
|
//refresh();
|
2020-05-09 19:56:37 +00:00
|
|
|
|
|
|
|
int r = 3;
|
|
|
|
for (string e : entries)
|
2020-04-03 09:58:19 +00:00
|
|
|
{
|
2020-05-09 19:56:37 +00:00
|
|
|
printAt(frame_window, r, 1, e.c_str(), COLOR_PAIR(WIN_PAIR));
|
|
|
|
r++;
|
2020-04-03 09:58:19 +00:00
|
|
|
}
|
2020-05-09 19:56:37 +00:00
|
|
|
wrefresh(frame_window);
|
2020-05-30 16:45:29 +00:00
|
|
|
wtimeout(frame_window, 1000);
|
2020-05-09 19:56:37 +00:00
|
|
|
|
|
|
|
bool running = true;
|
|
|
|
do
|
2020-04-03 09:58:19 +00:00
|
|
|
{
|
2020-05-09 19:56:37 +00:00
|
|
|
int c = wgetch(frame_window);
|
|
|
|
switch(c)
|
|
|
|
{
|
2020-05-30 16:45:29 +00:00
|
|
|
case ERR:
|
|
|
|
alwaysOnScreen();
|
|
|
|
redrawwin(frame_window);
|
|
|
|
break;
|
2020-05-09 19:56:37 +00:00
|
|
|
case 27:
|
|
|
|
case '\n':
|
|
|
|
running = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
wrefresh(frame_window);
|
|
|
|
} while (running);
|
|
|
|
|
|
|
|
delwin(frame_window);
|
|
|
|
erase();
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
2020-05-30 16:45:29 +00:00
|
|
|
void displayInformationNoWait(WINDOW **winp, string title, vector<string> entries, int px, int py)
|
|
|
|
{
|
|
|
|
WINDOW *win = *winp;
|
|
|
|
|
|
|
|
if (win != NULL)
|
|
|
|
{
|
|
|
|
delwin(win);
|
|
|
|
*winp = NULL;
|
|
|
|
}
|
|
|
|
int mw = maxWidth(entries)+1;
|
|
|
|
int mh = entries.size();
|
|
|
|
int w = mw+2;
|
|
|
|
int h = mh+4;
|
|
|
|
if (w-2 < (int)title.length())
|
|
|
|
{
|
|
|
|
w = (int)title.length()+2;
|
|
|
|
}
|
|
|
|
int x = screen_width/2-w/2;
|
|
|
|
int y = screen_height/2-h/2;
|
|
|
|
if (px != -1)
|
|
|
|
{
|
|
|
|
x = px;
|
|
|
|
}
|
|
|
|
if (py != -1)
|
|
|
|
{
|
|
|
|
y = py;
|
|
|
|
}
|
|
|
|
win = newwin(h, w, y, x);
|
|
|
|
*winp = win;
|
|
|
|
|
|
|
|
box(win, 0, 0);
|
|
|
|
wbkgd(win, COLOR_PAIR(WIN_PAIR));
|
|
|
|
|
|
|
|
printMiddle(win, 1, w, title.c_str(), COLOR_PAIR(WIN_PAIR));
|
|
|
|
mvwaddch(win, 2, 0, ACS_LTEE);
|
|
|
|
mvwhline(win, 2, 1, ACS_HLINE, 38);
|
|
|
|
mvwaddch(win, 2, w-1, ACS_RTEE);
|
|
|
|
// refresh();
|
|
|
|
|
|
|
|
int r = 3;
|
|
|
|
for (string e : entries)
|
|
|
|
{
|
|
|
|
printAt(win, r, 1, e.c_str(), COLOR_PAIR(WIN_PAIR));
|
|
|
|
r++;
|
|
|
|
}
|
|
|
|
wrefresh(win);
|
|
|
|
}
|
|
|
|
|
2020-06-29 14:35:58 +00:00
|
|
|
void detectWMBUSReceiver()
|
2020-05-09 19:56:37 +00:00
|
|
|
{
|
|
|
|
int c = selectFromMenu("Select your wmbus radio device", receivers_menu);
|
|
|
|
switch (static_cast<ReceiversType>(c))
|
2020-04-03 09:58:19 +00:00
|
|
|
{
|
2020-05-09 19:56:37 +00:00
|
|
|
case ReceiversType::AMB8465:
|
|
|
|
probeFor("amb8465", detectAMB8465);
|
|
|
|
break;
|
|
|
|
case ReceiversType::CUL:
|
|
|
|
probeFor("cul", detectCUL);
|
|
|
|
break;
|
|
|
|
case ReceiversType::IM871A:
|
|
|
|
probeFor("im871a", detectIM871A);
|
|
|
|
break;
|
2020-04-03 09:58:19 +00:00
|
|
|
}
|
2020-05-09 19:56:37 +00:00
|
|
|
}
|
2020-04-03 09:58:19 +00:00
|
|
|
|
2020-06-29 14:35:58 +00:00
|
|
|
void resetWMBUSReceiver()
|
|
|
|
{
|
|
|
|
int c = selectFromMenu("Select your wmbus radio device", receivers_menu);
|
|
|
|
switch (static_cast<ReceiversType>(c))
|
|
|
|
{
|
|
|
|
case ReceiversType::AMB8465:
|
|
|
|
{
|
|
|
|
vector<string> devices = handler->listSerialDevices();
|
|
|
|
if (devices.size() == 0)
|
|
|
|
{
|
|
|
|
vector<string> entries;
|
|
|
|
displayInformationAndWait("No serial ports!", entries);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int c = selectFromMenu("Select device", devices);
|
|
|
|
string device = devices[c];
|
|
|
|
int was_baud = 0;
|
2020-07-30 09:18:44 +00:00
|
|
|
AccessCheck ac = factoryResetAMB8465(device, handler.get(), &was_baud);
|
2020-06-29 14:35:58 +00:00
|
|
|
if (ac == AccessCheck::AccessOK)
|
|
|
|
{
|
|
|
|
vector<string> entries;
|
|
|
|
entries.push_back("amb8465 "+device+" using "+to_string(was_baud));
|
|
|
|
displayInformationAndWait("Factory reset successful", entries);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vector<string> entries;
|
|
|
|
entries.push_back(device);
|
|
|
|
displayInformationAndWait("No amb8465 response from", entries);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case ReceiversType::CUL:
|
|
|
|
notImplementedYet("Resetting cul");
|
|
|
|
break;
|
|
|
|
case ReceiversType::IM871A:
|
|
|
|
notImplementedYet("Resetting im871a");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void notImplementedYet(string msg)
|
|
|
|
{
|
|
|
|
vector<string> entries;
|
|
|
|
entries.push_back(msg);
|
|
|
|
displayInformationAndWait("Not implemented yet", entries);
|
|
|
|
}
|
|
|
|
|
2020-05-09 19:56:37 +00:00
|
|
|
void probeFor(string type, AccessCheck (*check)(string,SerialCommunicationManager*))
|
|
|
|
{
|
|
|
|
vector<string> devices = handler->listSerialDevices();
|
|
|
|
vector<string> entries;
|
|
|
|
for (string& device : devices)
|
|
|
|
{
|
|
|
|
string tty = "?";
|
|
|
|
AccessCheck ac = checkAccessAndDetect(
|
|
|
|
handler.get(),
|
|
|
|
[=](string d, SerialCommunicationManager* m){ return check(d, m);},
|
|
|
|
type,
|
|
|
|
device);
|
|
|
|
|
|
|
|
if (ac == AccessCheck::AccessOK)
|
|
|
|
{
|
|
|
|
tty = device+" DETECTED "+type;
|
|
|
|
}
|
|
|
|
else if (ac == AccessCheck::NotThere)
|
|
|
|
{
|
|
|
|
tty = device+" nothing there";
|
|
|
|
}
|
|
|
|
else if (ac == AccessCheck::NotSameGroup)
|
|
|
|
{
|
|
|
|
tty = device+" not same group";
|
|
|
|
}
|
|
|
|
entries.push_back(tty);
|
|
|
|
}
|
|
|
|
if (entries.size() == 0)
|
|
|
|
{
|
|
|
|
entries.push_back("No serial devices found.");
|
|
|
|
}
|
2020-05-30 16:45:29 +00:00
|
|
|
displayInformationAndWait("Probed serial devices", entries);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool detectIfRoot()
|
|
|
|
{
|
|
|
|
vector<string> args;
|
|
|
|
vector<string> envs;
|
|
|
|
args.push_back("-u");
|
|
|
|
string out;
|
|
|
|
invokeShellCaptureOutput("/usr/bin/id", args, envs, &out, true);
|
|
|
|
|
|
|
|
return out == "0\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void detectProcesses(string cmd, vector<int> *pids)
|
|
|
|
{
|
|
|
|
vector<string> args;
|
|
|
|
vector<string> envs;
|
|
|
|
args.push_back(cmd);
|
|
|
|
string out;
|
|
|
|
invokeShellCaptureOutput("/bin/pidof", args, envs, &out, true);
|
|
|
|
|
|
|
|
char buf[out.size()+1];
|
|
|
|
strcpy(buf, out.c_str());
|
|
|
|
char *pch;
|
|
|
|
pch = strtok (buf," \n");
|
|
|
|
while (pch != NULL)
|
|
|
|
{
|
|
|
|
pids->push_back(atoi(pch));
|
|
|
|
pch = strtok (NULL, " \n");
|
|
|
|
}
|
2020-04-03 09:58:19 +00:00
|
|
|
}
|