8 #include <sys/socket.h>
11 #include "../src/meshlink.h"
12 #include "../src/devtools.h"
14 static WINDOW *topwin;
15 static WINDOW *nodewin;
16 static WINDOW *splitwin;
17 static WINDOW *logwin;
18 static WINDOW *statuswin;
19 static float splitpoint = 0.5;
21 static meshlink_handle_t *mesh;
22 static meshlink_node_t **nodes;
25 static void log_message(meshlink_handle_t *mesh, meshlink_log_level_t level, const char *text) {
28 wattron(logwin, COLOR_PAIR(level));
29 wprintw(logwin, "%s\n", text);
30 wattroff(logwin, COLOR_PAIR(level));
34 static void do_resize() {
35 const int nodelines = lrintf((LINES - 3) * splitpoint);
36 const int loglines = (LINES - 3) - nodelines;
37 assert(nodelines > 1);
42 wresize(topwin, 1, COLS);
45 wresize(nodewin, nodelines, COLS);
47 mvwin(splitwin, 1 + nodelines, 0);
48 wresize(splitwin, 1, COLS);
50 mvwin(logwin, 2 + nodelines, 0);
51 wresize(logwin, loglines, COLS);
53 mvwin(statuswin, LINES - 1, 0);
54 wresize(statuswin, 1, COLS);
58 static void do_redraw_nodes() {
60 nodes = meshlink_get_all_nodes(mesh, nodes, &nnodes);
62 for(size_t i = 0; i < nnodes; i++) {
63 devtool_node_status_t status;
64 devtool_get_node_status(mesh, nodes[i], &status);
65 char host[NI_MAXHOST] = "";
66 char serv[NI_MAXSERV] = "";
67 getnameinfo((struct sockaddr *)&status.address, sizeof status.address, host, sizeof host, serv, sizeof serv, NI_NUMERICHOST | NI_NUMERICSERV);
70 switch(status.udp_status) {
71 case DEVTOOL_UDP_FAILED:
75 case DEVTOOL_UDP_IMPOSSIBLE:
79 case DEVTOOL_UDP_TRYING:
83 case DEVTOOL_UDP_WORKING:
87 case DEVTOOL_UDP_UNKNOWN:
93 if(!strcmp(nodes[i]->name, mesh->name)) {
100 if(status.minmtu != status.maxmtu) {
105 mvwprintw(nodewin, i, 0, "%-16s %-12s %-32s %5s %c%5d", nodes[i]->name, desc, host, serv, mtustate, status.maxmtu);
108 wnoutrefresh(nodewin);
111 static void do_redraw() {
114 mvwprintw(topwin, 0, 0, "%-16s %-12s %-32s %5s %6s", "Node:", "Status:", "UDP address:", "Port:", "MTU:");
115 wnoutrefresh(topwin);
119 mvwprintw(splitwin, 0, 0, "Log output:");
120 wnoutrefresh(splitwin);
124 mvwprintw(statuswin, 0, 0, "Status bar");
125 wnoutrefresh(statuswin);
127 wnoutrefresh(logwin);
132 static void node_status(meshlink_handle_t *mesh, meshlink_node_t *node, bool reachable) {
140 int main(int argc, char *argv[]) {
141 const char *confbase = ".monitor";
142 const char *id = NULL;
157 topwin = newwin(1, COLS, 0, 0);
158 nodewin = newwin(1, COLS, 1, 0);
159 splitwin = newwin(1, COLS, 2, 0);
160 logwin = newwin(1, COLS, 3, 0);
161 statuswin = newwin(1, COLS, 4, 0);
163 leaveok(topwin, true);
164 leaveok(nodewin, true);
165 leaveok(splitwin, true);
166 leaveok(logwin, true);
167 leaveok(statuswin, true);
169 wattrset(topwin, A_REVERSE);
170 wattrset(splitwin, A_REVERSE);
171 wattrset(statuswin, A_REVERSE);
173 wbkgdset(topwin, ' ' | A_REVERSE);
174 wbkgdset(splitwin, ' ' | A_REVERSE);
175 wbkgdset(statuswin, ' ' | A_REVERSE);
177 init_pair(1, COLOR_GREEN, -1);
178 init_pair(2, COLOR_YELLOW, -1);
179 init_pair(3, COLOR_RED, -1);
180 init_pair(4, COLOR_RED, -1);
182 scrollok(logwin, true);
188 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, log_message);
190 mesh = meshlink_open(confbase, id, "monitor", DEV_CLASS_STATIONARY);
194 fprintf(stderr, "Could not open MeshLink: %s\n", meshlink_strerror(meshlink_errno));
198 meshlink_set_log_cb(mesh, MESHLINK_DEBUG, log_message);
199 meshlink_set_node_status_cb(mesh, node_status);
201 if(!meshlink_start(mesh)) {
203 fprintf(stderr, "Could not start MeshLink: %s\n", meshlink_strerror(meshlink_errno));
209 wtimeout(topwin, 500);
215 int key = wgetch(topwin);
230 clearok(topwin, true);
231 clearok(nodewin, true);
232 clearok(splitwin, true);
233 clearok(logwin, true);
234 clearok(statuswin, true);
243 meshlink_close(mesh);