add protocol version2
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "console.h"
|
||||
|
||||
const char *device_config_file = "./flapconfig.json";
|
||||
char *device_config_file = "./flapconfig.json";
|
||||
int fd;
|
||||
// command handlers
|
||||
|
||||
@@ -133,7 +133,7 @@ void cmd_dm_print(json_object *req, json_object *res)
|
||||
{
|
||||
int x = json_object_get_int(jx);
|
||||
int y = json_object_get_int(jy);
|
||||
char *str = json_object_get_string(jstr);
|
||||
const char *str = json_object_get_string(jstr);
|
||||
devicemgr_printText(str, x, y);
|
||||
json_object_object_add(res, "ack", json_object_new_boolean(true));
|
||||
}
|
||||
@@ -332,7 +332,7 @@ json_object *parse_command(json_object *req)
|
||||
json_object *commandObj;
|
||||
json_object *res = json_object_new_object();
|
||||
json_object_object_get_ex(req, "command", &commandObj);
|
||||
char *command = json_object_get_string(commandObj);
|
||||
const char *command = json_object_get_string(commandObj);
|
||||
free(commandObj);
|
||||
// command 'table'
|
||||
if (strcmp(command, "dm_dump") == 0)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "devicemgr.h"
|
||||
#include <json-c/json_object.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
enum SFDEVICE_STATE
|
||||
{
|
||||
@@ -29,6 +30,7 @@ enum SFDEVICE_POWER
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
|
||||
struct SFDEVICE
|
||||
{
|
||||
int pos_x;
|
||||
@@ -262,7 +264,7 @@ void setSingleRaw(int id, int flap)
|
||||
devices[nextFreeSlot].current_flap = flap;
|
||||
}
|
||||
|
||||
void devicemgr_printText(char *text, int x, int y)
|
||||
void devicemgr_printText(const char *text, int x, int y)
|
||||
{
|
||||
for (int i = 0; i < strlen(text); i++)
|
||||
{
|
||||
@@ -340,7 +342,7 @@ int devicemgr_remove(int id)
|
||||
{
|
||||
devices[nextFreeSlot].deviceState = REMOVED;
|
||||
devices[nextFreeSlot].address = 0;
|
||||
devices[nextFreeSlot].rs485_descriptor = NULL;
|
||||
devices[nextFreeSlot].rs485_descriptor = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -361,7 +363,7 @@ int devicemgr_save(char *file)
|
||||
|
||||
json_object_object_add(root, "devices", device_array);
|
||||
|
||||
char *data = json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY);
|
||||
const char *data = json_object_to_json_string_ext(root, JSON_C_TO_STRING_PRETTY);
|
||||
printf("[INFO][console] store data to %s\n", file);
|
||||
|
||||
FILE *fptr;
|
||||
@@ -373,7 +375,7 @@ int devicemgr_save(char *file)
|
||||
int devicemgr_load(char *file)
|
||||
{
|
||||
FILE *fptr;
|
||||
const char *line_in_file = malloc(JSON_MAX_LINE_LEN); // maximum of 256 bytes per line;
|
||||
char *line_in_file = malloc(JSON_MAX_LINE_LEN); // maximum of 256 bytes per line;
|
||||
fptr = fopen(file, "r");
|
||||
json_tokener *tok = json_tokener_new();
|
||||
json_object *jobj = NULL;
|
||||
@@ -382,7 +384,7 @@ int devicemgr_load(char *file)
|
||||
|
||||
do
|
||||
{
|
||||
int read_ret = fgets(line_in_file, JSON_MAX_LINE_LEN, fptr); // read line from file
|
||||
char* read_ret = fgets(line_in_file, JSON_MAX_LINE_LEN, fptr); // read line from file
|
||||
stringlen = strlen(line_in_file);
|
||||
// printf("Read line with chars: %i : %s", stringlen, line_in_file); // only for testing
|
||||
jobj = json_tokener_parse_ex(tok, line_in_file, stringlen);
|
||||
|
||||
@@ -31,5 +31,8 @@ void devicemgr_init();
|
||||
int devicemgr_print(char *text);
|
||||
int devicemgr_refresh();
|
||||
int devicemgr_save(char *file);
|
||||
void devicemgr_printText(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);
|
||||
void devicemgr_printFlap(int flap, int x, int y);
|
||||
int devicemgr_load(char *file);
|
||||
int devicemgr_load_single(json_object *device_obj);
|
||||
int devicemgr_remove(int id);
|
||||
@@ -3,14 +3,7 @@
|
||||
* Copyright (c) 2024-2025 GuniaLabs (www.dennisgunia.de)
|
||||
* Authors: Dennis Gunia
|
||||
*
|
||||
* This program is free software (...)
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program (...)
|
||||
*
|
||||
* You can be released from the requirements of the license by purchasing
|
||||
* a commercial license. Buying such a license is mandatory as soon as you
|
||||
* develop commercial activities involving the split-flap software without
|
||||
* disclosing the source code of your own applications (...)
|
||||
* This program is licenced under AGPL-3.0 license.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -28,6 +21,7 @@
|
||||
#include "ftdi485.h"
|
||||
#include "sfbus.h"
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
void printUsage(char *argv[])
|
||||
{
|
||||
@@ -86,7 +80,7 @@ int main(int argc, char *argv[])
|
||||
setvbuf(stdout, NULL, _IONBF, 0); // do not buffer stdout!!!!
|
||||
|
||||
printf("Open device at %s\n", port);
|
||||
int fd = rs485_init(port, B19200); // setup rs485
|
||||
int fd = rs485_init(port, B57600); // setup rs485
|
||||
|
||||
if (strcmp(command, "ping") == 0)
|
||||
{
|
||||
|
||||
@@ -27,14 +27,14 @@ void print_bufferHexRx(char *buffer, int length, u_int16_t address)
|
||||
{
|
||||
printf("Rx (0x%04X): ", address);
|
||||
print_charHex(buffer, length);
|
||||
printf(" | %i bytes received\n", length);
|
||||
printf("| %i bytes received\n", length);
|
||||
}
|
||||
|
||||
void print_bufferHexTx(char *buffer, int length, u_int16_t address)
|
||||
{
|
||||
printf("Tx (0x%04X): ", address);
|
||||
print_charHex(buffer, length);
|
||||
printf(" | %i bytes sent\n", length);
|
||||
printf("| %i bytes sent\n", length);
|
||||
}
|
||||
|
||||
ssize_t sfbus_recv_frame_wait(int fd, u_int16_t address, char *buffer)
|
||||
@@ -43,7 +43,7 @@ ssize_t sfbus_recv_frame_wait(int fd, u_int16_t address, char *buffer)
|
||||
int retryCount = 2;
|
||||
do
|
||||
{
|
||||
len = sfbus_recv_frame(fd, address, buffer);
|
||||
len = sfbus_recv_frame_v2(fd, address, buffer);
|
||||
retryCount--;
|
||||
if (retryCount == 0)
|
||||
{
|
||||
@@ -51,12 +51,14 @@ ssize_t sfbus_recv_frame_wait(int fd, u_int16_t address, char *buffer)
|
||||
return -1;
|
||||
}
|
||||
} while (len <= 0);
|
||||
print_bufferHexRx(buffer, len - 3, address);
|
||||
print_bufferHexRx(buffer, len - 4, address);
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer)
|
||||
ssize_t sfbus_recv_frame_v2(int fd, u_int16_t address, char *buffer)
|
||||
{
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
// wait for start byte
|
||||
char byte = 0x00;
|
||||
int retryCount = 3;
|
||||
@@ -71,10 +73,9 @@ ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer)
|
||||
}
|
||||
}
|
||||
u_int8_t frm_version;
|
||||
u_int8_t frm_addr_l;
|
||||
u_int8_t frm_addr_h;
|
||||
u_int8_t frm_addr_l, frm_addr_h;
|
||||
u_int8_t frm_length;
|
||||
u_int8_t frm_eof;
|
||||
u_int8_t frm_crc_l, frm_crc_h;
|
||||
|
||||
read(fd, &frm_version, 1);
|
||||
read(fd, &frm_length, 1);
|
||||
@@ -84,60 +85,32 @@ ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer)
|
||||
u_int16_t dst_addr = frm_addr_l | (frm_addr_h << 8);
|
||||
if (dst_addr != address)
|
||||
{
|
||||
return 0;
|
||||
//return 0;
|
||||
}
|
||||
|
||||
u_int8_t frm_length_counter = frm_length - 3;
|
||||
// read all bytes:
|
||||
while (frm_length_counter > 0)
|
||||
{
|
||||
read(fd, buffer, 1);
|
||||
buffer++;
|
||||
frm_length_counter--;
|
||||
}
|
||||
read(fd, &frm_eof, 1);
|
||||
read(fd, buffer, frm_length - 4); // read n bytes from buffer where n = payload length
|
||||
// read crc
|
||||
u_int16_t frm_crc = 0xFFFF; // read crc value
|
||||
read(fd, &frm_crc, 2);
|
||||
|
||||
if (frm_eof == '$')
|
||||
u_int16_t calc_crc = calc_CRC16(buffer, frm_length - 4); // calculate CRC
|
||||
|
||||
|
||||
if (frm_crc == calc_crc)
|
||||
{
|
||||
printf("crc check okay! expected: %04X received: %04X\n", calc_crc, frm_crc);
|
||||
return frm_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_bufferHexRx(buffer, frm_length - 4, address);
|
||||
printf("crc check failed! expected: %04X received: %04X\n", calc_crc, frm_crc);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void sfbus_send_frame(int fd, u_int16_t address, u_int8_t length, char *buffer)
|
||||
{
|
||||
int frame_size_complete = length + 6;
|
||||
char *frame = malloc(frame_size_complete);
|
||||
char *frame_ptr = frame;
|
||||
|
||||
*frame = '+'; // startbyte
|
||||
frame++;
|
||||
*frame = 0; // protocol version
|
||||
frame++;
|
||||
*frame = length + 3; // length
|
||||
frame++;
|
||||
*frame = (address);
|
||||
frame++;
|
||||
*frame = ((address >> 8));
|
||||
frame++;
|
||||
while (length > 0)
|
||||
{
|
||||
*frame = *buffer;
|
||||
length--;
|
||||
buffer++;
|
||||
frame++;
|
||||
}
|
||||
*frame = '$'; // startbyte
|
||||
|
||||
int result = write(fd, frame_ptr, frame_size_complete);
|
||||
print_bufferHexTx(frame_ptr + 5, frame_size_complete - 6, address);
|
||||
free(frame_ptr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send SFBus frame with protocol version 2.0 and calculated CRC
|
||||
*/
|
||||
@@ -157,9 +130,8 @@ void sfbus_send_frame_v2(int fd, u_int16_t address, u_int8_t length, char *buffe
|
||||
|
||||
// add crc to end of frame
|
||||
u_int16_t crc = calc_CRC16(buffer, length); // calculate CRC
|
||||
*(frame + (frame_size_complete - 1)) = (crc); // address high byte
|
||||
*(frame + (frame_size_complete - 0)) = ((crc >> 8)); // address low byte
|
||||
|
||||
*(frame + (frame_size_complete - 2)) = (crc); // address high byte
|
||||
*(frame + (frame_size_complete - 1)) = ((crc >> 8)); // address low byte
|
||||
// send data
|
||||
int result = write(fd, frame, frame_size_complete);
|
||||
print_bufferHexTx(frame, frame_size_complete, address);
|
||||
@@ -194,9 +166,9 @@ int sfbus_read_eeprom(int fd, u_int16_t address, char *buffer)
|
||||
{
|
||||
char *cmd = "\xF0";
|
||||
char *_buffer = malloc(256);
|
||||
sfbus_send_frame(fd, address, strlen(cmd), cmd);
|
||||
sfbus_send_frame_v2(fd, address, strlen(cmd), cmd);
|
||||
int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer);
|
||||
if (len != 9)
|
||||
if (len != 10)
|
||||
{
|
||||
printf("Invalid data!\n");
|
||||
return -1;
|
||||
@@ -217,12 +189,12 @@ int sfbus_write_eeprom(int fd, u_int16_t address, char *wbuffer, char *rbuffer)
|
||||
char *cmd = malloc(5);
|
||||
*cmd = (char)0xF1; // write eeprom command
|
||||
memcpy(cmd + 1, wbuffer, 4);
|
||||
sfbus_send_frame(fd, address, 5, cmd);
|
||||
sfbus_send_frame_v2(fd, address, 5, cmd);
|
||||
free(cmd);
|
||||
// wait for readback
|
||||
char *_buffer = malloc(256);
|
||||
int len = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer);
|
||||
if (len != 9)
|
||||
if (len != 10)
|
||||
{
|
||||
printf("Invalid data!\n");
|
||||
return -1;
|
||||
@@ -243,7 +215,7 @@ int sfbus_display(int fd, u_int16_t address, u_int8_t flap)
|
||||
char *cmd = malloc(5);
|
||||
*cmd = (char)0x10; // write eeprom command
|
||||
*(cmd + 1) = flap;
|
||||
sfbus_send_frame(fd, address, 2, cmd);
|
||||
sfbus_send_frame_v2(fd, address, 2, cmd);
|
||||
free(cmd);
|
||||
return 0;
|
||||
}
|
||||
@@ -253,7 +225,7 @@ int sfbus_display_full(int fd, u_int16_t address, u_int8_t flap)
|
||||
char *cmd = malloc(5);
|
||||
*cmd = (char)0x11; // write eeprom command
|
||||
*(cmd + 1) = flap;
|
||||
sfbus_send_frame(fd, address, 2, cmd);
|
||||
sfbus_send_frame_v2(fd, address, 2, cmd);
|
||||
free(cmd);
|
||||
return 0;
|
||||
}
|
||||
@@ -262,7 +234,7 @@ u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage, u_int32_t
|
||||
{
|
||||
char *cmd = "\xF8";
|
||||
char *_buffer = malloc(256);
|
||||
sfbus_send_frame(fd, address, strlen(cmd), cmd);
|
||||
sfbus_send_frame_v2(fd, address, strlen(cmd), cmd);
|
||||
int res = sfbus_recv_frame_wait(fd, 0xFFFF, _buffer);
|
||||
if (res < 0)
|
||||
{
|
||||
@@ -282,7 +254,7 @@ u_int8_t sfbus_read_status(int fd, u_int16_t address, double *voltage, u_int32_t
|
||||
void sfbus_reset_device(int fd, u_int16_t address)
|
||||
{
|
||||
char *cmd = "\x30";
|
||||
sfbus_send_frame(fd, address, strlen(cmd), cmd);
|
||||
sfbus_send_frame_v2(fd, address, strlen(cmd), cmd);
|
||||
}
|
||||
|
||||
void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state)
|
||||
@@ -292,7 +264,7 @@ void sfbus_motor_power(int fd, u_int16_t address, u_int8_t state)
|
||||
{
|
||||
cmd = "\x21";
|
||||
}
|
||||
sfbus_send_frame(fd, address, 1, cmd);
|
||||
sfbus_send_frame_v2(fd, address, 1, cmd);
|
||||
}
|
||||
|
||||
u_int16_t calc_CRC16(char *buffer, u_int8_t len)
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
#include "ftdi485.h"
|
||||
|
||||
ssize_t sfbus_recv_frame(int fd, u_int16_t address, char *buffer);
|
||||
ssize_t sfbus_recv_frame_v2(int fd, u_int16_t address, char *buffer);
|
||||
ssize_t sfbus_recv_frame_wait(int fd, u_int16_t address, char *buffer);
|
||||
void sfbus_send_frame(int fd, u_int16_t address, u_int8_t length, char *buffer);
|
||||
void sfbus_send_frame_v2(int fd, u_int16_t address, u_int8_t length, char *buffer);
|
||||
void print_charHex(char *buffer, int length);
|
||||
int sfbus_ping(int fd, u_int16_t address);
|
||||
int sfbus_read_eeprom(int fd, u_int16_t address, char* buffer);
|
||||
|
||||
@@ -18,7 +18,7 @@ json_object *(*commandparser_func)(json_object *);
|
||||
|
||||
// this sections handles ws connections and communications
|
||||
// called on opening websocket client
|
||||
void onopen(ws_cli_conn_t client)
|
||||
void ws_opencon(ws_cli_conn_t client)
|
||||
{
|
||||
char *cli;
|
||||
cli = ws_getaddress(client);
|
||||
@@ -26,7 +26,7 @@ void onopen(ws_cli_conn_t client)
|
||||
}
|
||||
|
||||
// called on closing websocket client
|
||||
void onclose(ws_cli_conn_t client)
|
||||
void ws_closecon(ws_cli_conn_t client)
|
||||
{
|
||||
char *cli;
|
||||
cli = ws_getaddress(client);
|
||||
@@ -34,7 +34,7 @@ void onclose(ws_cli_conn_t client)
|
||||
}
|
||||
|
||||
// called on receiving websocket message
|
||||
void onmessage(ws_cli_conn_t client, const unsigned char *msg, uint64_t size, int type)
|
||||
void ws_messagehandler(ws_cli_conn_t client, const unsigned char *msg, uint64_t size, int type)
|
||||
{
|
||||
char *cli = ws_getaddress(client);
|
||||
printf("received message: %s (%zu), from: %s\n", msg, size, cli);
|
||||
@@ -55,7 +55,7 @@ void onmessage(ws_cli_conn_t client, const unsigned char *msg, uint64_t size, in
|
||||
printf("test");
|
||||
if (commandObj != NULL)
|
||||
{
|
||||
char *command = json_object_to_json_string(commandObj);
|
||||
const char *command = json_object_to_json_string(commandObj);
|
||||
// get key
|
||||
json_object *res = commandparser_func(req);
|
||||
if (res == NULL)
|
||||
@@ -79,11 +79,11 @@ void onmessage(ws_cli_conn_t client, const unsigned char *msg, uint64_t size, in
|
||||
|
||||
void send_json_response(ws_cli_conn_t client, json_object *res)
|
||||
{
|
||||
char *message = json_object_to_json_string_ext(res, JSON_C_TO_STRING_PRETTY);
|
||||
const char *message = json_object_to_json_string_ext(res, JSON_C_TO_STRING_PRETTY);
|
||||
ws_sendframe_txt(client, message);
|
||||
}
|
||||
|
||||
void send_json_error(ws_cli_conn_t client, char *error, char *detail)
|
||||
void send_json_error(ws_cli_conn_t client, char *error, const char *detail)
|
||||
{
|
||||
json_object *root = json_object_new_object();
|
||||
json_object_object_add(root, "error", json_object_new_string(error));
|
||||
@@ -105,9 +105,9 @@ int start_webserver(json_object *(*commandparser_func_ptr)(json_object *))
|
||||
.port = WS_SERVER_PORT,
|
||||
.thread_loop = 0,
|
||||
.timeout_ms = 1000,
|
||||
.evs.onopen = &onopen,
|
||||
.evs.onclose = &onclose,
|
||||
.evs.onmessage = &onmessage});
|
||||
.evs.onopen = &ws_opencon,
|
||||
.evs.onclose = &ws_closecon,
|
||||
.evs.onmessage = &ws_messagehandler});
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -18,3 +18,10 @@
|
||||
#define WS_SERVER_ADDR "localhost"
|
||||
|
||||
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 ws_messagehandler(ws_cli_conn_t client, const unsigned char *msg, uint64_t size, int type);
|
||||
void ws_opencon(ws_cli_conn_t client);
|
||||
void ws_closecon(ws_cli_conn_t client);
|
||||
Reference in New Issue
Block a user