# HG changeset patch # User John Tsiombikas # Date 1457922059 -7200 # Node ID 08ea0abdbb8aadaf4626cfb4f08ed9b2ee515caa # Parent 73b16c2ae6bf9e7b071a5a1d23f880174e90f8d8 argument parsing diff -r 73b16c2ae6bf -r 08ea0abdbb8a doorbelld/src/main.c --- a/doorbelld/src/main.c Sun Mar 13 07:56:26 2016 +0200 +++ b/doorbelld/src/main.c Mon Mar 14 04:20:59 2016 +0200 @@ -10,8 +10,11 @@ void *frame_proc(void *arg); int save_image(const char *fname, unsigned char *pixels, int xsz, int ysz); void sighandler(int s); +int parse_args(int argc, char **argv); -int fd; +const char *devfile = "/dev/video0"; +int fd = -1; +int port = 2828; int width = 640; int height = 480; int framerate = 30; @@ -23,18 +26,17 @@ int main(int argc, char **argv) { - char *devfile = "/dev/video0"; pthread_t thread; - if(argv[1]) { - devfile = argv[1]; + if(parse_args(argc, argv) == -1) { + return 1; } signal(SIGINT, sighandler); signal(SIGQUIT, sighandler); signal(SIGSEGV, sighandler); - if(srv_init(2828) == -1) { + if(srv_init(port) == -1) { return 1; } @@ -42,12 +44,28 @@ perror("failed to allocate frame"); return 1; } - - if((fd = wcam_open(devfile, width, height, framerate)) == -1) { - fprintf(stderr, "failed to open video device: %s\n", devfile); - return 1; + if(devfile) { + if((fd = wcam_open(devfile, width, height, framerate)) == -1) { + fprintf(stderr, "failed to open video device: %s\n", devfile); + return 1; + } + wcam_start(fd); + } else { + int i, j; + unsigned char *pptr = frame; + for(i=0; i maxfd) maxfd = fd; + FD_ZERO(&rdset); - FD_ZERO(&rdset); - FD_SET(fd, &rdset); + if(fd != -1) { + if(fd > maxfd) maxfd = fd; + FD_SET(fd, &rdset); + printf("select on socket: %d (video)\n", fd); + } for(i=0; i\n"); + printf(" -f,-fps \n"); + printf(" -d,-device \n"); + printf(" -p,-port \n"); + printf(" -novideo\n"); + printf(" -h,-help\n"); +} + +int parse_args(int argc, char **argv) +{ + int i; + + for(i=1; i= 65535) { + fprintf(stderr, "invalid port specified: %s\n", argv[i - 1]); + return -1; + } + } else { + int help = strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0; + if(!help) fprintf(stderr, "unrecognized option: %s\n", argv[i]); + print_usage(argv[0]); + exit(help ? 0 : 1); + } + } else { + fprintf(stderr, "unexpected argument: %s\n", argv[i]); + print_usage(argv[0]); + return -1; + } + } + return 0; +} diff -r 73b16c2ae6bf -r 08ea0abdbb8a doorbelld/src/srv.c --- a/doorbelld/src/srv.c Sun Mar 13 07:56:26 2016 +0200 +++ b/doorbelld/src/srv.c Mon Mar 14 04:20:59 2016 +0200 @@ -10,6 +10,8 @@ #include "srv.h" #include "dynarr.h" +/* TODO convert this whole thing to multicast */ + static int lis_sock = -1, max_socket = -1; static int *csock; @@ -45,6 +47,7 @@ lis_sock = -1; return -1; } + listen(lis_sock, 8); return 0; } @@ -84,16 +87,19 @@ if(s == lis_sock) { /* incoming connection */ struct sockaddr_in addr; - int addr_size; - - if((s = accept(lis_sock, (struct sockaddr*)&addr, (int*)&addr_size)) == -1) { - fprintf(stderr, "%s: failed to accept incoming connection\n", __func__); + socklen_t addr_size = sizeof addr; + if((s = accept(lis_sock, (struct sockaddr*)&addr, &addr_size)) == -1) { + fprintf(stderr, "%s: failed to accept incoming connection: %s\n", __func__, strerror(errno)); return -1; } printf("%s: incoming connection from %s:%d\n", __func__, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); csock = dynarr_push(csock, &s); assert(csock); + if(s > max_socket) { + max_socket = s; + } + fcntl(s, F_SETFD, fcntl(s, F_GETFD) | O_NONBLOCK); return 0; } @@ -101,23 +107,44 @@ while((sz = read(s, buf, sizeof buf - 1)) > 0) { printf("%s: got data: %s\n", __func__, buf); } - if(sz < 0 && errno != EAGAIN) { + if(sz <= 0 && errno != EAGAIN) { /* client closed connection probably */ int i, num_clients = dynarr_size(csock); printf("%s: removing client\n", __func__); close(s); + max_socket = lis_sock; for(i=0; i max_socket) { + max_socket = csock[i]; } } - assert(i < num_clients); + + csock = dynarr_pop(csock); + --num_clients; } return 0; } +struct video_block { + int frame; + int x, y; + int width, height; + char pixels[1]; +}; +#define VBLOCK_HEADER_SIZE (offsetof(struct video_block, pixels)) + void srv_send_frame(unsigned char *frame, int xsz, int ysz) { + static unsigned char *buffer; + struct video_block *vblock; + + /* for now just send a big block */ + if(!buffer && !(buffer = malloc(xsz * ysz * 2) + VBLOCK_HEADER_SIZE)) { + fprintf(stderr, "failed to allocate frame send buffer\n"); + return; + } + vblock = buffer; }