mirror of
https://github.com/gtxaspec/wz_mini_hacks.git
synced 2025-10-13 02:48:10 +00:00
move sources into seperate folder
This commit is contained in:
195
src/libcallback_wz_mod/command.c
Normal file
195
src/libcallback_wz_mod/command.c
Normal file
@@ -0,0 +1,195 @@
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
static const unsigned short CommandPort = 4000;
|
||||
static int SelfPipe[2];
|
||||
|
||||
extern char *JpegCapture(int fd, char *tokenPtr);
|
||||
extern char *VideoCapture(int fd, char *tokenPtr);
|
||||
extern char *AudioCapture(int fd, char *tokenPtr);
|
||||
extern char *MotorMove(int fd, char *tokenPtr);
|
||||
extern char *WaitMotion(int fd, char *tokenPtr);
|
||||
extern char *IrLed(int fd, char *tokenPtr);
|
||||
extern char *AudioPlay(int fd, char *tokenPtr);
|
||||
extern char *mp4Write(int fd, char *tokenPtr);
|
||||
|
||||
struct CommandTableSt {
|
||||
const char *cmd;
|
||||
char * (*func)(int, char *);
|
||||
};
|
||||
|
||||
struct CommandTableSt CommandTable[] = {
|
||||
{ "video", &VideoCapture },
|
||||
{ "audio", &AudioCapture },
|
||||
{ "jpeg", &JpegCapture },
|
||||
{ "move", &MotorMove },
|
||||
{ "waitMotion", &WaitMotion },
|
||||
{ "irled", &IrLed },
|
||||
{ "aplay", &AudioPlay },
|
||||
{ "mp4write", &mp4Write },
|
||||
|
||||
};
|
||||
|
||||
void CommandResponse(int fd, const char *res) {
|
||||
|
||||
unsigned char buf[256];
|
||||
buf[0] = strlen(res) + 1;
|
||||
buf[1] = fd;
|
||||
strncpy((char *)buf + 2, res, 253);
|
||||
write(SelfPipe[1], &buf, buf[0] + 2);
|
||||
}
|
||||
|
||||
static void *CommandThread(void *arg) {
|
||||
|
||||
static const int MaxConnect = 255;
|
||||
int maxFd = 0;
|
||||
fd_set targetFd;
|
||||
|
||||
int listenSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(listenSocket < 0) {
|
||||
fprintf(stderr, "socket : %s\n", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
int sock_optval = 1;
|
||||
if(setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR,
|
||||
&sock_optval, sizeof(sock_optval)) == -1) {
|
||||
fprintf(stderr, "setsockopt : %s\n", strerror(errno));
|
||||
close(listenSocket);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sockaddr_in saddr;
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_port = htons(CommandPort);
|
||||
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if(bind(listenSocket, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
|
||||
fprintf(stderr, "bind : %s\n", strerror(errno));
|
||||
close(listenSocket);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(listen(listenSocket, MaxConnect) == -1) {
|
||||
fprintf(stderr, "listen : %s\n", strerror(errno));
|
||||
close(listenSocket);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FD_ZERO(&targetFd);
|
||||
FD_SET(listenSocket, &targetFd);
|
||||
maxFd = listenSocket;
|
||||
FD_SET(SelfPipe[0], &targetFd);
|
||||
maxFd = (SelfPipe[0] > maxFd) ? SelfPipe[0] : maxFd;
|
||||
if(maxFd >= MaxConnect) maxFd = MaxConnect - 1;
|
||||
|
||||
while(1) {
|
||||
fd_set checkFDs;
|
||||
memcpy(&checkFDs, &targetFd, sizeof(targetFd));
|
||||
if(select(maxFd + 1, &checkFDs, NULL, NULL, NULL) == -1) {
|
||||
fprintf(stderr, "select error : %s\n", strerror(errno));
|
||||
} else {
|
||||
for(int fd = maxFd; fd >= 0; fd--) {
|
||||
if(FD_ISSET(fd, &checkFDs)) {
|
||||
if(fd == SelfPipe[0]) {
|
||||
while(1) {
|
||||
unsigned char buf[256];
|
||||
int length = read(SelfPipe[0], buf, 2);
|
||||
if(length <= 1) break;
|
||||
int resSize = buf[0];
|
||||
int resFd = buf[1];
|
||||
length = read(SelfPipe[0], buf, resSize);
|
||||
if(length < resSize) break;
|
||||
char *res = (char *)buf;
|
||||
if(strlen(res)) {
|
||||
strcat(res, "\n");
|
||||
send(resFd, res, strlen(res) + 1, 0);
|
||||
}
|
||||
close(resFd);
|
||||
FD_CLR(resFd, &targetFd);
|
||||
}
|
||||
} else if(fd == listenSocket) {
|
||||
struct sockaddr_in dstAddr;
|
||||
int len = sizeof(dstAddr);
|
||||
int newSocket = accept(fd, (struct sockaddr *)&dstAddr, (socklen_t *)&len);
|
||||
if(newSocket < 0) {
|
||||
fprintf(stderr, "Socket::Accept Error\n");
|
||||
continue;
|
||||
}
|
||||
if(strcmp(inet_ntoa(dstAddr.sin_addr), "127.0.0.1")) {
|
||||
fprintf(stderr, "Rejected request from %s\n", inet_ntoa(dstAddr.sin_addr));
|
||||
close(newSocket);
|
||||
continue;
|
||||
}
|
||||
int flag = fcntl(newSocket, F_GETFL, 0);
|
||||
fcntl(newSocket, F_SETFL, O_NONBLOCK|flag);
|
||||
FD_SET(newSocket, &targetFd);
|
||||
maxFd = (newSocket > maxFd) ? newSocket : maxFd;
|
||||
if(maxFd >= MaxConnect) maxFd = MaxConnect - 1;
|
||||
} else {
|
||||
char buf[256];
|
||||
int size = recv(fd, buf, 255, 0);
|
||||
if(!size) {
|
||||
FD_CLR(fd, &targetFd);
|
||||
break;
|
||||
}
|
||||
if(size < 0) {
|
||||
close(fd);
|
||||
FD_CLR(fd, &targetFd);
|
||||
break;
|
||||
}
|
||||
buf[size] = 0;
|
||||
char *tokenPtr;
|
||||
char *p = strtok_r(buf, " \t\r\n", &tokenPtr);
|
||||
if(!p) continue;
|
||||
int executed = 0;
|
||||
for(int i = 0; i < sizeof(CommandTable) / sizeof(struct CommandTableSt); i++) {
|
||||
if(!strcasecmp(p, CommandTable[i].cmd)) {
|
||||
char *res = (*CommandTable[i].func)(fd, tokenPtr);
|
||||
if(res) {
|
||||
send(fd, res, strlen(res) + 1, 0);
|
||||
char cr = '\n';
|
||||
send(fd, &cr, 1, 0);
|
||||
close(fd);
|
||||
FD_CLR(fd, &targetFd);
|
||||
}
|
||||
executed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!executed) {
|
||||
char *res = "error";
|
||||
send(fd, res, strlen(res) + 1, 0);
|
||||
close(fd);
|
||||
FD_CLR(fd, &targetFd);
|
||||
fprintf(stderr, "command error : %s\n", p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute ((constructor)) command_init(void) {
|
||||
|
||||
if(pipe(SelfPipe)) {
|
||||
fprintf(stderr, "pipe error\n");
|
||||
return;
|
||||
}
|
||||
int flag = fcntl(SelfPipe[0], F_GETFL, 0);
|
||||
fcntl(SelfPipe[0], F_SETFL, O_NONBLOCK|flag);
|
||||
flag = fcntl(SelfPipe[1], F_GETFL, 0);
|
||||
fcntl(SelfPipe[1], F_SETFL, O_NONBLOCK|flag);
|
||||
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, CommandThread, NULL);
|
||||
}
|
Reference in New Issue
Block a user