nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include nuclear@2: #include "srv.h" nuclear@2: #include "dynarr.h" nuclear@2: nuclear@4: /* TODO convert this whole thing to multicast */ nuclear@4: nuclear@2: static int lis_sock = -1, max_socket = -1; nuclear@2: static int *csock; nuclear@2: nuclear@2: int srv_init(int port) nuclear@2: { nuclear@2: struct sockaddr_in addr; nuclear@2: nuclear@2: if(lis_sock != -1) { nuclear@2: fprintf(stderr, "%s: already running\n", __func__); nuclear@2: return -1; nuclear@2: } nuclear@2: nuclear@2: if((lis_sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) { nuclear@2: fprintf(stderr, "%s: failed to create listening socket\n", __func__); nuclear@2: return -1; nuclear@2: } nuclear@2: if(!(csock = dynarr_alloc(1, sizeof *csock))) { nuclear@2: fprintf(stderr, "%s: failed to allocate client socket array\n", __func__); nuclear@2: return -1; nuclear@2: } nuclear@2: csock[0] = lis_sock; nuclear@2: max_socket = lis_sock; nuclear@2: nuclear@2: fcntl(lis_sock, F_SETFD, fcntl(lis_sock, F_GETFD) | O_NONBLOCK); nuclear@2: nuclear@2: memset(&addr, 0, sizeof addr); nuclear@2: addr.sin_family = AF_INET; nuclear@2: addr.sin_port = htons(port); nuclear@2: addr.sin_addr.s_addr = INADDR_ANY; nuclear@2: if(bind(lis_sock, (struct sockaddr*)&addr, sizeof addr) == -1) { nuclear@2: fprintf(stderr, "%s: failed to bind port %d\n", __func__, port); nuclear@2: close(lis_sock); nuclear@2: lis_sock = -1; nuclear@2: return -1; nuclear@2: } nuclear@4: listen(lis_sock, 8); nuclear@2: nuclear@2: return 0; nuclear@2: } nuclear@2: nuclear@2: void srv_shutdown(void) nuclear@2: { nuclear@2: int i, sz = dynarr_size(csock); nuclear@2: for(i=0; i max_socket) { nuclear@4: max_socket = s; nuclear@4: } nuclear@4: fcntl(s, F_SETFD, fcntl(s, F_GETFD) | O_NONBLOCK); nuclear@2: return 0; nuclear@2: } nuclear@2: nuclear@2: /* handle client */ nuclear@2: while((sz = read(s, buf, sizeof buf - 1)) > 0) { nuclear@2: printf("%s: got data: %s\n", __func__, buf); nuclear@2: } nuclear@4: if(sz <= 0 && errno != EAGAIN) { nuclear@2: /* client closed connection probably */ nuclear@2: int i, num_clients = dynarr_size(csock); nuclear@2: printf("%s: removing client\n", __func__); nuclear@2: close(s); nuclear@4: max_socket = lis_sock; nuclear@2: for(i=0; i max_socket) { nuclear@4: max_socket = csock[i]; nuclear@2: } nuclear@2: } nuclear@4: nuclear@4: csock = dynarr_pop(csock); nuclear@4: --num_clients; nuclear@2: } nuclear@2: return 0; nuclear@2: } nuclear@2: nuclear@4: struct video_block { nuclear@4: int frame; nuclear@4: int x, y; nuclear@4: int width, height; nuclear@4: char pixels[1]; nuclear@4: }; nuclear@4: #define VBLOCK_HEADER_SIZE (offsetof(struct video_block, pixels)) nuclear@4: nuclear@2: void srv_send_frame(unsigned char *frame, int xsz, int ysz) nuclear@2: { nuclear@4: static unsigned char *buffer; nuclear@4: struct video_block *vblock; nuclear@4: nuclear@4: /* for now just send a big block */ nuclear@4: if(!buffer && !(buffer = malloc(xsz * ysz * 2) + VBLOCK_HEADER_SIZE)) { nuclear@4: fprintf(stderr, "failed to allocate frame send buffer\n"); nuclear@4: return; nuclear@4: } nuclear@4: vblock = buffer; nuclear@2: }