From 09a4326e532b51d8417cbd680032951ed3b6c024 Mon Sep 17 00:00:00 2001 From: Dennis Gunia Date: Wed, 22 Oct 2025 23:12:43 +0200 Subject: [PATCH] add boradcast base and fix oob error on invalid flap char --- software/pc_client/src/console.c | 35 +++++++++++++--- software/pc_client/src/devicemgr.c | 66 +++++++++++++++++++++--------- software/pc_client/src/devicemgr.h | 13 +++++- software/pc_client/src/wsserver.c | 24 ++++++++--- software/pc_client/src/wsserver.h | 1 + 5 files changed, 107 insertions(+), 32 deletions(-) diff --git a/software/pc_client/src/console.c b/software/pc_client/src/console.c index 96f4541..e5dd6a9 100644 --- a/software/pc_client/src/console.c +++ b/software/pc_client/src/console.c @@ -177,7 +177,7 @@ void cmd_dm_load(json_object *req, json_object *res) * command: dm_print * description: print text to display at position (x,y) * -* request format: { "command": "dm_print", "x": , "y": , "string": } +* request format: { "command": "dm_print", "x": , "y": , "string": , "full": } * response format: { "ack": true } * * @param req: json request object @@ -188,6 +188,7 @@ void cmd_dm_print(json_object *req, json_object *res) json_object *jx = json_object_object_get(req, "x"); json_object *jy = json_object_object_get(req, "y"); json_object *jstr = json_object_object_get(req, "string"); + json_object *jfullrot = json_object_object_get(req, "full"); if (jx == NULL) { json_object_object_add(res, "error", json_object_new_string("format error")); @@ -208,8 +209,21 @@ void cmd_dm_print(json_object *req, json_object *res) int x = json_object_get_int(jx); int y = json_object_get_int(jy); const char *str = json_object_get_string(jstr); - devicemgr_printText(str, x, y); + if (jfullrot == NULL) + { + devicemgr_printText(str, x, y, DISPLAY_FULLROTATION); + } + else if (json_object_get_boolean(jfullrot) == false) + { + devicemgr_printText(str, x, y, DISPLAY_DIRECT); + } + else + { + devicemgr_printText(str, x, y, DISPLAY_FULLROTATION); + } + json_object_object_add(res, "ack", json_object_new_boolean(true)); + send_json_history(req); } } @@ -217,7 +231,7 @@ void cmd_dm_print(json_object *req, json_object *res) * command: dm_print_single * description: print single flap to display at position (x,y) * -* request format: { "command": "dm_print_single", "x": , "y": , "flap": } +* request format: { "command": "dm_print_single", "x": , "y": , "flap": , "full": } * response format: { "ack": true } * * @param req: json request object @@ -228,6 +242,7 @@ void cmd_dm_print_single(json_object *req, json_object *res) json_object *jx = json_object_object_get(req, "x"); json_object *jy = json_object_object_get(req, "y"); json_object *jflap = json_object_object_get(req, "flap"); + json_object *jfullrot = json_object_object_get(req, "full"); if (jx == NULL) { json_object_object_add(res, "error", json_object_new_string("format error")); @@ -248,8 +263,18 @@ void cmd_dm_print_single(json_object *req, json_object *res) int x = json_object_get_int(jx); int y = json_object_get_int(jy); int flap = json_object_get_int(jflap); - - devicemgr_printFlap(flap, x, y); + if (jfullrot == NULL) + { + devicemgr_printFlap(flap, x, y, DISPLAY_FULLROTATION); + } + else if (json_object_get_boolean(jfullrot) == false) + { + devicemgr_printFlap(flap, x, y, DISPLAY_DIRECT); + } + else + { + devicemgr_printFlap(flap, x, y, DISPLAY_FULLROTATION); + } json_object_object_add(res, "ack", json_object_new_boolean(true)); } } diff --git a/software/pc_client/src/devicemgr.c b/software/pc_client/src/devicemgr.c index 116060b..82f180b 100644 --- a/software/pc_client/src/devicemgr.c +++ b/software/pc_client/src/devicemgr.c @@ -32,7 +32,6 @@ enum SFDEVICE_POWER UNKNOWN // power state unknown (device offline) }; - struct SFDEVICE { int pos_x; // position in matrix @@ -50,10 +49,11 @@ struct SFDEVICE enum { - SFDEVICE_MAXDEV = 128, // maximum number of devices supported - SFDEVICE_MAX_X = 20, // maximum x size of device matrix - SFDEVICE_MAX_Y = 4, // maximum y size of device matrix - JSON_MAX_LINE_LEN = 256 // maximum length of a line in json file + SFDEVICE_MAXDEV = 128, // maximum number of devices supported + SFDEVICE_MAX_X = 20, // maximum x size of device matrix + SFDEVICE_MAX_Y = 4, // maximum y size of device matrix + JSON_MAX_LINE_LEN = 256, // maximum length of a line in json file + FLAP_COUNT = 45 // amount of installed flaps }; @@ -63,9 +63,9 @@ int deviceFd; // rs485 file descriptor struct SFDEVICE devices[SFDEVICE_MAXDEV]; // device array // symbol table for flap characters -const char *symbols[] = {" ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", - "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Ä", "Ö", "Ü", - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ".", "-", "?", "!"}; +const char *symbols[FLAP_COUNT] = {" ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", + "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Ä", "Ö", "Ü", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ".", "-", "?", "!"}; /* * Initialize device manager. @@ -314,9 +314,10 @@ void devicemgr_printDetailsAll(json_object *root) * * @param id ID of device to set * @param flap character to set +* @param displayMode do a full rotation * @return 0 on success, -1 on error */ -int setSingle(int id, char flap) +int devicemgr_setSingle(int id, char flap, sfdisplaymode displayMode) { if (id < 0 || id >= SFDEVICE_MAXDEV) { @@ -331,12 +332,24 @@ int setSingle(int id, char flap) // first convert char to flap id char test_char = toupper(flap); // printf("find char %c\n", test_char); - for (int ix = 0; ix < sizeof(symbols); ix++) + for (int ix = 0; ix < FLAP_COUNT; ix++) { if (*symbols[ix] == test_char) { // printf("match char %i %i %i\n", test_char, *symbols[ix], ix); - sfbus_display_full(devices[id].rs485_descriptor, devices[id].address, ix); + if (displayMode == DISPLAY_DIRECT) + { + sfbus_display(devices[id].rs485_descriptor, devices[id].address, ix); + } + else if (displayMode == DISPLAY_FULLROTATION) + { + sfbus_display_full(devices[id].rs485_descriptor, devices[id].address, ix); + } + else + { + log_message(LOG_ERROR, "invalid display mode %i", displayMode); + return -1; + } devices[id].current_flap = ix; return 0; } @@ -350,9 +363,10 @@ int setSingle(int id, char flap) * * @param id ID of device to set * @param flap flap ID to set +* @param displayMode do a full rotation * @return 0 on success, -1 on error */ -int devicemgr_setSingleRaw(int id, int flap) +int devicemgr_setSingleRaw(int id, int flap, sfdisplaymode displayMode) { if (id < 0 || id >= SFDEVICE_MAXDEV) { @@ -364,14 +378,26 @@ int devicemgr_setSingleRaw(int id, int flap) log_message(LOG_ERROR, "device id %i not defined", id); return -1; } - if (flap < 0 || flap >= sizeof(symbols) * sizeof(char)) + if (flap < 0 || flap >= FLAP_COUNT) { log_message(LOG_ERROR, "flap ID %i out of bounds", flap); return -1; } else { - sfbus_display_full(devices[id].rs485_descriptor, devices[id].address, flap); + if (displayMode == DISPLAY_DIRECT) + { + sfbus_display(devices[id].rs485_descriptor, devices[id].address, flap); + } + else if (displayMode == DISPLAY_FULLROTATION) + { + sfbus_display_full(devices[id].rs485_descriptor, devices[id].address, flap); + } + else + { + log_message(LOG_ERROR, "invalid display mode %i", displayMode); + return -1; + } devices[id].current_flap = flap; return 0; } @@ -384,7 +410,7 @@ int devicemgr_setSingleRaw(int id, int flap) * @param x x position to start printing * @param y y position to start printing */ -void devicemgr_printText(const char *text, int x, int y) +void devicemgr_printText(const char *text, int x, int y, sfdisplaymode displayMode) { if (x < 0 || x >= SFDEVICE_MAX_X || y < 0 || y >= SFDEVICE_MAX_Y) { @@ -413,7 +439,7 @@ void devicemgr_printText(const char *text, int x, int y) else { log_message(LOG_DEBUG, "print char '%c' to id:%i", *(text + i), devices[this_id].address); - setSingle(this_id, *(text + i)); + devicemgr_setSingle(this_id, *(text + i), displayMode); } } else @@ -434,9 +460,9 @@ void devicemgr_printText(const char *text, int x, int y) * @param x x position to print * @param y y position to print */ -void devicemgr_printFlap(int flap, int x, int y) +void devicemgr_printFlap(int flap, int x, int y, sfdisplaymode displayMode) { - if (flap < 0 || flap >= sizeof(symbols)) + if (flap < 0 || flap >= FLAP_COUNT) { log_message(LOG_ERROR, "flap ID %i out of bounds", flap); return; @@ -449,7 +475,7 @@ void devicemgr_printFlap(int flap, int x, int y) int this_id = deviceMap[x][y]; if (this_id >= 0 && this_id < SFDEVICE_MAXDEV) { - devicemgr_setSingleRaw(this_id, flap); + devicemgr_setSingleRaw(this_id, flap, displayMode); } else { @@ -472,7 +498,7 @@ void devicemgr_clearscreen() { if (devices[ix].current_flap != 0) { - devicemgr_setSingleRaw(ix, 0); + devicemgr_setSingleRaw(ix, 0, DISPLAY_FULLROTATION); } } } diff --git a/software/pc_client/src/devicemgr.h b/software/pc_client/src/devicemgr.h index e6607be..2d0f5e8 100644 --- a/software/pc_client/src/devicemgr.h +++ b/software/pc_client/src/devicemgr.h @@ -22,6 +22,15 @@ #include // Contains POSIX terminal control definitions #include // write(), read(), close() +#ifndef SFDEFICEMGR_H +#define SFDEFICEMGR_H +typedef enum SFDISPLAYMODE +{ + DISPLAY_DIRECT, + DISPLAY_FULLROTATION +} sfdisplaymode; +#endif + int devicemgr_readStatus(int device_id); int devicemgr_readCalib(int device_id); void devicemgr_printDetails(int device_id, json_object *root); @@ -31,8 +40,8 @@ void devicemgr_init(); int devicemgr_print(char *text); int devicemgr_refresh(); int devicemgr_save(char *file); -void devicemgr_printText(const char *text, int x, int y); -void devicemgr_printFlap(int flap, int x, int y); +void devicemgr_printText(const char *text, int x, int y, sfdisplaymode displayMode); +void devicemgr_printFlap(int flap, int x, int y, sfdisplaymode displayMode); int devicemgr_load(char *file); int devicemgr_load_single(json_object *device_obj); int devicemgr_remove(int id); diff --git a/software/pc_client/src/wsserver.c b/software/pc_client/src/wsserver.c index 491d414..df96db4 100644 --- a/software/pc_client/src/wsserver.c +++ b/software/pc_client/src/wsserver.c @@ -24,9 +24,10 @@ json_object *(*commandparser_func)(json_object *); */ void ws_opencon(ws_cli_conn_t client) { - char *cli; + char *cli, *port; cli = ws_getaddress(client); - log_message(LOG_DEBUG, "WebSocket connection opened, addr: %s", cli); + port = ws_getport(client); + log_message(LOG_DEBUG, "WebSocket connection opened, addr: %s, port: %s", cli, port); } /* @@ -35,9 +36,10 @@ void ws_opencon(ws_cli_conn_t client) */ void ws_closecon(ws_cli_conn_t client) { - char *cli; + char *cli, *port; cli = ws_getaddress(client); - log_message(LOG_DEBUG, "WebSocket connection closed, addr: %s", cli); + port = ws_getport(client); + log_message(LOG_DEBUG, "WebSocket connection closed, addr: %s, port: %s", cli, port); } /* @@ -55,7 +57,7 @@ void ws_messagehandler(ws_cli_conn_t client, const unsigned char *msg, uint64_t log_message(LOG_DEBUG, "WebSocket received message: %s (%zu), from: %s", msg, size, cli); json_tokener *tok = json_tokener_new(); - json_object *req = json_tokener_parse_ex(tok, (const char*)msg, size); + json_object *req = json_tokener_parse_ex(tok, (const char *)msg, size); enum json_tokener_error jerr; jerr = json_tokener_get_error(tok); if (jerr != json_tokener_success) @@ -118,6 +120,18 @@ void send_json_error(ws_cli_conn_t client, char *error, const char *detail) send_json_response(client, root); } +/* +* send json hisotry to all websocket clients +* +* @param msg: message +*/ +void send_json_history(json_object *msg) +{ + json_object *root = json_object_new_object(); + json_object_object_add(root, "history", root); + const char *message = json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY); + ws_sendframe_txt_bcast(-1, message); +} /* * Start websocket server * diff --git a/software/pc_client/src/wsserver.h b/software/pc_client/src/wsserver.h index 082b85d..27661c4 100644 --- a/software/pc_client/src/wsserver.h +++ b/software/pc_client/src/wsserver.h @@ -21,6 +21,7 @@ int start_webserver(); void send_json_error(ws_cli_conn_t client, char *error, const char *detail); void send_json_response(ws_cli_conn_t client, json_object *res); +void send_json_history(json_object *msg); void ws_messagehandler(ws_cli_conn_t client, const unsigned char *msg, uint64_t size, int type); void ws_opencon(ws_cli_conn_t client);