doorbell
view doorbelld/src/srv.c @ 2:d3f2a2b19504
doorbell server under construction
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 13 Mar 2016 07:56:03 +0200 |
parents | |
children | 08ea0abdbb8a |
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <assert.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <sys/socket.h>
9 #include <arpa/inet.h>
10 #include "srv.h"
11 #include "dynarr.h"
13 static int lis_sock = -1, max_socket = -1;
14 static int *csock;
16 int srv_init(int port)
17 {
18 struct sockaddr_in addr;
20 if(lis_sock != -1) {
21 fprintf(stderr, "%s: already running\n", __func__);
22 return -1;
23 }
25 if((lis_sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
26 fprintf(stderr, "%s: failed to create listening socket\n", __func__);
27 return -1;
28 }
29 if(!(csock = dynarr_alloc(1, sizeof *csock))) {
30 fprintf(stderr, "%s: failed to allocate client socket array\n", __func__);
31 return -1;
32 }
33 csock[0] = lis_sock;
34 max_socket = lis_sock;
36 fcntl(lis_sock, F_SETFD, fcntl(lis_sock, F_GETFD) | O_NONBLOCK);
38 memset(&addr, 0, sizeof addr);
39 addr.sin_family = AF_INET;
40 addr.sin_port = htons(port);
41 addr.sin_addr.s_addr = INADDR_ANY;
42 if(bind(lis_sock, (struct sockaddr*)&addr, sizeof addr) == -1) {
43 fprintf(stderr, "%s: failed to bind port %d\n", __func__, port);
44 close(lis_sock);
45 lis_sock = -1;
46 return -1;
47 }
49 return 0;
50 }
52 void srv_shutdown(void)
53 {
54 int i, sz = dynarr_size(csock);
55 for(i=0; i<sz; i++) {
56 close(csock[i]);
57 }
58 dynarr_free(csock);
59 csock = 0;
60 lis_sock = -1;
61 max_socket = -1;
62 }
64 int srv_num_sockets(void)
65 {
66 return dynarr_size(csock);
67 }
69 int *srv_sockets(void)
70 {
71 return csock;
72 }
74 int srv_max_socket(void)
75 {
76 return max_socket;
77 }
79 int srv_handle(int s)
80 {
81 static char buf[1024];
82 int sz;
84 if(s == lis_sock) {
85 /* incoming connection */
86 struct sockaddr_in addr;
87 int addr_size;
89 if((s = accept(lis_sock, (struct sockaddr*)&addr, (int*)&addr_size)) == -1) {
90 fprintf(stderr, "%s: failed to accept incoming connection\n", __func__);
91 return -1;
92 }
93 printf("%s: incoming connection from %s:%d\n", __func__,
94 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
95 csock = dynarr_push(csock, &s);
96 assert(csock);
97 return 0;
98 }
100 /* handle client */
101 while((sz = read(s, buf, sizeof buf - 1)) > 0) {
102 printf("%s: got data: %s\n", __func__, buf);
103 }
104 if(sz < 0 && errno != EAGAIN) {
105 /* client closed connection probably */
106 int i, num_clients = dynarr_size(csock);
107 printf("%s: removing client\n", __func__);
108 close(s);
109 for(i=0; i<num_clients; i++) {
110 if(csock[i] == s) {
111 csock[i] = csock[num_clients - 1];
112 csock = dynarr_pop(csock);
113 break;
114 }
115 }
116 assert(i < num_clients);
117 }
118 return 0;
119 }
121 void srv_send_frame(unsigned char *frame, int xsz, int ysz)
122 {
123 }