mirror of
https://github.com/eddyem/eddys_snippets.git
synced 2025-12-06 10:45:12 +03:00
First approach to websocket WEB-GUI
This commit is contained in:
parent
1a63497f04
commit
b53a659d40
@ -38,7 +38,7 @@ double t0; // start time
|
|||||||
uint32_t motor_speed = 10; // motor speed
|
uint32_t motor_speed = 10; // motor speed
|
||||||
|
|
||||||
FILE *fout = NULL; // file for messages duplicating
|
FILE *fout = NULL; // file for messages duplicating
|
||||||
char *comdev = "/dev/ttyUSB0";
|
char *comdev = "/dev/ttyUSB1";
|
||||||
int BAUD_RATE = B115200;
|
int BAUD_RATE = B115200;
|
||||||
struct termio oldtty, tty; // TTY flags
|
struct termio oldtty, tty; // TTY flags
|
||||||
struct termios oldt, newt; // terminal flags
|
struct termios oldt, newt; // terminal flags
|
||||||
@ -209,11 +209,12 @@ void help(){
|
|||||||
"R/L\tRotate motor 1 right/left\n"
|
"R/L\tRotate motor 1 right/left\n"
|
||||||
"r/l\tRotate motor 2 right/left\n"
|
"r/l\tRotate motor 2 right/left\n"
|
||||||
"S/s\tStop 1st or 2nd motor\n"
|
"S/s\tStop 1st or 2nd motor\n"
|
||||||
"W/w\tSet ustepping to 1/16\n"
|
"D/d\tSet ustepping to 1/16\n"
|
||||||
"E/e\tSet ustepping to 1/4\n"
|
"E/e\tSet ustepping to 1/4\n"
|
||||||
"Z/z\tSet to zero current position\n"
|
"Z/z\tSet to zero current position\n"
|
||||||
"G/g\tGet current position\n"
|
"G/g\tGet current position\n"
|
||||||
"A/a\tGet ALL information about\n"
|
"A/a\tGet ALL information about\n"
|
||||||
|
"W/w\tWait until position reached\n"
|
||||||
"q\tQuit\n"
|
"q\tQuit\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -351,7 +352,7 @@ void con_sig(int rb){
|
|||||||
case 's': // stop motor
|
case 's': // stop motor
|
||||||
*cmd = 3; // STP
|
*cmd = 3; // STP
|
||||||
break;
|
break;
|
||||||
case 'w': // 1/16
|
case 'd': // 1/16
|
||||||
*cmd = 5; // SAP
|
*cmd = 5; // SAP
|
||||||
command[2] = 140; // ustep resolution
|
command[2] = 140; // ustep resolution
|
||||||
value = 4;
|
value = 4;
|
||||||
@ -386,6 +387,12 @@ void con_sig(int rb){
|
|||||||
}
|
}
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt); // omit echo
|
tcsetattr(STDIN_FILENO, TCSANOW, &newt); // omit echo
|
||||||
break;
|
break;
|
||||||
|
case 'w': // wait till reached
|
||||||
|
*cmd = 138; // WAIT DIRECT
|
||||||
|
// set motor bit mask:
|
||||||
|
value = 5; // both motors
|
||||||
|
//value = 1 << command[3];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(*cmd){
|
if(*cmd){
|
||||||
// copy param to buffer
|
// copy param to buffer
|
||||||
@ -447,6 +454,16 @@ void copy_buf_to_file(uint8_t *buffer, int *cmd){
|
|||||||
free(buff);
|
free(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t log_2(const uint32_t x) {
|
||||||
|
uint32_t y;
|
||||||
|
asm ( "\tbsr %1, %0\n"
|
||||||
|
: "=r"(y)
|
||||||
|
: "r" (x)
|
||||||
|
);
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define log2(x) ((int)log_2((uint32_t)x))
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
int rb, oldcmd = -1;
|
int rb, oldcmd = -1;
|
||||||
@ -478,6 +495,10 @@ int main(int argc, char *argv[]){
|
|||||||
uint8_t *ptr = buff;
|
uint8_t *ptr = buff;
|
||||||
int ii;
|
int ii;
|
||||||
int32_t val = get_integer(buff);
|
int32_t val = get_integer(buff);
|
||||||
|
const uint8_t pattern[] = {2,1,128,138,0,0,0};
|
||||||
|
if(memcmp((void*)buff, (void*)pattern, sizeof(pattern)) == 0){ // motor has reached position
|
||||||
|
printf("Motor %d has reached position!\n", log2(val));
|
||||||
|
}else{
|
||||||
printf("value = %d (full answer: ", val);
|
printf("value = %d (full answer: ", val);
|
||||||
for(ii = L - 1; ii > 0; ii--){
|
for(ii = L - 1; ii > 0; ii--){
|
||||||
uint8_t C = *ptr++;
|
uint8_t C = *ptr++;
|
||||||
@ -485,7 +506,8 @@ int main(int argc, char *argv[]){
|
|||||||
//if(C > 31) printf("(%c)", C);
|
//if(C > 31) printf("(%c)", C);
|
||||||
printf(",");
|
printf(",");
|
||||||
}
|
}
|
||||||
printf("%u)\n", *ptr);
|
printf("%u\n", *ptr);
|
||||||
|
}
|
||||||
if(fout){
|
if(fout){
|
||||||
copy_buf_to_file(buff, &oldcmd);
|
copy_buf_to_file(buff, &oldcmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
PROGRAM = websocktest
|
PROGRAM = websocktest
|
||||||
LDFLAGS = $(shell pkg-config --libs libwebsockets)
|
LDFLAGS = $(shell pkg-config --libs libwebsockets) -lpthread
|
||||||
SRCS = test.c
|
SRCS = test.c
|
||||||
CC = gcc
|
CC = gcc
|
||||||
DEFINES = -D_XOPEN_SOURCE=501 -DCUR_PATH=\"$(shell pwd)\"
|
DEFINES = -D_XOPEN_SOURCE=501 -DCUR_PATH=\"$(shell pwd)\"
|
||||||
|
|||||||
@ -13,18 +13,157 @@
|
|||||||
#include <sys/stat.h> // read
|
#include <sys/stat.h> // read
|
||||||
#include <fcntl.h> // read
|
#include <fcntl.h> // read
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#define _U_ __attribute__((__unused__))
|
#define _U_ __attribute__((__unused__))
|
||||||
|
|
||||||
|
#define MESSAGE_QUEUE_SIZE 3
|
||||||
|
#define MESSAGE_LEN 128
|
||||||
|
// individual data per session
|
||||||
|
typedef struct{
|
||||||
|
int num;
|
||||||
|
int idxwr;
|
||||||
|
int idxrd;
|
||||||
|
char message[MESSAGE_QUEUE_SIZE][MESSAGE_LEN];
|
||||||
|
}per_session_data;
|
||||||
|
|
||||||
|
per_session_data global_queue;
|
||||||
|
pthread_mutex_t command_mutex;
|
||||||
|
|
||||||
|
char cmd_buf[5] = {0};
|
||||||
|
int data_in_buf = 0; // signals that there's some data in cmd_buf to send to motors
|
||||||
|
|
||||||
|
void put_message_to_queue(char *msg, per_session_data *dat){
|
||||||
|
int L = strlen(msg);
|
||||||
|
if(dat->num >= MESSAGE_QUEUE_SIZE) return;
|
||||||
|
dat->num++;
|
||||||
|
if(L < 1 || L > MESSAGE_LEN - 1) L = MESSAGE_LEN - 1;
|
||||||
|
strncpy(dat->message[dat->idxwr], msg, L);
|
||||||
|
dat->message[dat->idxwr][L] = 0;
|
||||||
|
if((++(dat->idxwr)) >= MESSAGE_QUEUE_SIZE) dat->idxwr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *get_message_from_queue(per_session_data *dat){
|
||||||
|
char *R = dat->message[dat->idxrd];
|
||||||
|
if(dat->num <= 0) return NULL;
|
||||||
|
if((++dat->idxrd) >= MESSAGE_QUEUE_SIZE) dat->idxrd = 0;
|
||||||
|
dat->num--;
|
||||||
|
return R;
|
||||||
|
}
|
||||||
|
|
||||||
int force_exit = 0;
|
int force_exit = 0;
|
||||||
|
|
||||||
uint8_t buf[9];
|
uint8_t buf[9];
|
||||||
|
#define TTYBUFLEN 128
|
||||||
|
uint8_t ttybuff[TTYBUFLEN];
|
||||||
char *comdev = "/dev/ttyUSB0";
|
char *comdev = "/dev/ttyUSB0";
|
||||||
int BAUD_RATE = B115200;
|
int BAUD_RATE = B115200;
|
||||||
int comfd = -1; // TTY fd
|
int comfd = -1; // TTY fd
|
||||||
|
uint32_t motor_speed = 50;
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
int32_t get_integer(uint8_t *buff){
|
||||||
|
int32_t val;
|
||||||
|
int ii;
|
||||||
|
uint8_t *valptr = (uint8_t*) &val + 3;
|
||||||
|
for(ii = 4; ii < 8; ii++)
|
||||||
|
*valptr-- = buff[ii];
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
void inttobuf(uint8_t *buf, int32_t value){// copy param to buffer
|
||||||
|
int i;
|
||||||
|
uint8_t *bytes = (uint8_t*) &value + 3;
|
||||||
|
for(i = 4; i < 8; i++)
|
||||||
|
buf[i] = *bytes--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read tty
|
||||||
|
* @return number of readed symbols
|
||||||
|
*/
|
||||||
|
size_t read_tty(){
|
||||||
|
ssize_t L = 0, l, buffsz = TTYBUFLEN;
|
||||||
|
struct timeval tv;
|
||||||
|
int sel;
|
||||||
|
fd_set rfds;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(comfd, &rfds);
|
||||||
|
tv.tv_sec = 0; tv.tv_usec = 100000;
|
||||||
|
sel = select(comfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
if(sel > 0){
|
||||||
|
if(FD_ISSET(comfd, &rfds)){
|
||||||
|
if((L = read(comfd, ttybuff, buffsz)) < 1){ // disconnect or other troubles
|
||||||
|
fprintf(stderr, "USB error or disconnected!\n");
|
||||||
|
exit(1);
|
||||||
|
}else{
|
||||||
|
if(L == 0){ // USB disconnected
|
||||||
|
fprintf(stderr, "USB disconnected!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if(L == 9) return 9;
|
||||||
|
// all OK continue reading
|
||||||
|
//DBG("readed %zd bytes, try more.. ", L);
|
||||||
|
buffsz -= L;
|
||||||
|
select(comfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
while(L < 9 && buffsz > 0 && (l = read(comfd, ttybuff+L, buffsz)) > 0){
|
||||||
|
L += l;
|
||||||
|
buffsz -= l;
|
||||||
|
select(comfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (size_t) L;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t log_2(const uint32_t x){
|
||||||
|
uint32_t y;
|
||||||
|
asm ( "\tbsr %1, %0\n"
|
||||||
|
: "=r"(y)
|
||||||
|
: "r" (x)
|
||||||
|
);
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int send_command(uint8_t *ninebytes);
|
||||||
|
|
||||||
|
#define log2(x) ((int)log_2((uint32_t)x))
|
||||||
|
/*
|
||||||
|
* check L bytes of ttybuf (maybe there was a command to check endpoint)
|
||||||
|
*/
|
||||||
|
void check_tty_sig(size_t l){
|
||||||
|
int L = l;
|
||||||
|
uint8_t movbk[]= {1,4,1,0,0,0,0,0,0};
|
||||||
|
//if(L < 9) return; // WTF?
|
||||||
|
uint8_t* buf = ttybuff;
|
||||||
|
char msg[128];
|
||||||
|
const uint8_t pattern[] = {2,1,128,138,0,0,0};
|
||||||
|
while(L > 0){
|
||||||
|
int32_t Ival = get_integer(buf);
|
||||||
|
if(memcmp((void*)buf, (void*)pattern, sizeof(pattern)) == 0){ // motor has reached position
|
||||||
|
int motnum = log2(Ival);
|
||||||
|
snprintf(msg, 127, "Motor %d has reached position!", motnum);
|
||||||
|
printf(" %s (%d)\n", msg, Ival);
|
||||||
|
put_message_to_queue(msg, &global_queue);
|
||||||
|
if(motnum == 0){ // move motor 0 to 2000 usteps
|
||||||
|
inttobuf(movbk, 2000);
|
||||||
|
send_command(movbk);
|
||||||
|
}else if(motnum == 2){ // move motor 2 to 3450 usteps
|
||||||
|
movbk[3] = 2;
|
||||||
|
inttobuf(movbk, 3450);
|
||||||
|
send_command(movbk);
|
||||||
|
}else{
|
||||||
|
printf(" WTF?\n");
|
||||||
|
}
|
||||||
|
}else printf(" %d\n", Ival);
|
||||||
|
L -= 9;
|
||||||
|
buf += 9;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
int send_command(uint8_t *ninebytes){
|
int send_command(uint8_t *ninebytes){
|
||||||
uint8_t crc = 0;
|
uint8_t crc = 0;
|
||||||
|
size_t L;
|
||||||
int i;
|
int i;
|
||||||
printf("send: ");
|
printf("send: ");
|
||||||
for(i = 0; i < 8; crc += ninebytes[i++])
|
for(i = 0; i < 8; crc += ninebytes[i++])
|
||||||
@ -35,67 +174,225 @@ int send_command(uint8_t *ninebytes){
|
|||||||
perror("Can't write to Trinamic");
|
perror("Can't write to Trinamic");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if((L = read_tty())){
|
||||||
|
printf("got %zd bytes from tty: ", L);
|
||||||
|
check_tty_sig(L);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillbuf(char *command){
|
void process_buf(char *command){
|
||||||
memset(buf, 0, 9);
|
memset(buf, 0, 9);
|
||||||
buf[0] = 1; // controller #
|
buf[0] = 1; // controller #
|
||||||
|
if(command[0] == 'W'){ // 1/16
|
||||||
|
buf[1] = 5;
|
||||||
|
buf[2] = 140; // ustep resolution
|
||||||
|
buf[7] = 4; // 1/16
|
||||||
|
send_command(buf);
|
||||||
|
buf[3] = 2; // motor #2
|
||||||
|
send_command(buf);
|
||||||
|
return;
|
||||||
|
}else if(command[0] == 'S'){ // change current speed
|
||||||
|
long X = strtol(&command[1], NULL, 10);
|
||||||
|
if(X > 9 && X < 501){
|
||||||
|
motor_speed = (uint32_t) X;
|
||||||
|
printf("set speed to %u\n", motor_speed);
|
||||||
|
buf[1] = 5; // SAP
|
||||||
|
buf[2] = 4; // max pos speed
|
||||||
|
inttobuf(buf, motor_speed);
|
||||||
|
send_command(buf);
|
||||||
|
buf[3] = 2; // 2nd motor
|
||||||
|
send_command(buf);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(command[1] == '0'){ // go to start point for further moving to middle
|
||||||
|
if(command[0] == 'U') return;
|
||||||
|
uint8_t wt[] = {1,138,0,0,0,0,0,5,0};
|
||||||
|
uint8_t movbk[]= {1,4,1,0,0,0,0,0,0};
|
||||||
|
inttobuf(movbk, -4500); // 1st motor
|
||||||
|
send_command(movbk);
|
||||||
|
movbk[3] = 2;
|
||||||
|
inttobuf(movbk, -7300); // 2nd motor
|
||||||
|
send_command(movbk);
|
||||||
|
send_command(wt); // wait
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(command[1] == 'X') buf[3] = 2; // X motor -> #2
|
if(command[1] == 'X') buf[3] = 2; // X motor -> #2
|
||||||
else buf[3] = 0; // Y motor -> #0
|
else if(command[1] == 'Y') buf[3] = 0; // Y motor -> #0
|
||||||
if(command[0] == 'D'){ // start moving
|
if(command[0] == 'D'){ // start moving
|
||||||
if(command[2] == '+') buf[1] = 1; // ROR
|
if(command[2] == '+') buf[1] = 1; // ROR
|
||||||
else buf[1] = 2; // ROL
|
else if(command[2] == '-') buf[1] = 2; // ROL
|
||||||
}else{ // stop
|
}else if(command[0] == 'U'){ // stop
|
||||||
buf[1] = 3; // STP
|
buf[1] = 3; // STP
|
||||||
}
|
}
|
||||||
buf[7] = 50; // speed = 50
|
inttobuf(buf, motor_speed);
|
||||||
send_command(buf);
|
if(!send_command(buf)){
|
||||||
|
printf("Can't send command");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void move_motor(char *where){
|
#define MESG(X) do{if(dat) put_message_to_queue(X, dat);}while(0)
|
||||||
printf("moving %s\n", where);
|
void websig(char *command, per_session_data *dat){
|
||||||
|
if(command[0] == 'W' || command[1] == '0' || command[0] == 'S'){
|
||||||
}
|
if(command[0] == 'W'){
|
||||||
void stop_motor(char *where){
|
MESG("Set microstepping to 1/16");
|
||||||
printf("stoping %s\n", where);
|
}else if(command[1] == '0'){
|
||||||
|
MESG("Go to the middle. Please, wait!");
|
||||||
|
}else{
|
||||||
|
MESG("Change speed");
|
||||||
|
}
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
if(command[1] != 'X' && command[1] != 'Y'){ // error
|
||||||
|
MESG("Undefined coordinate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(command[0] != 'D' && command[0] != 'U'){
|
||||||
|
MESG("Undefined command");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ret:
|
||||||
|
pthread_mutex_lock(&command_mutex);
|
||||||
|
strncpy(cmd_buf, command, 4);
|
||||||
|
data_in_buf = 1;
|
||||||
|
pthread_mutex_unlock(&command_mutex);
|
||||||
|
while(data_in_buf); // wait for execution
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void dump_handshake_info(struct libwebsocket *wsi){
|
||||||
my_protocol_callback(_U_ struct libwebsocket_context *context,
|
int n;
|
||||||
|
static const char *token_names[] = {
|
||||||
|
"GET URI",
|
||||||
|
"POST URI",
|
||||||
|
"OPTIONS URI",
|
||||||
|
"Host",
|
||||||
|
"Connection",
|
||||||
|
"key 1",
|
||||||
|
"key 2",
|
||||||
|
"Protocol",
|
||||||
|
"Upgrade",
|
||||||
|
"Origin",
|
||||||
|
"Draft",
|
||||||
|
"Challenge",
|
||||||
|
|
||||||
|
/* new for 04 */
|
||||||
|
"Key",
|
||||||
|
"Version",
|
||||||
|
"Sworigin",
|
||||||
|
|
||||||
|
/* new for 05 */
|
||||||
|
"Extensions",
|
||||||
|
|
||||||
|
/* client receives these */
|
||||||
|
"Accept",
|
||||||
|
"Nonce",
|
||||||
|
"Http",
|
||||||
|
|
||||||
|
/* http-related */
|
||||||
|
"Accept:",
|
||||||
|
"Ac-Request-Headers:",
|
||||||
|
"If-Modified-Since:",
|
||||||
|
"If-None-Match:",
|
||||||
|
"Accept-Encoding:",
|
||||||
|
"Accept-Language:",
|
||||||
|
"Pragma:",
|
||||||
|
"Cache-Control:",
|
||||||
|
"Authorization:",
|
||||||
|
"Cookie:",
|
||||||
|
"Content-Length:",
|
||||||
|
"Content-Type:",
|
||||||
|
"Date:",
|
||||||
|
"Range:",
|
||||||
|
"Referer:",
|
||||||
|
"Uri-Args:",
|
||||||
|
|
||||||
|
|
||||||
|
"MuxURL",
|
||||||
|
|
||||||
|
/* use token storage to stash these */
|
||||||
|
|
||||||
|
"Client sent protocols",
|
||||||
|
"Client peer address",
|
||||||
|
"Client URI",
|
||||||
|
"Client host",
|
||||||
|
"Client origin",
|
||||||
|
|
||||||
|
/* always last real token index*/
|
||||||
|
"WSI token count"
|
||||||
|
};
|
||||||
|
char buf[256];
|
||||||
|
int L = sizeof(token_names) / sizeof(token_names[0]);
|
||||||
|
for (n = 0; n < L; n++) {
|
||||||
|
if (!lws_hdr_total_length(wsi, n))
|
||||||
|
continue;
|
||||||
|
lws_hdr_copy(wsi, buf, sizeof buf, n);
|
||||||
|
printf(" %s = %s\n", token_names[n], buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int my_protocol_callback(_U_ struct libwebsocket_context *context,
|
||||||
_U_ struct libwebsocket *wsi,
|
_U_ struct libwebsocket *wsi,
|
||||||
enum libwebsocket_callback_reasons reason,
|
enum libwebsocket_callback_reasons reason,
|
||||||
_U_ void *user, void *in, _U_ size_t len)
|
_U_ void *user, void *in, _U_ size_t len){
|
||||||
{
|
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MESSAGE_LEN +
|
||||||
//int n, m;
|
LWS_SEND_BUFFER_POST_PADDING];
|
||||||
//unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
|
unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
|
||||||
// LWS_SEND_BUFFER_POST_PADDING];
|
char client_name[128];
|
||||||
//unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
|
char client_ip[128];
|
||||||
|
char *M, *msg = (char*) in;
|
||||||
char *msg = (char*) in;
|
per_session_data *dat = (per_session_data *) user;
|
||||||
|
int L, W;
|
||||||
|
void parse_queue_msg(per_session_data *d){
|
||||||
|
if((M = get_message_from_queue(d))){
|
||||||
|
L = strlen(M);
|
||||||
|
strncpy((char *)p, M, L);
|
||||||
|
W = libwebsocket_write(wsi, p, L, LWS_WRITE_TEXT);
|
||||||
|
if(L != W){
|
||||||
|
lwsl_err("Can't write to socket");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//struct lws_tokens *tok = (struct lws_tokens *) user;
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
|
|
||||||
case LWS_CALLBACK_ESTABLISHED:
|
case LWS_CALLBACK_ESTABLISHED:
|
||||||
printf("New Connection\n");
|
printf("New Connection\n");
|
||||||
|
memset(dat, 0, sizeof(per_session_data));
|
||||||
|
libwebsocket_callback_on_writable(context, wsi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||||
|
if(dat->num == 0 && global_queue.num == 0){
|
||||||
|
libwebsocket_callback_on_writable(context, wsi);
|
||||||
|
return 0;
|
||||||
|
}else{
|
||||||
|
parse_queue_msg(dat);
|
||||||
|
parse_queue_msg(&global_queue);
|
||||||
|
libwebsocket_callback_on_writable(context, wsi);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWS_CALLBACK_RECEIVE:
|
case LWS_CALLBACK_RECEIVE:
|
||||||
fillbuf(msg);
|
websig(msg, dat);
|
||||||
|
break;
|
||||||
|
case LWS_CALLBACK_FILTER_NETWORK_CONNECTION:
|
||||||
|
libwebsockets_get_peer_addresses(context, wsi, (int)(long)in,
|
||||||
|
client_name, 127, client_ip, 127);
|
||||||
|
printf("Received network connection from %s (%s)\n",
|
||||||
|
client_name, client_ip);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
|
case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
|
||||||
|
printf("Client asks for %s\n", msg);
|
||||||
|
dump_handshake_info(wsi);
|
||||||
|
break;
|
||||||
|
case LWS_CALLBACK_CLOSED:
|
||||||
|
printf("Client disconnected\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//**************************************************************************//
|
//**************************************************************************//
|
||||||
/* list of supported protocols and callbacks */
|
/* list of supported protocols and callbacks */
|
||||||
//**************************************************************************//
|
//**************************************************************************//
|
||||||
@ -105,43 +402,37 @@ static struct libwebsocket_protocols protocols[] = {
|
|||||||
{
|
{
|
||||||
"XY-protocol", // name
|
"XY-protocol", // name
|
||||||
my_protocol_callback, // callback
|
my_protocol_callback, // callback
|
||||||
30, // per_session_data_size
|
sizeof(per_session_data), // per_session_data_size
|
||||||
10, // max frame size / rx buffer
|
10, // max frame size / rx buffer
|
||||||
0, NULL, 0
|
0, NULL, 0
|
||||||
},
|
},
|
||||||
{ NULL, NULL, 0, 0, 0, NULL, 0} /* terminator */
|
{ NULL, NULL, 0, 0, 0, NULL, 0} /* terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
//**************************************************************************//
|
//**************************************************************************//
|
||||||
void sighandler(_U_ int sig){
|
void sighandler(_U_ int sig){
|
||||||
close(comfd);
|
close(comfd);
|
||||||
force_exit = 1;
|
force_exit = 1;
|
||||||
}
|
}
|
||||||
//**************************************************************************//
|
|
||||||
//**************************************************************************//
|
void *websock_thread(_U_ void *buf){
|
||||||
int main(_U_ int argc, _U_ char **argv)
|
|
||||||
{
|
|
||||||
int n = 0;
|
|
||||||
struct libwebsocket_context *context;
|
struct libwebsocket_context *context;
|
||||||
|
int n = 0;
|
||||||
int opts = 0;
|
int opts = 0;
|
||||||
const char *iface = NULL;
|
const char *iface = NULL;
|
||||||
int syslog_options = LOG_PID | LOG_PERROR;
|
int syslog_options = LOG_PID | LOG_PERROR;
|
||||||
//unsigned int oldus = 0;
|
//unsigned int oldus = 0;
|
||||||
struct lws_context_creation_info info;
|
struct lws_context_creation_info info;
|
||||||
|
|
||||||
int debug_level = 7;
|
int debug_level = 7;
|
||||||
|
|
||||||
|
if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)){
|
||||||
|
force_exit = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&info, 0, sizeof info);
|
memset(&info, 0, sizeof info);
|
||||||
info.port = 9999;
|
info.port = 9999;
|
||||||
|
|
||||||
signal(SIGINT, sighandler);
|
|
||||||
|
|
||||||
printf("\nOpen port...\n");
|
|
||||||
if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){
|
|
||||||
fprintf(stderr,"Can't use port %s\n",comdev);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* we will only try to log things according to our debug_level */
|
/* we will only try to log things according to our debug_level */
|
||||||
setlogmask(LOG_UPTO (LOG_DEBUG));
|
setlogmask(LOG_UPTO (LOG_DEBUG));
|
||||||
openlog("lwsts", syslog_options, LOG_DAEMON);
|
openlog("lwsts", syslog_options, LOG_DAEMON);
|
||||||
@ -160,24 +451,50 @@ int main(_U_ int argc, _U_ char **argv)
|
|||||||
info.options = opts;
|
info.options = opts;
|
||||||
|
|
||||||
context = libwebsocket_create_context(&info);
|
context = libwebsocket_create_context(&info);
|
||||||
if (context == NULL) {
|
if (context == NULL){
|
||||||
lwsl_err("libwebsocket init failed\n");
|
lwsl_err("libwebsocket init failed\n");
|
||||||
return -1;
|
force_exit = 1;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = 0;
|
while(n >= 0 && !force_exit){
|
||||||
while (n >= 0 && !force_exit) {
|
n = libwebsocket_service(context, 500);
|
||||||
|
}//while n>=0
|
||||||
n = libwebsocket_service(context, 50);
|
|
||||||
|
|
||||||
};//while n>=0
|
|
||||||
|
|
||||||
|
|
||||||
libwebsocket_context_destroy(context);
|
libwebsocket_context_destroy(context);
|
||||||
|
|
||||||
lwsl_notice("libwebsockets-test-server exited cleanly\n");
|
lwsl_notice("libwebsockets-test-server exited cleanly\n");
|
||||||
|
|
||||||
closelog();
|
closelog();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//**************************************************************************//
|
||||||
|
int main(_U_ int argc, _U_ char **argv){
|
||||||
|
pthread_t w_thread;
|
||||||
|
size_t L;
|
||||||
|
|
||||||
|
signal(SIGINT, sighandler);
|
||||||
|
|
||||||
|
if(argc == 2) comdev = argv[1];
|
||||||
|
|
||||||
|
printf("\nOpen port %s...\n", comdev);
|
||||||
|
if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){
|
||||||
|
fprintf(stderr,"Can't use port %s\n",comdev);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
process_buf("W"); // step: 1/16
|
||||||
|
|
||||||
|
pthread_create(&w_thread, NULL, websock_thread, NULL);
|
||||||
|
|
||||||
|
while(!force_exit){
|
||||||
|
if((L = read_tty())){
|
||||||
|
printf("got %zd bytes from tty:\n", L);
|
||||||
|
check_tty_sig(L);
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&command_mutex);
|
||||||
|
if(data_in_buf) process_buf(cmd_buf);
|
||||||
|
data_in_buf = 0;
|
||||||
|
pthread_mutex_unlock(&command_mutex);
|
||||||
|
}
|
||||||
|
pthread_join(w_thread, NULL); // wait for closing of libsockets thread
|
||||||
return 0;
|
return 0;
|
||||||
}//main
|
}//main
|
||||||
|
|||||||
@ -16,13 +16,17 @@
|
|||||||
<td></td></tr>
|
<td></td></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align='center'><button id='X-'>X-</button></td>
|
<td align='center'><button id='X-'>X-</button></td>
|
||||||
<td></td>
|
<td><button id='0'>0</button></td>
|
||||||
<td align='center'><button id='X+'>X+</button></td>
|
<td align='center'><button id='X+'>X+</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td></td>
|
<tr><td></td>
|
||||||
<td align='center'><button id='Y-'>Y-</button></td>
|
<td align='center'><button id='Y-'>Y-</button></td>
|
||||||
<td></td></tr>
|
<td></td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
<div class="content">
|
||||||
|
Speed: <input type="range" min="10" max="200" step="1" id="speed">
|
||||||
|
<span id="curspeed">50</span>
|
||||||
|
</div>
|
||||||
<p></p>
|
<p></p>
|
||||||
<div id = "connected">No connection</div>
|
<div id = "connected">No connection</div>
|
||||||
<div id = "answer"></div>
|
<div id = "answer"></div>
|
||||||
@ -31,6 +35,8 @@
|
|||||||
Global = function(){
|
Global = function(){
|
||||||
var socket = null;
|
var socket = null;
|
||||||
var connected = 0;
|
var connected = 0;
|
||||||
|
var globSpeed = 50;
|
||||||
|
function $(nm){return document.getElementById(nm);}
|
||||||
function get_appropriate_ws_url(){
|
function get_appropriate_ws_url(){
|
||||||
var pcol;
|
var pcol;
|
||||||
var u = document.URL;
|
var u = document.URL;
|
||||||
@ -55,19 +61,23 @@ Global = function(){
|
|||||||
socket = new WebSocket(get_appropriate_ws_url(),
|
socket = new WebSocket(get_appropriate_ws_url(),
|
||||||
"XY-protocol");
|
"XY-protocol");
|
||||||
}
|
}
|
||||||
|
if(!socket){
|
||||||
|
alert("Error: can't create websocket!\nMake sure that your browser supports websockets");
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
socket.onopen = function(){
|
socket.onopen = function(){
|
||||||
document.getElementById("connected").style.backgroundColor = "#40ff40";
|
$("connected").style.backgroundColor = "#40ff40";
|
||||||
document.getElementById("connected").textContent = "Connection opened";
|
$("connected").textContent = "Connection opened";
|
||||||
connected = 1;
|
connected = 1;
|
||||||
}
|
}
|
||||||
socket.onmessage = function got_packet(msg) {
|
socket.onmessage = function got_packet(msg) {
|
||||||
document.getElementById("answer").textContent = msg.data + "\n";
|
$("answer").textContent = msg.data;
|
||||||
}
|
}
|
||||||
socket.onclose = function(){
|
socket.onclose = function(){
|
||||||
document.getElementById("connected").style.backgroundColor = "#ff4040";
|
$("connected").style.backgroundColor = "#ff4040";
|
||||||
document.getElementById("connected").textContent = "Connection closed";
|
$("connected").textContent = "Connection closed";
|
||||||
document.getElementById("answer").textContent = "";
|
$("answer").textContent = "";
|
||||||
connected = 0;
|
connected = 0;
|
||||||
setTimeout(TryConnect, 1000);
|
setTimeout(TryConnect, 1000);
|
||||||
}
|
}
|
||||||
@ -83,20 +93,36 @@ Global = function(){
|
|||||||
//Buttons[i].addEventListener("click", btnclick);
|
//Buttons[i].addEventListener("click", btnclick);
|
||||||
Buttons[i].addEventListener("mousedown", btnmousedown);
|
Buttons[i].addEventListener("mousedown", btnmousedown);
|
||||||
Buttons[i].addEventListener("mouseup", btnmouseup);
|
Buttons[i].addEventListener("mouseup", btnmouseup);
|
||||||
|
Buttons[i].addEventListener("mouseout", btnmouseup);
|
||||||
|
Buttons[i].pressed = 0;
|
||||||
}
|
}
|
||||||
|
$("speed").value = globSpeed
|
||||||
|
$("speed").addEventListener("input", ChSpd);
|
||||||
|
$("speed").addEventListener("mouseup", SetSpd);
|
||||||
TryConnect();
|
TryConnect();
|
||||||
}
|
}
|
||||||
/*function btnclick(){
|
/*function btnclick(){
|
||||||
console.log("Click: " + this.id);
|
console.log("Click: " + this.id);
|
||||||
}*/
|
}*/
|
||||||
function btnmouseup(){
|
function btnmouseup(){
|
||||||
|
if(this.pressed == 0) return; // this function calls also from "mouseout", so we must prevent stopping twice
|
||||||
|
this.pressed = 0;
|
||||||
console.log("Mouse up: " + this.id);
|
console.log("Mouse up: " + this.id);
|
||||||
if(connected) socket.send("U"+this.id);
|
if(connected) socket.send("U"+this.id);
|
||||||
}
|
}
|
||||||
function btnmousedown(){
|
function btnmousedown(){
|
||||||
|
this.pressed = 1;
|
||||||
console.log("Mouse down: " + this.id);
|
console.log("Mouse down: " + this.id);
|
||||||
if(connected) socket.send("D"+this.id);
|
if(connected) socket.send("D"+this.id);
|
||||||
}
|
}
|
||||||
|
function ChSpd(){
|
||||||
|
if(globSpeed == this.value) return;
|
||||||
|
globSpeed = this.value;
|
||||||
|
$("curspeed").textContent = globSpeed;
|
||||||
|
}
|
||||||
|
function SetSpd(){
|
||||||
|
if(connected) socket.send("S"+globSpeed);
|
||||||
|
}
|
||||||
return{
|
return{
|
||||||
init: init
|
init: init
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user