1st approach

This commit is contained in:
2026-09-01 16:00:51 +03:00
parent 11f3553344
commit ae999fcd48
9 changed files with 104 additions and 38 deletions

View File

@@ -1,5 +1,6 @@
// (C) V.S. Shergin, SAO RAS
#include <err.h>
#include <crypt.h>
#include "bta_shdata.h"
#pragma pack(push, 4)
@@ -182,7 +183,12 @@ void get_cmd_queue(struct CMD_Queue *cq, int server){
cq->side = server;
if(server){
char buf[120]; /* выброÑ<C2BE>ить вÑ<C2B2>е команды из очереди */
/*
÷ ÓÔÒÕËÔÕÒÁÈ ÄÌÑ ÏÞÅÒÅÄÅÊ ÓÏÏÂÝÅÎÉÊ ÉÓÐÏÌØÚÕÅÔÓÑ int32_t mtype, ÎÏ ÓÉÓÔÅÍÎÙÅ ×ÙÚÏ×Ù (msgsnd, msgrcv) ÏÖÉÄÁÀÔ long (ÎÁ 64-ÂÉÔÎÙÈ ÓÉÓÔÅÍÁÈ 8 ÂÁÊÔ). üÔÏ ÎÁÒÕÛÁÅÔ ×ÙÒÁ×ÎÉ×ÁÎÉÅ É ÐÒÉ×ÏÄÉÔ Ë ÎÅÐÒÁ×ÉÌØÎÏÍÕ ÞÔÅÎÉÀ/ÚÁÐÉÓÉ ÄÁÎÎÙÈ.
ïÓÏÂÅÎÎÏ ÏÐÁÓÎÏ: ÐÒÉ ÏÞÉÓÔËÅ ÏÞÅÒÅÄÉ ÎÁ ÓÅÒ×ÅÒÅ:
*/
while(msgrcv(cq->id, (struct msgbuf *)buf, 112, 0, IPC_NOWAIT) > 0);
// òÁÚÍÅÒ ÄÁÎÎÙÈ (112) ×ÙÞÉÓÌÅÎ ÂÅÚ ÕÞ£ÔÁ ÒÁÚÍÅÒÁ long, ÞÔÏ ÍÏÖÅÔ ÐÒÉ×ÅÓÔÉ Ë ÓÂÏÑÍ.
}else
snd_id = cq->id;
cq->acckey = 0;

View File

@@ -102,7 +102,7 @@ static sl_sock_hresult_e send_motor_command(SSL *ssl, const char *cmd, value_t *
}
}else l = snprintf(buf, IOBUF_LEN-1, "%s\n", cmd);
buf[l] = 0;
DBG("Send to server: %s", buf);
//DBG("Send to server: %s", buf);
SSL_write(ssl, buf, l);
double t0 = sl_dtime();
while(sl_dtime() - t0 < G.acc_timeout){
@@ -113,35 +113,35 @@ static sl_sock_hresult_e send_motor_command(SSL *ssl, const char *cmd, value_t *
ERRX("Disconnected");
}
buf[l] = 0;
DBG("Received: \"%s\"\n", buf);
//DBG("Received %d bytes: \"%s\"", l, buf);
// parser
char key[SL_KEY_LEN] = {0}, val[SL_VAL_LEN] = {0};
int got = sl_get_keyval(buf, key, val);
DBG("got=%d, key=%s, val=%s", got, key, val);
//DBG("got=%d, key=%s, val=%s", got, key, val);
if(got == 0){
DBG("Empty answer");
//DBG("Empty answer");
continue;
}
if((!setter && got == 1) || (setter && got == 2)){ // wrong answer
if((setter && got == 2) || (getter && got == 1)){ // wrong answer
DBG("wrong answer");
continue;
}
if(setter){ // check errcode in answer
if(!getter){ // check errcode in answer
if(got == 2){
DBG("Getter answer");
DBG("Getter answer when setter called");
continue;
}
for(int i = 0; i < RESULT_SILENCE; ++i){
DBG("compare '%s' and '%s'", key, Ecodes[i]);
//DBG("compare '%s' and '%s'", key, Ecodes[i]);
if(0 == strcmp(key, Ecodes[i])){
DBG("Found errcode for '%s': %d", key, i);
//DBG("Found errcode for '%s': %d", key, i);
return i; // found
}
}
}else{ // check "cmd = val"
if(got == 1) continue;
if(strcmp(cmd, key)) continue;
if(getter){
//if(getter){
if(getter->type == ARG_TYPE_INT){
long long ll;
if(!sl_str2ll(&ll, val)) continue;
@@ -151,10 +151,12 @@ static sl_sock_hresult_e send_motor_command(SSL *ssl, const char *cmd, value_t *
if(!sl_str2d(&d, val)) continue;
getter->d = d;
}
}
//}
//DBG("Getter OK");
return RESULT_OK;
}
}
DBG("FAILED");
return RESULT_FAIL;
}
@@ -195,11 +197,19 @@ static int check_motor(SSL *ssl, int motno){
for(int i = 0; i < MOTORS_AMOUNT; ++i){
int s = MotorState[i].status;
if(s == MOT_OFF) continue;
if(s == MOT_ERROR){
*msg = MesgWarn;
printf(msg+1, "Dome: Error in motor %d!\n", i+1);
SendMessage(msg);
MotorState[i].status = MOT_OFF;
}
if(status < s) status = s;
if(status == MOT_RUN){
speed += MotorState[i].speed;
current += MotorState[i].current;
++N;
}
}
if(N){
speed /= (double)N;
current /= (double)N;
@@ -209,7 +219,7 @@ static int check_motor(SSL *ssl, int motno){
sprintf(msg+1, "Dome: All motors are Off!\n");
SendMessage(msg);
}else if(status != MOT_OFF && CommonState.status == MOT_OFF){
*msg = MesgFault;
*msg = MesgInfor;
sprintf(msg+1, "Dome: Start motors!\n");
SendMessage(msg);
}
@@ -222,15 +232,22 @@ static int check_motor(SSL *ssl, int motno){
// check for speed change and send given command to server
static void chk_dome_speed(SSL *ssl){
static int old_state = D_Off;
static double tlast = 0.;
int new_state = Dome_Speed;
double tlast = 0.;
if(D_Locked /*|| !PEP_K_On*/){
if(old_state != D_Off) new_state = D_Off; // stop dome in locked state
else return;
}
if(new_state == old_state){
if(sl_dtime() - tlast < G.speedchk_interval) return;
DBG("Time - tlast = %g", sl_dtime() - tlast);
if(CommonState.speed == set_speed){
tlast = sl_dtime();
return;
}
DBG("Speed set command still not sent");
}
DBG("state changed from %d to %d", old_state, new_state);
double new_speed = 0.;
switch(new_state){
case D_Lplus:
@@ -256,12 +273,15 @@ static void chk_dome_speed(SSL *ssl){
}
value_t Dval = {.type = ARG_TYPE_DOUBLE, .d = new_speed};
if(RESULT_OK == send_motor_command(ssl, cmd_speed, &Dval, NULL)){
DBG("New speed %g sent", new_speed);
if(RESULT_OK == send_motor_command(ssl, cmd_speed, NULL, &Dval) && fabs(Dval.d - new_speed) <= FLT_EPSILON){
DBG("Got answer with speed set: %g", Dval.d);
old_state = new_state; // all OK, command in work
set_speed = new_speed;
speedSEWD = new_speed;
tlast = sl_dtime();
}
}
}else WARNX("error getting speed");
}else WARNX("error sending motor command");
}
// SHM parser; return FALSE if SHM is in erroreous state
@@ -284,6 +304,14 @@ static int process_system(SSL *ssl){
if(++brokenshmctr < 10) return TRUE;
return FALSE;
}else brokenshmctr = 0;
// set/reset PEP_K_On by information from server!
value_t Ival = {.type = ARG_TYPE_INT, .i = 0};
if(RESULT_OK != send_motor_command(ssl, cmd_forbidden, &Ival, NULL)) return FALSE;
#ifdef EBUG
//if(PEP_K_On != Ival.i) DBG("Set PEP_K_On to %d", !Ival.i);
#endif
if(Ival.i) PEP_K_On = 0;
else PEP_K_On = 1;
static int modelused = FALSE;
if(!G.emulmode){
if(UseModel == FullModel){ // model
@@ -307,10 +335,15 @@ static int process_system(SSL *ssl){
}
if(check_motor(ssl, curMotNo)){
// TODO: check state for errors
if(++curMotNo >= MOTORS_AMOUNT) curMotNo = 0;
if(++curMotNo == DomeSEW_N){ // set `struct SEWdata` parameters
motor_state_t *st = &MotorState[curMotNo];
statusSEWD = st->status;
vel_SEWD = st->speed;
currentSEWD = st->current;
}
if(!D_Locked && Dome_State != D_Off) chk_dome_speed(ssl);
;
if(curMotNo >= MOTORS_AMOUNT) curMotNo = 0;
}
chk_dome_speed(ssl);
return TRUE;
}

View File

@@ -25,6 +25,7 @@
// Handlers in this list MUST be in sortered order (by name)!!!
#define HANDLERS_LIST() \
NEW_HANDLER(forbidden, "forbid (1) or permit (0) dome operations") \
NEW_HANDLER(motcurrent, "maximal motor current") \
NEW_HANDLER(motnum, "active motor number for status requests") \
NEW_HANDLER(motspeed, "motor speed") \

View File

@@ -42,6 +42,7 @@ static motor_state_t motstates[MOTORS_AMOUNT] = {0};
// set points
static double currentSet = DEFAULT_CURRENT, speedSet = 0.;
// flags for main routine
// TODO: add mutex or make flags atomic
static union{
struct{
uint32_t change_speed : 1;
@@ -85,7 +86,7 @@ static int motors_open_m(const char *path, int speed){
LOGERR("Can't open device %s @ %d", path, speed);
return FALSE;
}
modbus_set_response_timeout(modbus_ctx, 0, 50000); // 50ms response timeout
modbus_set_response_timeout(modbus_ctx, 0, MODBUS_RESPONCE_TIMEOUT); // response timeout
if(modbus_connect(modbus_ctx) < 0){
WARNX("Can't connect to device %s", path);
LOGERR("Can't connect to device %s", path);
@@ -135,7 +136,7 @@ int motors_set_speedsetpoint(double val){
int motors_get_activenum(){ return motindex; }
// set number of active motor
int motors_set_activenum(int N){
DBG("Set active motor=%d", N);
//DBG("Set active motor=%d", N);
if(N < 0 || N >= MOTORS_AMOUNT) return FALSE;
motindex = N;
return TRUE;
@@ -170,24 +171,29 @@ static void motors_process_m(){
if(flags.all){
if(-1 == modbus_set_slave(modbus_ctx, 0)) goto reg_error;
if(flags.stop){
DBG("User asks to stop");
speedSet = 0.;
// send command stop
if(-1 == modbus_write_register(modbus_ctx, REG_CMD, CMD_STOP)) goto reg_error;
flags.stop = 0;
}
if(flags.change_current){
DBG("User asks to change current to %g", currentSet);
// TODO: send command "max current"?
flags.change_current = 0;
}
if(flags.change_speed){
DBG("User asks to change speed to %g", speedSet);
// send command "set speed"
uint16_t dir = (speedSet > 0.) ? CMD_FORWARD : CMD_REVERSE;
uint16_t freq = (uint16_t)(fabs(speedSet) * FREQ_SCALE);
if(-1 == modbus_write_register(modbus_ctx, REG_FREQ_SET, freq)) goto reg_error;
if(-1 == modbus_write_register(modbus_ctx, REG_CMD, dir)) goto reg_error;
if(-1 == modbus_write_register(modbus_ctx, REG_FREQ_SET, freq)) goto reg_error;
flags.change_speed = 0;
}
flags.all = 0;
}
// set slave N
if(-1 == modbus_set_slave(modbus_ctx, curN)) goto reg_error;
if(-1 == modbus_set_slave(modbus_ctx, MOTOR_ID(curN))) goto reg_error;
// ask for speed/status/current
uint16_t regs[2];
if(-1 == modbus_read_registers(modbus_ctx, REG_STATUS_MAIN, 2, regs)){

View File

@@ -21,10 +21,11 @@
// max errors per motor to mean it OFF
#define MAX_ERRORS 5
#define MAX_SPEED 700.
// freq_scale == 100, so for UINT16_t we can't make speed more than 655.35
#define MAX_SPEED 655.
#define SPEED_TOLERANCE 0.01
// emulation acceleration, min^-2
#define EMUL_ACCEL 20000.
#define EMUL_ACCEL 10000.
#define MAX_CURRENT 15.
#define DEFAULT_CURRENT 10.
#define MOTORS_AMOUNT 10
@@ -33,10 +34,12 @@
#define MSpeed 350
#define HSpeed 610
// modbus responce timeout, ms
#define MODBUS_RESPONCE_TIMEOUT 100000
// ID of first motor minus 1
#define START_ID (0)
// ID of motor (n=1..MOTORS_AMOUNT)
// ID of first motor
#define START_ID (1)
// ID of nth motor (n=0..MOTORS_AMOUNT-1 - index)
#define MOTOR_ID(n) (n + START_ID)
// motors' status

View File

@@ -1,3 +1,3 @@
#!/bin/bash
rm client.log
rm -f client.log
./dome_client -a ca/ca/ca_cert.pem -c ca/client/client_cert.pem -k ca/client/private/client_key.pem -vvv -s localhost -l client.log $@

View File

@@ -1,3 +1,3 @@
#!/bin/bash
rm server.log
rm -f server.log
./dome_server -a ca/ca/ca_cert.pem -c ca/server/server_cert.pem -k ca/server/private/server_key.pem -vvvl server.log $@

View File

@@ -27,6 +27,9 @@
// handlers: `index` - command index in list, `value` - setter's value or getter's answer
typedef sl_sock_hresult_e (*handler_t)(int index, char value[SL_VAL_LEN]);
// == TRUE if dome management is forbidden
static int forbidden = FALSE;
// struct for setters/getters
typedef struct{
const char *command;
@@ -70,7 +73,7 @@ static int handle_connection(SSL *ssl){
int r = read_string(ssl, buf, IOBUF_LEN);
if(r < 0) return 0;
int sd = SSL_get_fd(ssl);
DBG("Client %d msg: \"%s\"\n", sd, buf);
//DBG("Client %d msg: \"%s\"\n", sd, buf);
LOGDBG("fd=%d, message=%s", sd, buf);
int got = sl_get_keyval(buf, key, val);
if(got == 0){
@@ -81,11 +84,11 @@ static int handle_connection(SSL *ssl){
sl_sock_hresult_e result = RESULT_BADKEY;
if(-1 != h_idx){
if(got == 1){
DBG("getter #%d", h_idx);
//DBG("getter #%d", h_idx);
val[0] = 0; // getter
}else DBG("setter #%d", h_idx);
} //else DBG("setter #%d", h_idx);
result = command_list[h_idx].handler(h_idx, val);
DBG("result: %d", result);
//DBG("result: %d", result);
}else{
DBG("Command not found or help?");
// check if user asks for help
@@ -186,6 +189,8 @@ void serverproc(SSL_CTX *ctx, int fd){
WARNX("SSL_accept()");
SSL_free(ssl);
send(client, sslerr, sizeof(sslerr)-1, MSG_NOSIGNAL);
shutdown(client, SHUT_WR);
usleep(50000);
close(client);
}
}
@@ -212,6 +217,16 @@ void serverproc(SSL_CTX *ctx, int fd){
}
/****************** Protocol handlers (return 0 in case of success or error code >0 if failed) ******************/
sl_sock_hresult_e forbidden_handler(int _U_ index, char _U_ value[SL_VAL_LEN]){
int I;
if(ISSETTER(value)){
if(!sl_str2i(&I, value)) return RESULT_BADVAL;
forbidden = I;
return RESULT_OK;
}
snprintf(value, SL_VAL_LEN-1, "%d", forbidden);
return RESULT_SILENCE;
}
// key - keyword (command name), value - i/o buffer (value[0]==0 for getters)
/*
sl_sock_hresult_e current_handler(int _U_ index, char _U_ value[SL_VAL_LEN]){
@@ -265,6 +280,7 @@ sl_sock_hresult_e relay_handler(int _U_ index, char _U_ value[SL_VAL_LEN]){
sl_sock_hresult_e speed_handler(int _U_ index, char _U_ value[SL_VAL_LEN]){
double D;
if(ISSETTER(value)){
if(forbidden) return RESULT_FAIL;
if(!sl_str2d(&D, value) || !motors_set_speedsetpoint(D)) return RESULT_BADVAL;
return RESULT_OK;
}
@@ -289,7 +305,7 @@ static int search_handler(const char *name){
// Compare the target string with the struct's string field
int res = strcmp(name, command_list[mid].command);
if(res == 0){
DBG("Found %s by %d iterations\n", name, iter);
//DBG("Found %s by %d iterations\n", name, iter);
return mid; // Target found, return index
}else if(res < 0){
high = mid - 1; // Target is smaller, search left half

View File

@@ -6,6 +6,7 @@ cmdlnopts.c
cmdlnopts.h
daemon.c
daemon.h
esq770.h
handlers_list.h
main.c
motors.c